215 lines
8.6 KiB
Go
215 lines
8.6 KiB
Go
package routers
|
||
|
||
import (
|
||
"context"
|
||
"sync"
|
||
"time"
|
||
)
|
||
|
||
var _ = sync.Mutex{}
|
||
var _ = context.Background
|
||
var _ = time.Now
|
||
|
||
//
|
||
// Light rail / metro scheduling.
|
||
// The client owns the whole carriage simulation: MetroManager builds the carriages, drives them
|
||
// along the baked MetroPath of a line and plays the gate/door animation. All the server has to do is
|
||
// answer AskGetAllMetroInfos and then keep telling the client "train X of line Y has been running for
|
||
// Z seconds" through SyncRunningMetroInfos - MetroClientInfo has no position field at all
|
||
// (Id, LineId, ElapsedTime, IsFinalTrain). That is why this feature needs no client patch.
|
||
// The schedule comes straight out of the client's own Rail*Config tables (RailLineConfig /
|
||
// RailStopConfig / RailStationConfig), which the panel exposes as "where is the train, which stop is
|
||
// it at, how long / how far until the next one".
|
||
// Round 54 got the scheduling right but not the clock: see MetroDefaultTimeFactor for the round-55 fix.
|
||
//
|
||
//
|
||
// 当前 raid 该推哪几条线。取 RaidConfig.LightRailLineIds
|
||
// (23300888 = 1–4,23300999 = 9–14 + 15,23301227 = 5–8,23301271 = 1–4),
|
||
// 取不到就落回 MetroDefaultLines。
|
||
//
|
||
func GameRouter_Metro_MetroLinesForRaid(ctx context.Context, session *GameSession) []any {
|
||
// Router implementation for GameRouter_Metro_MetroLinesForRaid
|
||
return nil
|
||
}
|
||
|
||
//
|
||
// raid 变了就把自动选的线换掉。手动模式(MetroSessionState.AutoRaidLines = false,
|
||
// 即面板显式下发过 lines)**一个字都不动**,免得和用户手选打架。
|
||
// 返回 true = 这次真的换过了,调用方负责打日志。
|
||
//
|
||
func GameRouter_Metro_SyncMetroLinesToRaid(ctx context.Context, session *GameSession, owner any, force bool) bool {
|
||
// Router implementation for GameRouter_Metro_SyncMetroLinesToRaid
|
||
return true
|
||
}
|
||
|
||
// ---------------------------------------------------------------- state
|
||
func GameRouter_Metro_TryGetMetroState(ctx context.Context, session *GameSession) any {
|
||
// Router implementation for GameRouter_Metro_TryGetMetroState
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Metro_GetMetroState(ctx context.Context, session *GameSession) any {
|
||
// Router implementation for GameRouter_Metro_GetMetroState
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Metro_EnsureMetroLoop(ctx context.Context, session *GameSession, owner any) any {
|
||
// Router implementation for GameRouter_Metro_EnsureMetroLoop
|
||
var zero any; return zero
|
||
}
|
||
|
||
// ---------------------------------------------------------------- protocol
|
||
//
|
||
// The scene asks once per load, with no arguments, and expects the list of metros currently
|
||
// running. Everything before round 54 answered with the typed-default empty list, which is why no
|
||
// carriage ever appeared.
|
||
//
|
||
func GameRouter_Metro_AskGetAllMetroInfos(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Metro_AskGetAllMetroInfos
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Metro_BuildMetroInfos(ctx context.Context, owner any) []any {
|
||
// Router implementation for GameRouter_Metro_BuildMetroInfos
|
||
return nil
|
||
}
|
||
|
||
func GameRouter_Metro_BuildMetroTrackSegments(ctx context.Context, ) []any {
|
||
// Router implementation for GameRouter_Metro_BuildMetroTrackSegments
|
||
return nil
|
||
}
|
||
|
||
// 点到轨道折线的最近距离(米)。段数为几十,每拍算一次开销可忽略。
|
||
func GameRouter_Metro_DistanceToMetroTrack(ctx context.Context, px float64, py float64, pz float64) float64 {
|
||
// Router implementation for GameRouter_Metro_DistanceToMetroTrack
|
||
return 0
|
||
}
|
||
|
||
//
|
||
// 玩家是否看得见列车。拿不到坐标时返回 true(按近处处理),宁可多推也不牺牲画面。
|
||
//
|
||
func GameRouter_Metro_IsPlayerNearMetroTrack(ctx context.Context, session *GameSession, metres float64) bool {
|
||
// Router implementation for GameRouter_Metro_IsPlayerNearMetroTrack
|
||
return true
|
||
}
|
||
|
||
func GameRouter_Metro_MetroLineSummary(ctx context.Context, owner any) string {
|
||
// Router implementation for GameRouter_Metro_MetroLineSummary
|
||
return ""
|
||
}
|
||
|
||
// ---------------------------------------------------------------- the loop
|
||
func GameRouter_Metro_RunMetroLoopAsync(ctx context.Context, session *GameSession, owner any, token context.Context) any {
|
||
// Router implementation for GameRouter_Metro_RunMetroLoopAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Metro_TickMetroAsync(ctx context.Context, session *GameSession, owner any, token context.Context) any {
|
||
// Router implementation for GameRouter_Metro_TickMetroAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
// ---------------------------------------------------------------- panel API
|
||
//
|
||
// Read-only snapshot for the web panel: the whole catalog plus, for every running train, the stop
|
||
// it is calling at, the next stop, and the remaining time / straight-line distance to it.
|
||
//
|
||
func GameRouter_Metro_MetroStatus(ctx context.Context, session any) any {
|
||
// Router implementation for GameRouter_Metro_MetroStatus
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Metro_MetroCatalogView(ctx context.Context, enabled []any) []any {
|
||
// Router implementation for GameRouter_Metro_MetroCatalogView
|
||
return nil
|
||
}
|
||
|
||
func GameRouter_Metro_MetroTrainView(ctx context.Context, owner any, stoppedSeconds int32) []any {
|
||
// Router implementation for GameRouter_Metro_MetroTrainView
|
||
return nil
|
||
}
|
||
|
||
func GameRouter_Metro_StopName(ctx context.Context, stop any) string {
|
||
// Router implementation for GameRouter_Metro_StopName
|
||
return ""
|
||
}
|
||
|
||
//
|
||
// Where the train is between two platforms. The stop tables only carry arrival times, so the fill
|
||
// is a straight line between the two station anchors scaled by the remaining fraction of the leg -
|
||
// good enough for a status readout, and it is the same information the client itself animates from.
|
||
// Null when the line has no station anchors (the depot ends of the ring, or the test paths).
|
||
//
|
||
func GameRouter_Metro_MetroInterpolate(ctx context.Context, progress any) any {
|
||
// Router implementation for GameRouter_Metro_MetroInterpolate
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Metro_SetMetroEnabled(ctx context.Context, session any, enabled bool) any {
|
||
// Router implementation for GameRouter_Metro_SetMetroEnabled
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// Panel update of the dispatcher. null keeps the current selection (that is
|
||
// how the panel changes only the push period or the time factor), an empty list turns every line off.
|
||
//
|
||
func GameRouter_Metro_ConfigureMetroLines(ctx context.Context, session any, lines []any, pushMs any, timeFactor any, auto any) any {
|
||
// Router implementation for GameRouter_Metro_ConfigureMetroLines
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Metro_StopMetro(ctx context.Context, session any) any {
|
||
// Router implementation for GameRouter_Metro_StopMetro
|
||
var zero any; return zero
|
||
}
|
||
|
||
type MetroSessionState struct {
|
||
SyncRoot any `json:"syncRoot"`
|
||
// Master switch. When false the loop idles without stopping, so nothing has to restart.
|
||
Enabled bool `json:"enabled"`
|
||
// Push cadence in milliseconds.
|
||
PushMs int32 `json:"pushMs"`
|
||
// Multiplier applied to the timetable second before it goes out as ElapsedTime (see MetroDefaultTimeFactor).
|
||
TimeFactor float64 `json:"timeFactor"`
|
||
// Lines currently being pushed.
|
||
Lines []uint32 `json:"lines"`
|
||
//
|
||
// 线路跟随当前 raid(RaidConfig.LightRailLineIds)自动切换。
|
||
// 面板一旦显式下发 lines 就置 false —— 之后不再自动改,避免和用户手选打架;
|
||
// 要切回自动,面板走 auto: true。
|
||
//
|
||
AutoRaidLines bool `json:"autoRaidLines"`
|
||
// 上次自动选线时用的 raid。只在它变化时才重建 Lines。
|
||
AutoRaidId uint32 `json:"autoRaidId"`
|
||
//
|
||
// The scene has actually asked for the metro list at least once. Pushes stay silent until then:
|
||
// the client only has its MetroPaths after it has loaded the scene, so an early
|
||
// SyncRunningMetroInfos could reach a half-built MetroManager.
|
||
//
|
||
Requested bool `json:"requested"`
|
||
//
|
||
// 上一拍玩家是否处在轨道附近。只用来在切换时打一条日志,避免在控制台刷屏。
|
||
// 初值 true = 还没拿到玩家坐标时按"近处"处理,不牺牲画面。
|
||
//
|
||
NearTrack bool `json:"nearTrack"`
|
||
// Seconds of service folded away by a previous stop, so a restart does not jump the trains.
|
||
OffsetSeconds float64 `json:"offsetSeconds"`
|
||
StartedUtc time.Time `json:"startedUtc"`
|
||
Cts *context.CancelFunc `json:"cts"`
|
||
Loop *any `json:"loop"`
|
||
Ticks int64 `json:"ticks"`
|
||
Pushes int64 `json:"pushes"`
|
||
TrainsSent int64 `json:"trainsSent"`
|
||
LastPushUtc time.Time `json:"lastPushUtc"`
|
||
LastError *string `json:"lastError"`
|
||
ElapsedSeconds float64 `json:"elapsedSeconds"`
|
||
}
|
||
|
||
type MetroPoint struct {
|
||
X float64 `json:"x"`
|
||
Y float64 `json:"y"`
|
||
Z float64 `json:"z"`
|
||
}
|
||
|