找回密码
 registerss
搜索
查看: 27|回复: 0

洱海月 v0-07-0300 封包解析:ID 777 LCRetCheckAllowCreateChar(创建角色资格检查结果)

[复制链接]
  • 打卡等级:本地老炮
  • 打卡总天数:603
  • 打卡月天数:1
  • 打卡总奖励:600
  • 最近打卡:2026-10-03 06:32:28
Waylee 发表于 2026-4-14 13:17 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?registerss

×

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;
}

结论

  1. LCRetCheckAllowCreateChar(777) 是 CLCheckAllowCreateChar(776) 的结果回包,固定长度为 4 字节。
  2. 包体只有一个 flag(int32) 字段,当前版本可以明确命名为“是否允许继续创建角色”。
  3. 现役登录服实现固定返回 flag = 1,因此服务端侧当前等同于始终放行创建角色资格检查。
  4. 客户端即使收到 flag = 1,仍会继续检查当前角色数是否已满;只有通过本地上限检查后才会继续进入创建角色流程。
您需要登录后才可以回帖 登录 | registerss

本版积分规则

QQ|手机版|雪舞知识库 ( 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 )|天天打卡

GMT+8, 2026-10-4 11:26 , Processed in 0.064893 second(s), 26 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表