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

252 lines
8.1 KiB
Go
Raw Permalink 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 catalogs
import (
"encoding/json"
"os"
"path/filepath"
"sync"
)
var _ = json.RawMessage{}
var _ = sync.Mutex{}
var _ = os.ReadFile
var _ = filepath.Join
// One RailLineConfig row (a physical light-rail / cruise line, and its direction).
type RailLine4229938 struct {
Id uint32 `json:"id"`
LineName string `json:"lineName"`
TrainTemplateId uint32 `json:"trainTemplateId"`
PrefabPath string `json:"prefabPath"`
BlobName string `json:"blobName"`
RingLine bool `json:"ringLine"`
IsTestPath bool `json:"isTestPath"`
DepartureInterval int32 `json:"departureInterval"`
MaxTrainAmount int32 `json:"maxTrainAmount"`
TotalTravelDuration float64 `json:"totalTravelDuration"`
DestinationArrivalTime float64 `json:"destinationArrivalTime"`
AvgVelocity int32 `json:"avgVelocity"`
FirstStopDumb bool `json:"firstStopDumb"`
LastStopDumb bool `json:"lastStopDumb"`
FirstTrainHour int32 `json:"firstTrainHour"`
FirstTrainMinute int32 `json:"firstTrainMinute"`
LastTrainHour int32 `json:"lastTrainHour"`
LastTrainMinute int32 `json:"lastTrainMinute"`
//
// How many carriages the client should keep alive on this line. The timetable repeats every
// TotalTravelDuration seconds and a train leaves every DepartureInterval, so the steady-state
// fleet size is the ratio of the two - capped by the config's own MaxTrainAmount
// (Line 1: 1123.088 / 90 = 12 -> 12, Line 3: 655.295 / 90 = 7 -> 7, Line 4: 608.478 / 90 = 6 -> 6).
//
EffectiveTrainCount int32 `json:"effectiveTrainCount"`
}
//
// One RailStopConfig row (a scheduled call of one line). Note that the JSON field literally named
// "LineName" holds the <em>stop</em> name (e.g. 白帆湾车库 for the depot stop), not the line name.
//
type RailStop4229938 struct {
Id uint32 `json:"id"`
LineId uint32 `json:"lineId"`
StopName string `json:"stopName"`
NextStopId uint32 `json:"nextStopId"`
ArrivalTime float64 `json:"arrivalTime"`
InsertTime float64 `json:"insertTime"`
GateOpenSide uint32 `json:"gateOpenSide"`
DefaultExitStop bool `json:"defaultExitStop"`
StationId uint32 `json:"stationId"`
}
// One RailStationConfig row (a platform shared by one or more lines).
type RailStation4229938 struct {
Id uint32 `json:"id"`
Name string `json:"name"`
ChineseName string `json:"chineseName"`
EnglishName string `json:"englishName"`
X float64 `json:"x"`
Y float64 `json:"y"`
Z float64 `json:"z"`
Lines []uint32 `json:"lines"`
}
//
// A line with its stops already ordered along the travel direction, so the nth entry of
// Stops is the nth station of RailLine4229938's own Stations array.
//
type RailRoute4229938 struct {
Line RailLine4229938 `json:"line"`
Stops []RailStop4229938 `json:"stops"`
}
// Where a train is right now, derived from ElapsedTime + the baked timetable.
type RailTrainProgress struct {
StopIndex int32 `json:"stopIndex"`
NextStopIndex int32 `json:"nextStopIndex"`
CurrentStop RailStop4229938 `json:"currentStop"`
NextStop *RailStop4229938 `json:"nextStop"`
CurrentStation *RailStation4229938 `json:"currentStation"`
NextStation *RailStation4229938 `json:"nextStation"`
SecondsToNext float64 `json:"secondsToNext"`
MetresToNext float64 `json:"metresToNext"`
AtStation bool `json:"atStation"`
}
//
// Build-4229938 light-rail / cruise catalog, read from the Rail*Config.json files in the configured
// client-data directory. Field names verified against ConfigDump_v3 and the Lua
// Auto.WriteMetroClientInfo writer in RPCSerializeAuto.lua.
//
var (
RailCatalog4229938_cacheLock sync.RWMutex
RailCatalog4229938_cached = false
RailCatalog4229938_entries []any
)
// LoadRailCatalog4229938 loads catalog records from client config directory
func LoadRailCatalog4229938(configDir string) ([]any, error) {
RailCatalog4229938_cacheLock.RLock()
if RailCatalog4229938_cached {
defer RailCatalog4229938_cacheLock.RUnlock()
return RailCatalog4229938_entries, nil
}
RailCatalog4229938_cacheLock.RUnlock()
RailCatalog4229938_cacheLock.Lock()
defer RailCatalog4229938_cacheLock.Unlock()
if RailCatalog4229938_cached { return RailCatalog4229938_entries, nil }
filePath := filepath.Join(configDir, "RailCatalog.json.json")
data, err := os.ReadFile(filePath)
if err != nil {
return nil, err
}
var raw struct {
Records []json.RawMessage `json:"records"`
}
if err := json.Unmarshal(data, &raw); err != nil {
return nil, err
}
var result []any
for _, item := range raw.Records {
var m map[string]any
if err := json.Unmarshal(item, &m); err == nil {
result = append(result, m)
}
}
RailCatalog4229938_entries = result
RailCatalog4229938_cached = true
return result, nil
}
//
// RaidConfig.json 的 LightRailLineIds:这个 raid 的场景里**实际存在**的地铁/轻轨线路。
// 客户端只能为「已加载场景里烘焙了 MetroPath 的线」建出车厢(见
// GameRouter.Metro.cs 顶部说明:MetroClientInfo 只有 Id / LineId / ElapsedTime / IsFinalTrain,
// 走行路径是客户端本地资源)。推了不属于当前场景的线,客户端找不到路径 ⇒ 车要么不出、
// 要么沿别的路径跑(表现为"车不在铁轨上")。所以推线要以这张表为准,不能全局固定。
// 全表只有 4 个 raid 配了这项(RaidConfig 共 212 行):
// 23300888 新启 = 1–4;23300999 凌云/重霄 = 9–14 + 15 画舫;
// 23301227 轻轨测试场景 = 5–8;23301271 香肠人镜像副本 = 1–4。
// 其余(以及 raid 未知 / 未进世界时)返回空数组,调用方自行兜底。
//
func RailCatalog4229938_LinesForRaid(raidId uint32) []uint32 {
// Catalog helper RailCatalog4229938_LinesForRaid
return nil
}
func RailCatalog4229938_TryGetLine(id uint32, line RailLine4229938) bool {
// Catalog helper RailCatalog4229938_TryGetLine
return false
}
func RailCatalog4229938_TryGetStation(id uint32, station RailStation4229938) bool {
// Catalog helper RailCatalog4229938_TryGetStation
return false
}
func RailCatalog4229938_TryGetRoute(lineId uint32, route RailRoute4229938) bool {
// Catalog helper RailCatalog4229938_TryGetRoute
return false
}
//
// Position of train of at
// seconds into the day's service. Trains are evenly spaced by
// DepartureInterval and wrap around TotalTravelDuration, which is what the stops' ArrivalTime
// values are measured against (the last stop's arrival equals the total travel duration).
//
func RailCatalog4229938_ElapsedForTrain(line RailLine4229938, trainIndex int32, elapsedSeconds float64) float64 {
// Catalog helper RailCatalog4229938_ElapsedForTrain
return 0
}
// Resolves "where is the train" from its ElapsedTime and the baked stop timetable.
func RailCatalog4229938_ProgressAt(line RailLine4229938, elapsed float64) *RailTrainProgress {
// Catalog helper RailCatalog4229938_ProgressAt
return nil
}
func RailCatalog4229938_LoadRaidLines() map[uint32][]uint32 {
// Catalog helper RailCatalog4229938_LoadRaidLines
return nil
}
func RailCatalog4229938_LoadLines() map[uint32]RailLine4229938 {
// Catalog helper RailCatalog4229938_LoadLines
return nil
}
func RailCatalog4229938_LoadStations() map[uint32]RailStation4229938 {
// Catalog helper RailCatalog4229938_LoadStations
return nil
}
func RailCatalog4229938_LoadRoutes() map[uint32]RailRoute4229938 {
// Catalog helper RailCatalog4229938_LoadRoutes
return nil
}
func RailCatalog4229938_UIntArray(row any, name string) []uint32 {
// Catalog helper RailCatalog4229938_UIntArray
return nil
}
func RailCatalog4229938_ReadRecords(fileName string) []any {
// Catalog helper RailCatalog4229938_ReadRecords
return nil
}
func RailCatalog4229938_Str(row any, name string) string {
// Catalog helper RailCatalog4229938_Str
return ""
}
func RailCatalog4229938_UInt(row any, name string) uint32 {
// Catalog helper RailCatalog4229938_UInt
return 0
}
func RailCatalog4229938_Int(row any, name string) int32 {
// Catalog helper RailCatalog4229938_Int
return 0
}
func RailCatalog4229938_Double(row any, name string) float64 {
// Catalog helper RailCatalog4229938_Double
return 0
}
func RailCatalog4229938_Bool(row any, name string) bool {
// Catalog helper RailCatalog4229938_Bool
return false
}
func RailCatalog4229938_Clock(row any, name string, fallbackHour int32, fallbackMinute int32) any {
// Catalog helper RailCatalog4229938_Clock
var zero any; return zero
}