288 lines
14 KiB
Go
288 lines
14 KiB
Go
package routers
|
||
|
||
import (
|
||
"context"
|
||
"sync"
|
||
)
|
||
|
||
var _ = sync.Mutex{}
|
||
var _ = context.Background
|
||
|
||
//
|
||
// 搜打撤(ExtractionShooter,本季「不要抬头!」)的服务端实现。
|
||
// 移植自捐赠端 handoff AI_HANDOFF不要抬头2.md(第二版),只取第一轮范围:
|
||
// ① 进图 / 退图 ② 容器搜索与刷物 ③ 背包搬运 / 丢弃 / 锁定 / 排序 / 拆分 / 扩容 / 入仓
|
||
// 不做武器实体化(轮盘 Tab 切枪)—— 那要 SyncSpiritWeaponDetail 整表,是第二轮。
|
||
// 三条先读再加代码:
|
||
// - ⛑️ [Handler] ≠ 已注册:不写进 GameRouter.cs 的
|
||
// Enabled4229938MethodIds 就是空注册 —— 请求不报错,只有一行
|
||
// unimplemented ... typed-default void 0b,且 unknown-methods.log 里反而没有。
|
||
// - ⛑️ 请求-应答型 RPC 必须回等价结构:midToReturnMessageReader[mid] 有 reader 的
|
||
// (典型是 SearchContainer/67410186,要求 ReadComplex(Reader[530])),回 EmptyOk 就是用 nil
|
||
// 覆盖客户端本地那份数据 —— 容器曾经就这么坏掉。
|
||
// - ⛑️ 容器 carrying 的实例 id 是客户端给的(8 字节),服务端按它确定性选容器形体;
|
||
// 所以同一实例在这一局里怎么搜都一致,换局才会重洗。
|
||
//
|
||
// ---------------------------------------------------------------- helpers
|
||
func GameRouter_Extraction_ExtractionCfg(ctx context.Context, ) any {
|
||
// Router implementation for GameRouter_Extraction_ExtractionCfg
|
||
var zero any; return zero
|
||
}
|
||
|
||
// 这个 raid 是不是搜打撤图。表里没有 raid↔图外键 ⇒ 用配置里的 raid 名单。
|
||
func GameRouter_Extraction_IsExtractionRaid(ctx context.Context, raidId uint32) bool {
|
||
// Router implementation for GameRouter_Extraction_IsExtractionRaid
|
||
return true
|
||
}
|
||
|
||
func GameRouter_Extraction_ExtractionStateOf(ctx context.Context, session *GameSession) any {
|
||
// Router implementation for GameRouter_Extraction_ExtractionStateOf
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// 首次用到时建包。为了避免 登录 flush 前就把包柜塞满,这里只做一次。
|
||
//
|
||
func GameRouter_Extraction_EnsureExtractionSeeded(ctx context.Context, session *GameSession) any {
|
||
// Router implementation for GameRouter_Extraction_EnsureExtractionSeeded
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Extraction_NowSeconds(ctx context.Context, ) uint32 {
|
||
// Router implementation for GameRouter_Extraction_NowSeconds
|
||
return 0
|
||
}
|
||
|
||
// ---------------------------------------------------------------- wire builders
|
||
// ClearBag 逐件 SetItemInfo 的整包重推 —— 只改了一格也要整包,客户端没有单删。
|
||
func GameRouter_Extraction_PushBagAsync(ctx context.Context, session *GameSession, bag any, phase string) any {
|
||
// Router implementation for GameRouter_Extraction_PushBagAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Extraction_PushBagCapacityAsync(ctx context.Context, session *GameSession, bag any, phase string) any {
|
||
// Router implementation for GameRouter_Extraction_PushBagCapacityAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
// =============================================================== handlers
|
||
//
|
||
// 搜索容器(67410186,Invoke)。
|
||
// ⛑ 这条必须回真正的包体:midToReturnMessageReader[67410186] 要求
|
||
// ReadComplex(Reader[530]),回 EmptyOk 会拿 nil 覆盖客户端本地那份 ContainerInfo。
|
||
// 回完之后再补一条 SyncExtractionShooterContainerInfo(68820459) 走推送路径,
|
||
// 两条同源同一个 BuildContainerInfo。
|
||
//
|
||
func GameRouter_Extraction_OnAskExtractionShooterSearchContainer(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterSearchContainer
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// 容器读条的收尾:seconds 秒后把这个 pid 的时间戳翻成过去,再推同一份容器数据。
|
||
// ⛑️ seconds 必须 > 0(取整箱最长 SearchTime)—— 传 0 会立刻揭晓,读条动画播不出来。
|
||
// 这是一次性的延时推,不是循环,但仍然要过 GameRouter.IsBackgroundPushPaused 门控
|
||
// (硬规则 37):等这几秒里客户端可能已经挂起,那时推等于往不消费的 TCP 里灌包。
|
||
//
|
||
func GameRouter_Extraction_RevealContainerAfterAsync(ctx context.Context, session *GameSession, owner any, instanceId uint64, pid uint64, seconds int32, phase string) any {
|
||
// Router implementation for GameRouter_Extraction_RevealContainerAfterAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Extraction_AnswerEmptyContainerAsync(ctx context.Context, conn any, msg any, instanceId uint64) any {
|
||
// Router implementation for GameRouter_Extraction_AnswerEmptyContainerAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// 结束搜索(67701506)。客户端读条走完自己发的收尾。
|
||
// ⛑️ 不能只 ack:这一条是「时间戳该翻回过去了」的信号,服务端必须真的
|
||
// ExtractionShooterRuntime4229938.TryRevealContainer 再补推一帧,
|
||
// 否则客户端手上那份还是未来时间戳 ⇒ 物品不显示。
|
||
// (旧实现在这里写的是「服务端无状态可清」,是错的 —— 状态就是那个时间戳。)
|
||
//
|
||
func GameRouter_Extraction_OnAskExtractionShooterEndSearchContainer(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterEndSearchContainer
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// 六合一搬运(63749738,25B):装备 / 卸下 / 放入安全箱 / 携带 / 放回仓库 / 旋转
|
||
// 全走这一条,区别只是 destBag。修一条等于修全部。
|
||
//
|
||
func GameRouter_Extraction_OnAskExtractionShooterShiftItem(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterShiftItem
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Extraction_OnAskExtractionShooterRemoveItem(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterRemoveItem
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Extraction_OnAskExtractionShooterLockItem(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterLockItem
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Extraction_OnAskExtractionShooterSortBag(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterSortBag
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Extraction_OnAskExtractionShooterSplitItem(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterSplitItem
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// 扩容(63115121,4B)。唯一的扩容入口 —— 客户端没有"直接换包"请求。
|
||
// Type=1 给目标包加一行 ⇒ 要回 ChangeBagCapacity;Type=2 解锁新仓库。
|
||
//
|
||
func GameRouter_Extraction_OnAskExtractionShooterBagExpansion(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterBagExpansion
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Extraction_OnAskExtractionShooterTransferAllToStash(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterTransferAllToStash
|
||
var zero any; return zero
|
||
}
|
||
|
||
// 全包整理(63009939,list7bit<u32>)。逐包重排后各自整包重推。
|
||
func GameRouter_Extraction_OnAskExtractionShooterSortBags(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterSortBags
|
||
var zero any; return zero
|
||
}
|
||
|
||
// 容器 ↔ 背包 / 槽位的六条搬运。
|
||
//
|
||
// ⛑️ 第一版这里的字段全是「按最可能的布局猜」的,实机一跑全错(捐赠端 §14.8/§14.10 用 C2S
|
||
// 抓包纠正):非槽位那两条是 (container, fromX, fromY, destBag/srcBag, toX, toY, isRotated),
|
||
// 槽位那两条是 (container…, slotBag, slotIndex) / (srcBag, slotIndex, container…)。
|
||
// 猜错的后果不是报错,而是 TryGetArgs 静默返回 false ⇒ 处理器什么也不做("点了没反应")。
|
||
// ⇒ 现在一律走 §8.14 的 ExtractionRequests 契约,并且解析失败要<b>打出来</b>(见 TryArgs)。
|
||
func GameRouter_Extraction_OnAskExtractionShooterShiftContainerItemToBag(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterShiftContainerItemToBag
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Extraction_OnAskExtractionShooterShiftContainerItemToSlot(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterShiftContainerItemToSlot
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Extraction_OnAskExtractionShooterBagItemToContainer(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterBagItemToContainer
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Extraction_OnAskExtractionShooterSlotItemToContainer(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterSlotItemToContainer
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Extraction_RunTakeAsync(ctx context.Context, conn any, msg any, container uint64, fromX uint32, fromY uint32, destBag uint32, toX uint32, toY uint32, isRotated bool, phase string) any {
|
||
// Router implementation for GameRouter_Extraction_RunTakeAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Extraction_RunPutAsync(ctx context.Context, conn any, msg any, srcBag uint32, fromX uint32, fromY uint32, container uint64, toX uint32, toY uint32, isRotated bool, phase string) any {
|
||
// Router implementation for GameRouter_Extraction_RunPutAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Extraction_RunMoveAsync(ctx context.Context, conn any, msg any, container uint64, fromX uint32, fromY uint32, toX uint32, toY uint32, isRotated bool, phase string) any {
|
||
// Router implementation for GameRouter_Extraction_RunMoveAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// TryGetArgs 的替代品 —— 它把异常 catch 掉并返回 false(见 UxRpcMessage),
|
||
// 是搜打撤最大的 bug 隐身衣:契约字段数 / 顺序 / Inline 写错的表现全都是
|
||
// 「处理器静默什么都不做」,日志里连一个字都没有(§14.8 三连故障的真根因)。
|
||
// 这里失败时把契约名 + 字节数 + 原始 hex 全部打出来,拿 packets-latest.log
|
||
// 里的 C2S INVOKE 对照一眼就知道差几个字段。
|
||
//
|
||
func GameRouter_Extraction_TryArgs(ctx context.Context, conn any, msg any, req any) bool {
|
||
// Router implementation for GameRouter_Extraction_TryArgs
|
||
return true
|
||
}
|
||
|
||
func GameRouter_Extraction_PushContainerAsync(ctx context.Context, session *GameSession, owner any, instanceId uint64, phase string) any {
|
||
// Router implementation for GameRouter_Extraction_PushContainerAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
// 容器内挪位 / 原地旋转(67007990)—— 现在真的挪。
|
||
func GameRouter_Extraction_OnAskExtractionShooterShiftContainerItem(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterShiftContainerItem
|
||
var zero any; return zero
|
||
}
|
||
|
||
// 容器内删除(67825663)—— 现在真的删。
|
||
func GameRouter_Extraction_OnAskExtractionShooterRemoveContainerItem(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterRemoveContainerItem
|
||
var zero any; return zero
|
||
}
|
||
|
||
// 容器内堆叠拆分(67597775,25B):u32 bag + u64 container + u32 x/y + u32 count + bool。
|
||
func GameRouter_Extraction_OnAskExtractionShooterRaidSplitItem(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskExtractionShooterRaidSplitItem
|
||
var zero any; return zero
|
||
}
|
||
|
||
// ------------------------------------------------------------- enter / exit
|
||
//
|
||
// 退出(67504722)。
|
||
// ⛑ 等待房 / 主城的点也会发这条请求 ⇒ 必须先用 IsExtractionRaid 守卫,
|
||
// 否则玩家在主城点个按钮就被扔回主城。
|
||
//
|
||
func GameRouter_Extraction_OnAskQuitExtractionShooter(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Extraction_OnAskQuitExtractionShooter
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// 退图:结算 → 清局 → 扔回主城。
|
||
//
|
||
func GameRouter_Extraction_ExitExtractionAsync(ctx context.Context, session *GameSession, state any) any {
|
||
// Router implementation for GameRouter_Extraction_ExitExtractionAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// 进图后补齐玩法侧的包结构:SyncPlayerEnterExtractionShooter(64811826) 空体 +
|
||
// 各包真实容量。
|
||
// 空体是必须的 —— 它是客户端把 UI 从标题切到背包 UI 的信号之一;缺它会出现
|
||
// "进得去、但整个 HUD 不认自己在副本里"。
|
||
//
|
||
func GameRouter_Extraction_PushExtractionEnterAsync(ctx context.Context, session *GameSession, state any) any {
|
||
// Router implementation for GameRouter_Extraction_PushExtractionEnterAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
// ---------------------------------------------------------------- utilities
|
||
//
|
||
// 轮盘 bag 被改动之后的收尾:把「物品存储」的变动同步成「实体化武器」的变动。
|
||
// 搜打撤里这两套是分开的 —— 往轮盘里挪进一把枪只改了 bag,Tab 切枪读的是
|
||
// gWeaponManager.CurrWeaponSlots,不补这一步 Tab 永远只在拳头和角色自带那把之间转。
|
||
// 传进来一串包 id 就行,只有真的碰到轮盘(99952004)才会动手 —— 其余包零开销。
|
||
//
|
||
func GameRouter_Extraction_SyncWheelAfterBagChangeAsync(ctx context.Context, session *GameSession, phase string, touchedBags []any) any {
|
||
// Router implementation for GameRouter_Extraction_SyncWheelAfterBagChangeAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
// list7bit<u32> 解包。7bit 计数带 +1 偏置 ⇒ 读出来的数要减一。
|
||
func GameRouter_Extraction_ReadU32List7Bit(ctx context.Context, body []byte) []any {
|
||
// Router implementation for GameRouter_Extraction_ReadU32List7Bit
|
||
return nil
|
||
}
|
||
|
||
func GameRouter_Extraction_ReadVarInt(ctx context.Context, body []byte, pos int32) int32 {
|
||
// Router implementation for GameRouter_Extraction_ReadVarInt
|
||
return 0
|
||
}
|
||
|