GCDetailXiulianList 是当前旧版项目里仍在 Lua 主链实际发送的一条角色修炼同步包。当前场景服会在修炼等级或修炼上限变化后下发该包,把 11 项修炼的等级、上限以及一个额外的修炼评分同步给客户端。当前 Game.exe 能直接确认包体是固定 48 字节,末尾 uint32 字段会落到客户端角色属性 XIULIANSCORE。
包信息
| 项目 |
内容 |
| 封包 ID |
655 |
| 包名 |
GCDetailXiulianList |
| 方向 |
GC 服务端 -> 客户端 |
| 包长模式 |
固定长度 |
| 包体长度 |
48 |
| 当前 Lua 状态 |
已定义协议结构并实际发送;当前服务端固定写入 xiulian_score = 54 |
| 主要作用 |
刷新客户端修炼面板中的 11 项修炼等级、上限和修炼评分 |
当前 Game.exe 的虚函数结论为:
GetPacketID() = 655;
GetPacketSize() = 48;
Execute() = 2;
包体结构
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x16 |
xiulian[1..11].level |
uint16[11] |
11 项修炼当前等级,按客户端固定修炼索引顺序排列 |
0x16 |
0x16 |
xiulian[1..11].upper_limit |
uint16[11] |
11 项修炼当前上限,顺序与前一段完全一致 |
0x2C |
0x04 |
xiulian_score |
uint32 |
客户端角色属性 XIULIANSCORE;当前 Lua 实际发送固定值 54 |
这条包没有额外尾随数据,也不是动态包;当前客户端 Read / Write / GetPacketSize 三处结论完全一致。
当前实际行为
- 当前 Lua 场景服的发送入口是
human:send_xiulian_list()。
human:xiulian_level_up() 和 human:xiulian_upper_limit_up() 在修改修炼数据后,都会立即调用 send_xiulian_list()。
- 当前 Lua 直接把
self:get_xiulian_list() 写入前 44 字节,因此网络层实际下发的是 11 组 { level, upper_limit }。
- 当前 Lua 没有发现独立的修炼评分计算链,发送时把
xiulian_score 固定写成 54。
- 当前
Game.exe 的 GCDetailXiulianListHandler.cpp 会按索引把 11 组 level + upper_limit 写入客户端角色修炼数据池。
- 同一个 handler 还会把末尾
uint32 写入客户端角色属性 XIULIANSCORE,然后触发一次角色修炼界面刷新。
服务端落点
- 协议定义与序列化:
/home/ubuntu/Game2/services/game/packet.lua
- 实际发送入口:
/home/ubuntu/Game2/services/scene/obj/human.lua
- 触发发送的当前链路:
human:xiulian_level_up()、human:xiulian_upper_limit_up() 最终都会调用 human:send_xiulian_list()
这是一条服务端主动下发的结果包,无专用回包。
关键代码
当前 Lua 的实际发送
function human:send_xiulian_list()
local ret = packet_def.GCDetailXiulianList.new()
ret.xiulian_score = 54
ret.xiulian = self:get_xiulian_list()
self:get_scene():send2client(self, ret)
end
当前 Lua 的序列化结构
for i = 1, 11 do
local xiulian = self.xiulian[i] or {}
stream:writeushort(xiulian.level or 0)
end
for i = 1, 11 do
local xiulian = self.xiulian[i] or {}
stream:writeushort(xiulian.upper_limit or 0)
end
stream:writeuint(self.xiulian_score or 0)
当前 Game.exe 的处理结论
Read(stream) {
for (i = 0; i < 11; ++i)
xiulian[i].level = read_u16();
for (i = 0; i < 11; ++i)
xiulian[i].upper_limit = read_u16();
xiulian_score = read_u32();
}
Execute() {
for (i = 0; i < 11; ++i)
player_xiulian_data.update(i, xiulian[i].level, xiulian[i].upper_limit);
player_data.XIULIANSCORE = xiulian_score;
refresh_xiulian_ui();
return 2;
}
客户端 handler 字符串还能直接看到:
GCDetailXiulianListHandler.cpp
XIULIANSCORE
s_pXiulianBookDBC
s_pXiuLianDetailDBC
这说明末尾字段不是保留填充,而是客户端角色修炼系统会实际消费的评分字段。
结论
GCDetailXiulianList 是当前旧版项目里仍在 Lua 主链实际发送的修炼同步包,封包 ID 为 655。
- 当前
Game.exe 可以明确确认它是固定 48 字节结构:11 个等级 + 11 个上限 + 1 个 xiulian_score。
- 末尾原先容易写成
unknow_2 的 uint32 字段,当前客户端已经能直接确认应命名为 xiulian_score,并对应角色属性 XIULIANSCORE。
- 当前 Lua 服务端确实会发送这条包,但
xiulian_score 现状是固定常量 54,并不是实时计算值。
- 这条包的现行作用很直接:刷新客户端修炼面板中的 11 项修炼数据,并同步一份修炼评分。
|