CGGuild 是旧版客户端里的帮会系统总请求包。当前 Temp_Release_v0-07-0300 里,成员列表、帮会详情、任命、招收、开除、离帮、禅让、修改宗旨、设置上线留言、自定义职位名等多个入口都复用这一个 PacketID。
这条包的核心特征是“packet_type 分流”:
- 固定头先携带
packet_type + askid
- 剩余包体再按具体子类型切换不同结构
- 当前 Lua 服务端已经真实接入其中一批主要子类型
包信息
| 项目 |
内容 |
| 封包 ID |
204 |
| 包名 |
CGGuild |
| 方向 |
CG 客户端 -> 消息服 |
| 包长 |
动态 |
| 直接处理 |
ma_guild:CGGuild() |
| 主要回包 |
GCGuild / GCGuildReturn / GCGuildError |
| 主要作用 |
按 packet_type 提交帮会系统请求 |
当前 Game.exe 的虚函数结论为:
GetPacketID() = 204;
Read() = sub_1405CA560;
Write() = sub_14060DAB0;
Execute() = sub_140328D60; // 直接返回 2
GetPacketSize() = sub_1402A8670; // 5 + 当前子结构长度
其中 Read() / Write() 的当前行为可以直接概括为:
read(packet_type, 1);
read(askid, 4);
dispatch_by_packet_type(packet_type)->Read(...);
write(packet_type, 1);
write(askid, 4);
dispatch_by_packet_type(packet_type)->Write(...);
这说明 CGGuild 在当前旧版客户端中不是单一固定结构,而是一个帮会请求复用总包。
包体结构
固定头
所有 CGGuild 请求都会先带这 5 字节固定头。
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x01 |
packet_type |
uint8 |
帮会请求子类型 |
0x01 |
0x04 |
askid |
uint32 |
请求流水号,服务端回包通常按 askid + 1 回传 |
当前 Lua 已接入的主要 packet_type
packet_type |
当前用途 |
当前结构长度 |
3 |
帮会信息查询复用请求 |
9 |
4 |
任命成员职位 |
12 |
6 |
招收申请人入帮 |
9 |
7 |
开除帮会成员 |
9 |
10 |
主动离帮 |
5 |
12 |
帮主禅让 |
5 |
13 |
修改帮会宗旨 |
6 + desc_len |
15 |
修改帮会上线留言 |
6 + leave_word_len |
17 |
提交自定义职位名称列表 |
9 + 64 * position_name_count |
18 |
自定义职位名兼容请求 |
5 |
19 |
获取当前职位名称列表 |
5 |
21 |
请求帮会名称列表 |
5 |
packet_type = 3 帮会信息查询复用请求
这组请求统一走“查询某类帮会数据”的入口。
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x01 |
packet_type |
uint8 |
固定为 3 |
0x01 |
0x04 |
askid |
uint32 |
请求流水号 |
0x05 |
0x02 |
guild_id |
int16 |
目标帮会 ID;当前 Lua 仅在 request_type = 5 / 6 时显式使用 |
0x07 |
0x01 |
request_type |
uint8 |
查询子类型 |
0x08 |
0x01 |
reserved_flag |
uint8 |
当前 Lua 已读取但未直接使用 |
当前 request_type 在 Lua 主链里的实际含义如下:
request_type |
当前用途 |
0 |
获取当前帮会成员列表 |
1 |
获取当前帮会详情 |
2 |
获取当前帮会任命信息 |
3 |
获取自己的帮会信息 |
5 |
按 guild_id 获取指定帮会详情 |
6 |
按 guild_id 获取指定帮会官员成员列表 |
packet_type = 4 任命成员职位
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x01 |
packet_type |
uint8 |
固定为 4 |
0x01 |
0x04 |
askid |
uint32 |
请求流水号 |
0x05 |
0x02 |
guild_id |
int16 |
当前帮会 ID |
0x07 |
0x04 |
target_guid |
int32 |
被任命成员 GUID |
0x0B |
0x01 |
new_position |
int8 |
新职位编号 |
packet_type = 6 招收申请人
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x01 |
packet_type |
uint8 |
固定为 6 |
0x01 |
0x04 |
askid |
uint32 |
请求流水号 |
0x05 |
0x04 |
proposer_guid |
int32 |
待招收入帮的申请人 GUID |
packet_type = 7 开除成员
当前 Game.exe RTTI 直接给出了子结构名 GUILD_CGW_EXPEL,因此这条分支的实际语义是“开除成员”。当前 Lua 内部函数名虽然仍写成 guild_expe,但处理行为已经明确属于开除帮众。
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x01 |
packet_type |
uint8 |
固定为 7 |
0x01 |
0x04 |
askid |
uint32 |
请求流水号 |
0x05 |
0x04 |
target_member_guid |
int32 |
被开除成员 GUID |
packet_type = 10 主动离帮
空包。
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x01 |
packet_type |
uint8 |
固定为 10 |
0x01 |
0x04 |
askid |
uint32 |
请求流水号 |
packet_type = 12 帮主禅让
空包。
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x01 |
packet_type |
uint8 |
固定为 12 |
0x01 |
0x04 |
askid |
uint32 |
请求流水号 |
packet_type = 13 修改帮会宗旨
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x01 |
packet_type |
uint8 |
固定为 13 |
0x01 |
0x04 |
askid |
uint32 |
请求流水号 |
0x05 |
0x01 |
desc_len |
uint8 |
宗旨文本长度,当前 Lua 限制最大 60 |
0x06 |
desc_len |
new_desc |
char[n] |
新帮会宗旨 |
packet_type = 15 修改帮会上线留言
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x01 |
packet_type |
uint8 |
固定为 15 |
0x01 |
0x04 |
askid |
uint32 |
请求流水号 |
0x05 |
0x01 |
leave_word_len |
uint8 |
留言文本长度,当前 Lua 允许 0..320 |
0x06 |
leave_word_len |
guild_leave_word |
char[n] |
新帮会上线留言 |
packet_type = 17 提交自定义职位名称列表
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x01 |
packet_type |
uint8 |
固定为 17 |
0x01 |
0x04 |
askid |
uint32 |
请求流水号 |
0x05 |
0x04 |
position_name_count |
int32 |
职位名称项数量,当前 Lua 限制最大 10 |
0x09 |
64 * n |
position_name_infos |
bytes[64*n] |
自定义职位名称列表 |
单个职位名称项固定为 64 字节:
| 偏移 |
长度 |
字段 |
类型 |
含义 |
+0x00 |
0x04 |
pos |
int32 |
职位编号 |
+0x04 |
0x19 |
std_name |
char[25] |
默认职位名 |
+0x1D |
0x19 |
name |
char[25] |
当前自定义职位名 |
+0x36 |
0x04 |
modify_time |
uint32 |
修改时间 |
+0x3A |
0x01 |
reset |
uint8 |
是否回退默认名 |
+0x3B |
0x05 |
padding |
bytes[5] |
结构补齐字节 |
packet_type = 18 / 19 / 21
这三种请求在当前 Lua 现状里都只带固定头,不附带额外参数。
packet_type |
当前用途 |
当前包体 |
18 |
自定义职位名称兼容请求 |
空包,长度 5 |
19 |
获取当前职位名称列表 |
空包,长度 5 |
21 |
请求帮会名称列表 |
空包,长度 5 |
当前实际行为 / 模式说明
- 当前
Game.exe 可以直接确认:CGGuild 是“固定头 + 帮会子结构”的复用请求包,而不是单一固定结构。
- 当前
Game.exe 的 RTTI 还能直接看到多组帮会子结构名称,包括:
GUILD_CGW_ASKINFO
GUILD_CGW_APPOINT
GUILD_CGW_RECRUIT
GUILD_CGW_EXPEL
GUILD_CGW_DEMISE
GUILD_CGW_LEAVE
GUILD_CGW_GET_POSITION_NAME
GUILD_CGW_REQUEST_POSITION_NAME
GUILD_CGW_CHANG_DESC
GUILD_CGW_MODIFY_LEAVE_WORD
- 当前 Lua 服务端收到本包后,会进入
request:CGGuild(),再转到 ma_guild:CGGuild(request) 做二次分发。
- 当前业务主链已经明确接入这些帮会功能:
packet_type = 3:帮会详情 / 成员列表 / 任命信息 / 自己的帮会信息 / 指定帮会信息
packet_type = 4:职位任命
packet_type = 6:招收入帮
packet_type = 7:开除成员
packet_type = 10:主动离帮
packet_type = 12:帮主禅让
packet_type = 13:修改帮会宗旨
packet_type = 15:设置帮会上线留言
packet_type = 17 / 18 / 19:自定义职位名称列表
packet_type = 21:帮会名称列表
- 当前
packet_type = 3 有一个额外细节:
- 大多数分支默认读取玩家当前帮会 ID
- 只有
request_type = 5 / 6 时,当前 Lua 会显式使用包里的 guild_id
- 当前
packet_type = 15 成功后,服务端会先回 GCGuildReturn(type=22),再给其他在线帮众推送 GCGuildReturn(type=23),并刷新自己的帮会信息。
- 当前
packet_type = 17 / 19 已和“帮会自定义职位名”功能打通:
19 获取当前职位名称列表
17 提交整份职位名称列表
18 在当前项目里保留为兼容请求
- 当前
packet_type = 13 与 15 都属于“字符串变长请求”:
13 修改帮会宗旨,当前 Lua 限制最大 60 字节
15 修改帮会上线留言,当前 Lua 限制最大 320 字节
服务端落点
- 协议定义:
/home/ubuntu/Game2/services/game/packet.lua
- 请求入口:
/home/ubuntu/Game2/services/msgagent.lua
- 消息服帮会分发:
/home/ubuntu/Game2/msgagent_module/ma_guild.lua
- 帮会管理器:
/home/ubuntu/Game2/services/guild/guildmanager_core.lua
关键代码
当前 Lua 协议定义
packet.CGGuild = {
xy_id = packet.XYID_CG_GUILD,
bis = function(self, buffer)
local stream = bistream.new()
stream:attach(buffer)
self.packet_type = stream:readuchar()
self.askid = stream:readuint()
if self.packet_type == 3 then
self:read_guild_ask_info(stream)
elseif self.packet_type == 4 then
self:read_guild_appoint(stream)
elseif self.packet_type == 6 then
self:read_guild_recruit(stream)
elseif self.packet_type == 7 then
self:read_guild_expe(stream)
elseif self.packet_type == 12 then
self:read_guild_demise(stream)
elseif self.packet_type == 13 then
self:read_guild_update_desc(stream)
elseif self.packet_type == 15 then
self:read_guild_modify_leave_word(stream)
elseif self.packet_type == 17 then
self:read_guild_position_name_list(stream)
elseif self.packet_type == 18 then
self:read_guild_request_position_name(stream)
elseif self.packet_type == 19 then
self:read_guild_get_position_name(stream)
end
end
}
当前 Lua 请求分发
function request:CGGuild()
ma_func:CGGuild(self)
end
function ma_guild:CGGuild(request)
if request.packet_type == 3 then
...
elseif request.packet_type == 4 then
self:guild_appoint(request, guild_id)
elseif request.packet_type == 6 then
self:guild_recruit(request, guild_id)
elseif request.packet_type == 7 then
self:guild_expe(request, guild_id)
elseif request.packet_type == 10 then
self:guild_leave(request, guild_id)
elseif request.packet_type == 12 then
self:guild_demise(request, guild_id)
elseif request.packet_type == 13 then
self:guild_new_desc(request, guild_id)
elseif request.packet_type == 15 then
self:guild_modify_leave_word(request, guild_id)
elseif request.packet_type == 17 then
self:guild_modify_position_name_list(request, guild_id)
elseif request.packet_type == 18 or request.packet_type == 19 then
self:get_guild_position_name_list(request, guild_id)
elseif request.packet_type == 21 then
self:guild_name_list(request, guild_id)
end
end
当前 Game.exe 关键结论
CGGuild 的客户端包类当前已经可以明确确认这些事实:
CGGuild::GetPacketID() = 204;
CGGuild::Execute() = 2;
CGGuild::Read() = read(packet_type) + read(askid) + dispatch_subpacket(packet_type);
CGGuild::Write() = write(packet_type) + write(askid) + dispatch_subpacket(packet_type);
CGGuild::GetPacketSize() = 5 + subpacket_size(packet_type);
也就是说,这条包真正的关键不是“总长度是多少”,而是“当前 packet_type 选择了哪一套帮会子结构”。
结论
CGGuild 在 Temp_Release_v0-07-0300 里已经可以明确归类为“帮会系统总请求包”:
- 包号固定是
204
- 固定头固定是
packet_type(uint8) + askid(uint32)
- 后续包体按
packet_type 进入不同帮会子结构
- 当前 Lua 主链已经真实接入帮会查询、任命、招收、开除、离帮、禅让、修改宗旨、上线留言、自定义职位名等多条业务链
因此,分析这条包时不能只盯一个固定结构,而要先看 packet_type,再看它落到哪一类帮会子请求。