diff --git a/CRSim.Core/Abstractions/IDatabaseService.cs b/CRSim.Core/Abstractions/IDatabaseService.cs index 5db1362..29b0cfe 100644 --- a/CRSim.Core/Abstractions/IDatabaseService.cs +++ b/CRSim.Core/Abstractions/IDatabaseService.cs @@ -9,9 +9,7 @@ namespace CRSim.Core.Abstractions List GetAllTrainNumbers(); Station GetStationByName(string name); TrainNumber GetTrainNumberByNumber(string number); - void AddStationByName(string name); void AddStation(Station station); - Task ImportStationFrom7D(string path); void AddTrainNumber(TrainNumber trainNumber); void DeleteStation(Station station); void DeleteTrainNumber(TrainNumber trainNumber); diff --git a/CRSim.Core/Services/DatabaseService.cs b/CRSim.Core/Services/DatabaseService.cs index 5e9b199..518e561 100644 --- a/CRSim.Core/Services/DatabaseService.cs +++ b/CRSim.Core/Services/DatabaseService.cs @@ -2,7 +2,6 @@ using CRSim.Core.Models; using CRSim.Core.Utils; using System.Text.Json; -using System.Text.Json.Serialization; namespace CRSim.Core.Services { @@ -39,13 +38,6 @@ namespace CRSim.Core.Services { return _trainNumbers.FirstOrDefault(x => x.Number == number); } - public void AddStationByName(string name) - { - _stations.Add(new Station() - { - Name = name, - }); - } public void DeleteStation(Station station) { @@ -110,81 +102,6 @@ namespace CRSim.Core.Services _trainNumbers.Add(trainNumber); } - public async Task ImportStationFrom7D(string path) - { - Station station = new() { Platforms = [], WaitingAreas = [], TrainStops = [] }; - var stationName = (await File.ReadAllTextAsync(path.Replace("车站广播系统.exe", "info.ini"))).Split("|")[0]; - if (_stations.Any(x => x.Name == stationName)) - { - _stations.Remove(GetStationByName(stationName)); - } - var lines = await File.ReadAllLinesAsync(path.Replace("车站广播系统.exe", "data.csv")); - station.Name = stationName; - foreach (var line in lines) - { - var data = line.Split(','); - var waitingAreaName = string.IsNullOrWhiteSpace(data.Last()) ? "未知" : data.Last(); - var platform = string.IsNullOrWhiteSpace(data[5]) ? "未知" : data[5]; - var ticketCheck = string.IsNullOrWhiteSpace(data[4]) ? string.Empty : data[4]; - - var existingPlatform = station.Platforms.FirstOrDefault(x => x.Name == platform); - if (existingPlatform == null) - { - station.Platforms.Add(new Platform { Name = platform, Length = 20 }); - } - - - var waitingArea = station.WaitingAreas.FirstOrDefault(x => x.Name == waitingAreaName); - if (waitingArea == null) - { - waitingArea = new WaitingArea() { Name = waitingAreaName }; - station.WaitingAreas.Add(waitingArea); - } - - foreach (var ticketCheckName in ticketCheck.Split('|')) - { - if (!string.IsNullOrWhiteSpace(ticketCheckName) && !waitingArea.TicketChecks.Any(x => x.Name == ticketCheckName)) - { - waitingArea.TicketChecks.Add(new TicketCheck { Name = ticketCheckName }); - } - } - - if (!string.IsNullOrEmpty(data[0]) && !station.TrainStops.Any(x => x.Number == data[0])) - { - TimeSpan? arrivalTime = null; - TimeSpan? departureTime = null; - - if (data[2] == stationName) - { - departureTime = TimeSpan.Parse(lines.FirstOrDefault(x => x.Split(",")[0] == data[0] && x.Split(",")[1].Contains("送车"))?.Split(",")[7] ?? string.Empty); - } - else if (data[3] == stationName) - { - arrivalTime = TimeSpan.Parse(data[7]); - } - else - { - arrivalTime = TimeSpan.Parse(data[7]); - departureTime = TimeSpan.Parse(lines.FirstOrDefault(x => x.Split(",")[0] == data[0] && x.Split(",")[1].Contains("送车"))?.Split(",")[7] ?? string.Empty); - } - - station.TrainStops.Add(new TrainStop - { - Number = data[0], - Terminal = data[3], - Origin = data[2], - TicketCheckIds = [.. waitingArea.TicketChecks.Select(x=>x.Id)], - ArrivalTime = arrivalTime, - DepartureTime = departureTime, - Platform = platform, - Length = data[0].StartsWith('G') || data[0].StartsWith('D') || data[0].StartsWith('C') ? Math.Abs(data[0].GetHashCode()) % 3 == 0 ? 8 : 16 : 18, - Landmark = data[8] + "色" ?? null, - }); - } - } - AddStation(station); - } - public void AddStation(Station station) { _stations.Add(station); diff --git a/CRSim.Core/Services/NetworkService.cs b/CRSim.Core/Services/NetworkService.cs index 1aece04..1ad1fc1 100644 --- a/CRSim.Core/Services/NetworkService.cs +++ b/CRSim.Core/Services/NetworkService.cs @@ -3,6 +3,7 @@ using CRSim.Core.Models; using CRSim.Core.Models.Plugin; using System.Net; using System.Text.Json; +using System.Text.Json.Nodes; namespace CRSim.Core.Services { diff --git a/CRSim.PlatformDiagram/CRSim.PlatformDiagram.csproj b/CRSim.PlatformDiagram/CRSim.PlatformDiagram.csproj index 6cdcf5d..1333cef 100644 --- a/CRSim.PlatformDiagram/CRSim.PlatformDiagram.csproj +++ b/CRSim.PlatformDiagram/CRSim.PlatformDiagram.csproj @@ -4,6 +4,7 @@ net9.0-windows10.0.19041.0 enable enable + x64 diff --git a/CRSim.sln b/CRSim.sln index fe707a7..e5d6b67 100644 --- a/CRSim.sln +++ b/CRSim.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.12.35424.110 +# Visual Studio Version 18 +VisualStudioVersion = 18.3.11218.70 d18.3 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CRSim.Core", "CRSim.Core\CRSim.Core.csproj", "{C72B16CC-AA3E-4E0F-A424-07D3987A9FD9}" EndProject @@ -31,10 +31,9 @@ Global {94927020-7AD7-4F6F-A456-F34A8E0BC40A}.Debug|x64.Build.0 = Debug|x64 {94927020-7AD7-4F6F-A456-F34A8E0BC40A}.Release|x64.ActiveCfg = Release|x64 {94927020-7AD7-4F6F-A456-F34A8E0BC40A}.Release|x64.Build.0 = Release|x64 - {895EE8B3-1A15-4CA8-9AFE-246585732AA5}.Debug|x64.ActiveCfg = Debug|Any CPU - {895EE8B3-1A15-4CA8-9AFE-246585732AA5}.Debug|x64.Build.0 = Debug|Any CPU - {895EE8B3-1A15-4CA8-9AFE-246585732AA5}.Release|x64.ActiveCfg = Release|Any CPU - {895EE8B3-1A15-4CA8-9AFE-246585732AA5}.Release|x64.Build.0 = Release|Any CPU + {895EE8B3-1A15-4CA8-9AFE-246585732AA5}.Debug|x64.ActiveCfg = Debug|x64 + {895EE8B3-1A15-4CA8-9AFE-246585732AA5}.Debug|x64.Build.0 = Debug|x64 + {895EE8B3-1A15-4CA8-9AFE-246585732AA5}.Release|x64.ActiveCfg = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/CRSim/App.xaml.cs b/CRSim/App.xaml.cs index 5ef7982..d7b1713 100644 --- a/CRSim/App.xaml.cs +++ b/CRSim/App.xaml.cs @@ -6,23 +6,38 @@ namespace CRSim { public partial class App : Application { - public static IHost AppHost { get; private set; } + public IHost AppHost { get; private set; } + public static MainWindow MainWindow; - public string[] commandLineArgs; - public CommandLineOptions parsedOptions; - public static string AppVersion { get; set; } = Assembly.GetAssembly(typeof(App)).GetName().Version.ToString(); - private readonly Mutex mutex; + public static string AppVersion { get; set; } + + private Mutex mutex; public App() { + InitializeComponent(); + } + + public static T GetService() + where T : class + { + if ((Current as App)!.AppHost.Services.GetService(typeof(T)) is not T service) + { + throw new ArgumentException($"{typeof(T)} needs to be registered in ConfigureServices within App.xaml.cs."); + } + + return service; + } + + protected override async void OnLaunched(LaunchActivatedEventArgs args) + { + AppVersion = Assembly.GetAssembly(typeof(App)).GetName().Version.ToString(); mutex = new Mutex(true, "CRSim", out bool isNewInstance); if (!isNewInstance) { Environment.Exit(0); } - - var args = Environment.GetCommandLineArgs(); - parsedOptions = CommandLineParser.Parse(args); + var parsedOptions = CommandLineParser.Parse(Environment.GetCommandLineArgs()); if (parsedOptions.Debug) { LaunchDebugConsole(); @@ -57,11 +72,6 @@ namespace CRSim PluginService.InitializePlugins(context, services, parsedOptions.ExternalPluginPath); }) .Build(); - InitializeComponent(); - } - - protected override async void OnLaunched(LaunchActivatedEventArgs args) - { var splashScreenWindow = AppHost.Services.GetRequiredService(); splashScreenWindow.Activate(); await PerformInitializationAsync(splashScreenWindow); @@ -76,10 +86,10 @@ namespace CRSim { if(!Debugger.IsAttached) await Task.Delay(2000); startWindow.Status = "正在加载设置..."; - AppHost.Services.GetService().LoadSettings(); + GetService().LoadSettings(); if (!Debugger.IsAttached) await Task.Delay(500); startWindow.Status = "正在加载数据库..."; - AppHost.Services.GetService().ImportData(AppPaths.ConfigFilePath); + GetService().ImportData(AppPaths.ConfigFilePath); if (!Debugger.IsAttached) await Task.Delay(500); startWindow.Status = new[] { "正在控票…", "正在关闭垃圾桶盖…", "正在刷绿车底…", "正在准备降弓用刑…" }[new Random().Next(4)]; if (!Debugger.IsAttached) await Task.Delay(500); diff --git a/CRSim/Assets/SplashScreen.scale-200.png b/CRSim/Assets/SplashScreen.scale-200.png index 32f486a..6ac2ecb 100644 Binary files a/CRSim/Assets/SplashScreen.scale-200.png and b/CRSim/Assets/SplashScreen.scale-200.png differ diff --git a/CRSim/Assets/Square150x150Logo.scale-200.png b/CRSim/Assets/Square150x150Logo.scale-200.png index 53ee377..e28ee03 100644 Binary files a/CRSim/Assets/Square150x150Logo.scale-200.png and b/CRSim/Assets/Square150x150Logo.scale-200.png differ diff --git a/CRSim/Assets/Square44x44Logo.scale-200.png b/CRSim/Assets/Square44x44Logo.scale-200.png index f713bba..3ae5799 100644 Binary files a/CRSim/Assets/Square44x44Logo.scale-200.png and b/CRSim/Assets/Square44x44Logo.scale-200.png differ diff --git a/CRSim/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/CRSim/Assets/Square44x44Logo.targetsize-24_altform-unplated.png index dc9f5be..061bf4f 100644 Binary files a/CRSim/Assets/Square44x44Logo.targetsize-24_altform-unplated.png and b/CRSim/Assets/Square44x44Logo.targetsize-24_altform-unplated.png differ diff --git a/CRSim/Assets/StoreLogo.png b/CRSim/Assets/StoreLogo.png index a4586f2..4bc10f0 100644 Binary files a/CRSim/Assets/StoreLogo.png and b/CRSim/Assets/StoreLogo.png differ diff --git a/CRSim/Assets/Wide310x150Logo.scale-200.png b/CRSim/Assets/Wide310x150Logo.scale-200.png index 8b4a5d0..50e6888 100644 Binary files a/CRSim/Assets/Wide310x150Logo.scale-200.png and b/CRSim/Assets/Wide310x150Logo.scale-200.png differ diff --git a/CRSim/CRSim.csproj b/CRSim/CRSim.csproj index facf08f..52b7469 100644 --- a/CRSim/CRSim.csproj +++ b/CRSim/CRSim.csproj @@ -11,7 +11,6 @@ true true enable - None preview @@ -45,13 +44,10 @@ - - - - - - - + + + + @@ -152,15 +148,20 @@ - False - True - False - False + False + False 10.0.19041.0 Assets\CRSimIcon.ico - False CRSimIcon.png - true False + False + False + SHA256 + False + True + Never + True + 0 + zh-CN \ No newline at end of file diff --git a/CRSim/Package.appxmanifest b/CRSim/Package.appxmanifest index b1cf795..c91189b 100644 --- a/CRSim/Package.appxmanifest +++ b/CRSim/Package.appxmanifest @@ -8,15 +8,15 @@ IgnorableNamespaces="uap rescap"> + Name="53D4FFDC.CRSim" + Publisher="CN=A0D23678-D7D4-4933-B369-1877DD38719C" + Version="3.1.3.0" /> - + - 国铁信息显示模拟 - 电排骨 + CRSim + 电排骨工坊 Assets\CRSimIcon.png @@ -34,7 +34,7 @@ Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$"> + diff --git a/CRSim/Services/DialogService.cs b/CRSim/Services/DialogService.cs index 8739e1c..9956f19 100644 --- a/CRSim/Services/DialogService.cs +++ b/CRSim/Services/DialogService.cs @@ -252,5 +252,28 @@ namespace CRSim.Services } return null; } + + public async Task CreateStationAsync() + { + ContentDialog dialog = new() + { + XamlRoot = XamlRoot, + Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style, + Title = "新增车站", + PrimaryButtonText = "确定", + CloseButtonText = "取消", + DefaultButton = ContentDialogButton.Primary, + IsPrimaryButtonEnabled = false + }; + var createStationDialog = new CreateStationDialog(isValid => dialog.IsPrimaryButtonEnabled = isValid); + dialog.Content = createStationDialog; + var result = await dialog.ShowAsync(); + if (result == ContentDialogResult.Primary) + { + var inputDialog = dialog.Content as CreateStationDialog; + return inputDialog.GeneratedStation; + } + return null; + } } } diff --git a/CRSim/Services/IDialogService.cs b/CRSim/Services/IDialogService.cs index 00f98bf..1468e9c 100644 --- a/CRSim/Services/IDialogService.cs +++ b/CRSim/Services/IDialogService.cs @@ -4,6 +4,7 @@ { string? GetFile(string[] filter); string? SaveFile(string filter,string fileName); + Task CreateStationAsync(); Task GetInputAsync(string title,string placeholder); Task GetConfirmAsync(string title); Task ShowMessageAsync(string title, string message); diff --git a/CRSim/ViewModels/SettingsPageViewModel.cs b/CRSim/ViewModels/SettingsPageViewModel.cs index 667d0f6..20cf36d 100644 --- a/CRSim/ViewModels/SettingsPageViewModel.cs +++ b/CRSim/ViewModels/SettingsPageViewModel.cs @@ -3,6 +3,8 @@ using System.Diagnostics; using System.Diagnostics.Metrics; using System.IO.Packaging; using System.Reflection; +using System.Security.Policy; +using Windows.System; namespace CRSim.ViewModels { @@ -134,71 +136,8 @@ namespace CRSim.ViewModels } else { - await _dialogService.ShowTextAsync("发现新版本 " + update.Name, update.Body + "\n系统即将下载安装新版本。"); - DispatcherQueue dispatcherQueue = DispatcherQueue.GetForCurrentThread(); - var downloader = new DownloadService(); - UpdateProgress = 0; - try - { - int lastProgress = 0; - var lastUpdate = DateTime.MinValue; - downloader.DownloadProgressChanged += (s, e) => - { - var now = DateTime.Now; - if ((e.ProgressPercentage - lastProgress >= 1) || (now - lastUpdate).TotalMilliseconds >= 100) - { - lastProgress = (int)e.ProgressPercentage; - lastUpdate = now; - - dispatcherQueue.TryEnqueue(() => - { - UpdateProgress = (int)e.ProgressPercentage; - }); - } - }; - var path = Path.Combine(AppPaths.TempPath, "update.zip"); - await downloader.DownloadFileTaskAsync(update.Assets[0].BrowserDownloadUrl, path); - UpdateProgress = 0; - - if (!FileHashHelper.VerifySHA256(path, update.Assets[0].Digest.Split(':')[1])) - { - await _dialogService.ShowMessageAsync("错误", "下载的文件校验失败,请重试。"); - return; - } - - var programDirectory = AppDomain.CurrentDomain.BaseDirectory; - var appExePath = Environment.ProcessPath; - var appName = Path.GetFileName(appExePath); - string batchScript = $@" - @echo off - taskkill /F /IM ""{appName}"" >nul 2>&1 - timeout /t 2 >nul - cd /d ""{programDirectory}"" - powershell -Command ""Expand-Archive -Path '{path}' -DestinationPath '{programDirectory}' -Force"" - del /f /q ""{path}"" - start """" ""{appExePath}"" - exit /b 0 - "; - string batchFilePath = Path.Combine(Path.GetTempPath(), "CRSimUpdate.bat"); - File.WriteAllText(batchFilePath, batchScript); - var processInfo = new ProcessStartInfo - { - FileName = "cmd.exe", - Arguments = $"/c \"{batchFilePath}\"", - WindowStyle = ProcessWindowStyle.Hidden, - UseShellExecute = false, - CreateNoWindow = true - }; - - Process.Start(processInfo); - Application.Current.Exit(); - } - catch (Exception e) - { - await _dialogService.ShowTextAsync("错误", "更新失败。若使用“官方站”,可尝试更换到“镜像站”。\n" + e); - UpdateProgress = 0; - return; - } + await _dialogService.ShowTextAsync("发现新版本 " + update.Name, update.Body + "\n请前往微软商店下载新版本。"); + await Launcher.LaunchUriAsync(new Uri("https://apps.microsoft.com/detail/9n4xhrrmph8v")); } } [RelayCommand] diff --git a/CRSim/ViewModels/StationManagementPageViewModel.cs b/CRSim/ViewModels/StationManagementPageViewModel.cs index fa44d6f..544fad5 100644 --- a/CRSim/ViewModels/StationManagementPageViewModel.cs +++ b/CRSim/ViewModels/StationManagementPageViewModel.cs @@ -1,4 +1,5 @@ using CRSim.Converters; +using CRSim.Core.Models; using CRSim.Core.Models.Plugin; using System.Text.RegularExpressions; @@ -34,11 +35,11 @@ public partial class StationManagementPageViewModel : ObservableObject public ObservableCollection TrainStops { get; private set; } = []; public ObservableCollection FilteredTrainStops =>[.. TrainStops.Where(x => x.Number.ToUpper().Contains(SearchTrainNumberText.ToUpper()))]; - private readonly IDatabaseService _databaseService = App.AppHost.Services.GetService(); + private readonly IDatabaseService _databaseService = App.GetService(); - private readonly IDialogService _dialogService = App.AppHost.Services.GetService(); + private readonly IDialogService _dialogService = App.GetService(); - private readonly INetworkService _networkService = App.AppHost.Services.GetService(); + private readonly INetworkService _networkService = App.GetService(); public StationManagementPageViewModel() { TrainStops.CollectionChanged += (sender, e) => @@ -121,15 +122,15 @@ public partial class StationManagementPageViewModel : ObservableObject [RelayCommand] public async Task AddStation() { - string? station = await _dialogService.GetInputAsync("请输入车站名称", string.Empty); + var station = await _dialogService.CreateStationAsync(); if (station != null) { - if (StationNames.Contains(station)) + if (StationNames.Contains(station.Name)) { - await _dialogService.ShowMessageAsync("添加失败", $"车站 {station} 已存在。"); + await _dialogService.ShowMessageAsync("添加失败", $"车站 {station.Name} 已存在。"); return; } - _databaseService.AddStationByName(station); + _databaseService.AddStation(station); await _databaseService.SaveData(); RefreshStations(); } @@ -167,20 +168,18 @@ public partial class StationManagementPageViewModel : ObservableObject return station; } [RelayCommand] - public async Task ImportFrom7D() + public async Task ExportStation() { - var path = _dialogService.GetFile([".exe"]); + if (!await Validate()) return; + var path = _dialogService.SaveFile(".json", $"{SelectedStation.Name}车站配置"); if (path == null) return; - try + string json = JsonSerializer.Serialize(new Json() { - await _databaseService.ImportStationFrom7D(path); - await _databaseService.SaveData(); - RefreshStations(); - } - catch (Exception e) - { - await _dialogService.ShowMessageAsync("导入失败", "文件格式错误或被占用。\n" + e.Message); + Stations = [GenerateStation(SelectedStation.Name, WaitingAreas, TrainStops, Platforms) ], + TrainNumbers = [] } + , JsonContext.Default.Json); + await File.WriteAllTextAsync(path, json); } #endregion diff --git a/CRSim/Views/DashboardPage.xaml.cs b/CRSim/Views/DashboardPage.xaml.cs index adf9c22..ae9c2f7 100644 --- a/CRSim/Views/DashboardPage.xaml.cs +++ b/CRSim/Views/DashboardPage.xaml.cs @@ -2,7 +2,7 @@ namespace CRSim.Views; public sealed partial class DashboardPage : Page { - public DashboardPageViewModel ViewModel { get; } = App.AppHost.Services.GetService(); + public DashboardPageViewModel ViewModel { get; } = App.GetService(); public DashboardPage() { diff --git a/CRSim/Views/DialogContents/CreateStationDialog.xaml b/CRSim/Views/DialogContents/CreateStationDialog.xaml new file mode 100644 index 0000000..25a814e --- /dev/null +++ b/CRSim/Views/DialogContents/CreateStationDialog.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CRSim/Views/DialogContents/CreateStationDialog.xaml.cs b/CRSim/Views/DialogContents/CreateStationDialog.xaml.cs new file mode 100644 index 0000000..c23b7c7 --- /dev/null +++ b/CRSim/Views/DialogContents/CreateStationDialog.xaml.cs @@ -0,0 +1,144 @@ +namespace CRSim.Views; +public sealed partial class CreateStationDialog : Page +{ + + private readonly IDialogService _dialogService = App.GetService(); + + private Station? _parsedStation = null; + + public Station? GeneratedStation => ToBoolean(Blank.IsChecked) ? new Station + { + Name = textBoxBlank.Text, + Platforms = [], + WaitingAreas = [], + TrainStops = [] + } : _parsedStation; + + private readonly Action _onValidityChanged; + + public bool ToBoolean(bool? value) + { + return value == true; + } + + private void Validate(object sender, object e) + { + if (textBoxBlank == null) return; + bool isValid; + if (ToBoolean(Blank.IsChecked)) + { + isValid = !string.IsNullOrWhiteSpace(textBoxBlank.Text); + } + else + { + isValid = _parsedStation != null; + } + _onValidityChanged?.Invoke(isValid); + } + + public CreateStationDialog(Action onValidityChanged) + { + _onValidityChanged = onValidityChanged; + InitializeComponent(); + } + + private async void ImportFromSS7DSAsync(object sender, RoutedEventArgs e) + { + var path = _dialogService.GetFile([".exe"]); + textBoxBroadcast.Text = path; + if (path == null) return; + try + { + Station station = new() { Platforms = [], WaitingAreas = [], TrainStops = [] }; + var stationName = (await File.ReadAllTextAsync(path.Replace("վ㲥ϵͳ.exe", "info.ini"))).Split("|")[0]; + var lines = await File.ReadAllLinesAsync(path.Replace("վ㲥ϵͳ.exe", "data.csv")); + station.Name = stationName; + foreach (var line in lines) + { + var data = line.Split(','); + var waitingAreaName = string.IsNullOrWhiteSpace(data.Last()) ? "δ֪" : data.Last(); + var platform = string.IsNullOrWhiteSpace(data[5]) ? "δ֪" : data[5]; + var ticketCheck = string.IsNullOrWhiteSpace(data[4]) ? string.Empty : data[4]; + + var existingPlatform = station.Platforms.FirstOrDefault(x => x.Name == platform); + if (existingPlatform == null) + { + station.Platforms.Add(new Platform { Name = platform, Length = 20 }); + } + + + var waitingArea = station.WaitingAreas.FirstOrDefault(x => x.Name == waitingAreaName); + if (waitingArea == null) + { + waitingArea = new WaitingArea() { Name = waitingAreaName }; + station.WaitingAreas.Add(waitingArea); + } + + foreach (var ticketCheckName in ticketCheck.Split('|')) + { + if (!string.IsNullOrWhiteSpace(ticketCheckName) && !waitingArea.TicketChecks.Any(x => x.Name == ticketCheckName)) + { + waitingArea.TicketChecks.Add(new TicketCheck { Name = ticketCheckName }); + } + } + + if (!string.IsNullOrEmpty(data[0]) && !station.TrainStops.Any(x => x.Number == data[0])) + { + TimeSpan? arrivalTime = null; + TimeSpan? departureTime = null; + + if (data[2] == stationName) + { + departureTime = TimeSpan.Parse(lines.FirstOrDefault(x => x.Split(",")[0] == data[0] && x.Split(",")[1].Contains("ͳ"))?.Split(",")[7] ?? string.Empty); + } + else if (data[3] == stationName) + { + arrivalTime = TimeSpan.Parse(data[7]); + } + else + { + arrivalTime = TimeSpan.Parse(data[7]); + departureTime = TimeSpan.Parse(lines.FirstOrDefault(x => x.Split(",")[0] == data[0] && x.Split(",")[1].Contains("ͳ"))?.Split(",")[7] ?? string.Empty); + } + + station.TrainStops.Add(new TrainStop + { + Number = data[0], + Terminal = data[3], + Origin = data[2], + TicketCheckIds = [.. waitingArea.TicketChecks.Select(x => x.Id)], + ArrivalTime = arrivalTime, + DepartureTime = departureTime, + Platform = platform, + Length = data[0].StartsWith('G') || data[0].StartsWith('D') || data[0].StartsWith('C') ? Math.Abs(data[0].GetHashCode()) % 3 == 0 ? 8 : 16 : 18, + Landmark = data[8] + "ɫ" ?? null, + }); + } + } + _parsedStation = station; + } + catch (Exception ex) + { + _parsedStation = null; + } + Validate(this, EventArgs.Empty); + } + + private async void ImportFromFileAsync(object sender, RoutedEventArgs e) + { + var path = _dialogService.GetFile([".json"]); + textBoxFile.Text = path; + if (path == null) return; + try + { + var json = File.ReadAllText(path).Replace("StationStop", "TrainStop"); + var data = JsonSerializer.Deserialize(json, JsonContext.Default.Json); + _parsedStation = data?.Stations.FirstOrDefault(); + } + catch (Exception ex) + { + _parsedStation = null; + } + Validate(this, EventArgs.Empty); + } +} diff --git a/CRSim/Views/PlatformDiagramPage.xaml.cs b/CRSim/Views/PlatformDiagramPage.xaml.cs index 2b48a20..5ea7578 100644 --- a/CRSim/Views/PlatformDiagramPage.xaml.cs +++ b/CRSim/Views/PlatformDiagramPage.xaml.cs @@ -2,7 +2,7 @@ namespace CRSim.Views; public sealed partial class PlatformDiagramPage : Page { - public PlatformDiagramPageViewModel ViewModel { get; } = App.AppHost.Services.GetService(); + public PlatformDiagramPageViewModel ViewModel { get; } = App.GetService(); public PlatformDiagramPage() { @@ -12,6 +12,6 @@ public sealed partial class PlatformDiagramPage : Page private void Page_Loaded(object sender, RoutedEventArgs e) { - App.AppHost.Services.GetService().XamlRoot = this.XamlRoot; + App.GetService().XamlRoot = this.XamlRoot; } } diff --git a/CRSim/Views/PluginManagementPage.xaml.cs b/CRSim/Views/PluginManagementPage.xaml.cs index 303c7cb..0e107f0 100644 --- a/CRSim/Views/PluginManagementPage.xaml.cs +++ b/CRSim/Views/PluginManagementPage.xaml.cs @@ -4,7 +4,7 @@ namespace CRSim.Views; public sealed partial class PluginManagementPage : Page { - public PluginManagementPageViewModel ViewModel { get; } = App.AppHost.Services.GetService(); + public PluginManagementPageViewModel ViewModel { get; } = App.GetService(); public PluginManagementPage() { @@ -18,6 +18,6 @@ public sealed partial class PluginManagementPage : Page private void Page_Loaded(object sender, RoutedEventArgs e) { - App.AppHost.Services.GetService().XamlRoot = this.XamlRoot; + App.GetService().XamlRoot = this.XamlRoot; } } diff --git a/CRSim/Views/ScreenSimulatorPage.xaml.cs b/CRSim/Views/ScreenSimulatorPage.xaml.cs index 8ff3407..ac4ec3c 100644 --- a/CRSim/Views/ScreenSimulatorPage.xaml.cs +++ b/CRSim/Views/ScreenSimulatorPage.xaml.cs @@ -2,7 +2,7 @@ namespace CRSim.Views; public sealed partial class ScreenSimulatorPage : Page { - public ScreenSimulatorPageViewModel ViewModel { get; } = App.AppHost.Services.GetService(); + public ScreenSimulatorPageViewModel ViewModel { get; } = App.GetService(); public ScreenSimulatorPage() { diff --git a/CRSim/Views/SettingsPage.xaml.cs b/CRSim/Views/SettingsPage.xaml.cs index 194e2ff..366e460 100644 --- a/CRSim/Views/SettingsPage.xaml.cs +++ b/CRSim/Views/SettingsPage.xaml.cs @@ -4,7 +4,7 @@ namespace CRSim.Views; public sealed partial class SettingsPage : Page { - public SettingsPageViewModel ViewModel { get; } = App.AppHost.Services.GetService(); + public SettingsPageViewModel ViewModel { get; } = App.GetService(); public SettingsPage() { @@ -18,6 +18,6 @@ public sealed partial class SettingsPage : Page private void Page_Loaded(object sender, RoutedEventArgs e) { - App.AppHost.Services.GetService().XamlRoot = this.XamlRoot; + App.GetService().XamlRoot = this.XamlRoot; } } diff --git a/CRSim/Views/StationManagementPage.xaml b/CRSim/Views/StationManagementPage.xaml index d0ba63b..e7e09f3 100644 --- a/CRSim/Views/StationManagementPage.xaml +++ b/CRSim/Views/StationManagementPage.xaml @@ -55,7 +55,6 @@ - - - - - -