乐队活动(操作队列校验+随机种子)
小镇上线的乐队活动本身逻辑并不复杂,和普通的爬塔类活动一样,通过棋盘操作、订单等获得积分,领取相应的奖励,但乐队活动涉及到一个很棘手的需求:积分附着。
随机种子
在点击母体(消耗体力)生成子体时,子体有一定概率携带乐队积分(这个乐队积分分为剪刀石头布三种),所以为了保证前后端生成积分概率一致,采用了自定义的活动随机种子,通过前后端一致的随机种子,保证生成积分一致:

操作队列校验
乐队积分通过合成、出售、拆解、提交订单(bingo、百人、收垃圾、扎气球等活动也算)、吸收等操作会将该子体中的积分提取出来,所以该积分字段一定是附着在棋盘物品item类型上的一个元素,我们命名为bandScoreType(后续为了通用用boardActivityData包了一层)。当添加上这个字段后,操作队列就会出现问题:
一、前端会有一个初始值bandScoreType = 0
1. 如果后端添加初始值bandScoreType = 0,老版本的前端或客户端存储的操作队列数据就会报错(测试过),这里可能要判断前端版本来额外处理;
2. 如果后端不添加初始值,这里就要一个一个去处理该字段;
二、后端进行md5校验是通过ItemCreatorServices类来创建的,不同类型的母体会有不同的结果,而且没有bandScoreType 字段,所以还要拿到后端存储的bandScoreType 来进行挂载来通过md5校验
三、棋盘操作有很多,而且逻辑比较独立。合成/万能合成、拆解、吸收、交换、点击、放入仓库,放入棋盘等,他们的校验的核心逻辑各不相同,分布在不同的函数中,如果将前面两点考虑进去,一个一个处理,那将是一个巨大的工作量。
我给出的解决方案是,除了产出操作用随机种子校验外,其余操作通通不校验bandScoreType 字段:在md5比对以后,拿到后端存储的bandScoreType 来挂载,这样新字段就绕过了操作队列的校验,以后端存储为准。这个解决方案太妙了,大大简化了处理难度

我封装了两个函数,removeBoardActivityData用于去除前端物品携带的活动数据,transferBoardActivityData用于挂载后端存储的活动数据
通过这两个函数基本处理完棋盘操作了,还差一个取出仓库到棋盘

我这里将仓库子体的boardActivityData存储到一个数组中,依次挂载到棋盘物品上
隐患&bug
对于随机种子这里,还是有一定隐患:如果前端操作队列有产出操作没有提交上来之前同步了后端种子,那么提交以后后端种子会被刷新,前端的种子落后于后端,导致概率不一致,所以我和小飞哥商议:前端本地要存储随机种子、同步后端种子时要保证操作队列为空
仓库取出物品到棋盘有隐藏bug:这里不熟悉仓库取出的可以先了解一下代码,我简单讲一下bug场景:两个同itemid的子体存储在仓库warehouseGridId1、warehouseGridId2位置,取出摆放至棋盘gridId1、gridId2,这里怪就怪在他们是没有对应关系的,从代码中你不知道gridId1是对应warehouseGridId1还是warehouseGridId2,如果这两个子体挂载的乐队积分不一致,取出过程就有可能会挂载反。后面询问俊哥得知前端传参数是保证有顺序的,这个bug被排除了