129 lines
7.8 KiB
Go
129 lines
7.8 KiB
Go
package methods
|
||||
|
|
|
|||
|
|
// ---------------------------------------------------------------- agent commands(donor1 第 39/40 轮实机验证)
|
|||
|
|
//
|
|||
|
|
// <c>SyncLogicAgentCommand(ulong agentId, int commandId, AgentCommandData data)</c> 是唯一能给
|
|||
|
|
// 服务端接管的 logic agent 派<b>移动任务</b>的通道:客户端的 LogicBehaviorSchedulerModule 负责跑
|
|||
|
|
// 任务 —— ZoneGraph 寻路、避障、以及随之而来的 locomotion 状态;纯位置流(SyncLogicAgentSyncData)
|
|||
|
|
// 不携带任何任务,产生不了步态(donor1 第 39 轮实测:Servo 流 = 走两秒动画然后站住)。
|
|||
|
|
//
|
|||
|
|
// 每个 AgentCommandData 具体子类的线格式由反汇编客户端得到(GameAssembly, image base 0x180000000):
|
|||
|
|
// TypeSerializer.ReadStaticAgentCommandData RVA 0x9EAA8A0 - reads the tag byte and dispatches
|
|||
|
|
// jump table RVA 0x1DAC574 - 45 entries for tag 3..47
|
|||
|
|
// ReadTaskWayPointMoveCommandData RVA 0x9F67ED0
|
|||
|
|
// ReadTaskMoveCommandData RVA 0x9F66940
|
|||
|
|
// ReadMoveCommandData RVA 0x9F1DA10
|
|||
|
|
// ReadNavigationMoveCommandData RVA 0x9F1F870
|
|||
|
|
// ReadZoneGraphPathCommandData RVA 0x9F745A0
|
|||
|
|
// ReadClientZoneGraphPathPoint RVA 0x9EF12A0
|
|||
|
|
// 一个具体命令 = <b>一个 tag 字节</b> + 扁平化字段(0x00 = null,0xFF = 基类型,具体子类 = 自己的 tag),
|
|||
|
|
// 这正是 [UxContract(TypeMark = n)] 写出来的东西。tag = 类型名按字母序从 3 起的位置:
|
|||
|
|
// 47 = ZoneGraphPathCommandData, 39 = TaskWayPointMoveCommandData, 28 = MoveCommandData,
|
|||
|
|
// 31 = NavigationMoveCommandData, 38 = TaskMoveCommandData, 27 = MotionLookAtCommandData.
|
|||
|
|
// Drmk.Proxy 里的 Lua 表(RPCDeserializeAuto.Concrete / Auto.Reader)偏了 1(key = 真实 tag - 1),
|
|||
|
|
// ⛔ 不能当 tag 来源(与 KNOWLEDGEBASE「crowd locomotion 是纯 C#」互证)。
|
|||
|
|
//
|
|||
|
|
// 两个基类贡献每个命令的最后三字节,顺序如下(IL2CPP 偏移):
|
|||
|
|
// AgentMoveTokenCommandData.MoveId [0x18] 1 字节;
|
|||
|
|
// AgentCommandData.DataSource [0x10] 占 <b>2</b> 字节(enum 是 byte 底、但客户端读 1 字节后
|
|||
|
|
// 游标前进 2 —— 第二字节是 padding,也必须发)。非 stim 来源的命令 DataSource = Other(255),
|
|||
|
|
// MoveId = 0(客户端自己的移动上报里就是 0)。
|
|||
|
|
// UX ByteAngle: one byte quantised yaw, the last byte of a ClientZoneGraphPathPoint.
|
|||
|
|
// One point of a path command (client reader ReadClientZoneGraphPathPoint 0x9EF12A0):
|
|||
|
|
// three singles then one byte, 13 bytes per point.
|
|||
|
|
//
|
|||
|
|
// ZoneGraphPathCommandData - wire tag 47, LogicAgentCommandType.ZoneGraphPath (2).
|
|||
|
|
// The client picks the lane itself and walks the agent towards these world positions, which is why
|
|||
|
|
// TargetLocationReason exists: it tells the navigation what the points mean (1 = Wander).
|
|||
|
|
//
|
|||
|
|
//
|
|||
|
|
// TaskWayPointMoveCommandData - wire tag 39, LogicAgentCommandType.TaskWayPointMove (8).
|
|||
|
|
// The self-contained variant: it carries the speed, the move action and the animation group with the
|
|||
|
|
// waypoints, so the client needs no navigation data at all to run the walk.
|
|||
|
|
// ★ donor1 第 51 轮用户亲测:这就是"完整路人"(一直有走路动画、会移动、到目的地停下)的驱动协议。
|
|||
|
|
//
|
|||
|
|
// AgentCommandDataSource (client enum, values from the IL2CPP dump).
|
|||
|
|
const (
|
|||
|
|
LogicAgentCommandDataSources_None int16 = 0
|
|||
|
|
LogicAgentCommandDataSources_Stim int16 = 1
|
|||
|
|
LogicAgentCommandDataSources_Other int16 = 255
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// The remaining two walks are the "aim at one target" family - MoveCommandData (tag 28) and
|
|||
|
|
// NavigationMoveCommandData (tag 31, the same fields preceded by the navigation tolerances). Both aim at a
|
|||
|
|
// ClientActionTarget, which is why the position target needs StimTargetType.Position: the client resolves
|
|||
|
|
// the command against that enum, and a target of type None would be thrown away as "nothing to do".
|
|||
|
|
// Field order is again "most derived class first", read straight off the client readers
|
|||
|
|
// ReadMoveCommandData (0x9F1DA10) and ReadNavigationMoveCommandData (0x9F1F870).
|
|||
|
|
// StimTargetType (client enum, values from the IL2CPP dump).
|
|||
|
|
const (
|
|||
|
|
StimTargetTypes_None byte = 0
|
|||
|
|
StimTargetTypes_Player byte = 1
|
|||
|
|
StimTargetTypes_Agent byte = 2
|
|||
|
|
StimTargetTypes_Destructible byte = 3
|
|||
|
|
StimTargetTypes_Position byte = 4
|
|||
|
|
StimTargetTypes_Vehicle byte = 5
|
|||
|
|
StimTargetTypes_Metro byte = 6
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// MovementMethod (client enum, values from the IL2CPP dump): the gait a move picks.
|
|||
|
|
const (
|
|||
|
|
AgentMovementMethods_Dynamic byte = 0
|
|||
|
|
AgentMovementMethods_Walk byte = 1
|
|||
|
|
AgentMovementMethods_Run byte = 2
|
|||
|
|
AgentMovementMethods_Flee byte = 3
|
|||
|
|
AgentMovementMethods_MatchPlayer byte = 4
|
|||
|
|
AgentMovementMethods_Appointed byte = 5
|
|||
|
|
AgentMovementMethods_FearWalk byte = 6
|
|||
|
|
AgentMovementMethods_VariablePaceMove byte = 7
|
|||
|
|
AgentMovementMethods_Scurry byte = 8
|
|||
|
|
AgentMovementMethods_Rush byte = 9
|
|||
|
|
AgentMovementMethods_PogoStick byte = 10
|
|||
|
|
AgentMovementMethods_Skateboard byte = 11
|
|||
|
|
AgentMovementMethods_Prowl byte = 12
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// ClientActionTarget - client reader ReadClientActionTarget 0x9B3AF40: what a move
|
|||
|
|
// command aims at. A plain world position is StimTargetTypes.Position with the id left at
|
|||
|
|
// zero.
|
|||
|
|
// MoveCommandData - wire tag 28, LogicAgentCommandType.Move (1).
|
|||
|
|
//
|
|||
|
|
// NavigationMoveCommandData - wire tag 31, LogicAgentCommandType.NavigationMove. Same payload as
|
|||
|
|
// MoveCommandData with the three navigation fields in front; the client navigates to the
|
|||
|
|
// target itself instead of walking straight at it.
|
|||
|
|
//
|
|||
|
|
//
|
|||
|
|
// Body of SyncLogicAgentCommand (mid 68050574) with a zone graph path payload. The marker byte
|
|||
|
|
// written in front of data is the declared field type's, so this body is only correct for
|
|||
|
|
// ZoneGraphPathCommandData - hence one body per command kind instead of one body with a
|
|||
|
|
// base typed field.
|
|||
|
|
//
|
|||
|
|
// Body of SyncLogicAgentCommand (mid 68050574) with a waypoint move payload.
|
|||
|
|
// Body of SyncLogicAgentCommand (mid 68050574) with a plain move payload.
|
|||
|
|
// Body of SyncLogicAgentCommand (mid 68050574) with a navigating move payload.
|
|||
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|||
|
|
// 回报侧(2026-09-24 自捐赠端 DremkaPS 移植)
|
|||
|
|
//
|
|||
|
|
// SyncLogicAgentCommand 对服务端是 fire-and-forget:客户端装了这条命令、还是拿到就丢了,
|
|||
|
|
// 在出站日志里长得一模一样。下面这两条就是客户端的回答 —— 有了它们,
|
|||
|
|
// 「行人还是不走」才能细分成「收了 12 条一条没跑」还是「每一条都被拒了」。
|
|||
|
|
// 布局照抄客户端自己的 writer(RPCSerializeAuto.WriteLogicAgentCommandSuccessData /
|
|||
|
|
// WriteLogicAgentCommandReportData)。
|
|||
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|||
|
|
//
|
|||
|
|
// Client -> server WriteLogicAgentCommandSuccessData:一条命令的回执。
|
|||
|
|
// ⛔⛔ 本服不用这个契约解包 —— 它照抄自捐赠端 DremkaPS,而捐赠端声称
|
|||
|
|
// AskReportLogicAgentCommandSuccess2(67057559) 与 AskReportLogicAgentCommandFail(67193144)
|
|||
|
|
// 共用这一个 12 字节布局(u64 + int,无标记)。本服抓包证伪了这一点:
|
|||
|
|
// <code>
|
|||
|
|
// Success2 bytes=14 FF 02 | u64 agentId | int commandId
|
|||
|
|
// Fail bytes=16 u64 agentId | int commandId | int 0
|
|||
|
|
// </code>
|
|||
|
|
// 两条的 agentId 起点不同(2 与 0),长度也不同。实际解析走
|
|||
|
|
// GameRouter.AgentCommandAck.cs 的 TryReadCommandAck(按实测偏移读字节)。
|
|||
|
|
// 保留这个契约仅供参考,别拿它去 TryGetArgs。
|
|||
|
|
//
|
|||
|
|
//
|
|||
|
|
// Client -> server WriteLogicAgentCommandReportData(AskReportLogicAgentCommandData2
|
|||
|
|
// 67780469):一个 agent 的状态 / 层报告。Data 是 7Bit 计数的字节列表。
|
|||
|
|
//
|