WGCXBWTeamRankList 是当前客户端华山论剑战队排行界面使用的分页同步包。按当前 Game.exe 的 Read / Write / Execute 结果,它固定长度为 4548 字节,由 28 字节包头和 10 条固定 452 字节的战队排行记录组成。客户端执行时会校验 sync_flag == 1,将排行页基础信息与 10 支战队数据写入本地缓存,然后触发排行界面刷新。
现役 /home/ubuntu/Game2 Lua 主链中未找到这条协议定义、发送入口或 AskPlayerTeamRank 处理逻辑,因此当前能确认的行为以 Game.exe 与客户端界面脚本为准。
包信息
| 项目 |
内容 |
| 封包 ID |
1283 |
| 包名 |
WGCXBWTeamRankList |
| 方向 |
WGC 服务端 -> 客户端 |
| 固定包长 |
4548(0x11C4) |
| 当前客户端请求入口 |
AskPlayerTeamRank(stage, page, locked_flag) |
| 当前 Lua 协议定义 |
未在 /home/ubuntu/Game2/services/game/packet.lua 中找到 |
| 当前 Lua 发送入口 |
未在 /home/ubuntu/Game2/services/msgagent.lua 或 /home/ubuntu/Game2/lualib/script_base.lua 中找到 |
| 当前客户端消费 |
客户端/Interface/HuaShanLunJian_TopList2/HuaShanLunJian_TopList2.lua、客户端/Interface/HuaShanLunJian_TeamInfo2/HuaShanLunJian_TeamInfo2.lua |
| 当前用途 |
同步华山论剑战队排行榜当前页数据,并驱动排行/战队详情界面刷新 |
当前 Game.exe 可直接确认:
GetPacketID() = 1283;
GetPacketSize() = 4548;
Read() = read_7_u32_header + repeat(10, read_team_rank_entry);
Write() = write_7_u32_header + repeat(10, write_team_rank_entry);
Execute() = if (sync_flag == 1) refresh rank cache, push update path 1416, return 2;
包体结构
主包头
主包头固定 0x1C 字节。
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x04 |
sync_flag |
uint32 |
同步类型/结果标记;当前客户端仅在值为 1 时继续处理 |
0x04 |
0x04 |
reserved_1 |
uint32 |
当前 Execute 未直接使用 |
0x08 |
0x04 |
stage |
uint32 |
排行阶段;脚本通过 NewXBW:GetRankBaseInfo("Stage") 读取 |
0x0C |
0x04 |
page |
uint32 |
当前页号,客户端按 0 基处理 |
0x10 |
0x04 |
total |
uint32 |
排行总战队数;客户端缓存阶段会额外按 50 封顶 |
0x14 |
0x04 |
is_locked_team |
uint32 |
锁队榜标记;刷新事件会把它作为界面参数传给 HuaShanLunJian_TopList2_Show(arg0) |
0x18 |
0x04 |
reserved_2 |
uint32 |
当前 Execute 未直接使用 |
0x1C |
0x1C4 * 10 |
team_rank_list[10] |
bytes[4520] |
固定 10 条战队排行记录,每条固定 452 字节 |
team_rank_list[i] 战队排行条目
单条战队排行记录固定 0x1C4 字节。
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x04 |
reserved_1 |
uint32 |
当前脚本 getter 未直接暴露 |
0x04 |
0x04 |
rank_zero_based |
uint32 |
0 基排名;GetRankTeamInfo() 返回时会自动 +1 |
0x08 |
0x04 |
world_id |
uint32 |
战队所属区服 / 世界 ID |
0x0C |
0x04 |
team_id |
uint32 |
战队 ID |
0x10 |
0x04 |
reserved_2 |
uint32 |
当前脚本 getter 未直接暴露 |
0x14 |
0x04 |
reserved_3 |
uint32 |
当前脚本 getter 未直接暴露 |
0x18 |
0x04 |
reserved_4 |
uint32 |
当前脚本 getter 未直接暴露 |
0x1C |
0x18 |
team_name |
char[24] |
战队名称 |
0x34 |
0x04 |
star |
uint32 |
当前排行星数 |
0x38 |
0x42 * 6 |
member_list[6] |
bytes[396] |
固定 6 个成员槽 |
当前脚本层 GetRankTeamInfo(index) 实际暴露的字段为:
rank = rank_zero_based + 1
worldid = world_id
teamid = team_id
star = star
count = 有效成员槽数量
name = team_name
其中 count 不是包里单独传的顶层字段,而是客户端通过遍历 member_list[6],统计 guid > 0 的成员槽数后动态计算出来。
member_list[j] 成员槽
单个成员槽固定 0x42 字节。
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x04 |
guid |
uint32 |
成员 GUID;无效槽通常不大于 0 |
0x04 |
0x04 |
level |
uint32 |
等级 |
0x08 |
0x04 |
menpai |
uint32 |
门派 ID |
0x0C |
0x04 |
post |
uint32 |
战队职位 |
0x10 |
0x04 |
dw1 |
uint32 |
段位主级别 |
0x14 |
0x04 |
dw2 |
uint32 |
段位子级别 |
0x18 |
0x04 |
dw3 |
uint32 |
星阶 / 附加段位值 |
0x1C |
0x04 |
reserved_1 |
uint32 |
当前脚本 getter 未直接暴露 |
0x20 |
0x04 |
reserved_2 |
uint32 |
当前脚本 getter 未直接暴露 |
0x24 |
0x1E |
member_name |
char[30] |
成员名字 |
当前脚本层 GetRankMemberInfo(teamidx, memberidx) 实际暴露的字段为:
guid
level
menpai
post
dw1
dw2
dw3
name = member_name
当前实际行为
当前客户端界面链路表现为:
HuaShanLunJian_TopList2 / HuaShanLunJian_TopList3 通过 AskPlayerTeamRank(stage, page, locked_flag) 请求某个阶段、某一页、某种榜单类型的数据。
Game.exe 收到 WGCXBWTeamRankList 后,仅在 sync_flag == 1 时继续处理。
- 客户端先清空本地战队排行缓存。
- 然后把包头里的
stage、page、total、is_locked_team 写入本地基表,并按 total <= 50 重新计算:
PageMax = ceil(min(total, 50) / 10)
Count = 当前页 team_id > 0 的有效条目数
- 再顺序复制固定
10 条战队排行记录。
- 最后触发编号
1416 的客户端刷新路径;当前脚本消费侧对应 XBW_TEAMRANK_UPDATE,参数即 is_locked_team。
当前界面脚本可直接验证几项实际消费结果:
NewXBW:GetRankBaseInfo("Stage" | "Page" | "PageMax" | "Count" | "Total") 读取的是执行阶段写入的本地基表
NewXBW:GetRankTeamInfo(i) 只使用 rank、worldid、teamid、star、name 和动态计算的成员数
NewXBW:GetRankMemberInfo(teamidx, memberidx) 读取 member_list[6] 槽位中的成员信息
HuaShanLunJian_TopList2_Show(arg0) 会把刷新事件参数解释为“锁队榜 / 普通榜”开关
服务端落点
现役 /home/ubuntu/Game2 中未找到这条协议的服务端主链落点:
/home/ubuntu/Game2/services/game/packet.lua
/home/ubuntu/Game2/services/msgagent.lua
/home/ubuntu/Game2/lualib/script_base.lua
也就是说,当前仓库里没有可直接对照的现役 Lua 协议定义、构包代码或发送入口。
当前可确认的实际消费链路在客户端:
客户端/Interface/HuaShanLunJian_TopList2/HuaShanLunJian_TopList2.lua
- 发起
AskPlayerTeamRank(stage, page, locked_flag)
- 使用
NewXBW:GetRankBaseInfo() 与 NewXBW:GetRankTeamInfo()
客户端/Interface/HuaShanLunJian_TeamInfo2/HuaShanLunJian_TeamInfo2.lua
- 使用
NewXBW:GetRankMemberInfo(teamidx, memberidx) 展示成员详情
客户端/Interface/HuaShanLunJian_TopList3/HuaShanLunJian_TopList3.lua
- 复用同一
AskPlayerTeamRank(stage, page, locked_flag) 请求入口
关键代码
当前客户端脚本请求排行的方式可概括为:
Clear_XSCRIPT()
Set_XSCRIPT_ScriptID(g_HuaShanLunJian_TopList2_SvrScriptId)
Set_XSCRIPT_Function_Name("AskPlayerTeamRank")
Set_XSCRIPT_Parameter(0, stage)
Set_XSCRIPT_Parameter(1, page)
Set_XSCRIPT_Parameter(2, locked_flag)
Set_XSCRIPT_ParamCount(3)
Send_XSCRIPT()
当前 Game.exe 的执行逻辑可概括为:
if (packet.sync_flag != 1) {
return 2;
}
ClearRankCache();
cache.stage = packet.stage;
cache.page = packet.page;
cache.total = min(packet.total, 50);
cache.page_max = (cache.total + 9) / 10;
cache.count = count(packet.team_rank_list[i].team_id > 0, i = 0..9);
cache.is_locked_team = packet.is_locked_team;
for (int i = 0; i < 10; ++i) {
CopyRankTeamEntry(i, packet.team_rank_list[i]);
}
PushEvent(1416, packet.is_locked_team);
return 2;
当前 Game.exe 脚本绑定的 getter 可概括为:
GetRankBaseInfo("Stage") -> cache.stage;
GetRankBaseInfo("Page") -> cache.page;
GetRankBaseInfo("PageMax") -> cache.page_max;
GetRankBaseInfo("Count") -> cache.count;
GetRankBaseInfo("Total") -> cache.total;
GetRankTeamInfo(i) -> {
rank = entry.rank_zero_based + 1,
worldid = entry.world_id,
teamid = entry.team_id,
star = entry.star,
count = count_nonzero_guid(entry.member_list[6]),
name = entry.team_name,
}
GetRankMemberInfo(teamidx, memberidx) -> {
guid, level, menpai, post, dw1, dw2, dw3, name
}
结论
WGCXBWTeamRankList 是当前版本 Game.exe 中仍然完整保留并正在被客户端排行界面消费的华山论剑战队排行分页同步包。它不是旧式变长榜单包,而是固定 4548 字节的大包:28 字节包头加 10 条固定 452 字节战队记录,每条战队又固定带 6 个成员槽。
当前可以明确命名的关键字段包括:
- 包头:
stage、page、total、is_locked_team
- 战队条目:
rank_zero_based、world_id、team_id、team_name、star
- 成员槽:
guid、level、menpai、post、dw1、dw2、dw3、member_name
其余头部整型字段和战队条目中的补充数值,当前 Game.exe 读写保留但现役脚本层没有直接暴露,文档暂按 reserved_x 记录更稳妥。另一个需要保留的现状是:当前客户端对 total 做了 50 条封顶,并固定按每页 10 条、每队 6 个成员槽解释这条包。