CGSelectTargetOfObject 是当前客户端仍保留的一条“对象目标选择”上行包。按当前 Game.exe 现状,这条包固定长度为 4 字节,包体只有一个 int32 字段;客户端包类本身保留了完整的 Read / Write / GetPacketID / GetPacketSize,但 Execute() 已经是空返回。当前 Lua Game2 主链没有这条协议的定义,也没有发现请求入口;现役目标相关主链实际使用的是 CGLockTarget(115)。
包信息
| 项目 |
内容 |
| 封包 ID |
601 |
| 包名 |
CGSelectTargetOfObject |
| 对应回包 |
无专用回包 |
| 作用 |
客户端向服务端上报一次对象目标选择;当前现役 Lua 主链未接入 |
当前 Game.exe 的虚函数结论为:
CGSelectTargetOfObject
GetPacketID() = 0x1405EC7D0 -> 601;
GetPacketSize() = 0x1403A0C40 -> 4;
Read = 0x1405C6D30;
Write = 0x140606B30;
Execute thunk = 0x1405C6B90 -> 0x1403288E0 -> 2;
包体结构
按当前 Game.exe 的 Read / Write 逻辑,这条包固定为 4 字节。
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x04 |
target_obj_id |
int32 |
目标场景对象 ID;当前类工厂默认值为 0 |
把字段整理为 target_obj_id 的依据主要有两层:
- 当前包名直接指向“选择某个对象作为目标”。
- 当前现役同类目标锁定请求
CGLockTarget(115) 也是固定 4 字节单字段结构,Lua 侧把它明确读取为 target_id = stream:readint()。
总长度为:
0x04 = 4 字节
当前实际行为
- 当前
Game.exe 明确保留了 CGSelectTargetOfObject 的完整包类,结构上是一条固定 4 字节的单字段请求。
- 当前工厂函数构造默认实例时,会把唯一字段初始化为
0。
- 当前客户端
Execute() 仅返回常量 2,没有继续展开本地逻辑,因此它更像一条旧上行协议壳,而不是仍在客户端内部承载复杂流程的现役请求。
- 当前 Lua
Game2 主链未定义 CGSelectTargetOfObject 协议,也未发现 request:CGSelectTargetOfObject() 或任何同名处理入口。
- 当前现役目标相关主链实际走的是
CGLockTarget(115):
msgagent.lua 接收请求后转到场景层;
scenecore.lua 调用 set_locked_target(target_id);
- 场景对象把目标记录到本地
locked_target。
- 与之对应的下行旧包
GCSelectTarget(581) 也已经补档,现状同样是客户端保留、Lua 主链未发送。
- 因此,
CGSelectTargetOfObject 更适合视为客户端保留的旧目标选择请求;在当前项目中,它已经被更直接的 CGLockTarget 现役链路替代。
服务端落点
当前检查以下现役 Lua 主链位置,均未检出 CGSelectTargetOfObject:
/home/ubuntu/Game2/services/game/packet.lua
/home/ubuntu/Game2/services/msgagent.lua
/home/ubuntu/Game2/services/scene/scenecore.lua
/home/ubuntu/Game2/services/scene/obj
当前真正落地的目标锁定链路为:
- 协议定义:
/home/ubuntu/Game2/services/game/packet.lua
- 请求入口:
/home/ubuntu/Game2/services/msgagent.lua
- 场景处理:
/home/ubuntu/Game2/services/scene/scenecore.lua
- 对象记录:
/home/ubuntu/Game2/services/scene/obj/character.lua
关键代码
以下代码块中,将 sub_1403F9B00 按读取/写入语义简化记为 read_u32 / write_u32,便于对照结构理解。
当前 Game.exe 的读写与空执行
__int64 __fastcall sub_1405C6D30(__int64 a1, __int64 a2)
{
read_u32(a2, a1 + 24);
return 1;
}
__int64 __fastcall sub_140606B30(__int64 a1, __int64 a2)
{
write_u32(a2, a1 + 24);
return 1;
}
__int64 sub_1403288E0()
{
return 2;
}
当前 Game.exe 的默认构造
_DWORD *sub_1405E0220()
{
_DWORD *v1 = operator new(0x20u);
if ( !v1 )
return nullptr;
sub_1403F94D0((__int64)v1);
*(_QWORD *)v1 = &Packets::CGSelectTargetOfObject::`vftable';
v1[6] = 0;
return v1;
}
当前现役目标锁定请求对照
packet.CGLockTarget = {
xy_id = packet.XYID_CG_LOCK_TARGET,
new = function(o)
o = o or {}
setmetatable(o, {__index = packet.CGLockTarget})
o:ctor()
return o
end,
ctor = function(self) self.target_id = 0 end,
bis = function(self, buffer)
local stream = bistream.new()
stream:attach(buffer)
self.target_id = stream:readint()
end
}
function request:CGLockTarget()
skynet.call(my_scene, "lua", "char_lock_target", my_obj_id, self)
end
function scenecore:char_lock_target(me, lock)
local obj_me = self.objs[me]
if obj_me then
obj_me:set_locked_target(lock.target_id)
end
end
结论
CGSelectTargetOfObject 的封包 ID 是 601,固定长度 4 字节。
- 当前
Game.exe 明确确认,包体只有一个 int32 类型字段,最稳妥的命名是 target_obj_id。
- 当前客户端仍保留这条包的完整读写结构,但
Execute() 已经为空返回。
- 当前 Lua
Game2 主链没有这条包的协议定义和请求入口,现役目标选择/锁定流程使用的是 CGLockTarget(115)。
- 因此在
Temp_Release_v0-07-0300 现状下,CGSelectTargetOfObject 更适合视为客户端保留的旧对象目标选择请求,而不是当前 Lua 主链中的现役协议。