GCPTDBSyncMonsterInfo 是客户端仍保留的一条 PTDB 怪物同步包。当前 Game.exe 已能稳定确认它以 count 开头,后续按条目顺序携带 8 字节 key 和 4 字节 monster_id;客户端最多只处理前 8 条。现役 /home/ubuntu/Game2 Lua 主链未检出同名定义。
包信息
| 项目 |
内容 |
| 封包 ID |
1306 |
| 包名 |
GCPTDBSyncMonsterInfo |
| 方向 |
GC 游戏服 -> 客户端 |
| 长度 |
变长,1 + 12 * count |
| 专用请求 |
无专用请求 |
| 当前 Lua 协议定义 |
未在 /home/ubuntu/Game2 现役 Lua 主链中检出 |
| 主要作用 |
向客户端同步一组 PTDB 怪物条目,并按怪物表 ID 填充本地名称缓存 |
当前 Game.exe 可直接确认:
GetPacketID() = 1306;
GetPacketSize() = 1 + 12 * count;
Read() = read_u8(count), repeat(count){ read_u64(entry_key), read_u32(monster_id); } // 最多处理 8 条
Write() = 同上顺序写回; // 最多写出 8 条
Execute() = count == 0 ? clear() : refresh_local_monster_cache();
包体结构
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x01 |
count |
uint8 |
条目数量;当前客户端读写与执行都只处理前 8 条 |
0x01 + 12 * i |
0x08 |
entry_key[i] |
uint64 |
第 i 条条目的 8 字节 key;客户端落地时会拆成两个 uint32 值保存 |
0x09 + 12 * i |
0x04 |
monster_id[i] |
uint32 |
第 i 条怪物表 ID |
总长度公式:
1 + 12 * count
需要特别说明:
GetPacketSize() 使用包内 count 直接计算长度。
- 但
Read() / Write() / Execute() 实际只循环处理前 8 条,因此这条协议在客户端侧的有效上限应视为 8。
当前实际行为
count == 0 时,客户端会先清空本地 PTDB 怪物缓存,然后直接返回。
count > 0 时,客户端同样先清空旧缓存,再设置“怪物同步数据已就绪”标记。
- 随后客户端会固定遍历
8 个槽位:
- 如果槽位索引小于
count,就写入对应条目的 entry_key 与 monster_id。
- 如果槽位索引超出
count,就写入默认无效值。
- 当
monster_id > 0 时,客户端会从本地 CreatureDBC 中查表,取出怪物名称并写入对应的 32 字节名称槽。
- 因此该包的实际作用不仅是同步 ID,还会同步客户端展示层需要的本地怪物名缓存。
- 现役
/home/ubuntu/Game2 Lua 主链未检出该协议定义,因此这里记录的是客户端当前保留行为。
服务端落点
- 当前检索
/home/ubuntu/Game2/services 与 /home/ubuntu/Game2/lualib,未命中 GCPTDBSyncMonsterInfo。
- 已重点复核但未命中的现役文件包括:
/home/ubuntu/Game2/services/game/packet.lua
/home/ubuntu/Game2/services/msgagent.lua
/home/ubuntu/Game2/services/scene/scenecore.lua
/home/ubuntu/Game2/services/scene/obj/human.lua
- 因此本文结构与行为结论以当前
Game.exe 为准;服务端现役链路仅能确认“未见接入”。
关键代码
当前 Game.exe 结构
GetPacketID() = 1306;
GetPacketSize() = 1 + 12 * count;
Read() / Write():
uint8 count;
for (int i = 0; i < count && i < 8; ++i) {
uint64 entry_key[i];
uint32 monster_id[i];
}
当前客户端执行逻辑
if (count == 0) {
clear_ptdb_monster_cache();
return 2;
}
clear_ptdb_monster_cache();
set_ptdb_monster_cache_ready();
for (int i = 0; i < 8; ++i) {
store_entry_key_pair(i, entry_key[i]);
store_monster_id(i, monster_id[i]);
if (monster_id[i] > 0)
store_monster_name(i, lookup_creature_name(monster_id[i]));
}
return 2;
结论
GCPTDBSyncMonsterInfo 是一条 count 开头的变长同步包,每条记录由 entry_key(8) 和 monster_id(4) 组成。
- 当前客户端虽然按
1 + 12 * count 计算包长,但实际只处理前 8 条,因此有效上限应视为 8。
- 客户端收到该包后会刷新本地 PTDB 怪物缓存,并按
monster_id 补出怪物名称字符串。
- 现役
/home/ubuntu/Game2 Lua 主链未检出该协议,因此当前更应视作客户端保留同步链路。
|