LCRetCheckAllowCreateChar 是登录服返回给客户端的一条创建角色资格检查结果包,对应客户端请求包 CLCheckAllowCreateChar(776)。当前版本的登录服实现会固定返回 flag = 1,表示允许继续进入创建角色流程;客户端收到后仍会再做一次本地角色数量上限判断。
包信息
| 项目 |
内容 |
| 封包 ID |
777 |
| 包名 |
LCRetCheckAllowCreateChar |
| 方向 |
LC 登录服 -> 客户端 |
| 固定包长 |
4 |
| 对应请求 |
CLCheckAllowCreateChar(776) |
| 当前 Lua 状态 |
现役协议;登录服已接入并固定回 flag = 1 |
| 作用 |
返回当前账号是否允许继续创建角色 |
包体结构
当前 Game.exe 与当前 Lua 一致,这条回包固定只有一个 int32 字段:
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x04 |
flag |
int32 |
创建角色资格标记;1 表示允许继续创建,非 1 表示不允许 |
当前实际行为
- 客户端会先发送
CLCheckAllowCreateChar(776) 空包,向登录服询问当前是否允许创建角色。
- 当前登录服在收到
CLCheckAllowCreateChar 后,会直接构造 LCRetCheckAllowCreateChar 并回发。
- 当前 Lua 的
ctor() 默认把 flag 设为 1,logind.lua 里也没有再改写这个值,因此现役服务端返回结果固定为允许。
- 当前
Game.exe 可确认该包固定长度为 4 字节,读写结构只有 flag(int32)。
- 当前客户端处理逻辑里,
flag == 1 时会继续走创建角色入口;但如果本地已存在的角色数达到上限,客户端仍会弹出“角色已满”提示。
- 当前客户端处理逻辑里,
flag ~= 1 时不会进入创建角色流程,而是直接弹出禁止创建角色的提示文本。
服务端落点
- 登录协议定义:
/home/ubuntu/Game2/services/login/packet.lua
- 登录包处理:
/home/ubuntu/Game2/services/login/logind.lua
关键代码
当前 Lua 协议定义
packet.CLCheckAllowCreateChar = {
xy_id = packet.XYID_CL_CHECK_ALLOW_CREATE_CHAR,
new = function()
local o = {}
setmetatable(o, {__index = packet.CLCheckAllowCreateChar})
o:ctor()
return o
end,
ctor = function(self)
end,
bis = function(self, buffer)
local stream = bistream.new()
stream:attach(buffer)
end
}
packet.LCRetCheckAllowCreateChar = {
xy_id = packet.XYID_LC_RET_CHECK_ALLOW_CREATE_CHAR,
new = function()
local o = {}
setmetatable(o, {__index = packet.LCRetCheckAllowCreateChar})
o:ctor()
return o
end,
ctor = function(self)
self.flag = 1
end,
bis = function(self, buffer)
local stream = bistream.new()
stream:attach(buffer)
self.flag = stream:readint()
end,
bos = function(self)
local stream = bostream.new()
stream:writeint(self.flag)
return stream:get()
end
}
当前登录服回包逻辑
elseif packet.xy_id == packet_def.XYID_CL_CHECK_ALLOW_CREATE_CHAR then
ret = packet_def.LCRetCheckAllowCreateChar.new()
loginservice.send(fd, idx, ret)
当前 Game.exe 读写与包长
__int64 __fastcall LCRetCheckAllowCreateChar_Read(__int64 packet, __int64 stream)
{
read(stream, packet + 24, 4);
return 1;
}
__int64 __fastcall LCRetCheckAllowCreateChar_Write(__int64 packet, __int64 stream)
{
write(stream, packet + 24, 4);
return 1;
}
__int64 LCRetCheckAllowCreateChar_GetPacketID()
{
return 777;
}
__int64 LCRetCheckAllowCreateChar_GetPacketSize()
{
return 4;
}
当前客户端收包处理
__int64 __fastcall LCRetCheckAllowCreateChar_Execute(__int64 packet)
{
if (*(_DWORD *)(packet + 24) == 1)
{
if ((int)sub_140390520() < 3)
{
sub_140390430(qword_140911000);
return 2;
}
// 角色已满提示
}
else
{
// 禁止创建角色提示
}
return 2;
}
当前客户端对应请求包
__int64 CLCheckAllowCreateChar_Send()
{
CLCheckAllowCreateChar packet;
SendPacket(packet);
return 0;
}
结论
LCRetCheckAllowCreateChar(777) 是 CLCheckAllowCreateChar(776) 的结果回包,固定长度为 4 字节。
- 包体只有一个
flag(int32) 字段,当前版本可以明确命名为“是否允许继续创建角色”。
- 现役登录服实现固定返回
flag = 1,因此服务端侧当前等同于始终放行创建角色资格检查。
- 客户端即使收到
flag = 1,仍会继续检查当前角色数是否已满;只有通过本地上限检查后才会继续进入创建角色流程。