包信息
| 项目 |
值 |
| PacketID |
169 |
| 方向 |
Server -> Client |
| 长度 |
变长,30 + sum(entry_size) |
| 对应请求 |
CGWFriendADAskSimpleVoteInfo |
| 作用 |
向客户端下发征友系统中的投票简要列表与分页上下文 |
包体结构
包头
| 偏移 |
长度 |
字段 |
类型 |
含义 |
| 0x00 |
0x04 |
reserved_header_1 |
int32 |
当前 Game.exe 会读写但 Execute() 未直接消费的头字段 |
| 0x04 |
0x02 |
reserved_header_2 |
int16 |
当前 Game.exe 会读写但 Execute() 未直接消费的头字段 |
| 0x06 |
0x04 |
reserved_header_3 |
int32 |
当前 Game.exe 会读写但 Execute() 未直接消费的头字段 |
| 0x0A |
0x04 |
list_context_1 |
int32 |
客户端刷新投票列表时透传给本地刷新流程的上下文参数 1 |
| 0x0E |
0x04 |
list_context_2 |
int32 |
客户端刷新投票列表时透传给本地刷新流程的上下文参数 2 |
| 0x12 |
0x04 |
list_context_3 |
int32 |
客户端刷新投票简表时透传给本地刷新流程的上下文参数 3 |
| 0x16 |
0x04 |
list_context_4 |
int32 |
客户端刷新投票简表时透传给本地刷新流程的上下文参数 4 |
| 0x1A |
0x04 |
entry_count |
int32 |
当前包携带的条目数量 |
条目结构 FindFriendAD_DetailInfo
单条记录为变长结构:
4 + 4 + 4 + text_len_1 + 4 + 1 + 1 + 4 + text_len_2 + 1 + 10*4 = 63 + text_len_1 + text_len_2
| 偏移 |
长度 |
字段 |
类型 |
含义 |
| 0x00 |
0x04 |
target_guid |
uint32 |
目标角色 GUID;客户端后续投票与留言请求都会从列表项里取出此值 |
| 0x04 |
0x04 |
friend_type |
int32 |
征友类型;客户端后续投票与留言请求会从列表项里取出此值 |
| 0x08 |
0x04 |
text_len_1 |
int32 |
第一段文本长度 |
| 0x0C |
text_len_1 |
text_1 |
char[text_len_1] |
第一段变长文本 |
| 0x0C + text_len_1 |
0x04 |
reserved_value_1 |
int32 |
当前客户端保留的整型字段 |
| 0x10 + text_len_1 |
0x01 |
reserved_flag_1 |
uint8 |
当前客户端保留的单字节标志 |
| 0x11 + text_len_1 |
0x01 |
reserved_flag_2 |
uint8 |
当前客户端保留的单字节标志 |
| 0x12 + text_len_1 |
0x04 |
text_len_2 |
int32 |
第二段文本长度 |
| 0x16 + text_len_1 |
text_len_2 |
text_2 |
char[text_len_2] |
第二段变长文本 |
| 0x16 + text_len_1 + text_len_2 |
0x01 |
reserved_flag_3 |
uint8 |
当前客户端保留的单字节标志 |
| 0x17 + text_len_1 + text_len_2 |
0x04 |
reserved_value_2 |
int32 |
当前客户端保留的整型字段 |
| 0x1B + text_len_1 + text_len_2 |
0x04 |
reserved_value_3 |
int32 |
当前客户端保留的整型字段 |
| 0x1F + text_len_1 + text_len_2 |
0x04 |
reserved_value_4 |
int32 |
当前客户端保留的整型字段 |
| 0x23 + text_len_1 + text_len_2 |
0x04 |
reserved_value_5 |
int32 |
当前客户端保留的整型字段 |
| 0x27 + text_len_1 + text_len_2 |
0x04 |
reserved_value_6 |
int32 |
当前客户端保留的整型字段 |
| 0x2B + text_len_1 + text_len_2 |
0x04 |
reserved_value_7 |
int32 |
当前客户端保留的整型字段 |
| 0x2F + text_len_1 + text_len_2 |
0x04 |
reserved_value_8 |
int32 |
当前客户端保留的整型字段 |
| 0x33 + text_len_1 + text_len_2 |
0x04 |
reserved_value_9 |
int32 |
当前客户端保留的整型字段 |
| 0x37 + text_len_1 + text_len_2 |
0x04 |
reserved_value_10 |
int32 |
当前客户端保留的整型字段 |
| 0x3B + text_len_1 + text_len_2 |
0x04 |
reserved_value_11 |
int32 |
当前客户端保留的整型字段 |
当前实际行为
- 当前
Game.exe 中,这条包拥有完整的客户端类定义,GetPacketID() 明确返回 169。
- 当前
Temp_Release_v0-07-0300 Lua 服务端没有找到:
packet.WGCFriendADGiveSimpleVoteInfo
- 对应发送点
CGWFriendADAskSimpleVoteInfo -> WGCFriendADGiveSimpleVoteInfo 的现役 Lua 处理链
- 因此按当前项目现状,这条包应视为客户端保留的旧征友系统下行包,现役 Lua 主链未接入。
- 当前
Game.exe 的构造函数会预置 20 个 FindFriendAD_DetailInfo 槽位,因此正常协议应控制在 20 条以内。
- 当前
Read() / Write() 会按 entry_count 直接循环处理条目,没有在包函数层额外截断,说明这条包的正常上限依赖发送端自觉控制。
- 当前条目结构里,
target_guid 与 friend_type 已可由客户端后续请求链明确确认:
RequestVoteFindFriendInfo() 会从列表项取出 target_guid + friend_type 继续构造 CGWFriendADIssueOrEdit(operate_mode = 3)
RequestOpenZhengyouMessage() 也会从列表项取出相同两项继续构造 CGWFriendADPlayerMsg
- 当前客户端本地还保留了
GetSimpleVoteInfoByPos / GetVoteInfoNum / GetVoteInfoByPos / ContexMenuForVoteInfo 一组脚本接口,说明这条包确实对应征友投票列表界面的本地缓存数据源。
WGCFriendADGiveSimpleVoteInfo(169) 与 WGCFriendADGiveSimpleInfo(407) 复用了同一套包头与 FindFriendAD_DetailInfo 条目结构,区别主要在客户端 Execute() 进入的本地缓存与刷新路径不同。
服务端落点
当前 Lua 主链未发现这条包的正式落点:
/home/ubuntu/Game2/services/game/packet.lua
/home/ubuntu/Game2/services/msgagent.lua
/home/ubuntu/Game2/services/scene/scenecore.lua
关键代码
// Game.exe
GetPacketID() = 169;
GetPacketSize() = 30 + sum(entry_size);
Read() {
read(reserved_header_1, 4);
read(reserved_header_2, 2);
read(reserved_header_3, 4);
read(list_context_1, 4);
read(list_context_2, 4);
read(list_context_3, 4);
read(list_context_4, 4);
read(entry_count, 4);
repeat entry_count times:
read(FindFriendAD_DetailInfo);
}
// Game.exe
FindFriendAD_DetailInfo::Read() {
read(target_guid, 4);
read(friend_type, 4);
read(text_len_1, 4);
read(text_1, text_len_1);
read(reserved_value_1, 4);
read(reserved_flag_1, 1);
read(reserved_flag_2, 1);
read(text_len_2, 4);
read(text_2, text_len_2);
read(reserved_flag_3, 1);
read(reserved_value_2 ... reserved_value_11, 10 * 4);
}
// Game.exe
Lua_RequestVoteFindFriendInfo(opt, row_index, vote_type, channel_type) {
resolved_target_guid = GetCachedFindFriendEntry(row_index, &resolved_friend_type, channel_type);
msg.friend_type = resolved_friend_type;
msg.target_guid = resolved_target_guid;
msg.vote_type = vote_type;
msg.channel_type = channel_type;
SendPacket(CGWFriendADIssueOrEdit);
}
// Game.exe
Lua_RequestOpenZhengyouMessage(channel_type, row_index) {
resolved_target_guid = GetCachedFindFriendEntry(row_index, &resolved_friend_type, channel_type);
msg.target_guid = resolved_target_guid;
msg.friend_type = resolved_friend_type;
SendPacket(CGWFriendADPlayerMsg);
}
// Game.exe
Execute() {
cache FindFriendAD_DetailInfo entries into the local vote list cache;
trigger local refresh path 558;
trigger local refresh path 562;
return 2;
}
结论
WGCFriendADGiveSimpleVoteInfo(169) 是旧征友系统中的“投票简要列表下发包”。当前 Game.exe 已能明确确认它采用 30 字节包头加变长条目列表的结构,并且条目里至少已经能确定 target_guid 与 friend_type 两个关键字段。当前 Temp_Release_v0-07-0300 Lua 服务端没有这条包的协议定义与发送主链,因此现阶段应把它归类为客户端保留的旧征友系统下行包,而不是当前服正在运行的现役 Lua 协议。