106 lines
5.7 KiB
Go
106 lines
5.7 KiB
Go
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)。
|
|||
|
|
// <h3>⛑⛑ 2026-09-30:这里只 ack 不推 SyncTeleport,就是「进电梯黑屏、ESC 返回不了」的根因</h3>
|
|||
|
|
// 客户端 RpcUtils.AskEnterRaidByMapEntrance(E:\lua\lua\LX6\Utils\RpcUtils.lua:88):
|
|||
|
|
// <code>
|
|||
|
|
// 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)
|
|||
|
|
// </code>
|
|||
|
|
// 实测(packets-latest.log):
|
|||
|
|
// <code>
|
|||
|
|
// 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 秒后放弃 ⇒ 黑屏
|
|||
|
|
// </code>
|
|||
|
|
// 对照同一份日志里成功的一次(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
|
|||
|
|
}
|
|||
|
|
|