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/ride_methods4229938.go
T

72 lines
4.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
//
// 骑乘 / 厕所 QTE(马桶鸵鸟)契约 — 处理器在 GameRouter.ToiletQte.cs。
// <para>★★ 触发链(2026-09-30 从客户端反查,三条证据都实锤)</para>
// <list type="number">
// <item>Lua/LuaFiles/LX6/SGUI/StoreDefine/ToiletOstrichGamePanelStore.lua 就是那个 QTE 面板:
// 音游式三键判定,本地常量 QTE_DURATION=2 / PERFECT_WINDOW=0.1 /
// GREAT_WINDOW=0.2,满分 100(perfect 30 / normal 20)。判定纯客户端,
// 服务端不参与打分。</item>
// <item>面板由 C#→lua 回调打开,不是服务端推的:
// LX6/Manager/CsToLuaHandler.lua 里
// module.OnStartRideQTE(riderPid, beRidenPid) ⇒
// gPanelManager:CheckShow(gPanelId.TOILET_OSTRICH_GAME_PANEL, { npcPid = beRidenPid })。
// 所以 C# 只在「骑乘成立」时才 fire ⇒ 我们要做的是让骑乘坐实。</item>
// <item>面板里 SceneDataMgr.GetUnit(self.npcPid) ⇒ 被骑的那只必须是**世界里真实存在的 unit**。</item>
// </list>
// <para>★★ 马桶鸵鸟 = 标准 Agent,不是 Gadget / SceneItem</para>
// NpcCatalog.json 里 5 条同名(40122028 / 40652007 / 40922011 / 42046401 / 45000446),
// 同一具模型 GeneralModelId=86963029,EnemyClassType=1(与普通敌人同类),
// faction 18000300「通用怪物」;AgentConfig.ToiletOstrich = 42046401 是客户端自己的常量。
// 骑乘能力由**客户端 AI 状态树**给出(MassAI.Npc.MassAetherAI.Tasks.TryOnRideAgent /
// TryDownRideAgent,走 BehaviorActionConfigId 40214321 + AISetting 40213146),
// 服务端不需要给任何「可骑」标记 ⇒ 现有的 NPC/敌人生成通道(GameAdminBridge.SpawnAgentAsync)
// 直接就能出。
//
//
// AskRideAgent(67575069) —— 玩家请求骑上 agentId 这只单位。
// <para>形状(LuaGen/AutoGen/ClientToGameSceneDelegate.lua:3314,C2S Invoke):
// SerializeBase.WritePrimitive(writer, agentid, writer.WriteUInt64, 0) ⇒ 单个 u64。</para>
// 回包(RPCDeserializeAuto.lua:15516 midToReturnMessageReader[67575069])
// 函数体是空的 ⇒ 服务端必须回 0 字节;ReturnEmptyOkAsync 正是这个形状。
// ⛑ DefaultReturnCatalog4229938 里 没有 这个 mid ⇒ 不注册的话框架会走
// ReturnEmptyOkAsync 兜底,**形状恰好也是对的**,所以这一条不注册也未必报错;
// 注册的意义是:能观测(打日志)、以及把「骑上去了」这件事变成服务端可推的状态。
//
//
// AskToiletOstrichFlee(67154315) —— QTE 失败时**客户端主动上报**「鸵鸟跑了」。
// <para>形状(ClientToGameSceneDelegate.lua:945-951):self.Notify(self, 67154315, …)
// ⇒ Notify,不是 Invoke(无回包);载荷单个 u64 agentid。</para>
// 调用点是 ToiletOstrichGamePanelStore.lua:485 的失败分支:
// <code>
// gCS.BaseUnitUtils.DismountCheckScore()
// gCS.LogicStateMachineManager.SendGameplayInwardSignal(unit, 5754)
// gClientToGameSceneDelegate:AskToiletOstrichFlee(self.npcPid)
// </code>
// 成功分支则是 SendGameplayInwardSignal(unit, 5753),**不发这条**。
// ⛑ 因为它是 Notify,不注册只会落进 DefaultUnknownNotify(无害),但服务端就永远不知道
// QTE 失败过 ⇒ 这条必须接住,否则「鸵鸟该跑不跑」。
//
//
// SyncRideAgent(68906846) —— 服务端权威的骑乘状态(IGameSceneToClient.SyncRideAgent
// (ulong rider, ulong ridee, bool hasRideOn))。
// <para>形状:RPCDeserializeAuto.lua:7142 midToReader[68906846] 读
// UInt64 + UInt64 + Boolean = 17 字节,无对象 marker ⇒ Inline = true;
// 且 midToExportOption[68906846] = LuaAndCSharp(lua 侧也有 reader)。</para>
// ⛑ 是否必需尚未实测:OnStartRideQTE 也可能由 AskRideAgent 的回包路径直接 fire。
// 所以这条挂在开关 gameplay.toiletQte.pushRideState 后面,**默认关**;
// 若只注册骑乘回执时面板不出,把它打开(这与自动驾驶那条「服务端推状态」是同一个模式,
// 见 GameRouter.VehicleNav.cs 的包序教训:状态包要**早于**动作包)。
//
//
// SyncToiletPosture(68122107) —— 马桶鸵鸟的「蹲 / 起」姿态。
// <para>形状:ulong agentId + bool isSquatting = 9 字节(Inline = true)。
// ⛑ RPCDeserializeAuto.lua:714 把它标成 CSharpOnly ⇒ lua 侧没有 reader,
// 只由 C# 表现层消费。**别指望在 lua 日志里看到它**,判据只能在实机画面上。</para>
// ⛔ 官方还有一个「直接生成一只蹲着的马桶」的 GM 入口
// GmCreateToilet / GmCreateToiletSquatting(69686776 / 69250152,**无参** C2S GM Invoke),
// 那是开发调试用的,我们不走那条路(我们的生成都在服务端,见面板的
// /api/agent/spawn)⇒ 这条 S2C 挂在开关 gameplay.toiletQte.pushPosture 后面,默认关。
//