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

108 lines
5.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
}