From 8ed37655628d9b1fba7d7a7f000bdf30e354a4cd Mon Sep 17 00:00:00 2001 From: maj00r Date: Mon, 31 Aug 2026 00:44:56 +0200 Subject: [PATCH] read rolling stock from dynamic/*/*/textures.txt, drop vehicles.json --- StarterNG/Classes/GameData.cs | 49 ++--- ...egacyTextureDatabase.cs => TexturesTxt.cs} | 7 +- StarterNG/Classes/VehicleDatabase.cs | 195 +++++------------- StarterNG/startercfg/lang/cz.xml | 2 +- StarterNG/startercfg/lang/en.xml | 2 +- StarterNG/startercfg/lang/hu.xml | 2 +- StarterNG/startercfg/lang/pl.xml | 2 +- StarterNG/startercfg/lang/ru.xml | 2 +- 8 files changed, 82 insertions(+), 179 deletions(-) rename StarterNG/Classes/{LegacyTextureDatabase.cs => TexturesTxt.cs} (96%) diff --git a/StarterNG/Classes/GameData.cs b/StarterNG/Classes/GameData.cs index ba716e5..348d8e5 100644 --- a/StarterNG/Classes/GameData.cs +++ b/StarterNG/Classes/GameData.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading; using System.Threading.Tasks; namespace StarterNG.Classes; @@ -25,43 +26,25 @@ public sealed class GameData public bool Loaded { get; private set; } public void Load(IProgress? progress = null, - string vehiclesDir = "databases/vehicles/", string sceneryDir = "scenery/", - string miniDir = "textures/mini/") + string miniDir = "textures/mini/", + string dynamicRoot = "dynamic") { if (Loaded) return; - var vehicleFiles = VehicleDatabase.EnumerateFiles(vehiclesDir); var scnFiles = EnumerateScenery(sceneryDir); - int total = Math.Max(1, vehicleFiles.Count + scnFiles.Count); + int total = Math.Max(1, scnFiles.Count); int done = 0; - Vehicles.BeginLoad(); - foreach (string file in vehicleFiles) - { - progress?.Report(new LoadStatus((double)done / total, LoadPhase.Vehicles, - Path.GetFileName(file))); - try { Vehicles.LoadFile(file); } - catch { } - done++; - } - try - { - int legacy = Vehicles.ImportLegacy(); - if (legacy > 0) - Infrastructure.Diagnostics.Log($"textures.txt: wczytano {legacy} tekstur"); - } - catch (Exception ex) - { - Infrastructure.Diagnostics.Log("textures.txt import", ex); - } + progress?.Report(new LoadStatus(0, LoadPhase.Vehicles, "textures.txt")); + int vehicles = Vehicles.LoadFromTexturesTxt(dynamicRoot); + if (vehicles == 0) + Infrastructure.Diagnostics.Log($"{dynamicRoot}: brak plikow textures.txt"); - Vehicles.EndLoad(); - - VehicleDatabase.PreloadMiniIndex(miniDir); - - Physics.PreloadIndex(); + Parallel.Invoke( + () => VehicleDatabase.PreloadMiniIndex(miniDir), + () => Physics.PreloadIndex()); var sceneryLock = new object(); var doneCount = done; @@ -79,7 +62,10 @@ public sealed class GameData Path.GetFileName(file))); } } - catch { } + catch (Exception ex) + { + StarterNG.Infrastructure.Diagnostics.Log($"scenery/{Path.GetFileName(file)}", ex); + } }); done = doneCount; @@ -101,7 +87,10 @@ public sealed class GameData lock (sceneryLock) Sceneries.Add(scenery); } - catch { } + catch (Exception ex) + { + StarterNG.Infrastructure.Diagnostics.Log($"scenery/{Path.GetFileName(file)}", ex); + } }); } diff --git a/StarterNG/Classes/LegacyTextureDatabase.cs b/StarterNG/Classes/TexturesTxt.cs similarity index 96% rename from StarterNG/Classes/LegacyTextureDatabase.cs rename to StarterNG/Classes/TexturesTxt.cs index b633842..01e517f 100644 --- a/StarterNG/Classes/LegacyTextureDatabase.cs +++ b/StarterNG/Classes/TexturesTxt.cs @@ -5,7 +5,7 @@ using System.Text; namespace StarterNG.Classes; -public static class LegacyTextureDatabase +public static class TexturesTxt { public static List EnumerateFiles(string dynamicRoot = "dynamic") { @@ -139,8 +139,7 @@ public static class LegacyTextureDatabase Id = groupId, Category = categorySign, Mini = first.Mini, - Archived = archived, - Implicit = true + Archived = archived }); var texture = new VehicleTexture @@ -148,6 +147,8 @@ public static class LegacyTextureDatabase Uuid = $"legacy:{dir}{skin}", Directory = dir, Skinfile = skin, + Wreck = skin.Contains("wreck", StringComparison.OrdinalIgnoreCase) || + skin.Contains("wrak", StringComparison.OrdinalIgnoreCase), Model = first.Model, Group = groupId, MiniRef = first.Mini, diff --git a/StarterNG/Classes/VehicleDatabase.cs b/StarterNG/Classes/VehicleDatabase.cs index d1f0f4c..8d827db 100644 --- a/StarterNG/Classes/VehicleDatabase.cs +++ b/StarterNG/Classes/VehicleDatabase.cs @@ -2,78 +2,68 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Text.Json.Serialization.Metadata; +using System.Threading.Tasks; namespace StarterNG.Classes; public class VehicleEntry { - [JsonPropertyName("uuid")] public string? Uuid { get; set; } - [JsonPropertyName("schema_version")] public int SchemaVersion { get; set; } - [JsonPropertyName("groups")] public List Groups { get; set; } = new(); - [JsonPropertyName("textures")] public List Textures { get; set; } = new(); - [JsonPropertyName("sets")] public List Sets { get; set; } = new(); - [JsonPropertyName("unknown")] public List Unknown { get; set; } = new(); -} - -public class VehicleEntryCollection -{ - [JsonPropertyName("vehicles")] public List Vehicles { get; set; } = new(); + public string? Uuid { get; set; } + public List Groups { get; set; } = new(); + public List Textures { get; set; } = new(); + public List Sets { get; set; } = new(); } public class VehicleGroup { - [JsonPropertyName("id")] public string Id { get; set; } = ""; - [JsonPropertyName("category")] public string? Category { get; set; } - [JsonPropertyName("mini")] public string? Mini { get; set; } - [JsonPropertyName("archived")] public bool Archived { get; set; } - [JsonPropertyName("implicit")] public bool Implicit { get; set; } + public string Id { get; set; } = ""; + public string? Category { get; set; } + public string? Mini { get; set; } + public bool Archived { get; set; } } public class VehicleTexture { - [JsonPropertyName("uuid")] public string? Uuid { get; set; } - [JsonPropertyName("directory")] public string Directory { get; set; } = ""; - [JsonPropertyName("skinfile")] public string Skinfile { get; set; } = ""; - [JsonPropertyName("model")] public string? Model { get; set; } - [JsonPropertyName("group")] public string? Group { get; set; } - [JsonPropertyName("mini_ref")] public string? MiniRef { get; set; } - [JsonPropertyName("texture_mini")] public string? TextureMini { get; set; } - [JsonPropertyName("wreck")] public bool Wreck { get; set; } - [JsonPropertyName("aliases")] public List Aliases { get; set; } = new(); - [JsonPropertyName("meta")] public VehicleMeta? Meta { get; set; } + public string? Uuid { get; set; } + public string Directory { get; set; } = ""; + public string Skinfile { get; set; } = ""; + public string? Model { get; set; } + public string? Group { get; set; } + public string? MiniRef { get; set; } + public string? TextureMini { get; set; } + public bool Wreck { get; set; } + public List Aliases { get; set; } = new(); + public VehicleMeta? Meta { get; set; } - [JsonIgnore] public string FullPath => Directory + Skinfile; + public string FullPath => Directory + Skinfile; - [JsonIgnore] public string ResolvedClass { get; internal set; } = ""; + public string ResolvedClass { get; internal set; } = ""; - [JsonIgnore] public string? ResolvedCategory { get; internal set; } + public string? ResolvedCategory { get; internal set; } - [JsonIgnore] public bool ResolvedArchived { get; internal set; } + public bool ResolvedArchived { get; internal set; } } public class VehicleAlias { - [JsonPropertyName("model")] public string? Model { get; set; } - [JsonPropertyName("group")] public string? Group { get; set; } - [JsonPropertyName("mini_ref")] public string? MiniRef { get; set; } - [JsonPropertyName("texture_mini")] public string? TextureMini { get; set; } + public string? Model { get; set; } + public string? Group { get; set; } + public string? MiniRef { get; set; } + public string? TextureMini { get; set; } } public class VehicleMeta { - [JsonPropertyName("raw")] public string? Raw { get; set; } - [JsonPropertyName("version")] public string? Version { get; set; } - [JsonPropertyName("vehicle")] public string? Vehicle { get; set; } - [JsonPropertyName("operator")] public string? Operator { get; set; } - [JsonPropertyName("depot")] public string? Depot { get; set; } - [JsonPropertyName("revision_date")] public string? RevisionDate { get; set; } - [JsonPropertyName("revision_place")] public string? RevisionPlace { get; set; } - [JsonPropertyName("texture_author")] public string? TextureAuthor { get; set; } - [JsonPropertyName("photo_author")] public string? PhotoAuthor { get; set; } - [JsonPropertyName("extra")] public List Extra { get; set; } = new(); + public string? Raw { get; set; } + public string? Version { get; set; } + public string? Vehicle { get; set; } + public string? Operator { get; set; } + public string? Depot { get; set; } + public string? RevisionDate { get; set; } + public string? RevisionPlace { get; set; } + public string? TextureAuthor { get; set; } + public string? PhotoAuthor { get; set; } + public List Extra { get; set; } = new(); } public class VehicleDatabase @@ -88,20 +78,22 @@ public class VehicleDatabase public Dictionary TextureBySkin { get; } = new(); - private static readonly JsonSerializerOptions JsonOpts = new() - { - PropertyNameCaseInsensitive = true, - ReadCommentHandling = JsonCommentHandling.Skip, - AllowTrailingCommas = true, - TypeInfoResolver = VehicleJsonContext.Default, - }; - - public void Load(string directory = "databases/vehicles/") + public int LoadFromTexturesTxt(string dynamicRoot = "dynamic") { BeginLoad(); - foreach (string file in EnumerateFiles(directory)) - LoadFile(file); + + int count = 0; + foreach (string file in TexturesTxt.EnumerateFiles(dynamicRoot)) + { + var entry = TexturesTxt.Parse(file, dynamicRoot); + if (entry is null) continue; + + count += entry.Textures.Count; + Ingest(entry); + } + EndLoad(); + return count; } public void BeginLoad() @@ -120,79 +112,6 @@ public class VehicleDatabase BuildTextureIndex(); } - public static List EnumerateFiles(string directory = "databases/vehicles/") - { - if (!Directory.Exists(directory)) - return new List(); - - string merged = Path.Combine(directory, "vehicles.json"); - if (File.Exists(merged)) - return new List { merged }; - - return Directory.GetFiles(directory, "*.json").ToList(); - } - - public void LoadFile(string file) - { - if (string.Equals(Path.GetFileName(file), "vehicles.json", StringComparison.OrdinalIgnoreCase)) - LoadMerged(file); - else - LoadEntryFile(file); - } - - private void LoadMerged(string file) - { - try - { - var collection = JsonSerializer.Deserialize( - File.ReadAllText(file), - (JsonTypeInfo)JsonOpts.GetTypeInfo(typeof(VehicleEntryCollection))); - if (collection?.Vehicles is null) return; - foreach (var entry in collection.Vehicles) - Ingest(entry); - } - catch - { - - } - } - - private void LoadEntryFile(string file) - { - try - { - var entry = JsonSerializer.Deserialize( - File.ReadAllText(file), - (JsonTypeInfo)JsonOpts.GetTypeInfo(typeof(VehicleEntry))); - if (entry is not null) - Ingest(entry); - } - catch - { - - } - } - - public int ImportLegacy(string dynamicRoot = "dynamic") - { - int added = 0; - foreach (string file in LegacyTextureDatabase.EnumerateFiles(dynamicRoot)) - { - var entry = LegacyTextureDatabase.Parse(file, dynamicRoot); - if (entry is null) continue; - - entry.Textures.RemoveAll(t => - TextureBySkin.ContainsKey( - Path.GetFileNameWithoutExtension(t.Skinfile).ToLowerInvariant())); - - if (entry.Textures.Count == 0) continue; - - added += entry.Textures.Count; - Ingest(entry); - } - return added; - } - private void Ingest(VehicleEntry entry) { foreach (var group in entry.Groups) @@ -386,14 +305,8 @@ public class VehicleDatabase public class VehicleSet { - [JsonPropertyName("uuid")] public string? Uuid { get; set; } - [JsonPropertyName("mode")] public string? Mode { get; set; } - [JsonPropertyName("count")] public int Count { get; set; } - [JsonPropertyName("texture_refs")] public List TextureRefs { get; set; } = new(); -} - -[JsonSerializable(typeof(VehicleEntry))] -[JsonSerializable(typeof(VehicleEntryCollection))] -internal partial class VehicleJsonContext : JsonSerializerContext -{ + public string? Uuid { get; set; } + public string? Mode { get; set; } + public int Count { get; set; } + public List TextureRefs { get; set; } = new(); } diff --git a/StarterNG/startercfg/lang/cz.xml b/StarterNG/startercfg/lang/cz.xml index 4df5809..dc1d901 100644 --- a/StarterNG/startercfg/lang/cz.xml +++ b/StarterNG/startercfg/lang/cz.xml @@ -90,7 +90,7 @@ Vozidlo s osádkou otočeno - Ve složce databases/vehicles/ nebyla nalezena žádná vozidla. + Ve složce dynamic/**/textures.txt nebyla nalezena žádná vozidla. Přidejte vozidla z databáze vlevo nebo načtěte existující soupravu ze souboru scenérie. Posunout doleva Posunout doprava diff --git a/StarterNG/startercfg/lang/en.xml b/StarterNG/startercfg/lang/en.xml index 551fba2..4afecb2 100644 --- a/StarterNG/startercfg/lang/en.xml +++ b/StarterNG/startercfg/lang/en.xml @@ -90,7 +90,7 @@ Vehicle with crew reversed - No vehicles found in databases/vehicles/. + No vehicles found in dynamic/**/textures.txt. Add vehicles from the database on the left, or load an existing consist from a scenery file. Move left Move right diff --git a/StarterNG/startercfg/lang/hu.xml b/StarterNG/startercfg/lang/hu.xml index 1fbc627..0972b0a 100644 --- a/StarterNG/startercfg/lang/hu.xml +++ b/StarterNG/startercfg/lang/hu.xml @@ -90,7 +90,7 @@ Jármű személyzettel megfordítva - A databases/vehicles/ mappában nem található jármű. + A dynamic/**/textures.txt fájlokban nem található jármű. Adjon hozzá járműveket a bal oldali adatbázisból, vagy töltsön be meglévő szerelvényt egy pályafájlból. Mozgatás balra Mozgatás jobbra diff --git a/StarterNG/startercfg/lang/pl.xml b/StarterNG/startercfg/lang/pl.xml index 89fa8de..676981d 100644 --- a/StarterNG/startercfg/lang/pl.xml +++ b/StarterNG/startercfg/lang/pl.xml @@ -90,7 +90,7 @@ Pojazd z obsadą obrócony - Nie znaleziono pojazdów w databases/vehicles/. + Nie znaleziono pojazdów w dynamic/**/textures.txt. Dodaj pojazdy z bazy po lewej stronie lub wczytaj istniejący skład z pliku scenerii. Przesuń w lewo Przesuń w prawo diff --git a/StarterNG/startercfg/lang/ru.xml b/StarterNG/startercfg/lang/ru.xml index bef75ae..d3f0f1a 100644 --- a/StarterNG/startercfg/lang/ru.xml +++ b/StarterNG/startercfg/lang/ru.xml @@ -90,7 +90,7 @@ Единица с бригадой развёрнут - В databases/vehicles/ подвижной состав не найден. + В dynamic/**/textures.txt подвижной состав не найден. Добавьте единицы из базы слева или загрузите готовый состав из файла сценерии. Сдвинуть влево Сдвинуть вправо