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