GCNotifyMail 是当前版本邮件系统里的现役结果包,用来把“当前邮箱邮件数量”通知给客户端。当前 Lua 服务端会在角色登录检查邮件时,以及服务端检测到有新邮件时发送这条包;当前 Game.exe 也能明确确认,它的包体只有一个 uint8 数量字段。
这条包不是邮件正文列表,也不是完整邮件内容同步。它的作用更接近“邮件提示数量刷新包”,客户端收到后会更新本地邮件数量并触发一次界面刷新。
包信息
| 项目 |
内容 |
| 封包 ID |
633 |
| 包名 |
GCNotifyMail |
| 方向 |
GC 服务端 -> 客户端 |
| 固定包长 |
1 |
| 相关请求 |
CGAskMail(登录检查模式) |
| 其他触发 |
msgagent 内部 CMD.new_mail() 主动推送 |
| 主要作用 |
通知客户端当前邮箱邮件数量,并刷新邮件提示 |
当前 Game.exe 的虚函数结论为:
GetPacketID() = 633;
GetPacketSize() = 1;
Execute() = 2;
包体结构
按当前 Game.exe 与当前 Lua 服务端现状,这条包固定为 1 字节。
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x01 |
mail_count |
uint8 |
当前邮箱邮件数量,Lua 发送时最大截断到 255 |
当前实际行为
- 当前 Lua 的
packet.GCNotifyMail 同时实现了 bis 和 bos,但在现役链路里主要由服务端主动发送给客户端。
- 当前 Lua 有两个明确发送点:
CMD.new_mail():检测到角色存在邮件时,主动下发 GCNotifyMail
request:CGAskMail():当 m_askType == ASK_TYPE_LOGIN 时,不直接发正文,而是先发 GCNotifyMail
- 当前 Lua 发送时直接使用
#mail_list 作为数量来源,因此这条包表示的是“当前邮箱中的邮件数量”。
- 当前 Lua 在
bos 里会把 m_MailCount 截断到 define.UCHAR_MAX,也就是最大 255:
- 如果邮件数量超过
255,封包里仍然只发 255
- 这与当前
uint8 包体结构保持一致
- 当前客户端
Game.exe 收到这条包后,会:
- 把这个单字节数量写入邮件相关对象
- 随后触发一次编号为
192 的刷新调用
- 因此,这条包的实际作用不是传输邮件内容,而是更新客户端邮件提示数量和相关界面状态。
服务端落点
- 协议定义:
/home/ubuntu/Game2/services/game/packet.lua
- 发送点:
/home/ubuntu/Game2/services/msgagent.lua
关键代码
当前 Lua 协议定义
packet.GCNotifyMail = {
xy_id = packet.XYID_GC_NOTIFY_MAIL,
ctor = function(self) self.m_MailCount = 0 end,
bis = function(self, buffer)
local stream = bistream.new()
stream:attach(buffer)
self.m_MailCount = stream:readuchar()
end,
bos = function(self)
local stream = bostream.new()
self.m_MailCount = self.m_MailCount > define.UCHAR_MAX and define.UCHAR_MAX or self.m_MailCount
stream:writeuchar(self.m_MailCount)
return stream:get()
end
}
当前 Lua 登录检查邮件时的发送
function request:CGAskMail()
local mail_list = get_db_mail_list()
if self.m_askType == define.ASK_TYPE.ASK_TYPE_LOGIN then
local msg = packet_def.GCNotifyMail.new()
msg.m_MailCount = #mail_list
Net:send(msg)
else
...
end
end
当前 Lua 新邮件主动通知
function CMD.new_mail()
local mail_list = get_db_mail_list()
if #mail_list > 0 then
local msg = packet_def.GCNotifyMail.new()
msg.m_MailCount = #mail_list
Net:send(msg)
end
end
当前 Game.exe 的读写与执行结论
Read(stream) {
read_u8(mail_count);
}
Write(stream) {
write_u8(mail_count);
}
GetPacketID() = 633;
GetPacketSize() = 1;
Execute() {
mail_system->mail_count = mail_count;
mail_system->refresh(192);
return 2;
}
结论
GCNotifyMail 的封包 ID 是 633,固定长度 1 字节。
- 当前版本的包体结构已经可以明确确定为单字段
mail_count。
- 当前 Lua 服务端会在登录检查邮件和收到新邮件时发送这条包。
- 这条包的作用是更新客户端邮件数量提示,而不是传输邮件正文。
- 当前 Lua 发送时会把数量限制在
255 以内,以对齐 uint8 协议结构。
|