214 lines
8.6 KiB
Go
214 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"`
|
|||
|
|
}
|
|||
|
|
|