This repository has been archived on 2026-10-31. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Ananta-ps/internal/gameserver/routers/game_router_map_entrance.go
T

107 lines
5.8 KiB
Go
Raw Normal View History

package routers
import (
"context"
"sync"
)
var _ = sync.Mutex{}
var _ = context.Background
//
// 大地图入口(传送点 / 地铁站)—— 2026-09-27 从 kpect 捐赠端移植的「入口四连发 + 点击真传送」。
// ## 为什么之前大地图上什么都没有
// 客户端地图入口是**服务端下发驱动**的,四条 S2C 在此之前**全服零命中**(grep 过整个 v0.3):
// · SyncMapEntrance (64067363) 全量清单 → MapUtils._visibleEntrance / _unlockedEntrance
// · UpdateMapEntrance (64239821) 逐点开关
// · SyncPrepareMapEntrance (64610549) 逐点准备(交通层入口的注册步骤)
// · SyncSubwayFare (64660858) 地铁票价
// 判据链:MapUtils.IsEntranceVisible(id) 只查 _visibleEntrance,而这个表
// **只能**由上面前两条帧写入 ⇒ 一条不发 = 地图上一个传送点图标都没有。
// ## 点击传送
// AskTouchMapEntrance(63284182) 是客户端 Notify(void,不等回包),
// 调用点 MapCsApi.Legacy_DoFightMapEntrance(gRaidDataManager.RaidId, mapEntranceId)。
// 以前没有 handler ⇒ 落到 RPC 兜底 ⇒ 点了没反应。
// · 同 raid → TeleportPlayerWithLoadingAsync(官方 loading 传送流程)
// · 跨 raid → SwitchSceneAsync(GameRouter.SceneSwitch.cs,换图事务)
// ## 数据来源
// 用我们自己的 MapentranceConfig(93 行)+ RaidConfig
// (SceneCatalog4229938.MapEntrances),**不用** kpect 的 ExtraCatalog,
// 也不动主线已经完整的 GameRouter.Metro.cs(SyncRunningMetroInfos 68333359)。
// ## 回滚
// gameplay.mapEntrance.enabled=false ⇒ 四帧都不发、点击也不传送,逐字节回到移植前。
// 逐帧也能单独关(pushSync / pushUpdate / pushPrepare / pushSubwayFare)。
//
//
// 进世界后推一次地图入口四连发。
// ⛑ 派发量:93 个入口 × (UpdateMapEntrance + SyncPrepareMapEntrance) = 186 帧。
// 收包循环是串行的(读完一帧 → await DispatchAsync → 才读下一帧),同步连发会把
// 客户端这一秒的上报全部堵住 —— 与 PublishMapFogUnlockAsync 那次 260 帧
// 是同一个坑,所以这里照抄它的「后台分批 + 10ms/25 帧」摊平写法。
//
func GameRouter_MapEntrance_PublishMapEntrancesAsync(ctx context.Context, rpcCtx *RpcContext) any {
// Router implementation for GameRouter_MapEntrance_PublishMapEntrancesAsync
var zero any; return zero
}
//
// AskTouchMapEntrance (63284182):客户端 void notify。命中配置就真传送。
// 判据分支(grep [MAP-TOUCH]):
// ① teleport-in-place 同 raid 命中并传送
// ② switch-raid 跨 raid 命中并换图
// ③ unknown-id / raid-mismatch / bad-coordinate / malformed / no-world-state / disabled
//
func GameRouter_MapEntrance_AskTouchMapEntrance(ctx context.Context, conn any, msg any) any {
// Router implementation for GameRouter_MapEntrance_AskTouchMapEntrance
var zero any; return zero
}
//
// 载荷解析:主路径 = 严格 8 B(raidId @0 / mapEntranceId @4,小端裸值)。
// 长度不为 8 时做一次自校验容错扫描(要求第二个 u32 能命中入口表、第一个与该行 RaidId 一致),
// 命中即采用并在判据行里写明「容错扫描@N」,不会静默成功。
//
func GameRouter_MapEntrance_TryParseMapTouchBody(ctx context.Context, body []byte, raidId uint32, entranceId uint32, note string) bool {
// Router implementation for GameRouter_MapEntrance_TryParseMapTouchBody
return true
}
//
// AskPlayerChangePositionByScenePortal (67006840, invoke u32 mapEntranceId):
// 大地图「交通直达」(地铁站 / 公交站 / 传送点)**同图**传送的 domain RPC。
// 客户端 MapSubSystem_Entrance.lua:559 MapTeleport 的时序:
// ① gLoadingManager:AskTeleport(loadingConfigId, preTeleportOption, ...) —— 客户端
// 自己填好了 afterPosition(=MapTeleportPos) / afterResName(=TeleportEndTimeLine) /
// loadingResName,服务端 AskTeleport handler 只登记 + ack;
// ② ack 回来后回调里 gClientUtils.MapTeleport()(**只关 UI,不动坐标**),再按
// 「目标 raid == 当前 raid」分流:同图 → 本 RPC;跨图 → AskPublicSwitchToPublicScene;
// ③ 本 RPC 回 Ok 才 StopLoading。
// ⛑ 本 RPC 之前**连 method id 都没有**(服务端 0 处引用),又是 Invoke ⇒ 客户端 await
// 永久挂起 ⇒ 「长按 F / 点交通直达没反应」。跨图那条(AskPublicSwitchToPublicScene)
// 早就有 handler,所以只有同图(25 个地铁站绝大多数都在 23300888 内)表现为完全无响应。
// 位移用 SyncTeleport 推,teleportId 取客户端自己那次 AskTeleport 登记的
// PendingTeleportId(客户端只认自己事务的那一帧)。
// 判据分支(grep [MAP-PORTAL]):
// disabled / malformed / unknown-id / bad-coordinate / no-world-state / ok。
//
func GameRouter_MapEntrance_AskPlayerChangePositionByScenePortal(ctx context.Context, conn any, msg any) any {
// Router implementation for GameRouter_MapEntrance_AskPlayerChangePositionByScenePortal
var zero any; return zero
}
//
// 载荷解析:主路径 = 严格 4 B(mapEntranceId u32 小端裸值)。
// 长度不为 4 时做一次自校验容错扫描(要求该 u32 能命中入口表),命中即采用并写明
// 「容错扫描@N」,不会静默成功。
//
func GameRouter_MapEntrance_TryParsePortalBody(ctx context.Context, body []byte, entranceId uint32, note string) bool {
// Router implementation for GameRouter_MapEntrance_TryParsePortalBody
return true
}
// 坐标可用性:有限数且不在原点(表里有 (0,0,0) 占位行)。
func GameRouter_MapEntrance_IsUsableEntranceCoordinate(ctx context.Context, x float32, y float32, z float32) bool {
// Router implementation for GameRouter_MapEntrance_IsUsableEntranceCoordinate
return true
}