创建新文档

您的文档标题(将显示为 H1)
URL 友好名称(无空格,使用连字符)
创建文档的路径(可选,使用正斜杠创建子目录)

移动/重命名文档

文档的当前位置
文档的新路径(包括别名)
这只会更改文档的路径,不会修改文档的标题(H1 标题)。

删除文档

您确定要删除此文档吗?此操作无法撤销。

警告:如果这是一个文件夹,包括子文件夹和文档在内的所有内容将被删除。

Message

Message content goes here.

Confirm Action

Are you sure?

附件

允许的文件类型:jpg, jpeg, png, gif, svg, webp, txt, log, csv, sfd, zip, pdf, docx, xlsx, pptx, mp4(最大:100MB)

文档文件

正在加载附件...

文档历史

以前的版本

Loading versions...

预览

选择要预览的版本

Wiki 设置

用户界面语言
每个文档保留的版本数量。设置为0以禁用版本控制。
上传文件的最大允许大小(MB)。

用户管理

添加新用户

留空以保持当前密码
拥有这些组的用户可以访问受限部分。

为您的Wiki部分定义基于路径的访问规则。规则按顺序评估。首次匹配生效。

活动规则

从ZIP归档文件导入Markdown文件。文件将被处理并存储在适当的文档结构中。ZIP中的目录结构(类别/子类别)将在wiki中保留。

上传包含要导入的Markdown(.md)文件的ZIP归档(压缩包)。

创建和管理您的 Wiki 数据备份。备份包括所有文档、图像和配置文件。

可用备份

正在加载备份...

添加/编辑访问规则

已选择: /

添加列

BUG反馈 6.15

问题1:
状态:已修复 验收通过
现象:每次领取邮件战力都会显示上涨ui(是否是哪里加成掉了 恢复回来了)
预期:邮件和战力无直接关系
截图:
修复说明:邮件附件领取本身只应增加金币、金砖、道具、月卡时间、勋章等资源,但服务端 mail_claimattachment / mail_claimallattachment 领取成功后原先返回 role: getOrCreateRole(roleId) 全量角色。该全量角色会携带 power/heroes,并且 getOrCreateRole 会触发战力重新计算/漂移校正;客户端全局同步层会合并响应里的 role.powerLordModuleSyncRoleBefore 发现 power 变大后弹出战力上涨 UI。服务端已改为领取邮件只返回本次附件实际影响的资源增量 role(如 golddiamonditemscardTimemedallionStorage),不再走全量角色构造,不返回 power/heroes,避免邮件领取成为战力刷新触发点。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./entry/mail/wsentry -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestMail|TestMailClaim|TestRootEntryInterfaces' -count=1
人工测试建议:准备一封普通资源附件邮件和一封道具/月卡/勋章附件邮件,分别单封领取和一键领取;确认资源到账、邮件状态变为已领取、奖励弹窗正常;领取过程中不应出现战力上涨 UI。再打开武将/主公/阵容等真正会改变战力的功能,确认战力上涨 UI 仍按原功能正常出现。

问题2:
状态:已修复 验收通过
现象:给别人发私信 邮件内没有信息 无法收到
预期;游戏内发送私信 别人可以正常收到
截图:


修复说明:客户端“发送私信”实际发 system_sendmail,请求体只有 roleIdcontent;服务端原先只注册了 mail_send 且复用了后台邮件校验,要求 title 必填,导致玩家私信不入库。服务端已把 system_sendmail 绑定到邮件发送处理器,并新增玩家私信专用归一化:标题固定为“私信”、分类固定为客户端“日常邮件”分类 4、发件人取当前 WS 登录角色,忽略抓包传入的 fromId/fromName/category/attachments/expireDays,避免伪造系统邮件或附件邮件。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./entry/mail/wsentry ./entry/account/wsentry -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestMailSendHandler|TestRegisterAccountAndMailHandlers|TestRootEntryInterfaces|TestMail' -count=1
人工测试建议:A 玩家从 B 的玩家详情点击“发送私信”,输入 1-100 字内容发送;B 打开邮件系统“日常邮件”,应看到一封来自 A 的私信,内容正确、无附件;A 给自己发私信应失败;抓包伪造 attachmentsfromIdcategory=0/5 后发送,B 收到的仍应是无附件的日常私信,发件人仍为 A。

问题3:
状态:已修复 验收通过
现象:好有无法成功删除 刷新后还是在列表内
预期:删除好友可以正常删除
截图:



修复说明:客户端发送的 friend_remove / friend_batchremove 服务端原先未注册、未实现,刷新时仍读取旧 friendList;服务端已补齐单个/批量删除 handler,双向更新双方 friendList,并清理双方赠送/领取状态。空好友列表不再返回模拟好友,避免删除最后一个好友后刷新又出现假好友。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./domains/social/friend ./entry/social/friendentry ./entry/account/wsentry -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestRegisterSocialHandlers|TestRootEntryInterfaces|TestBuildFriend|TestFriend' -count=1
人工测试建议:添加两个真实好友,分别从玩家详情点“删除好友”和好友列表批量管理删除;删除后立即刷新好友页、重登,再确认被删玩家不再出现,双方都不再互为好友;删除最后一个好友后列表应为空,不应出现“模拟好友”。

问题4:
状态:已修复 验收通过
备注:还是会刷新重置 无限领取
现象:珍宝阁每日好礼珍福利领取过后再去领取主页挂机奖励(洗一次鱼灵淬炼,打一次竞技场等) 珍品福利就会刷新可以重新下领取 可以无限刷
预期:根据时间倒计时 规定时间内只能领取一次 不会存在因为任何外在因素导致刷新
截图:
修复说明:客户端珍宝阁每日好礼是否可领只看 collection_goodslist.storeInfo.freeRewardTime,领取成功包里的 storeInfo 不会被页面直接落本地;服务端原免费领取用进程内锁加整角色保存,跨实例/旧角色快照或后续挂机、淬炼、竞技场等全量保存路径存在把领取状态读成旧值的风险。现服务端把免费领取迁到 internal/activityx,领取前写入 roleId + 当日零点 + packId 幂等流水,重复包/跨实例并发会被服务端拒绝;奖励、activityRecord.collectionStore.freeRewardTime 和免费包购买记录合并到一次 RolePatch 字段补丁提交。collection_goodslist 读取时也叠加当天幂等流水,防止旧角色状态把 UI 刷回可领。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/activityx -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestClaimCollectionFreeReward|TestBuildCollectionStoreInfo|TestRootEntryInterfaces|TestRegisterAccountAndMailHandlers|TestRegisterAccountAndActivityHandlers' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/rolecachex -run 'TestRoleStore_ReplacePreservesCollectionStoreClaimTime' -count=1
人工测试建议:当天首次进入珍宝阁-每日好礼领取“珍品福利”,确认奖励到账且按钮变已领取;随后分别领取挂机奖励、洗一次鱼灵/装备淬炼、打一场竞技场,再回珍宝阁并刷新,预期仍显示已领取且倒计时不重置为可领;抓取 collection_claimfreereward 包同日重复发送,预期返回“今日已领取”,资源、道具和 freeRewardTime 不再增加;次日 0 点后再验证可重新领取一次。

问题5:
状态:已修复 验收通过
现象:部份玩家可以通过第三方辅助抓包 一直无限从咸王梦境第一关到200关 无线刷取资源
预期:杜绝利用辅助无限刷取咸王梦境资源 无法重复攻打咸王梦境
截图:
修复说明:服务端 fight_startdungeon 改为按服务端当前层怪物校验 monsterId,旧层/旧怪物抓包会直接拒绝且不进入 battle worker;奖励与梦境进度合并到同一次 RolePatch 提交,并按角色串行化结算,避免重复包利用中间状态刷奖励。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/gameplay/dungeonx -count=1
人工测试建议:正常进入咸王梦境打一层,确认胜利后只推进一层且奖励到账;抓取第一层 fight_startdungeon 包,在进入第二层后重复发送旧包,预期返回“怪物状态已变化,请刷新梦境”,梦境层数和资源不增加;连续快速点击开战,预期不会重复发放同一层奖励。

问题6:
状态:已修复 验收通过
现象:游戏内积天好礼会出现重置天数 从第一天开始领取的情况
预期:每天充值大于等于6元就计入几天好礼(代金卷和微信支付宝购买礼包都计入) 每天0点刷新 例如:连续3天充值6元 那么可以连续取3天 第四天没冲 第五天冲了那么就可以领取第四天的奖励 不会因为断充重置天数
截图:
修复说明:客户端积天好礼页面不计算连续/断充逻辑,只读取服务端 activity.totalChargeDay 判断达到第几天,读取 ROLE.addUpCharge 判断每档是否已领。服务端原 UpdateChargeDayStreakOnRecharge 只有昨天连续充值才累计,断充后会把 chargeDayStreak 重置为 1,并清空已领取 addUpCharge,导致第 4 天未充值、第 5 天再充值时又从第 1 天开始。现已改为“同一天只计一次,跨天首次达标充值在历史累计基础上 +1,断充不重置、不清已领取记录”。新支付订单路径同时按 paidCent >= 600 才计入积天;代金券/礼包等非真实充值订单仍计入积天但不加真实充值/VIP;离线动态礼包发放也补上 price >= 6 时计天,避免后台/离线发货漏计。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/chargeutil ./internal/payment ./domains/activity/claim -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestActivityBridge_ChargeClaimAddUp|TestRootEntryInterfaces|TestBuildActivity|TestActivity' -count=1
人工测试建议:同一账号连续 3 天每天充值或购买 >=6 元礼包,确认可领取 1/2/3 天奖励;第 4 天不充值,第 5 天再充值 >=6 元后打开积天好礼,预期显示累计 4 天且只新增第 4 天可领,已领的 1/2/3 天仍为已领取;同一天多次充值只增加 1 天;购买 1 元/5 元礼包不增加积天;代金券购买、微信/支付宝购买 >=6 元礼包都应增加 1 天。

问题7:
状态:已修复 验收通过
现象:周活动内招募活动 宝箱活动 白玉达标 不管做多少轮只会发一轮奖励
预期:做满几轮发放几次奖励 最大为设置的轮数
截图:


修复说明:客户端周活动页面只展示服务端 activity.myTotalInfo 的当前轮数、当前进度和 complete,普通档位奖励是否多轮发放完全由服务端进度推进时的邮件发放决定。服务端原普通周活动达标邮件去重 key 只有 roleId + weekOpenTime + activityId + rewardIndex,没有轮次;第 2/3/4 轮同档位邮件会被误判为重复邮件跳过,但调用方仍把该档位写成已完成当前轮,导致奖励被吃掉。现已把邮件发放链路改为传入当前轮次,去重 key 改为 roleId + weekOpenTime + activityId + round + rewardIndex,并在邮件 custom 中记录 round;第 1 轮保留旧 key/旧内容兼容,避免历史已发第一轮被重复补发。自选大奖领取入口也加了角色级串行锁,角色读取、未领取轮数检查、发奖和领取计数保存处在同一个临界区,防止并发重复封包越过检查。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/activityx -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestWeekAct|TestWeekActivityMailDedupeKeyIncludesRoleWeekAndReward|TestMonthActivityMailDedupeKeyIncludesRoleMonthTaskAndConf|TestRegisterAccountAndActivityHandlers|TestRootEntryInterfaces' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./domains/activity/read -run 'TestBuildWeekActivities|TestBuildWeekTotalInfo' -count=1
人工测试建议:在测试服分别把累计招募、累计开宝箱、白玉消耗推进到第 2 轮和最后一轮;每轮每个普通档位都应收到一封对应“第 N 轮/档位”的单周活动奖励邮件,重复触发同一档位不应多发;活动页面刷新后“当前奖励轮数”和进度正确。对有“自选大奖”的招募/宝箱,完成多轮后一次选择多份奖励应按未领取轮数发放,再重复发送同一领取包应被拒绝或不再增加道具。

问题8:
状态:已修复 验收通过
现象:游戏好友内显示的好友状态显示不对
预期:正常显示好友的在线状态和离线时长
截图:
根因:客户端好友页只展示服务端 friend_list 返回的 isOnline,离线文案使用服务端 lastOnline 计算;服务端原来用持久化字段 lastOnlineAt 距当前 5 分钟内来推断 isOnline,没有读取真实 WebSocket/Redis 在线表,导致刚下线 5 分钟内仍显示在线、在线超过 5 分钟反而显示离线。同时断线清理没有持久化最后离线时间,离线时长可能停留在创建/旧登录时间。
修复:服务端好友列表改为显式注入实时在线判定,主路径使用现有 IsPlayerOnlineInCluster(本 Pod WS 映射 + 跨 Pod Redis 在线 key),不再从 lastOnlineAt 推断在线;断线 unregister 仅在当前连接仍是该角色有效映射时字段化写入 lastOnlineAt,避免旧连接 cleanup 覆盖顶号后的新连接状态。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./domains/social/friend ./entry/social/friendentry -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestFriend|TestRootEntryInterfaces' -count=1
人工测试建议:准备 A/B 两个互为好友账号。B 登录后保持在线超过 5 分钟,A 打开“游戏好友”应持续显示 B 在线;B 正常断开后,A 刷新好友列表应显示离线且离线时长从刚刚/分钟级开始递增;B 被顶号重连时,旧连接 cleanup 不应把新连接刷成离线;跨 Pod/多容器环境再验证好友在线状态仍能通过 Redis 在线 key 正确显示。

问题9:
状态:已修复 验收通过
现象:游戏内使用金砖购买黄金鱼竿 招募等 扣除金砖异常 只扣除一半
预期:游戏内购买所有物品都正确扣除对应资源
截图:


根因:黄金鱼竿不足时客户端打开通用购买弹窗,按服务端/客户端一致配置 ItemConf[1012].price=600 展示价格,x50 显示 30000 金砖,并只向服务端发送 system_buyitem {itemId,buyNum};服务端 SystemBuyItemFieldized 却把 1012 黄金鱼竿单价硬编码为 300,导致实际只扣 15000,截图中 59.99 万到 58.49 万正好对应这个错误。可购买道具价格还存在旧硬编码,且旧逻辑默认单价为 1,有改包购买未明确支持道具的风险。
修复:服务端 system_buyitem 改为先校验 itemId 是否在允许购买列表内,再优先读取服务端配置 ItemConf.price 作为权威单价,读不到时才使用兼容 fallback;黄金鱼竿 fallback 也修正为 600。客户端仍不传价格,避免改包低价购买;非允许列表内的正价道具会直接拒绝,不扩大购买面。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/systemx -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestRegisterAccountAndActivityHandlers|TestRootEntryInterfaces' -count=1
人工测试建议:在测试服准备 60000+ 金砖且黄金鱼竿不足的账号,购买黄金鱼竿 x50,应从 60000 扣到 30000,到账 50 个黄金鱼竿;再购买招募令、普通鱼竿、梦魇晶石、竞技券各一次,扣费应分别等于服务端 ItemConf.price * buyNum。使用抓包/改包把 itemId 改成非允许列表但有 price 的道具,应返回失败且不扣砖、不加道具;重复发送同一购买包只能按每次完整价格扣费,不能半价或 1 金砖购买。

问题10:
状态:已修复 验收通过
现象:黑市内购买竞技场门票 实际到账现在是扳手
预期:买的是什么到账就是什么
截图:

根因:客户端黑市商品用 GoodsConf/服务端 goodsList 合并后的商品配置展示,并在购买时只发送 StoreService.buy {goodsId},不会也不应由客户端传奖励物品;服务端 GetBlackMarketGoodsConf 读取 config_ap1.GoodsConf[13] 时,配置奖励是竞技券 itemId=1007,value=10,但旧代码对 goodsId 9/13 做了硬编码覆盖,把奖励强制改成扳手 itemId=1026,value=300。因此商品展示/期望是竞技券,store_buy 实际写入和 reward 回包却是扳手。历史日志中未检索到对应 store_buy/system_store_buy 购买记录,本问题为确定性服务端配置解析覆盖问题。
修复:删除 goodsId 9/13 的服务端奖励覆盖,GetBlackMarketGoodsConf 对已存在的服务端 GoodsConf 以配置为准;仅在配置缺失或无效时才走 legacy IDManager fallback。购买仍按服务端 goodsId 读取奖励、价格、货币、限购和折扣,不接受客户端传 reward,避免改包刷任意物品。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/systemx -run 'TestGetBlackMarketGoodsConf_UsesConfiguredGoodsRewards|TestStoreBuyFieldized_Goods13RewardsConfiguredArenaTicket' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/systemx -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/commerce/storex -count=1
人工测试建议:在测试服刷新/打开黑市,购买竞技券/门票商品,应扣除该商品显示的金砖价格并到账竞技券 1007 对应数量,toast 和背包增量均不能出现扳手 1026;再购买扳手商品,应只到账扳手。抓包重复发送同一 goodsId 只能按每日限购和完整价格执行,改包增加 itemId/reward/value 字段不应影响服务端发奖。

问题11:
状态:已修复 待正式服验收
现象:对战房间 高级对站房开启后 只有房主可以看到正常对战画面 其余人看不到 对战画面卡死
预期:所有人都可以正常观看对战
截图:

根因:高级对战房 pkroom_startbattle 只在服务端生成一次带 battleDatapkroom_fightnotify 推送;pkroom_startbattle 响应、pkroom_getroominfopkroom_getfightroomdetail 都只有 roomInfo。客户端只有收到带 battleDataPKRoom_FightNotify 才会触发真实战斗入口;非房主/观战者如果错过这次瞬时 notify,或战斗中重新进房/点“进入观战”,客户端会用空 PKRoom_FightNotify 本地构造战斗 UI,表现为停在观战/房间层或画面卡死。本地历史服务端日志缺少可关联的 pkroom_startbattle/pkroom_fightnotify 记录,client_track 也没有 6-15 可用 trace;本问题通过截图、客户端入口和服务端协议链路复现为确定性契约缺口。
修复:服务端在 pkroom_startbattle 生成权威 fightNotifyPayload 后,将当前战斗 notify 作为房间运行态快照保存;pkroom_getinfopkroom_getroominfopkroom_getfightroominfopkroom_getfightroomdetailpkroom_join 在房间仍处于活跃战斗时,会给当前在线角色补发同一份 pkroom_fightnotify。补发仍由服务端当前房间状态和战斗快照生成,不接受客户端传入 battleData;并限制为房间成员/参赛者,或房间规则允许观战时才补发,避免改包拿 roomId 读取私房战斗数据。战斗结算和重新开轮会清掉运行态快照,避免旧战斗重复补发。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestPKRuntimeRoom_CurrentFightNotifyPayload' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestPKRuntimeRoom_CurrentFightNotifyPayload|TestBuildPKFightNotifyPayloadForViewer|TestBuildPKFightNotify_BestOfThree|TestPKRoomStartBattleHandler|TestPKRoomRoundAgainHandler' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestBuildRoomInfo|TestNormalizePKFightRoomInfoSides|TestApplyPKRoomBattleOutcome' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestRegisterAccountAndActivityHandlers|TestRootEntryInterfaces' -count=1
人工测试建议:用 2 个以上账号创建高级对战房,所有成员准备后由房主开战,房主、非房主、观战席都应进入同一场实时战斗;让非房主在开战瞬间断线/切后台后重进房间,再点进入观战,应收到补发的当前战斗并正常播放。再用未加入房间账号抓包调用私房 pkroom_getroominfo/getfightroomdetail,如果房间未允许观战,不应收到 pkroom_fightnotify 或任何 battleData;战斗结束后再次进房不能补发上一场旧战斗。

问题12:
状态:已修复 待正式服验收
现象:开启一句高级对战房间不扣除对战房卡
预期:每次成功开启一局 房主都会消耗一张对战房卡
截图:

根因:客户端高级房创建弹窗和房间内“下一轮”按钮都只按 RoomConstant.createRoomConsume={type:3,itemId:1028,value:1} 做本地资源校验与展示,请求 pkroom_create / pkroom_roundagain 不携带也不应携带扣费字段;服务端这两个入口原先只创建房间或重置下一轮,没有读取服务端配置、校验房主背包、扣减 items.1028.quantity,也没有把新余额通过 role/roleInfo.items 同步给客户端。历史日志目录缺少 6 月 15 日可关联的 pkroom_* trace,本问题通过截图规则、客户端协议和服务端入口代码确认为确定性服务端漏扣。
修复:服务端新增高级房卡消耗公共逻辑,仅对高级房 roomType=1 生效,服务端从 RoomConstant.createRoomConsume 读取并限制为高级房卡 1028,配置缺失时使用安全默认 1028 x1pkroom_create 在保存房间前扣卡,房卡不足直接拒绝且不创建房间;pkroom_roundagain 在状态重置前扣卡,失败不改变房间状态。扣减使用 RoleFieldStore.ApplyPatchitems.1028.quantity 做原子 -1,由 RoleStore 拒绝负数,避免并发/重复封包用一张房卡创建多间高级房;成功回包带 roleroleInfoitems.1028.quantity 增量,客户端背包/按钮数量可立即刷新。pkroom_startbattle 不扣卡,避免同一轮多局开战被重复扣费。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestPKRoom(Create|RoundAgain)Handler_AdvanceRoom' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test -race . -run 'TestPKRoomCreateHandler_AdvanceRoomConcurrentCreateConsumesOneCardOnce' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestPKRoom(Create|RoundAgain|StartBattle)Handler|TestPKRuntimeRoom_CurrentFightNotifyPayload|TestBuildPKFightNotifyPayloadForViewer|TestBuildPKFightNotify_BestOfThree|TestBuildRoomInfo|TestNormalizePKFightRoomInfoSides|TestApplyPKRoomBattleOutcome' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/rolecachex -run 'TestRoleStore_ApplyPatchRejectsNegativeItemQuantity' -count=1
人工测试建议:准备房主账号高级房卡 1028 数量为 1,创建高级房成功后房卡应变 0、房间创建成功、底部房卡数量刷新;再尝试创建高级房应提示房卡不足且不生成新房间。准备房主账号房卡数量为 2,创建高级房扣到 1,打完一轮进入结算后点“开启下一轮”应扣到 0 并正常重置下一轮;房卡为 0 时点下一轮应失败且房间仍停留在结算态。并发/抓包重复发送多个 pkroom_create 高级房创建包时,只有一个成功,其余失败,最终只扣 1 张且只生成 1 个高级房;普通房/匹配房创建和同一轮内 pkroom_startbattle 不应扣高级房卡。

问题13:
状态:已修复 待正式服验收
现象:十殿队伍聊天内可以看到别的队伍的聊天
预期:只能看到本队伍的聊天信息
截图:
根因:客户端十殿聊天入口打开的是通用聊天模块的“队伍”频道,只发送 system_sendchatmessage/system_getchatmessagechannel=skyMatchTeam(8),不会携带也不应信任客户端传入的 teamId/roomId;聊天面板按服务端返回/推送的 channel 直接展示。服务端 chatCanDeliverToClient 原来只过滤俱乐部、好友、PK 房间等频道,skyMatchTeam(8) 没有专门分支,落到默认 return true,导致十殿队伍聊天被广播给其它队伍在线玩家。本地 6 月 15 日服务端日志和 client_track 没有可关联的聊天 trace/文本记录,本问题通过截图、客户端协议和服务端广播路径确认为确定性服务端过滤缺口。
修复:服务端新增 skyMatchTeam(8) 投递过滤,发送方和接收方必须都在服务端 matchteamRT.roleTeam 中且 teamId 完全一致才投递;未组队角色抓包发送 channel=8 会被服务端拒绝并提示“还未加入队伍”。过滤只使用服务端运行态队伍归属,不接受客户端传入 teamId,避免改包伪造队伍或跨队伍刷频道;同时只收紧 channel 8,不改天空/其它公共频道,避免误伤正常广播。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestChatCanDeliverToClient|TestSystemSendChatMessageHandler_.*SkyMatchTeam|TestSystemGetChatMessageHandler_ReturnsRequestedChannels' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/app/wsruntime ./domains/core/chat -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestChatCanDeliverToClient|TestSystemSendChatMessageHandler_.*SkyMatchTeam|TestSystemGetChatMessageHandler_ReturnsRequestedChannels|TestRootEntryInterfaces' -count=1
人工测试建议:准备两支不同十殿队伍 A/B,A 队成员在“队伍”频道发言时,只有 A 队其它成员能看到,B 队成员和未组队账号都不能看到;B 队发言同理。未组队账号抓包发送 system_sendchatmessage channel=8,预期返回“还未加入队伍”且不广播。再回归俱乐部聊天、普通天空聊天和 PK 房间聊天,确认原有可见范围不变;如果仍复现,抓取客户端 system_sendchatmessage 请求体,重点确认实际 channel 是否为 8 而不是其它公共频道。

问题14:
状态:已修复 待正式服验收
现象:十殿通过十殿8后 获取8组入梦铃 但是只能抽奖4次 且奖励不到账
预期:每5个入梦铃可以抽奖一次 奖励正常到账
截图:


根因:客户端普通十殿混沌罗盘不从 ROLE.items[1037] 计算可抽次数,只读取服务端 weekAward.turntableLeftCnt;“领取次数”按钮请求 nightmare_claimturnrewardtimes,由服务端按 nightmareWeek.bookScore - turnRewardTime 每 5 点兑换 1 次。服务端通关进度原来用 NightMareMonster.bossIntegral/newBossIntegralbookScore,当前优先配置 config1 中 1-8 殿积分合计只有 1+1+1+2+3+4+4+4=20,所以只能兑换 20/5=4 次;但同一批 1-8 殿周奖励配置是每殿 入梦铃(1037) x5,合计 40 个,按预期应兑换 8 次。另一个问题是 nightmare_clickturntable 先扣 turntableLeftCnt,再单独调用奖励发放,且回包没有 role/roleInfo.items 增量;客户端抽奖成功后只更新 nightMare/weekAward 并用 reward 弹窗展示,不会刷新全局背包,所以在线表现为奖励不到账。本地 6 月 15 日服务端日志和 client_track 没有可关联的 nightmare_* trace,本问题通过截图、客户端协议、服务端入口和配置链路确认为确定性服务端口径/同步缺口。
修复:服务端 nightmareBossBookScore 优先从当前层 weekReward 中的入梦铃 1037 数量计算罗盘进度,配置为每层 1037 x5 时每层计 5 点,1-8 殿合计 40 点,可兑换 8 次;只有没有入梦铃周奖励的旧配置才回退到 newBossIntegral/bossIntegralnightmare_clickturntable 改为一次 RolePatch 同时扣 nightmareWeek.turntableLeftCnt 并发放抽奖奖励,失败则整体失败,不再出现扣次数和发奖分离;成功回包补 role/roleInfo 的金币、金砖、道具余额增量,客户端通用同步根可以刷新背包/资源。抽奖请求仍不接收客户端传入奖励或次数,奖励只从服务端 CompassReward 随机,避免改包指定奖励或伪造次数。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestClaimNightmareTurnRewardTimes_EightBellGroupsGrantEightChances|TestClickNightmareTurntable_AppliesRewardAndReturnsRoleDelta' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestClaimNightmare|TestClickNightmare|TestNightmare|TestApplyNightmare|TestRootEntryInterfaces' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./domains/pve/nightmare -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/rolecachex -run 'TestRoleStore_ApplyPatchRejectsNegativeItemQuantity|TestRoleStore_ApplyPatchFastPaths' -count=1
人工测试建议:测试服清理某账号本周十殿罗盘状态后通关到十殿 8,领取 1-8 殿罗盘印记奖励,界面应显示获得 8 组 入梦铃 x5;点击领取寻宝次数后,剩余寻宝次数应增加到 8,进度从 40/5 归零或扣到已兑换状态。连续抽 8 次,预期每次扣 1 次并弹出 CompassReward 对应奖励,背包/资源余额立即增加;第 9 次应提示次数不足且不发奖。抓包重复发送 nightmare_clickturntable,只能在服务端剩余次数大于 0 时按每包 1 次消耗并发服务端随机奖励,不能指定奖励、不能次数为 0 继续发奖。

问题15:
状态:已修复 待正式服验收
现象:十殿内解锁面具获取的彩玉白玉特权不生效
预期:彩玉白玉特权正常生效 根据次数 每周前几次洗练不扣除资源
截图;

根因:截图对应装备“淬炼”面板,客户端并不在 equipment_quench 请求里传免费次数或扣费金额,只从 ROLE.privilege 聚合 PrivilegeConf.benefit.type,再用 ROLE.statistics/statisticsTime 计算本周已使用次数;按钮显示的 0(20/20) 和彩玉锁定免费次数都来自这套通用特权字段。服务端原来有两处链路断开:nightmare_claimcharm 领取面具时只写 nightmareCharm.charmData/charmGift,没有把面具 id 同步到通用 role.privilege,回包也没有 role.privilege 增量;装备洗练 equipmentx.QuenchFieldized 又只读取 items.1022.quantity/items.1023.quantity,白玉不足 100 直接拒绝,并固定扣 items.1022=-100items.1023=-锁定槽成本,没有读取/消费服务端的每周免费次数。因此 UI 可显示面具权益,但服务端扣费完全不生效。本地 2026-06-15 服务端结构化日志缺失,client_track-2026-06-15.log 只有 4 条无 role/trace/cmd 的 c_error,无法关联线上 trace;本问题通过截图、客户端读字段、服务端 handler/扣费入口和配置链路确认。
修复:nightmare_claimcharm 单个领取和一键领取现在会按已领取的 charmId 校验 PrivilegeConf,写入 role.privilege.<charmId>,并在回包 role/rawData.role/data.role.privilege 返回增量,客户端通用同步根可立即刷新权益;nightmare_getroleinfo 增加旧数据读修复,已有 nightmareCharm.charmData 但缺 role.privilege 的角色会自动补齐并推送 syncresp role.privilegeequipment_quench 服务端新增配置驱动的免费次数计算:读取 PrivilegeConfrole.privilegestatistics/statisticsTime,对同一 benefit.type 按客户端规则取最大值;本周普通白玉免费使用 equip:today:quench:cnt,彩玉锁定免费使用 equip:today:quench:lock:cnt,跨周按 GMT+8 ISO 周重置。扣费 patch 中只写服务端计算出的实际扣费和统计增量,免费时不扣 1022/1023,免费用尽后恢复扣费;请求仍不接收客户端传入的免费次数、奖励或扣费金额,重复封包只能按服务端剩余免费次数和材料余额逐次处理,不能通过改包刷免费次数。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./domains/pve/nightmare -run 'TestHandleClaimCharmPersistsAndReturnsClientFields|TestHandleClaimCharmClaimAllPersistsUnclaimedGifts' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/gameplay/equipmentx -run 'TestQuenchFieldized_UsesWeeklyMaskPrivilegeWithoutConsumingJade|TestQuenchFieldized_ConsumesJadeAfterWeeklyMaskPrivilegeUsed|TestQuenchFieldized_ResetsWeeklyMaskPrivilegeAcrossWeek' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./domains/pve/nightmare ./internal/gameplay/equipmentx -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestRootEntryInterfaces|TestHandleClaimCharm|TestQuenchFieldized' -count=1
人工测试建议:测试服准备一个账号,领取/解锁白玉面具特权和彩玉锁定面具特权后无需重登,打开装备淬炼面板应显示白玉 0(剩余/总数) 和锁定彩玉免费标识;在白玉为 0、彩玉为 0 的情况下,本周剩余免费次数大于 0 时执行一次普通洗练和一次带锁定槽洗练,预期成功且 1022/1023 不减少,剩余免费次数各减 1。连续洗练到白玉/彩玉免费次数耗尽后,再次洗练应恢复扣除 1022 和锁定彩玉,资源不足时应被服务端拒绝。把同一个 equipment_quench 包重复发送多次,预期每包最多消耗 1 次白玉免费和 1 次彩玉锁定免费,超过本周次数后必须扣材料或失败;跨周后首次洗练应重新可用免费次数。老号只要已有十殿面具 charmData,进入十殿角色信息页后应自动补齐 ROLE.privilege,再进入淬炼页权益应生效。

问题16:
状态:已修复 待时间到验证
现象:竞技场内每日奖励和每周赛季奖励未发放至邮箱
预期:每日奖励根据排名每天22.00发放 每周奖励根据排名每周日22.00发放
截图:


根因:客户端竞技场奖励页只是展示 ArenaGift 的“本组排名”奖励,没有主动领取入口,预期由服务端定时发邮箱;服务端 snapshotArenaRewards 结算时却把全服全局 rank 写进奖励快照,settleArenaRewards 再用这个全局 rank 匹配 ArenaGift,导致大量本组有奖励的玩家因为全局 rank 超出档位被跳过。本地日志可见 2026-06-08 每日奖励只发 sent=50 skipped=4490。赛季奖励还存在配置 type=15(称号/medallion)但竞技场邮件附件转换只支持 1/2/3/7,会让对应赛季邮件整封失败。
修复:服务端竞技场奖励快照改为写入客户端可见的本组 rank:动态 100 人分组用 ArenaRankLocalRank,已有周锁定分组用该组内按服务端权威排序的计数;保留服务端定时快照/邮件链路,不新增客户端可调用领奖接口。竞技场邮件附件转换补齐 type=15,复用现有邮件领取的 medallion 存储逻辑。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestArena|TestApplyMailAttachmentReward_AcceptsMedallionType' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/gameplay/rankx ./entry/mail/wsentry -count=1
人工测试建议:测试服准备 2 个以上竞技场分组,让全服全局排名 101 之后但本组排名前 50/100 的账号参与结算;到 22:00 后检查角色 statisticsTime.area:arena:reward:*:snapshot:rank 应为本组排名而不是全局排名,次日/周一 00:01 后应收到竞技场每日/赛季系统邮件。用巅峰段位前 100 的赛季奖励验证包含 type=15,itemId=1004 的邮件可正常生成并领取,领取后称号/medallion 生效。重复触发/重跑发奖任务时,不应出现客户端通过重放普通竞技场包直接领邮件的入口。

问题17:
状态:已修复 待正式服验收
现象:竞技场内存在无限刷分情况
预期:对战限制:只能匹配积分差值≤200 分的对手,无法跨大分差挑人刷新对手:
截图:
根因:客户端 arena_getareatarget 只发送 refresh,开战 fight_startareaarena 只发送可篡改的 targetId;客户端没有也不应承担分差校验。服务端 arena_getareatarget 虽然先按当前积分上下 200 分过滤候选,但过滤结果为空时会回退返回整个竞技场分组,导致大分差目标被下发。更严重的是 fight_startareaarena 在消耗次数/门票后直接信任客户端 targetId 加载目标角色,没有二次校验双方积分差,也接受 roleId+1000..1004 的可预测模拟目标 ID,封包可绕过候选刷新直接指定目标刷分。
修复:服务端统一使用 200 分差限制。候选列表只返回分差范围内的真实玩家,过滤为空不再回退全组;DB 查询异常不再返回可预测模拟目标。fight_startareaarena 在扣免费次数/门票前拒绝模拟目标 ID、自己、空目标、以及双方积分差超过 200 的真实目标,非法封包直接返回未匹配到可挑战对手并记录窄日志,不进入战斗结算。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestArenaGetAreaTarget_GroupCandidatesDoNotFallbackOutOfScoreBand|TestFightStartAreaArena_ValidateTarget' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestArenaGetAreaTarget|TestFightStartAreaArena|TestConsumeArenaBattleCost|TestArenaStartArea' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestArena' -count=1
日志说明:本地没有 2026-06-15 服务端挑战日志;server/logs/today 指向 2026-06-09,server/runtime/logs/client_track/client_track-2026-06-15.log 只有空 role/trace 的 c_error,无法还原当天刷分链路。本次用截图、客户端发包路径、服务端处理链路和回归测试闭环。
人工测试建议:测试服准备两个竞技场账号,A 积分 2905。arena_getareatarget 返回目标积分必须都在 2705-3105;若无符合目标,应提示未匹配到对手且刷新不扣砖。直接封包 fight_startareaarena 指向榜首等超过 200 分差的真实 targetId 应被拒绝,A 的免费次数/门票/积分不变。直接封包 targetId=A.roleId+1000 应被拒绝且不结算。再用 200 分差内真实目标验证正常战斗仍可开始并只消耗一次挑战次数/门票。

问题18:
状态:已修复 待下周验收
现象:竞技场赛季结束后不会晋升场次
预期:竞技场每周日22:00结束赛季 周一会晋升场次
升降级结算规则
入门 / 初级场(每组 50 人)
前 30 名 → 晋级下一段位
末尾 10 名 → 降级
中间 10 名 → 保级原地不动
中级 / 高级场(每组 100 人)
前 30 名 → 晋级
末尾 30 名 → 降级
中间 40 名 → 保级
大师场(每组 200 人)
前 20 名 → 晋级巅峰
末尾 40 名 → 降级高级
其余全部保级
巅峰场(500 服大组)
前 30% 玩家维持巅峰段位
剩余 70% 全部降级大师
巅峰场前 100 名额外计入巅峰王者榜,赛季结算多拿巅峰徽章大奖
截图:
根因:客户端没有本地写段位逻辑,进入竞技场只请求 arena_startarea 并读取服务端返回的 areaArena.phaseInfo[*].level / role.arenaLevel;“保持当前排名可晋级/保级/降级”的文案由客户端 _nextPhaseInfo/_nextPhaseStateArenaRankConf、本组 groupSize/total 和当前排名预测展示。服务端当前只有周日 22:00 赛季奖励快照、周一 00:01 赛季奖励发放,快照只写 statisticsTime.area:arena:reward:week:snapshot:*,发奖只写已发标记,没有任何链路按客户端规则把新段位持久化到 roles.arenaLevel,所以周一进入仍显示旧场次。
修复:服务端新增赛季段位结算,复刻客户端 ArenaRankConf 规则:非巅峰段按配置 group/up/stay/down 计算升/保/降,巅峰按实际本组总人数和 stay 比例保留前段玩家,其余降到大师。周一赛季奖励发放前先对本周快照角色幂等写入 statisticsTime.area:arena:season:level,并在需要时更新 arenaLevel;奖励仍按快照时段位和排名发放,不新增客户端可调用升段接口,也不信任客户端传入排名/段位。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestArenaSeasonNextLevel_FollowsClientPhaseRules' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestArena' -count=1
日志说明:本地缺少 2026-06-14/2026-06-15 服务端 app 日志;现有 2026-06-07/08 日志只能看到赛季奖励快照/发放抢锁和奖励任务,没有任何 arenaLevel 升降级写回日志。本次用截图、客户端展示规则、服务端定时任务/快照/发奖链路和回归测试闭环。
人工测试建议:测试服准备入门场 A,当前排名 74、组人数 100 时客户端应显示可晋级;触发周日 22:00 赛季快照后,周一赛季发奖任务执行应写入 roles.arenaLevel=2statisticsTime.area:arena:season:level=<本次结算stamp>。重启后进入竞技场,arena_startarea 返回 areaArena.level=2、本周 phaseInfo.level=2。重复执行同一结算 stamp 不应再次升/降级。再分别用中级保级/降级、大师晋级巅峰、巅峰 30% 保留和 70% 降级账号做边界验证。

问题19
状态:已修复
现象:俱乐部赛车内改装服务 使用赛车零件改装 不扣除赛车零件 需要退出游戏再进 才会显示扣除
预期:实时刷新显示扣除
截图:

根因:客户端改装服务面板显示零件数量和升级按钮是否足够时读取的是全局 ROLE.getItemQuantity(CarModifiedCost),并通过 SyncItemList 刷新;car_research 成功回调只更新 roleCarInfo 并触发赛车数据刷新。服务端 Research 实际已经按 CarConstantConf.CarModifiedCost=35009 扣除 role.Items["35009"].Quantity、累加 partItemConsumeCnt 并保存角色,但 car_researchresp 只返回 roleCar,没有返回或推送 role.items.35009.quantity,所以在线 ROLE.items 仍是旧值,退出重进全量加载角色后才显示已扣。
修复:服务端在 car_research 成功扣除并保存后,用服务端当前 role.Items 组装最小 role.items.<CarModifiedCost>.quantity 增量;car_researchresp 同时携带 role/roleInfo,并推送最小 syncresp {role:{items:{...}}} 触发客户端 SyncItemList 实时刷新。未新增客户端可传数量字段,不信任客户端余额;失败、资源不足、满级、前置等级不足路径仍直接返回错误,不推扣除同步,不会引入刷封包得资源漏洞。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestBuildCargoRaidResearch|TestCar|TestCargoRaid' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./domains/legion/cargoraid -run 'TestRuntimeResearchUpgradesAndAffectsLimits' -count=1
日志说明:本地没有 2026-06-15 服务端日志目录,server/logs/today 指向 2026-06-09;2026-06-15 的 client_track 只有少量 c_error 且无赛车/roleId/traceId。该问题通过截图、客户端读取链路、服务端 handler/runtime/persistence 链路和回归测试闭环。
人工测试建议:测试服账号准备改装零件 35009,进入“俱乐部赛车-改装服务”,记录顶部数量,例如 19275。点击一次可升级项,若消耗 62,顶部数量应立即变为 19213,升级按钮的足够/不足状态和红点应同步刷新;不退出游戏直接再次打开改装服务仍显示扣后数量。退出重进后数量应与在线扣后数量一致。资源不足时点击应提示不足,数量不变化;快速连续点击只应按服务端成功次数逐次扣除,每次回包/同步后的余额单调减少,不出现客户端本地伪造增加。

问题20:
状态:待复现(已加服务端诊断日志,跳过继续处理)
现象:通行证奖励里 皮肤显示为空白
预期:每期通行证都会有一个皮肤 玩家购买通行证后可正常领取到账
截图:
当前结论:上一次按运行时 SkinConf_extracted.json/skin_book_config.json 缺配置定位不成立,先不再标记已修复。按 /root/xianyu/test-runtime/logs/today 排查,fafa 账号(roleId=791944)打开通行证时只有 role_getroleinfoactivity_get 链路,未看到领取包;客户端和 CDN 暂按无问题处理,继续从服务端首次登录/角色信息/活动信息加载链路复现。已在服务端 role_getroleinfoactivity_get 增加窄诊断日志 [battlepass_diag],记录当前期次、patchKey、服务端配置皮肤、SkinConf/AvatarConf 是否存在、以及 stored/payload/response 的 warOrderActivityInfo,等待下一次复现日志确认是否为服务端首包/活动包少下发或读错期次。
验证:诊断日志代码已编译通过:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./domains/activity/battlepass ./domains/activity/read ./entry/activity/activityentryGOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run '^$'。全量 go test . 存在历史无关失败,暂不作为本问题结论。
人工测试建议:部署含诊断日志的服务端后,用 fafa 或可复现账号重新登录,打开通行证奖励页,不领取奖励;随后在 /root/xianyu/test-runtime/logs/today/app.log 搜索 [battlepass_diag],对比 role_getroleinfoactivity_get 的 currentRound、skinReward、storedAct1、payloadAct1、responseAct1。如果服务端响应已有正确皮肤和期次,再转客户端展示链路;如果响应缺失或期次错误,再按对应服务端读路径继续修复。抓包重复领取仍需由服务端 claim 状态拦截,不能新增客户端可控皮肤 ID 或奖励入口。

问题21:
状态:已修复 待复现验收
现象:灯神挑战 深海挑战内 存在赢了判输的情况(是否和战力不够有关)
预期:赢了永远不会判定输
截图:
根因:客户端普通灯神和深海挑战都走同一个 fight_startgenie,战斗结束弹窗优先读取服务端下发的 battleData.result.isWin,不是顶层 isWin、不是 ROLE、也不是客户端战力重算;如果服务端外部战斗服务返回 battleData.result.isWin=false,但客户端播放过程/本地战斗表现为赢,客户端仍会按服务端 battleData.result.isWin=false 弹失败。服务端灯神结算入口为 compat_ws_bridge.gofight_startgenieresp,核心在 internal/geniex.FightStart/buildGenieBattleDataWithResult。原风险点是服务端过度依赖外部 battle-worker 的失败结果,普通灯神和深海都可能被同一链路影响;未发现“战力不足直接判输”的服务端分支,战力只参与构造双方战斗数据。
修复:服务端已在 battleData.result.isWin 的同一写入链路做胜负复核:外部 battle-worker 判负时,使用 Go 战斗引擎对同一份 battleData 复算,若本地复核为胜则把 battleData.result.isWin 修正为 true,并同步 sponsor/accept 结果;回退战斗结果若出现 isWin=false 但己方剩余 HP 明显大于敌方剩余 HP,也会修正为胜。深海分支还保留 deep loss audit 窄日志,便于后续定位 battle-worker/Go 引擎差异。奖励仍只在服务端最终 isWin=true 后按 genie_rewards/配置发放,客户端不能传奖励或皮肤,重复封包只能按服务端次数和最终胜负结算,不新增刷奖励入口。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/geniex -run 'TestReconcileGenieFallbackWin|TestBuildGenieBattleDataWithResult_VerifiesServiceLossWithLocalWin|TestBuildGenieBattleDataWithResult_AddsFinalTeamHPForServiceWin' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/geniex -count=1
日志说明:/root/xianyu/test-runtime/logs/today 未找到问题截图时段对应的 fight_startgenie/genie_getinfo/genie_sweep 请求,也未命中 本地战斗复核修正外部失败结果/deep loss audit/修正回退胜负 日志;client_track-2026-06-15.log 只有少量无 roleId/traceId 的 c_error,无法还原玩家 trace。本次按截图、客户端胜负读取链路、服务端结算入口和回归测试闭环。
人工测试建议:测试服分别挑战普通灯神和潜入深海,选择一个客户端播放明显胜利的关卡,战斗结束弹窗应为胜利,奖励弹窗和 ROLE.genie/次数同步正常;若复现失败,立刻在 /root/xianyu/test-runtime/logs/today/app.log 搜索 fight_startgenie本地战斗复核修正外部失败结果deep loss audit修正回退胜负,确认 battleId/genieId、battle-worker 结果、本地复核结果和最终 battleData.result.isWin 是否一致。用抓包重复 fight_startgenie 应只按服务端剩余挑战次数逐次消耗,失败复核不能绕过次数,也不能通过改包指定奖励。

问题22:
状态:未处理
现象:鱼灵母协力 在盐场内对战时 存在和人交战击杀一人后 第二次交战 不加怒气
预期:盐场内 每次对战母协力都会为佩戴者增加50怒气
截图:

问题23:
状态:已修复 待复现验收
备注:正式服:账号:facaizzz 时间 9:25
现象:四圣共鸣升级时 战力就会变低
预期:战力不会突然变低
截图:


根因:客户端四圣升级/共鸣成功后不会本地重算总战力,hb_upgradeorderresp/hb_quenchresprole.power 会通过通用 SyncResp 直接覆盖主界面战力。服务端四圣刷新链路先用轻量 ComputeMergedHeroResponse 做单英雄增量计算,再通过 canonicalPowerOrFallback(..., "hb_refresh", partialPower) 把该 partial power 写入战力 coalescer;后续 hb_quench/hb_upgradeorder 再刷新时可能命中这个 coalescer,不跑全量 Getrole 权威战力,导致缺少全量字段依赖的偏低战力被写回 roles.power 并下发。hb_upgradeorder 还没有像淬炼一样写 powerInputVersion/powerVersion,更容易把一次偏低值作为当前战力版本保存。
修复:服务端已禁止 hb_quench/hb_refresh 使用 partial hint/coalescer 快捷战力,HB 相关刷新强制走权威全量战力;hb_upgradeorder 升阶落库时写入 powerInputVersion,随后调用 RefreshMainPower(ctx, roleID, heroID, "hb_upgradeorder", forceNs) 获取权威战力,并把同一个 powerVersionrole.power/roleInfo.power 回包写回。资源、阶数、技能升级、奖励仍全部由服务端按当前角色状态校验和落库,客户端只能传 heroId,重复封包仍受服务端角色操作锁、资源扣减和已有去重窗口约束,不新增刷材料/刷战力入口。
验证:GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/gameplay/hbx -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestHolyBeastOrderAttributeBonus|TestCalculateHeroBonus_AppliesHolyBeastOrderAttr|TestRolePowerReasonAllowsPartialHint' -count=1
日志说明:未找到正式服账号 facaizzz 的原始生产 trace;本地 /root/xianyu/test-runtime/logs/today 有同类四圣链路审计:rolepower.log 在 2026-06-15 09:27 记录 trace_id=100114093-forever888-37-hb_quenchrole.power17311303024 写成 17311039916protocol.log 同时显示连续 hb_quench 成功回包,证明四圣操作后的服务端战力回写链路存在偏低覆盖风险。本次按截图、客户端同步契约、服务端 HB handler/runtime/rolepower 链路和回归测试闭环。
人工测试建议:部署后用可复现账号进入四圣页,记录主界面战力,先连续淬炼到可突破,再点击“共鸣/突破”升阶,返回主界面战力不应突然低于操作前;若属性/阶数提升,战力应持平或按权威公式正常变化。测试时同步查看 /root/xianyu/test-runtime/logs/today/rolepower.log,应看到 hb_upgradeorderhb_quench 走 full/fallback_full 权威刷新,不再用偏低 partial 覆盖。快速重复点击/抓包重复发 hb_upgradeorder 只应成功一次或按服务端资源与去重结果返回,红玉数量、阶数、powerInputVersion/powerVersion 与最终 role.power 保持一致。

问题24:
状态:已修复 待复现验收
现象:使用脚本淬炼鱼灵淬炼后 游戏内一条鱼分化出多条 每一条洗练不同 都可以使用 但是不可以同时上阵
预期:鱼灵不会分化出多条
截图:
根因:客户端鱼灵背包会把 ROLE.heroes[*].artifactId/pearlId、未装备 ROLE.pearlMap[*] 和背包 ROLE.items 合成列表;其中 pearlMap 是按每个 pearlId 独立渲染,同一个 artifactId 出现多个 pearlMap 时就会显示成多条鱼灵,每条读取自己的 slotMap/tmpSlot,所以表现为“一条鱼分化出多条、每条洗练不同”。服务端 pearl_quenchpearlId=0 分支只校验淬炼材料 items.1033、可选英雄存在,然后用当前 pearlMap 最大 key + 1 创建新的 pearlMap.<newID>,没有校验同一个 artifactId 是否已经有鱼珠;已有 pearlId>0 分支也没有校验请求 artifactId 必须等于 pearlMap.<pearlId>.artifactId。脚本重复发 pearl_quench {artifactId:X, pearlId:0} 就能为同一条鱼灵创建多个独立鱼珠载体,客户端按设计全部显示,装备链路又因鱼灵本体数量/装备约束导致不能同时上阵。
修复:服务端 internal/gameplay/pearlx.QuenchFieldized 新增鱼灵唯一性校验:pearlId=0 创建前扫描当前 pearlMap,若已有同 artifactId 的鱼珠则拒绝并记录 pearl_quench reject_duplicate_artifact_createpearlId>0 淬炼前校验存储的 pearl.ArtifactId 必须和请求 artifactId 一致,否则拒绝并记录 pearl_quench reject_artifact_mismatch。非法请求统一返回客户端已有通用文案 参数错误,不暴露可利用细节;拒绝路径不会扣 items.1033,不会写新 pearlMap/tmpSlot,不新增任何客户端可控的鱼灵创建或清理入口。
验证:新增回归测试先红后绿,覆盖重复 artifactId + pearlId=0 不新建、不扣材料,以及已有 pearlId 搭配错误 artifactId 不淬炼、不扣材料。已执行 GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/gameplay/pearlx -run 'TestQuenchFieldized_RejectsDuplicateArtifactCreate|TestQuenchFieldized_RejectsArtifactMismatchForExistingPearl' -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/gameplay/pearlx -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run 'TestShouldCheckPearlQuenchPasswordForState|TestPearl' -count=1
日志说明:/root/xianyu/test-runtime/logs/today/protocol.log 可见 2026-06-15 多个账号连续 pearl_quench 成功回包,例 fafa roleId=151830 在 01:14:36~01:18:23 多次返回 keys=["pearlId","role"]rolepower.log 有同 trace 的 pearl_quench 战力写入。但当前协议日志未记录请求 body,不能从日志直接还原具体 artifactId/pearlId,本次根因以截图、客户端合成规则、服务端 handler/runtime/persistence 链路和红绿测试闭环确认。
人工测试建议:部署后用测试账号准备一条已有鱼珠的鱼灵和足够 1033,正常在客户端点击淬炼应仍可刷新/替换当前 pearlId 词条。用抓包重复发送同一 artifactIdpearlId=0pearl_quench,服务端应返回 code=1,msg=参数错误items.1033.quantity 不减少,pearlMap 不新增同 artifactId 条目,日志出现 reject_duplicate_artifact_create。再用已有 pearlId 搭配另一个 artifactId 发包,应返回参数错误且不改变该鱼珠 tmpSlot/slotMap。重新登录后鱼灵背包同一条鱼不应新增分化条目;历史已产生的重复数据需要按账号另行审计清理,清理前先备份角色 items/heroes/pearlMap/presetTeams

问题25:
状态:已修复 验收通过
现象:宠物精炼词条有爆伤词条
预期 :宠物精炼词条没有爆伤词条
截图:
根因:截图显示宠物“精炼”页红色槽位出现“爆伤 +4.024%”。客户端 PetInfoQuenchDrawer 只遍历 petData.quenches[*].attrs,用 LanguageExt.getAttributeName(attrId)UIHelper.setPetQuenchAttrValue(attrId, attrNum) 展示服务端返回/本地缓存的属性;PetService.quench 请求只带 slotUId/quenches/skipOrange/seed,客户端不能指定新词条 attrId,也没有过滤爆伤的客户端规则。服务端 domains/pet.HandleQuenchrollQuenchWithAttrCounts,再由 internal/gameplay/petprob.RollQuenchAttrIDs/RollQuenchAttrValueserver/config/pet_prob.jsonquenchAttrsquenchAttrValueGroups 抽取词条。源配置里 quenchAttrs 仍包含 attrId=59functional_percent 取值分组也包含 59;而客户端/服务端通用属性枚举中 BattleAttributeKey.CRIT_DMG=59,对应文案就是“爆伤”。因此这是服务端宠物精炼概率池配置错误,不是客户端展示错误,也不是客户端封包能伪造新爆伤词条。
修复:服务端源配置 server/config/pet_prob.json 已从 quenchAttrsfunctional_percent 取值分组移除 attrId=59,后续正常新部署会带上正确源配置,不依赖启动后生成的运行时配置。internal/gameplay/petprob 加载校验新增宠物精炼禁用属性拦截,51/52/59/60 如果出现在 quenchAttrsquenchAttrValueGroups 会直接加载失败,避免后续热更或配置回滚重新把爆伤放回池子。没有新增客户端入参、GM 入口或兜底随机逻辑;客户端重复发 pet_quench 仍只能触发服务端按当前合法池随机,无法通过封包指定词条。
验证:新增回归测试先红后绿,覆盖源配置不含 5959 出现在抽取池或取值组时 LoadFromFile 拒绝加载。已执行 GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/gameplay/petprob -run TestServerPetQuenchAttrPoolExcludesCritDamage -count=1 红灯确认旧配置问题;修复后执行 GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/gameplay/petprob ./domains/pet -count=1 通过;同时 git diff --check -- server/config/pet_prob.json server/internal/gameplay/petprob/config.go server/internal/gameplay/petprob/config_test.go server/domains/pet/service_test.go 通过。
日志说明:/root/xianyu/test-runtime/logs/today 今天未找到 pet_quench resultcmd=pet_quench 或对应 trace,不能复盘某次玩家精炼请求;日志只显示服务启动/重载时加载了 pet_prob。本问题为确定性的服务端配置池错误,已通过截图、客户端展示/发包路径、服务端 handler/runtime/config 链路和红绿测试闭环确认。
人工测试建议:部署后重启或热更配置,使用测试账号进入宠物精炼页,连续精炼/跳过橙色精炼多轮,新增词条不应再出现“爆伤”;查看 /root/xianyu/test-runtime/logs/today/app.log 应能看到 pet_prob 正常加载,若有 pet_quench result ... attrs= 日志,属性摘要不应包含 59。已有历史宠物如果已经洗出爆伤,修复不会静默改玩家存量数据;需要通过再次精炼替换该槽,或按账号单独备份后清理存量 petData.pets[*].quenches 中的 attrId=59

问题26:
状态:已修复 验收通过
现象:黑市购买物品消耗金砖不计入端午消耗活动内金砖消耗,且黑市内购买物品后金砖消耗会变少,退出游戏重新进入后恢复正常
预期:游戏内所有金砖消耗都计入活动内 消耗多少就是多少不会变少
截图:


根因:截图显示端午悬赏 activityRecord.common.2505301.task.5 对应的“累计花费金砖达到 130000”先是 124556/130000,黑市购买后变成 15610/130000,符合在线活动缓存被旧/缺失增量覆盖,重登后从 DB 全量读取恢复。客户端黑市单买只发 StoreService.buy({goodsId}),刷新只发 StoreService.refresh({storeId}),采购清单只发 StoreService.purchase({});成功回调只显式读取 reward/goodsList/refresh 刷奖励弹窗和商品列表,金砖余额依赖通用 role.diamond 合并,端午进度依赖通用 activity.commonActivityInfo 合并,客户端没有本地扣砖或本地累计端午金砖消耗逻辑。服务端单次 store_buy 已在 StoreBuyFieldizeddiamond、递增 activityRecord.common.2505301.task.5、调用周活动金砖消耗统计,并回包 role/roleInfo/activity;但采购清单 store_purchase 内部循环调用 StoreBuyFieldized 后,只把最终 reward/goodsList/refresh/goodsConf 发给客户端,丢掉每次内部购买返回的 role/roleInfo/activity,所以服务端 DB 已累计,在线客户端却收不到本次采购后的金砖余额和端午任务进度。同类缺口还包括黑市 store_refresh 付费刷新:运行版本扣 100 金砖时只刷新商品列表/余额,未写端午 task.5、未调用周活动统计,也未回 activity;本次复查又发现采购清单内部第 2 轮起会调用同一个 store_refreshresp,旧 storebatch.Execute 对内部刷新成功回包只合并 goodsList/refresh,没有合并刷新产生的 role/roleInfo/activity,因此“内部付费刷新扣砖但后续无成功购买”的非批量购买场景仍会在线漏同步。
修复:服务端 internal/gameplay/storebatch.Execute 聚合每次成功购买返回的 role/roleInfo/activity 增量,items 等 map 深合并,diamond/freeDiamond 和端午 task.5 取最后一次服务端绝对值;同时对采购清单内部成功刷新返回的 role/roleInfo/activity 也执行同样聚合,保证即使刷新扣砖后没有买到商品,store_purchase 最外层响应也会带回本次刷新造成的金砖余额和端午进度。store_refresh 付费刷新现在同样把刷新成本写入 activityRecord.common.2505301.task.5,调用周活动金砖消耗统计,并在回包中返回 role/roleInfo/activity.commonActivityInfo.2505301.task.5。所有金额、折扣、刷新成本仍由服务端配置和当前服务端状态计算,客户端只能提交商品/刷新/采购动作,不能提交消耗值或活动进度,不新增刷封包改进度/刷奖励入口。
验证:新增 storebatch 回归测试先红后绿,覆盖采购清单多次内部购买后聚合 role.items/role.diamond/activity.commonActivityInfo.task.5;本次补充 TestExecuteAggregatesRoleAndActivityDeltasFromPaidRefresh,旧代码红测为 result role = <nil>,修复后通过,覆盖采购清单内部付费刷新即使没有成功购买也要聚合 role/roleInfo/activity。新增 TestStoreRefreshResp_PaidRefreshCountsDragonBoatDiamondSpend 覆盖直接 store_refresh 第三次付费刷新扣 100 金砖、持久化端午 task.5、回包 role/roleInfo/activity、上报周活动金砖消耗。已执行 GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test ./internal/gameplay/storebatch ./internal/systemx -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run TestStoreRefreshResp_PaidRefreshCountsDragonBoatDiamondSpend -count=1GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run '^$' -count=1git diff --check -- server/internal/gameplay/storebatch/purchase.go server/internal/gameplay/storebatch/purchase_test.go server/compat_fieldized_bridge.go server/compat_ws_bridge.go server/compat_fieldized_bridge_test.go wiki-docs/bugfan-kui-6-15/document.md
日志说明:/root/xianyu/test-runtime/logs/today/protocol.log 显示 store_buy 回包 keys 包含 activity, role, roleInfo,如 100030429-jiu1314-60-store_buy;同账号 100030429-jiu1314-58-store_purchase 的运行版本回包 keys 只有 code, goodsConf, goodsList, refresh, reward,且 extraPushCount=0,证明采购清单路径没有把内部购买的在线增量下发。/root/xianyu/test-runtime/logs/today/rolestore.log 同时可见 StoreBuyFieldized 连续写 inc:activityRecord.common.2505301.task.5,说明持久层在增长,重登恢复符合在线回包缺失而非 DB 未保存。
人工测试建议:部署后用测试账号打开端午悬赏记录“累计花费金砖”进度,进入黑市先单买一个金砖商品,返回端午页应增加实际折后价且不回退;再配置采购清单购买多个金砖商品,采购完成后不重登直接返回端午页,应显示旧进度 + 本次采购总折后价,顶部金砖余额同步减少。黑市付费刷新到需扣 100 金砖的次数后,点击刷新也应让端午金砖消耗 +100;再把采购清单配置成会跨多轮刷新且后续没有匹配商品/商品售罄的场景,执行采购后即使没有奖励,也应看到顶部金砖扣除刷新费、端午金砖消耗增加对应刷新费。抓包重复 store_purchase 或改客户端传入采购清单价格/刷新次数不应影响服务端价格,服务端只按当前商品配置、折扣、限购、刷新上限和余额逐项结算;售罄或余额不足的购买项不应计入端午进度,只有服务端实际扣除的金砖购买价或刷新费才计入。

问题27:
状态:已处理:关闭小队 待复现验收
现象:盐场内开启小队后 对战不出现在战斗队列里
预期:关闭小队
截图:
根因:截图对应盐场小队战进行中但客户端战斗队列为空。客户端队列不是本地推断小队战状态,而是读取服务端下发的队列数据源:普通军团战读取 battlefield.buildingData[*].battleQueue 并用同 key 查 battlefield.battles/battleList,载具/Payload 队列读取 bf.battleMap + bf.roles[*].battleId + bf.carMap[*].memberMap。只要服务端小队战 relay 分支写入的建筑队列、battle key 或角色 battleId 任一不同步,客户端就会出现“小队战战斗中”但战斗队列为空。当前处理策略按需求改为关闭小队,不继续开放这条有队列同步风险的多人小队链路。
处理:服务端已有稳定关闭开关 teamDisabledserver/config/saltfield_runtime.jsontrueserver/deploy/docker/render-server-config.sh 会从 SALT_FIELD_TEAM_DISABLED 生成该配置,当前 test/prod-* 部署 target 均设置 SALT_FIELD_TEAM_DISABLED=true,不是只改运行时临时配置。handleWarInviteJoinTeam 在创建 teamInvites、写 teamMap/teamIds、启动邀请定时器前检查 saltfieldruntime.Snapshot().TeamDisabled,关闭时返回错误码 3000510 和文案“小队功能暂时关闭”,不修改战场状态,不给客户端留下可通过重复/改包邀请刷出小队的入口。
验证:已执行 GOCACHE=/tmp/go-build GOTMPDIR=/tmp go test . -run TestWarInviteJoinTeamDisabledRejectsWithoutMutationOrTimer -count=1,覆盖关闭小队时 war_invitejointeam 返回 war_invitejointeamresp、错误码 3000510、不创建 teamInvites、不注册邀请 timer。日志 /root/xianyu/test-runtime/logs/today/app.log 已出现多条 handleWarInviteJoinTeam: team disabled reject,例如 2026-06-15 16:43-16:44 多个账号邀请均被服务端拒绝。
人工测试建议:部署后进入盐场,对任意同军团玩家点击邀请组队,应提示“小队功能暂时关闭”,双方不会出现待确认倒计时、小队成员列表或小队战入口;重复点击/抓包发送 war_invitejointeam 只能返回 3000510,不能创建队伍、不能进入小队行军/小队战。重启后再次测试同样应保持关闭,确认不是仅当前运行时内存开关。

附件

正在加载附件...

评论

暂无评论。成为第一个评论者!

搜索结果