package methods
// ---------------------------------------------------------------- agent commands(donor1 第 39/40 轮实机验证)
//
// SyncLogicAgentCommand(ulong agentId, int commandId, AgentCommandData data) 是唯一能给
// 服务端接管的 logic agent 派移动任务的通道:客户端的 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
// 一个具体命令 = 一个 tag 字节 + 扁平化字段(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] 占 2 字节(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,无标记)。本服抓包证伪了这一点:
//
// Success2 bytes=14 FF 02 | u64 agentId | int commandId
// Fail bytes=16 u64 agentId | int commandId | int 0
//
// 两条的 agentId 起点不同(2 与 0),长度也不同。实际解析走
// GameRouter.AgentCommandAck.cs 的 TryReadCommandAck(按实测偏移读字节)。
// 保留这个契约仅供参考,别拿它去 TryGetArgs。
//
//
// Client -> server WriteLogicAgentCommandReportData(AskReportLogicAgentCommandData2
// 67780469):一个 agent 的状态 / 层报告。Data 是 7Bit 计数的字节列表。
//