From 19a2ac8d590a035d0c3cdb02080d096b92ab05ef Mon Sep 17 00:00:00 2001 From: Hirek Date: Wed, 11 Feb 2026 14:40:16 +0100 Subject: [PATCH] Add scenery list parser --- StarterNG.sln | 12 ++ StarterNG.sln.DotSettings.user | 8 +- StarterNG/Assets/Logo/splash.png | Bin 0 -> 11886 bytes StarterNG/Classes/Scenery.cs | 50 ++++++++ StarterNG/Classes/Trainset.cs | 155 +++++++++++++++++++++++ StarterNG/MainWindow.axaml | 2 +- StarterNG/MainWindow.axaml.cs | 2 + StarterNG/Properties/launchSettings.json | 8 ++ StarterNG/StarterNG.csproj | 5 +- StarterNG/Views/Scenarios.axaml | 16 +-- StarterNG/Views/Scenarios.axaml.cs | 62 ++++++++- 11 files changed, 300 insertions(+), 20 deletions(-) create mode 100644 StarterNG/Assets/Logo/splash.png create mode 100644 StarterNG/Classes/Scenery.cs create mode 100644 StarterNG/Classes/Trainset.cs create mode 100644 StarterNG/Properties/launchSettings.json diff --git a/StarterNG.sln b/StarterNG.sln index 7831d20..4165ee9 100644 --- a/StarterNG.sln +++ b/StarterNG.sln @@ -1,16 +1,28 @@  Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 18 +VisualStudioVersion = 18.1.11312.151 d18.0 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StarterNG", "StarterNG\StarterNG.csproj", "{D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}.Debug|x64.ActiveCfg = Debug|x64 + {D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}.Debug|x64.Build.0 = Debug|x64 {D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}.Release|Any CPU.ActiveCfg = Release|Any CPU {D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}.Release|Any CPU.Build.0 = Release|Any CPU + {D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}.Release|x64.ActiveCfg = Release|x64 + {D1E8A3A3-3269-415A-94AD-D6F370D7E4FD}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection EndGlobal diff --git a/StarterNG.sln.DotSettings.user b/StarterNG.sln.DotSettings.user index daa1893..6827f48 100644 --- a/StarterNG.sln.DotSettings.user +++ b/StarterNG.sln.DotSettings.user @@ -1,9 +1,15 @@  + ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded - ForceIncluded \ No newline at end of file + ForceIncluded + E:\Program Files\Microsoft Visual Studio\18\Community\MSBuild\Current\Bin\amd64\MSBuild.exe + 1179648 \ No newline at end of file diff --git a/StarterNG/Assets/Logo/splash.png b/StarterNG/Assets/Logo/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..9b9fb579193059fbfccec8b5a5044af5764b59a9 GIT binary patch literal 11886 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

xVk3EPGgPJs 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 Lines; + public List Trainsets; + public string Group; + public string Path; + public Scenery(string path) + { + this.Path = path; + Trainsets = new List(); + if (!File.Exists(path)) + throw new FileNotFoundException(path); + var encoding = Encoding.GetEncoding(1250); // Windows-1250 + string content = File.ReadAllText(path, encoding); + + // property scanning + var match = Regex.Match( + content, + @"^//\$l\s*([^\r\n]*)", + RegexOptions.Multiline + ); + this.Group = match.Success ? match.Groups[1].Value : null; + + + // parsing trainsets + List trainsetEntries = new List(); + Regex regex = new Regex( + @"trainset\b[\s\S]*?\bendtrainset\b", + RegexOptions.IgnoreCase + ); + int idx = 0; + content = regex.Replace(content, match => + { + trainsetEntries.Add(match.Value); + return $"{{{{{idx++}}}}}"; + }); + + foreach (string trainsetEntry in trainsetEntries) + { + Trainsets.Add(new Trainset(trainsetEntry)); + } + } +} \ No newline at end of file diff --git a/StarterNG/Classes/Trainset.cs b/StarterNG/Classes/Trainset.cs new file mode 100644 index 0000000..9679db9 --- /dev/null +++ b/StarterNG/Classes/Trainset.cs @@ -0,0 +1,155 @@ +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Reflection.Metadata.Ecma335; +using System.Text.RegularExpressions; + +namespace StarterNG.Classes; + +public enum eDriverType +{ + Headdriver, + Reardriver, + Passanger, + Nobody +} + +public class Trainset +{ + public string Name; + public string Track; + public float Offset; + public float Velocity; + public List Vehicles; + public Trainset(string trainsetEntry) + { + + Vehicles = new List(); + + List tokens = Regex + .Matches(trainsetEntry, @"\r\n|\n|[^\s]+") + .Select(m => m.Value) + .ToList(); + + for (int i = 0; i < tokens.Count; i++) + { + // handle comments + if (tokens[i].StartsWith("//")) + { + while (tokens[i] != "\n" && tokens.Count < i) i++; + } + + + // trainset properties + if (tokens[i] == "trainset") + { + i++; + this.Name = tokens[i++]; + this.Track = tokens[i++]; + this.Offset = float.Parse(tokens[i++], CultureInfo.InvariantCulture); + this.Velocity = float.Parse(tokens[i++], CultureInfo.InvariantCulture); + continue; + } + + // skip entire assignments block + if (tokens[i] == "assignments") + { + while (tokens[i] != "endassignment") i++; + } + + // load vehicles + if (tokens[i] == "node") + { + i++; // node keyword + Dynamic nodeDynamic = new Dynamic(); + nodeDynamic.RangeMax = float.Parse(tokens[i++], CultureInfo.InvariantCulture); + nodeDynamic.RangeMin = float.Parse(tokens[i++], CultureInfo.InvariantCulture); + nodeDynamic.Name = tokens[i++]; + i++; // dynamic keyword + nodeDynamic.DataFolder = tokens[i++]; + nodeDynamic.SkinFile = tokens[i++]; + nodeDynamic.MmdFile = tokens[i++]; + i++; // skip offset + string driverType = tokens[i++]; + switch (driverType) + { + case "headdriver": + nodeDynamic.DriverType = eDriverType.Headdriver; + break; + case "reardriver": + nodeDynamic.DriverType = eDriverType.Reardriver; + break; + case "passanger": + nodeDynamic.DriverType = eDriverType.Passanger; + break; + default: + nodeDynamic.DriverType = eDriverType.Nobody; + break; + } + + nodeDynamic.couplingData = (byte)int.Parse(tokens[i++].Split('.')[0]); + + nodeDynamic.Tail = ""; + while (tokens[i] != "enddynamic") + { + nodeDynamic.Tail += " " + tokens[i]; + i++; + } + + Vehicles.Add(nodeDynamic); + } + } + } + + public string GetTrainsetEntry() + { + string entry = ""; + + entry += "trainset "; + entry += this.Name + " "; + entry += this.Track + " "; + entry += this.Offset + " "; + entry += this.Velocity + " "; + entry += "\n"; + foreach (Dynamic vehicle in Vehicles) + { + string driverType = ""; + switch (vehicle.DriverType) + { + case eDriverType.Headdriver: + driverType = "headdriver"; + break; + case eDriverType.Reardriver: + driverType = "reardriver"; + break; + case eDriverType.Passanger: + driverType = "passanger"; + break; + default: + driverType = "nobody"; + break; + } + + entry += + $"node {vehicle.RangeMax} {vehicle.RangeMin} {vehicle.Name} dynamic {vehicle.DataFolder} {vehicle.SkinFile} {vehicle.MmdFile} {driverType} {vehicle.couplingData} {vehicle.Tail}\n"; + } + + + return entry; + } +} + +public class Dynamic +{ + public float RangeMax; + public float RangeMin; + public string Name; + public string DataFolder; + public string SkinFile; + public string MmdFile; + public string PathName; + public float Offset; + public eDriverType DriverType; + public byte couplingData; + public string Tail; +} \ No newline at end of file diff --git a/StarterNG/MainWindow.axaml b/StarterNG/MainWindow.axaml index 3cb8cc0..03ef0cc 100644 --- a/StarterNG/MainWindow.axaml +++ b/StarterNG/MainWindow.axaml @@ -8,7 +8,7 @@ xmlns:svg="clr-namespace:Avalonia.Svg;assembly=Avalonia.Svg" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:views="clr-namespace:StarterNG.Views" BackgroundStyle="Bubble" - Title="MaSzyna - Symulator pojazdów szynowych" Height="600" Width="800"> + Title="MaSzyna - Symulator pojazdów szynowych" Height="800" Width="1000"> diff --git a/StarterNG/MainWindow.axaml.cs b/StarterNG/MainWindow.axaml.cs index d54f5f1..f281283 100644 --- a/StarterNG/MainWindow.axaml.cs +++ b/StarterNG/MainWindow.axaml.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using System.Text; using Avalonia.Controls; using Avalonia.Interactivity; using SukiUI.Controls; @@ -8,6 +9,7 @@ public partial class MainWindow : SukiWindow { public MainWindow() { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); InitializeComponent(); } private void linkClick(object? sender, RoutedEventArgs e) diff --git a/StarterNG/Properties/launchSettings.json b/StarterNG/Properties/launchSettings.json new file mode 100644 index 0000000..1a403fd --- /dev/null +++ b/StarterNG/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "StarterNG": { + "commandName": "Project", + "workingDirectory": "E:\\Hirek\\Games\\Steam\\steamapps\\common\\MaSzyna" + } + } +} \ No newline at end of file diff --git a/StarterNG/StarterNG.csproj b/StarterNG/StarterNG.csproj index e86cfd5..109fb63 100644 --- a/StarterNG/StarterNG.csproj +++ b/StarterNG/StarterNG.csproj @@ -6,6 +6,7 @@ true app.manifest true + AnyCPU;x64 x64 @@ -30,10 +31,6 @@ - - - - diff --git a/StarterNG/Views/Scenarios.axaml b/StarterNG/Views/Scenarios.axaml index 7bf33fd..aa41533 100644 --- a/StarterNG/Views/Scenarios.axaml +++ b/StarterNG/Views/Scenarios.axaml @@ -7,7 +7,7 @@ x:Class="StarterNG.Views.Scenarios"> - + @@ -17,18 +17,8 @@ - - - - - - - - - - - - + + diff --git a/StarterNG/Views/Scenarios.axaml.cs b/StarterNG/Views/Scenarios.axaml.cs index b5fc727..0da08ae 100644 --- a/StarterNG/Views/Scenarios.axaml.cs +++ b/StarterNG/Views/Scenarios.axaml.cs @@ -1,13 +1,73 @@ -using Avalonia; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Avalonia; using Avalonia.Controls; using Avalonia.Markup.Xaml; +using StarterNG.Classes; namespace StarterNG.Views; public partial class Scenarios : UserControl { + public List sceneries; + public Scenarios() { InitializeComponent(); + sceneries = new List(); + + // load sceneries + List scnFiles = Directory.GetFiles("scenery/", "*.scn").ToList(); + foreach (string scnFile in scnFiles) + { + // skip temp sceneries + if (Path.GetFileName(scnFile).StartsWith("$")) + continue; + + // Parse all files + sceneries.Add(new Scenery(scnFile)); + } + + var groupNodes = new Dictionary(); + + for (int i = 0; i < sceneries.Count; i++) + { + var scenery = sceneries[i]; + + // case 1: no group - put without parent + if (string.IsNullOrEmpty(scenery.Group)) + { + sceneryList.Items.Add(new TreeViewItem + { + Header = Path.GetFileNameWithoutExtension(scenery.Path), + Tag = i + }); + + continue; + } + + // case 2 - group scenery with others + if (!groupNodes.TryGetValue(scenery.Group, out var groupNode)) + { + groupNode = new TreeViewItem + { + Header = scenery.Group, + IsExpanded = true + }; + + groupNodes[scenery.Group] = groupNode; + sceneryList.Items.Add(groupNode); + } + + groupNode.Items.Add(new TreeViewItem + { + Header = Path.GetFileNameWithoutExtension(scenery.Path), + Tag = i + }); + } + + + } } \ No newline at end of file