This repository has been archived on 2026-10-31. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Ananta-ps/pkg/protocol/methods/logic_agent_command_methods.go
T

130 lines
7.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 -&gt; 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 -&gt; server WriteLogicAgentCommandReportData(AskReportLogicAgentCommandData2
// 67780469):一个 agent 的状态 / 层报告。Data 是 7Bit 计数的字节列表。
//