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;
}
结论
这条包在当前旧版项目里要记住六点:
CGAskLockObj 的封包 ID 是 246。
- 它是固定
18 字节结构:obj_type + lock_type + item_guid(8) + pet_guid(8)。
- 当前版本支持两类目标:
0=ITEM、1=PET;支持两类操作:0=LOCK、1=UNLOCK。
- 这条包在进入场景服前,必须先通过二级密码已设置且已解锁的校验。
- 当前物品锁定支持背包和银行,当前珍兽锁定现状只处理珍兽背包。
- 当前版本的“解锁成功”含义是开始解锁倒计时,不是立刻清除锁状态。