147 lines
7.6 KiB
Go
147 lines
7.6 KiB
Go
package routers
|
||||
|
|
|
|||
|
|
import (
|
|||
|
|
"context"
|
|||
|
|
"sync"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
var _ = sync.Mutex{}
|
|||
|
|
var _ = context.Background
|
|||
|
|
|
|||
|
|
//
|
|||
|
|
// 巡卫官(里希 / 15021021)执勤终端里的三条派遣,C2S 都是 AskPoliceDispatch(63500791),
|
|||
|
|
// 只靠 dispatchid 区分:
|
|||
|
|
// <code>
|
|||
|
|
// PoliceDispatchCatalog.json
|
|||
|
|
// Id=2 NCCA Dog 巡卫犬 SkillId 51938184 / SwitchSkillId 51938186
|
|||
|
|
// Id=3 Helicopter Search 直升机搜查 SkillId 0 → 走 S2C SyncPoliceDispatchHelicopter(68359668)
|
|||
|
|
// Id=4 Armed Support 战术支援 SkillId 0 Des「冲锋枪2人」,DialogId 100025472
|
|||
|
|
// </code>
|
|||
|
|
// 2026-09-24 抓包:按钮一直在发,服务端一直在回空 OK。
|
|||
|
|
// logs/packets-20260924-233242.log:209939 23:46:42 C2S AskPoliceDispatch id=3,
|
|||
|
|
// 服务端 DefaultUnknownInvoke4229938 回 error=0 body=0b ⇒ 客户端不卡死,
|
|||
|
|
// 但世界上什么也没发生。unknown-methods.log 里 09-21 还有 id=2/3/4 各一次。
|
|||
|
|
// 本文件只接管 dispatchid=4(战术支援)。2 走技能链(GameRouter.HackerSummon.cs),
|
|||
|
|
// 3(直升机)契约只有两个参数但目前没有实体模板可刷,先留日志位。
|
|||
|
|
// ⛑ 硬规则 94:光写 [Handler] 不算注册,GameRouter.cs 的
|
|||
|
|
// Enabled4229938MethodIds 必须同步加 MethodId.AskPoliceDispatch,
|
|||
|
|
// 否则编译通过、功能零生效,而这是个 INVOKE —— 客户端会 await 到超时。
|
|||
|
|
//
|
|||
|
|
// =================================================================================
|
|||
|
|
// ① C2S AskPoliceDispatch(63500791)
|
|||
|
|
// =================================================================================
|
|||
|
|
//
|
|||
|
|
// 执勤终端 / 轮盘的派遣按钮。INVOKE —— 客户端 gReliableRpcManager 等回执,
|
|||
|
|
// 无论 dispatchid 认不认都得先回 empty OK,否则按钮 await 永不落地。
|
|||
|
|
//
|
|||
|
|
func GameRouter_PoliceDispatch_AskPoliceDispatch(ctx context.Context, conn any, msg any) any {
|
|||
|
|
// Router implementation for GameRouter_PoliceDispatch_AskPoliceDispatch
|
|||
|
|
var zero any; return zero
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func GameRouter_PoliceDispatch_OnPoliceDispatch(ctx context.Context, rpcCtx *RpcContext, dispatchId uint32) any {
|
|||
|
|
// Router implementation for GameRouter_PoliceDispatch_OnPoliceDispatch
|
|||
|
|
var zero any; return zero
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// =================================================================================
|
|||
|
|
// ② 战术支援:刷两个友方冲锋枪巡卫官
|
|||
|
|
// =================================================================================
|
|||
|
|
func GameRouter_PoliceDispatch_DispatchArmedSupportAsync(ctx context.Context, rpcCtx *RpcContext) any {
|
|||
|
|
// Router implementation for GameRouter_PoliceDispatch_DispatchArmedSupportAsync
|
|||
|
|
var zero any; return zero
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//
|
|||
|
|
// 收掉当前在场的支援单位。SpawnAgentAsync 出来的单位配对的移除通道是
|
|||
|
|
// SyncLogicAgentLeave(68281244)(第一句话是 SyncLogicAgentEnter)—— 与
|
|||
|
|
// GameRouter.HackerSummon.cs 里回收召唤物用的是同一条,别用 SyncAetherAINpcRemove(那是
|
|||
|
|
// ambient 行人 / functional NPC 的通道,对这类单位发了等于没发)。
|
|||
|
|
//
|
|||
|
|
func GameRouter_PoliceDispatch_DismissArmedSupportAsync(ctx context.Context, rpcCtx *RpcContext) any {
|
|||
|
|
// Router implementation for GameRouter_PoliceDispatch_DismissArmedSupportAsync
|
|||
|
|
var zero any; return zero
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// =================================================================================
|
|||
|
|
// ②b 直升机载具:让场景里真的出现一架直升机
|
|||
|
|
//
|
|||
|
|
// ⛑ 这是替代方案,不是官方实现的复刻 —— 官方直升机搜查面板在 build 4229938 里是半成品
|
|||
|
|
// (硬规则 134:无 Open 入口 / SyncPoliceDispatchHelicopter 空实现 / dump.cs 无 C# 类),
|
|||
|
|
// 服务端再怎么接也只是在后台记账。刷这台载具是唯一能"看见直升机"的手段。
|
|||
|
|
// =================================================================================
|
|||
|
|
//
|
|||
|
|
// 刷一台搜查直升机载具(81007007 Helicopter01a_Rope)。
|
|||
|
|
// ⛑ SpawnDirectAsync 内部自带 replacement:刷之前会把 runtime.SummonedEntity
|
|||
|
|
// 上那台(可能是玩家自己召唤的车)DestroyVehicleAsync 掉。这里只提前打一行
|
|||
|
|
// warn,不拦 —— 玩家点「直升机搜查」时通常没在开车,而且顶掉比堆车好。
|
|||
|
|
// 落点是玩家右侧 5.5 m、+0.15 m(SpawnDirectAsync 里的 proven offset)。对直升机来说
|
|||
|
|
// 就是停在旁边地面上,不需要抬高度(抬了反而会卡在半空下不来)。
|
|||
|
|
//
|
|||
|
|
func GameRouter_PoliceDispatch_SpawnHelicopterVehicleAsync(ctx context.Context, rpcCtx *RpcContext) bool {
|
|||
|
|
// Router implementation for GameRouter_PoliceDispatch_SpawnHelicopterVehicleAsync
|
|||
|
|
return true
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//
|
|||
|
|
// 收掉这架搜查直升机(一轮搜查结束时调)。
|
|||
|
|
// 走 DestroyVehicleAsync ⇒ S2C SyncDestroyVehicle,与玩家召唤车 / 交通车
|
|||
|
|
// 用的是同一条通道,不是 SyncLogicAgentLeave(那是 agent 的)。
|
|||
|
|
//
|
|||
|
|
func GameRouter_PoliceDispatch_DismissHelicopterVehicleAsync(ctx context.Context, rpcCtx *RpcContext) any {
|
|||
|
|
// Router implementation for GameRouter_PoliceDispatch_DismissHelicopterVehicleAsync
|
|||
|
|
var zero any; return zero
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//
|
|||
|
|
// C2S AskHelicopterNpc(67113443),INVOKE —— 玩家在直升机视角里框住一个 NPC 并下判定。
|
|||
|
|
// ⛑⛑ 这条以前不在 Enabled4229938MethodIds 里,等于走中性兜底;而它是 INVOKE,
|
|||
|
|
// 客户端四个调用点(PoliceHelicopterPanelStore.lua:162 / :378 / :470 / :558)全在用
|
|||
|
|
// gReliableRpcManager:RegisterRPC 等回调 ⇒ 面板会卡在"点了没反应"。
|
|||
|
|
// 硬规则 94 的老坑,别再踩。
|
|||
|
|
//
|
|||
|
|
func GameRouter_PoliceDispatch_AskHelicopterNpc(ctx context.Context, conn any, msg any) any {
|
|||
|
|
// Router implementation for GameRouter_PoliceDispatch_AskHelicopterNpc
|
|||
|
|
var zero any; return zero
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//
|
|||
|
|
// C2S AskHelicopterScanChange(67898923),NOTIFY —— 直升机扫描开关。
|
|||
|
|
// 客户端用的是 self.Notify(ClientToGameSceneDelegate.lua:5198),没有回执;
|
|||
|
|
// 这里登记 Both 兜住,将来客户端改成 Invoke 也不用改代码(AskControlAgent 那次就是这么栽的)。
|
|||
|
|
//
|
|||
|
|
func GameRouter_PoliceDispatch_AskHelicopterScanChange(ctx context.Context, conn any, msg any) any {
|
|||
|
|
// Router implementation for GameRouter_PoliceDispatch_AskHelicopterScanChange
|
|||
|
|
var zero any; return zero
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//
|
|||
|
|
// C2S AskPoliceStopHelicopterDispatch(63057829),INVOKE,无参 —— 一轮搜查结束
|
|||
|
|
// (客户端在"扫描成功"后延迟 1 s 发它,见 PoliceHelicopterPanelStore.lua:483)。
|
|||
|
|
// 收到后清账,并推一次 S2C SynExitHelicopterView(68309986) 收视角。客户端那个
|
|||
|
|
// handler 就是 Close(gPanelId.S_POLICE_HELICOPTER),幂等 —— 面板已经关了再 Close 一次无害。
|
|||
|
|
//
|
|||
|
|
func GameRouter_PoliceDispatch_AskPoliceStopHelicopterDispatch(ctx context.Context, conn any, msg any) any {
|
|||
|
|
// Router implementation for GameRouter_PoliceDispatch_AskPoliceStopHelicopterDispatch
|
|||
|
|
var zero any; return zero
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func GameRouter_PoliceDispatch_GetOrCreateHelicopterScan(ctx context.Context, rpcCtx *RpcContext) any {
|
|||
|
|
// Router implementation for GameRouter_PoliceDispatch_GetOrCreateHelicopterScan
|
|||
|
|
var zero any; return zero
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// =================================================================================
|
|||
|
|
// ③ 直升机搜查:AskHelicopterNpc / AskHelicopterScanChange / AskPoliceStopHelicopterDispatch
|
|||
|
|
// =================================================================================
|
|||
|
|
//
|
|||
|
|
// 一轮直升机搜查的服务端记账。官方玩法里这些标记会喂给"盘查 / 通缉 / 案件"那条链,
|
|||
|
|
// 我们那条链是空的,所以先只把玩家框过的单位记下来 —— 至少让 RPC 有回执、有日志可查。
|
|||
|
|
//
|
|||
|
|
type HelicopterScanState struct {
|
|||
|
|
// 扫描开关(AskHelicopterScanChange)。
|
|||
|
|
ScanOpen bool `json:"scanOpen"`
|
|||
|
|
// instanceid → 最后一次 optype。
|
|||
|
|
Marks map[uint64]byte `json:"marks"`
|
|||
|
|
}
|
|||
|
|
|