252 lines
8.1 KiB
Go
252 lines
8.1 KiB
Go
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
|
||
}
|
||
|