package routers import ( "context" "sync" ) var _ = sync.Mutex{} var _ = context.Background // // Scene ("raid") switching: re-push SyncEnterScene with a new raid/instance/universe // destination and re-arm the world-entry barrier lifecycle so the client's normal // AskLoadSceneCompleted → quartet → AskLoadingFinished → movement flow runs again. // Ported from the proven newcityps (4091149) airport handoff, adapted to the minimal // 4229938 world entry (no timelines, no AOI streaming). // // // Client -> server map/teleport request: AskPublicSwitchToPublicScene // (63491547, invoke raidId/delay/mapEntranceId). Known raid ids switch via the // preset arrivals; anything else is accepted and logged for future mapping. // func GameRouter_SceneSwitch_AskPublicSwitchToPublicScene(ctx context.Context, conn any, msg any) any { // Router implementation for GameRouter_SceneSwitch_AskPublicSwitchToPublicScene var zero any; return zero } // // Client -> server EnterRaid (62899289, invoke raidId/immediate) —— GM 传送面板用的 // 原生副本切换请求。移植自捐赠端 DremkaPS(2026-09-24)。 // 捐赠端硬编码两个 raid(主城 / 重霄)加一个出生点,本服改成查既有的 // GameAdminBridge.ScenePresets —— 那份表覆盖的副本更多,落点还是 2026-09-20 // 实机量过的;没有 preset 的 raid 按本服既有约定「接受并记日志」,不静默丢弃。 // ⛑ 与同文件另两条不同,这里先回 EmptyOk 再切换(照捐赠端):EnterRaid 是 Invoke, // 客户端在 await 返回值,而 SwitchSceneAsync 要连发 SyncGamePause + // SyncEnterScene;先回包可以避免切换耗时把控制台那次调用拖到超时。 // func GameRouter_SceneSwitch_EnterRaid(ctx context.Context, conn any, msg any) any { // Router implementation for GameRouter_SceneSwitch_EnterRaid var zero any; return zero } // // AskEnterRaidByMapEntrance(63510026, invoke u32 mapEntranceId): // 景点 / 电梯传送门(MapentranceConfig.Type == 1)。 //
// AskTeleport(LoadingConfig.EnterExitRoomId=2, option, extParams, cb)
// option.beforeResName = cfg.JiguanStartTimeline -- "loading_elevator02"
// option.beforePosition = cfg.Coordinate -- 电梯门自己那一格
// option.afterResName = cfg.JiguanEndTimeline -- "loading_general_end"
// option.afterPosition = (0,0,0) -- ★ 客户端不知道目的地
// option.customAfterTrans = false -- ★ 所以不会自己套 afterPosition
// cb(= ReportPreTeleportFinish 被 ack 之后)→ gClientToGameDelegate:AskEnterRaidByMapEntrance(id)
//
// 实测(packets-latest.log):
//
// 01:07:55.716 C2S AskTeleport config=2 before=loading_elevator02 beforePosition=(2257.781,0,1458.242)
// 01:07:55.717 S2C RETURN AskTeleport e=0
// 01:07:55.717 S2C NOTIFY SyncPreTeleportOption 146b ← EchoPreTeleport 回显成功
// 01:08:01.359 C2S ReportPreTeleportFinish {"teleportId":0} ← 过场动画播完
// 01:08:01.362 C2S AskEnterRaidByMapEntrance {"mapEntranceId":337}
// 01:08:01.366 S2C RETURN AskEnterRaidByMapEntrance e=0 ← 只 ack,没有 SyncTeleport
// 01:09:30.020 C2S ReportPostTeleportFinish {"result":2} ← 86 秒后放弃 ⇒ 黑屏
//
// 对照同一份日志里成功的一次(01:07:39,大地图传送 / 地铁):
// AskPlayerChangePositionByScenePortal → S2C NOTIFY SyncTeleport 31b →
// ReportPostTeleportFinish result=0。差别就在那一帧 SyncTeleport。
// 目的地由 JiguanElevatorCatalog4229938 从 MapentranceConfig 自己推出来
// (客户端只给 Spoon 航点 id,本地没有 Spoon 图)。推不出目的地时退化成
// 「推到入口自己那一格」——仍然推,因为「不推」才是黑屏。
// 顺序照 AskPlayerChangePositionByScenePortal:先 SyncTeleport 再 ack。
// 回滚 = gameplay.mapEntrance.jiguanElevator=false(只 ack,逐字节回到改动前)。
//
func GameRouter_SceneSwitch_AskEnterRaidByMapEntrance(ctx context.Context, conn any, msg any) any {
// Router implementation for GameRouter_SceneSwitch_AskEnterRaidByMapEntrance
var zero any; return zero
}
// SyncTeleport.MapEntranceId 到底填哪个 id。
// "dest"(默认)= 落点那一层的门;"source" = 起点门(一修旧行为);
// "none" = 0(逼客户端只用 Position,用来验证「客户端拿 MapEntranceId 去
// MapentranceConfig / Spoon 航点反查、本地没图所以落空」这个猜想)。
// 落点门为 0(推导失败)时退回起点门,保证 Position 与 MapEntranceId 不打架。
//
func GameRouter_SceneSwitch_JiguanEntranceIdToSend(ctx context.Context, cfg any, sourceEntranceId uint32, dest any) uint32 {
// Router implementation for GameRouter_SceneSwitch_JiguanEntranceIdToSend
return 0
}
//
// Server-driven scene switch. Re-arms the world-entry transaction for a new
// generation, then pushes SyncEnterScene. The existing barrier handlers
// (OnLoadSceneCompleted / OnLoadingFinished / movement) complete the handoff.
//
func GameRouter_SceneSwitch_SwitchSceneAsync(ctx context.Context, session *GameSession, raidId uint32, instanceId uint64, universeId uint32, x float32, y float32, z float32, facing float32, reason string) any {
// Router implementation for GameRouter_SceneSwitch_SwitchSceneAsync
var zero any; return zero
}
func GameRouter_SceneSwitch_GetStateStatic(ctx context.Context, session *GameSession) any {
// Router implementation for GameRouter_SceneSwitch_GetStateStatic
var zero any; return zero
}