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

洱海月 v0-07-0300 封包解析:ID 246 CGAskLockObj(物品 / 珍兽加锁与解锁请求)

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

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

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

×

CGAskLockObj 是旧版客户端里用于给物品或珍兽执行加锁、解锁申请的请求包。

包信息

项目 内容
封包 ID 246
包名 CGAskLockObj
相关回包 GCAddLockObj
相关回包 ID 365
作用 请求对指定物品或珍兽执行加锁,或发起解锁倒计时

包体结构

当前 Game.exe 与 Lua 协议定义都能确认,这条包固定为 18 字节。

偏移 长度 字段 类型 含义
0x00 0x01 obj_type uint8 目标类型:0=ITEM,1=PET
0x01 0x01 lock_type uint8 操作类型:0=LOCK,1=UNLOCK
0x02 0x08 item_guid bytes[8] 物品 GUID
0x0A 0x08 pet_guid bytes[8] 珍兽 GUID

其中:

字段 子结构 类型 含义
item_guid world uint8 物品 GUID 的 world 段
item_guid server uint8 物品 GUID 的 server 段
item_guid mask uint16 物品 GUID 的 mask 段
item_guid series uint32 物品 GUID 的 series 段
pet_guid m_uHighSection uint32 珍兽 GUID 高 32 位
pet_guid m_uLowSection uint32 珍兽 GUID 低 32 位

当前 Game.exe 的 GetPacketSize() 返回固定值:

18

当前实际行为 / 模式说明

  • 当前 Game.exe 中,CGAskLockObj::GetPacketID() 返回 246,GetPacketSize() 返回 18。
  • 当前 Game.exe 的 Read() / Write() 顺序固定为:
    • obj_type
    • lock_type
    • item_guid 8 字节
    • pet_guid 8 字节
  • 当前 Game.exe 的 Execute() 对客户端侧是空处理,直接返回。
  • 当前 Lua 请求入口 request:CGAskLockObj() 在进入场景服前,先做两层二级密码校验:
    • 未设置二级密码:返回 OR_NEED_SETMINORPASSWORD
    • 二级密码未解锁:返回 OR_NEED_UNLOCKMINORPASSWORD
  • 通过校验后,场景服 char_ask_lock_obj() 会先刷新当前角色的物品 / 珍兽解锁状态缓存。
  • 当前版本对物品与珍兽的处理分开执行:
    • obj_type == ITEM 时,按 item_guid 处理
    • obj_type == PET 时,按 pet_guid 处理
  • 当前物品查找范围包括:
    • 背包
    • 银行
  • 当前珍兽查找范围现状只处理:
    • 珍兽背包
  • 当前加锁流程:
    • 已经上锁:返回失败
    • 未上锁:立即设为锁定,清除历史解锁时间,刷新对应数据,并返回成功
  • 当前解锁流程:
    • 未上锁:返回失败
    • 已经在解锁倒计时中:返回 UNLOCKING
    • 首次发起解锁:记录未来解锁时间,刷新对应数据,并返回 UNLOCK_SUCCESS
  • 也就是说,当前版本里的“解锁成功”不是立刻清掉锁,而是进入解锁倒计时状态。

服务端落点

  • 协议定义:
    • /home/ubuntu/Game2/services/game/packet.lua
  • 请求入口:
    • /home/ubuntu/Game2/services/msgagent.lua
  • 场景处理:
    • /home/ubuntu/Game2/services/scene/scenecore.lua

关键代码

当前 Lua 协议定义

packet.CGAskLockObj = {
    xy_id = packet.XYID_CG_ASK_LOCK_OBJ,
    OBJ_TYPE = {
        ITEM = 0,
        PET = 1,
    },
    LOCK_TYPE = {
        LOCK = 0,
        UNLOCK = 1,
    },
    bis = function(self, buffer)
        local stream = bistream.new()
        stream:attach(buffer)
        self.obj_type = stream:readuchar()
        self.lock_type = stream:readuchar()
        self.item_guid = packet.ItemGUID.new()
        self.item_guid:bis(stream)
        self.pet_guid = packet.PetGUID.new()
        self.pet_guid:bis(stream)
    end
}

当前 Lua 请求入口

function request:CGAskLockObj()
    if ma_func:get_minor_password() == nil then
        ma_func:send_operate_result_msg(define.OPERATE_RESULT.OR_NEED_SETMINORPASSWORD)
        return
    end
    if not ma_func:is_minor_password_is_unlock() then
        ma_func:send_operate_result_msg(define.OPERATE_RESULT.OR_NEED_UNLOCKMINORPASSWORD)
        return
    end
    skynet.call(my_scene, "lua", "char_ask_lock_obj", my_obj_id, self)
end

当前 Lua 场景处理

function scenecore:char_ask_lock_obj(me, request)
    local obj_me = self.objs[me]
    if not obj_me then
        return
    end

    obj_me:refresh_locked_item_unlock_state(true)
    obj_me:refresh_locked_pet_unlock_state(true)

    local function send_lock_result(obj_type, result)
        local msg = packet_def.GCAddLockObj.new()
        msg.obj_type = obj_type
        msg.result = result
        self:send2client(obj_me, msg)
    end
    ...
end
if request.lock_type == packet_def.CGAskLockObj.LOCK_TYPE.LOCK then
    item:set_lock(true)
    obj_me:clear_item_unlock_time_by_guid(item:get_guid())
    send_item_info(container_kind, bag_index)
    send_lock_result(obj_type, packet_def.GCAddLockObj.RESULT.LOCK_SUCCESS)
    return
end

if request.lock_type == packet_def.CGAskLockObj.LOCK_TYPE.UNLOCK then
    if obj_me:is_item_unlocking_by_guid(item:get_guid()) then
        send_item_info(container_kind, bag_index)
        send_lock_result(obj_type, packet_def.GCAddLockObj.RESULT.UNLOCKING)
        return
    end

    obj_me:set_item_unlock_time_by_guid(item:get_guid(), os.time() + obj_me:get_item_unlock_delay_seconds())
    send_item_info(container_kind, bag_index)
    send_lock_result(obj_type, packet_def.GCAddLockObj.RESULT.UNLOCK_SUCCESS)
    return
end

当前 Game.exe 的读写与执行结论

GetPacketID() = 246;
GetPacketSize() = 18;

Read(stream) {
    read_u8(obj_type);
    read_u8(lock_type);
    read_bytes(item_guid, 8);
    read_bytes(pet_guid, 8);
}

Write(stream) {
    write_u8(obj_type);
    write_u8(lock_type);
    write_bytes(item_guid, 8);
    write_bytes(pet_guid, 8);
}

Execute() {
    return 2;
}

结论

这条包在当前旧版项目里要记住六点:

  1. CGAskLockObj 的封包 ID 是 246。
  2. 它是固定 18 字节结构:obj_type + lock_type + item_guid(8) + pet_guid(8)。
  3. 当前版本支持两类目标:0=ITEM、1=PET;支持两类操作:0=LOCK、1=UNLOCK。
  4. 这条包在进入场景服前,必须先通过二级密码已设置且已解锁的校验。
  5. 当前物品锁定支持背包和银行,当前珍兽锁定现状只处理珍兽背包。
  6. 当前版本的“解锁成功”含义是开始解锁倒计时,不是立刻清除锁状态。
您需要登录后才可以回帖 登录 | registerss

本版积分规则

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

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

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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