package routers import ( "context" "sync" ) var _ = sync.Mutex{} var _ = context.Background // // 马桶坐骑的原生操控桥:让骑乘状态下的「加速 / 跳跃」按键真的送到坐骑身上 // (2026-10-02 自 7k-v0.6 捐赠端 GameRouter.ToiletControls.cs 逐字搬运)。 // ★ 为什么需要这一段 Lua:客户端 GameplayMountPanelStore 本来就会把 // JumpPress/Release、DashPress/Release 通过 // UnitAttachModule.CheckAndSend3CEventToRideTarget(RVA 0x11CFBCE0)转给坐骑, // 但这条路被骑手自身的战斗 / 跑酷输入闸门挡住了(骑着马桶时按键被判定成人物动作)。 // 本桥直接把同一批 3C 事件送到已确认的挂载目标,绕过那道闸门。 // ★ 挂的钩子(原生 HUD 回调,不是硬编码轮询按键): // C_GameplayMountPanelStore.OnRushBtnPress/Release(加速)、 // OnJumpBtnPress/Release(跳跃)、 // C_CoreHudCharacterControlStore.OnJumpSwingBtnPress/Release、 // gBattleMgr.HighSpeedDown/Up。 // ⛑⛑ 边界(捐赠端原注释,别自行夸大): // "Animation, speed and jump physics remain native; event delivery is NOT proof // that an incomplete client animal graph implements every transition." // ⇒ 这段只保证事件送达;坐骑动画图里缺的过渡(比如马桶鸵鸟根本没有冲刺状态)送到了也不会动。 // ⛑ 安全设计(照抄,别改): // // 只在 PlayerIsRiding() 且 GetAttachUnitID(pid) == mountUid 时才转发 // —— 必须是真正的原生挂载,不是旁边站着一只沙盒 NPC。 // 0.1s 定时器 + Application.isFocused 检查 ⇒ 下马 / QTE / 重生 / 失焦后 // 一定会补一条 Release,不会把加速或跳跃卡在按下状态。 // QTE 面板 TOILET_OSTRICH_GAME_PANEL 显示期间不转发,避免和音游判定抢按键。 // mode='clear' 会反注册全部钩子并清状态,不留残留。 // // ★ 触发点:GameRouter.ToiletQte.PublishToiletRideAsync —— // 上马(enter=true)下发 arm,下马 / 逃跑(enter=false)下发 clear。 // 开关 gameplay.toiletQte.nativeControls(默认 true)。 // ⛑ 回滚:① 配置里 nativeControls=false(最快,不下发 Lua); // ② 删本文件 + 撤 PublishToiletRideAsync 里那一次调用(备份 // GameRouter.ToiletQte.cs.bak-20261002-toiletcontrols)。 // 客户端文件一个都没动,Lua 走的是已有 GATE 通道。 // // // 下发 / 撤销坐骑操控桥。 // // 游戏会话(GATE 会话从它身上取,取不到就只记日志,不抛)。 // 骑手 unit uid(脚本里的 owner,用来确认「是本人在操作」)。 // 坐骑 unit uid(脚本里的 npc,事件转发目标)。 // ToiletControlsArm 或 ToiletControlsClear。 func GameRouter_ToiletControls_PublishToiletControls4229938(ctx context.Context, session *GameSession, rider uint64, mount uint64, mode string) any { // Router implementation for GameRouter_ToiletControls_PublishToiletControls4229938 var zero any; return zero }