问题现象
玩家自己的武魂幻魂已经激活,但其他玩家查看他的武魂界面时,TargetWuhun_TupuItem_1~6 仍然显示蒙红,表现为幻魂未激活。
客户端界面入口:
\Interface\TargetWuhun\TargetWuhun.lua
关键逻辑在 TargetWuhun_UpdateTupu():
local nUnLocked = CachedTarget:LuaFnGetWHWGInfo(wgID, "UnLocked")
if nUnLocked == 1 then
g_TupuMask[idx]:Hide()
else
g_TupuMask[idx]:Show()
end
也就是说,别人查看目标玩家时,客户端只看 CachedTarget 里的幻魂解锁数据。如果服务端没有把目标玩家的幻魂列表正确同步给客户端,界面就会全部显示未激活。
根因分析
当前客户端 Game.exe 中,GCWuhunWG type=0 的结构是:
uint32 type
int32 target_obj_id
uint32 huanhun_unlock_count
repeated {
ushort id
ushort level
ushort grade
ushort today_count
}
重点是:type=0 后面的 4 字节,客户端实际当作“目标角色 obj_id”使用,不是武魂外观 ID。
原服务端逻辑错误地发送了:
id = obj:get_wuhun_visual()
并写入:
msg.wuhun_visual = id or 0
客户端收到后会用这个值查目标对象。因为这是外观 ID,不是目标玩家 obj_id,所以客户端找不到对应目标对象,无法刷新 CachedTarget 的幻魂数据,最终导致 UnLocked 全部读不到,图谱全部蒙红。
修复目标:
GCWuhunWG type=0 下发目标玩家 obj_id
- 幻魂列表仍然跟随目标玩家数据一起下发
- 保留旧字段名兼容,避免其他地方按
wuhun_visual 构包时报错
修改 1:修正查看目标玩家时传入的 ID
文件:
\ubuntu\tlbb\services\scene\scenecore\char_misc.lua
修改前:
id = obj:get_wuhun_visual()
ntype = 0
修改后:
id = obj:get_obj_id()
ntype = 0
说明:
GCWuhunWG type=0 要传目标对象 ID,让客户端能找到目标玩家并刷新 CachedTarget。
修改 2:服务端发送 GCWuhunWG 时写 target_id
文件:
\ubuntu\tlbb\services\scene\obj\human\wuhun_visual.lua
修改前:
if type >= 2 and type <= 4 then
msg.huanhun_id = id or huanhun_id
else
msg.wuhun_visual = id or 0
end
修改后:
if type >= 2 and type <= 4 then
msg.huanhun_id = id or huanhun_id
else
msg.target_id = id or self:get_obj_id()
msg.wuhun_visual = msg.target_id
end
说明:
target_id 是当前客户端真实语义,wuhun_visual 保留为兼容别名。
修改 3:修正 GCWuhunWG 包定义字段语义
文件:
\ubuntu\tlbb\services\game\packet_parts\guild_misc\char_state_ability.lua
读取部分修改前:
self.wuhun_visual = stream:readint()
修改后:
self.target_id = stream:readint()
self.wuhun_visual = self.target_id
写入部分修改前:
stream:writeint(self.wuhun_visual)
修改后:
stream:writeint(self.target_id or 0)