GCByname 是旧版客户端里一条按 type 分流的回包。当前版本里,它不是通用大列表回包,而是一个小型文本/数值通知包,主要用于结拜相关界面文本刷新。
包信息
| 项目 |
内容 |
| 封包 ID |
13 |
| 包名 |
GCByname |
| 对应请求 |
CGByname |
| 对应请求 ID |
282 |
| 作用 |
按 type 向客户端回推单字节参数或短文本数据,用于结拜相关界面提示与名字刷新 |
包体结构
当前 Game.exe 与 Lua 协议定义都能确认,GCByname 不是单一固定结构,而是按 type 走两种变体。
变体一:type = 0x11
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x01 |
type |
uint8 |
业务类型,固定为 0x11 |
0x01 |
0x01 |
num |
uint8 |
单字节参数,当前 Lua 发送的是 TeamSize |
当前 Game.exe 的 GetPacketSize() 在 type = 0x11 时返回:
2
变体二:type = 0x12 / 0x13 / 0x21 / 0x22
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x01 |
type |
uint8 |
业务类型 |
0x01 |
0x01 |
data_len |
uint8 |
文本长度 |
0x02 |
data_len |
data |
char[n] |
业务文本内容 |
当前 Game.exe 的 GetPacketSize() 在这几个 type 下返回:
data_len + 2
当前客户端类对这类文本的内部缓冲上限是 34 字节,因此正常总长度上限为 36 字节。
当前实际行为 / 模式说明
- 当前
Game.exe 中,GCByname::GetPacketID() 返回 13。
- 当前
Game.exe 的 Read() / Write() 顺序固定为:
- 先写
type
type = 0x11 时再写 num
type = 0x12 / 0x13 / 0x21 / 0x22 时写 data_len + data
- 当前
Game.exe 的 Execute() 会按 type 进入不同的客户端处理分支。
- 当前 Lua 协议定义的
bos() 与 Game.exe 结构一致:
0x11:写 num
0x12 / 0x13 / 0x21 / 0x22:先把 data 转成 GBK,再写 len + data
- 当前 Lua 主链实际发送到客户端的
GCByname 只有两种:
- 当前
type = 0x11 由 LuaFnDrawJieBaiName() 发送,载荷字段是 num = TeamSize。
- 当前
type = 0x13 由 LuaFnChangeJieBaiName() 发送,载荷字段是 data = human:get_jiebai_name()。
- 当前两个发送点都由结拜脚本
b_swear.lua 调用,说明这条回包在现版主链里主要服务于结拜界面。
- 当前
Game.exe 里,0x12 / 0x13 / 0x21 / 0x22 四个文本型分支都会经过一套 GCByNameHandler_* 字符串模板处理链,最终投递到客户端内部事件 133。
- 当前
type = 0x11 分支只消费 1 个字节参数;客户端对这个字节值还带有 100 / 101 的特殊判断,其余值会继续转入内部处理。
- 当前代码库里没有找到
type = 0x12 / 0x21 / 0x22 的 Lua 发送点,现版服务端主链未实际发出这三种分支。
服务端落点
- 协议定义:
/home/ubuntu/Game2/services/game/packet.lua
- 当前发送辅助:
/home/ubuntu/Game2/lualib/script_base.lua
- 当前触发脚本:
/home/ubuntu/Game2/services/scripts/event/relation/b_swear.lua
关键代码
当前 Lua 协议定义
packet.GCByname = {
xy_id = packet.XYID_GC_BY_NAME,
bos = function(self)
local stream = bostream.new()
stream:writeuchar(self.type)
if self.type == 0x11 then
stream:writeuchar(self.num)
elseif self.type == 0x12 or self.type == 0x13 or self.type == 0x21 or self.type == 0x22 then
self.data = gbk.fromutf8(self.data)
local len = string.len(self.data)
stream:writeuchar(len)
stream:write(self.data, len)
end
return stream:get()
end
}
当前 Lua 发送点
function script_base:LuaFnDrawJieBaiName(selfId, TeamSize)
local msg = packet_def.GCByname.new()
msg.type = 0x11
msg.num = TeamSize
self:get_scene():send2client(selfId, msg)
end
function script_base:LuaFnChangeJieBaiName(selfId)
local human = self:get_scene():get_obj_by_id(selfId)
local msg = packet_def.GCByname.new()
msg.type = 0x13
msg.data = human:get_jiebai_name()
self:get_scene():send2client(selfId, msg)
end
当前 Game.exe 的读写与长度结论
GetPacketID() = 13;
Read(stream) {
read_u8(type);
if (type == 0x11) {
read_u8(num);
} else if (type == 0x12 || type == 0x13 || type == 0x21 || type == 0x22) {
read_u8(data_len);
read_bytes(data, data_len);
}
}
Write(stream) {
write_u8(type);
if (type == 0x11) {
write_u8(num);
} else if (type == 0x12 || type == 0x13 || type == 0x21 || type == 0x22) {
write_u8(data_len);
write_bytes(data, data_len);
}
}
GetPacketSize() {
if (type == 0x11) {
return 2;
}
if (type == 0x12 || type == 0x13 || type == 0x21 || type == 0x22) {
return data_len + 2;
}
return 0;
}
Execute() {
return 2;
}
结论
这条包在当前旧版项目里要记住六点:
GCByname 的封包 ID 是 13。
- 它是按
type 分流的回包,不是固定单结构。
type = 0x11 时包体只有 type + num 两个字节。
type = 0x12 / 0x13 / 0x21 / 0x22 时包体是 type + data_len + data,文本最大 34 字节。
- 当前 Lua 主链实际只发送
0x11 和 0x13,并且都用于结拜相关界面逻辑。
- 当前客户端类虽然还保留了
0x12 / 0x21 / 0x22 三个文本分支,但现版服务端代码里没有找到实际发送点。
|