From 13c88f2dc717602647e7765117bd7e57d167bf63 Mon Sep 17 00:00:00 2001 From: Bod9001 Date: Wed, 27 Nov 2024 19:57:54 +0000 Subject: [PATCH 1/9] TTS Download --- .../ViewModels/ServersPanelViewModelTests.cs | 5 +- UnitystationLauncher/Constants/ApiUrls.cs | 3 + .../Infrastructure/MessageBoxBuilder.cs | 3 + .../Models/Api/VersionModel.cs | 6 + .../Models/ConfigFile/Preferences.cs | 9 +- .../Models/Enums/DownloadState.cs | 3 +- .../Services/InstallationService.cs | 24 +- .../Services/Interface/ITTSService.cs | 12 + UnitystationLauncher/Services/TTSService.cs | 320 ++++++++++++++++++ UnitystationLauncher/StandardModule.cs | 1 + .../UnitystationLauncher.csproj | 2 + .../ViewModels/InstallationViewModel.cs | 12 +- .../ViewModels/InstallationsPanelViewModel.cs | 87 ++++- .../ViewModels/LauncherViewModel.cs | 18 +- .../ViewModels/ServersPanelViewModel.cs | 46 ++- .../Views/InstallationsPanelView.xaml | 3 + 16 files changed, 535 insertions(+), 19 deletions(-) create mode 100644 UnitystationLauncher/Models/Api/VersionModel.cs create mode 100644 UnitystationLauncher/Services/Interface/ITTSService.cs create mode 100644 UnitystationLauncher/Services/TTSService.cs diff --git a/UnitystationLauncher.Tests/ViewModels/ServersPanelViewModelTests.cs b/UnitystationLauncher.Tests/ViewModels/ServersPanelViewModelTests.cs index 10749bb7..a0813329 100644 --- a/UnitystationLauncher.Tests/ViewModels/ServersPanelViewModelTests.cs +++ b/UnitystationLauncher.Tests/ViewModels/ServersPanelViewModelTests.cs @@ -3,6 +3,7 @@ using UnitystationLauncher.Tests.MocksRepository.PingService; using UnitystationLauncher.Tests.MocksRepository.ServerService; using UnitystationLauncher.ViewModels; +using Xunit.Sdk; namespace UnitystationLauncher.Tests.ViewModels; @@ -16,7 +17,7 @@ public static void ServersPanelViewModel_ShouldFetchServers() IPingService mockPingService = new MockPingStaticPingTime(5); IServerService mockServerService = new MockRandomServers(1, 20); - ServersPanelViewModel serversPanelViewModel = new(mockInstallationService, mockPingService, mockServerService); + ServersPanelViewModel serversPanelViewModel = new(mockInstallationService, mockPingService, mockServerService, null, null); serversPanelViewModel.ServerViews.Should().NotBeEmpty(); } @@ -27,7 +28,7 @@ public static void ServersPanelViewModel_ShouldHandleExceptionInServerService() IPingService mockPingService = new MockPingStaticPingTime(5); IServerService mockServerService = new MockServersThrowsException(); - Func act = () => new(mockInstallationService, mockPingService, mockServerService); + Func act = () => new(mockInstallationService, mockPingService, mockServerService, null, null); act.Should().NotThrow(); act.Invoke().ServerViews.Should().NotBeNull().And.BeEmpty(); } diff --git a/UnitystationLauncher/Constants/ApiUrls.cs b/UnitystationLauncher/Constants/ApiUrls.cs index 30ca5437..51888832 100644 --- a/UnitystationLauncher/Constants/ApiUrls.cs +++ b/UnitystationLauncher/Constants/ApiUrls.cs @@ -18,4 +18,7 @@ public static class ApiUrls private static string RawGitHubFileBaseUrl => "https://raw.githubusercontent.com/unitystation/unitystation/develop"; public static string CodeScanListUrl => $"{RawGitHubFileBaseUrl}/CodeScanList.json"; + public static string TTSFiles => $"{CdnBaseUrl}/STTBundleTTS/TTS"; + public static string TTSVersionFile => $"{TTSFiles}/version.txt"; + } \ No newline at end of file diff --git a/UnitystationLauncher/Infrastructure/MessageBoxBuilder.cs b/UnitystationLauncher/Infrastructure/MessageBoxBuilder.cs index 4534ffc1..5e482bf9 100644 --- a/UnitystationLauncher/Infrastructure/MessageBoxBuilder.cs +++ b/UnitystationLauncher/Infrastructure/MessageBoxBuilder.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; using MsBox.Avalonia; using MsBox.Avalonia.Base; using MsBox.Avalonia.Dto; @@ -14,6 +16,7 @@ public static IMsBox CreateMessageBox(MessageBoxButtons buttonLayout, st { IMsBox msgBox = MessageBoxManager.GetMessageBoxCustom(new MessageBoxCustomParams { + Topmost = true, SystemDecorations = Avalonia.Controls.SystemDecorations.BorderOnly, WindowStartupLocation = Avalonia.Controls.WindowStartupLocation.CenterScreen, ContentHeader = header, diff --git a/UnitystationLauncher/Models/Api/VersionModel.cs b/UnitystationLauncher/Models/Api/VersionModel.cs new file mode 100644 index 00000000..f7546196 --- /dev/null +++ b/UnitystationLauncher/Models/Api/VersionModel.cs @@ -0,0 +1,6 @@ +namespace UnitystationLauncher.Models.Api; + +public class VersionModel +{ + public string version { get; set; } +} \ No newline at end of file diff --git a/UnitystationLauncher/Models/ConfigFile/Preferences.cs b/UnitystationLauncher/Models/ConfigFile/Preferences.cs index 7f9b340f..ce1908d4 100644 --- a/UnitystationLauncher/Models/ConfigFile/Preferences.cs +++ b/UnitystationLauncher/Models/ConfigFile/Preferences.cs @@ -7,7 +7,8 @@ public class Preferences : ReactiveObject private bool _autoRemove = true; private int _ignoreVersionUpdate; private string _installationPath = string.Empty; - + private bool? _TTSEnabled = null; + public bool AutoRemove { get => _autoRemove; @@ -25,4 +26,10 @@ public string InstallationPath get => _installationPath; set => this.RaiseAndSetIfChanged(ref _installationPath, value); } + + public bool? TTSEnabled + { + get => _TTSEnabled; + set => this.RaiseAndSetIfChanged(ref _TTSEnabled, value); + } } diff --git a/UnitystationLauncher/Models/Enums/DownloadState.cs b/UnitystationLauncher/Models/Enums/DownloadState.cs index a7acd417..a06d81fe 100644 --- a/UnitystationLauncher/Models/Enums/DownloadState.cs +++ b/UnitystationLauncher/Models/Enums/DownloadState.cs @@ -10,5 +10,6 @@ public enum DownloadState InProgress, Scanning, Installed, - Failed + Failed, + Extracting } \ No newline at end of file diff --git a/UnitystationLauncher/Services/InstallationService.cs b/UnitystationLauncher/Services/InstallationService.cs index 7e1ff3d5..6cfa5ee7 100644 --- a/UnitystationLauncher/Services/InstallationService.cs +++ b/UnitystationLauncher/Services/InstallationService.cs @@ -41,10 +41,11 @@ public class InstallationService : IInstallationService private readonly List _downloads; private List _installations = new(); private readonly string _installationsJsonFilePath; + private readonly ITTSService _TTSVersionService; public InstallationService(HttpClient httpClient, IPreferencesService preferencesService, IEnvironmentService environmentService, IServerService serverService, ICodeScanService codeScanService, - ICodeScanConfigService codeScanConfigService) + ICodeScanConfigService codeScanConfigService, ITTSService ITTSVersionService) { _httpClient = httpClient; _preferencesService = preferencesService; @@ -52,6 +53,7 @@ public InstallationService(HttpClient httpClient, IPreferencesService preference _serverService = serverService; _codeScanService = codeScanService; _codeScanConfigService = codeScanConfigService; + _TTSVersionService = ITTSVersionService; _downloads = new(); _installationsJsonFilePath = Path.Combine(_environmentService.GetUserdataDirectory(), "installations.json"); @@ -85,6 +87,10 @@ public List GetInstallations() public async Task<(Download?, string)> DownloadInstallationAsync(Server server) { + + + + string? downloadUrl = server.GetDownloadUrl(_environmentService); if (string.IsNullOrWhiteSpace(downloadUrl)) { @@ -133,12 +139,17 @@ public List GetInstallations() } _downloads.Add(download); + + + RxApp.MainThreadScheduler.ScheduleAsync((_, _) => StartDownloadAsync(download)); return (download, string.Empty); } public (bool, string) StartInstallation(Guid installationId, string? server = null, short? port = null) { + _TTSVersionService.StartTTS(); + Installation? installation = GetInstallationById(installationId); if (installation == null) { @@ -422,6 +433,9 @@ private static string GetArguments(string? server, long? port) private async Task StartDownloadAsync(Download download) { + //Update TTS if it's needed + await _TTSVersionService.CheckAndDownloadLatestVersion(download); + Log.Information("Download requested, Installation Path '{Path}', Url '{Url}'", download.InstallPath, download.DownloadUrl); try { @@ -433,13 +447,11 @@ private async Task StartDownloadAsync(Download download) await using Stream responseStream = await request.Content.ReadAsStreamAsync(); Log.Information("Download connection established"); await using ProgressStream progressStream = new(responseStream); - download.Size = request.Content.Headers.ContentLength ?? - throw new ContentLengthNullException(download.DownloadUrl); + download.Size = request.Content.Headers.ContentLength ?? throw new ContentLengthNullException(download.DownloadUrl); using IDisposable logProgressDisposable = LogProgress(progressStream, download); - using IDisposable progressDisposable = progressStream.Progress - .Subscribe(p => { download.Downloaded = p; }); + using IDisposable progressDisposable = progressStream.Progress.Subscribe(p => { download.Downloaded = p; }); // ExtractAndScan() must be run in a separate thread, but we want this one to wait for that one to finish // Without this download progress will not work properly @@ -558,7 +570,7 @@ private static async Task ShowScanFailPopUp(string message, string logFolder) } } - private static IDisposable LogProgress(ProgressStream progressStream, Download download) + public static IDisposable LogProgress(ProgressStream progressStream, Download download) { long lastPosition = 0L; DateTime lastTime = DateTime.Now; diff --git a/UnitystationLauncher/Services/Interface/ITTSService.cs b/UnitystationLauncher/Services/Interface/ITTSService.cs new file mode 100644 index 00000000..49096298 --- /dev/null +++ b/UnitystationLauncher/Services/Interface/ITTSService.cs @@ -0,0 +1,12 @@ +using System.Threading.Tasks; +using UnitystationLauncher.Models; + +namespace UnitystationLauncher.Services.Interface; + +public interface ITTSService +{ + public Task CheckAndDownloadLatestVersion(Download Download); + + public void StartTTS(); + public void StopTTS(); +} \ No newline at end of file diff --git a/UnitystationLauncher/Services/TTSService.cs b/UnitystationLauncher/Services/TTSService.cs new file mode 100644 index 00000000..de4aa292 --- /dev/null +++ b/UnitystationLauncher/Services/TTSService.cs @@ -0,0 +1,320 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.IO.Compression; +using System.Net.Http; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using Avalonia.Controls.Shapes; +using Mono.Unix; +using Serilog; +using SharpCompress.Archives; +using SharpCompress.Archives.Tar; +using SharpCompress.Common; +using UnitystationLauncher.Constants; +using UnitystationLauncher.Exceptions; +using UnitystationLauncher.Infrastructure; +using UnitystationLauncher.Models; +using UnitystationLauncher.Models.Api; +using UnitystationLauncher.Models.Enums; +using UnitystationLauncher.Services.Interface; +using Path = System.IO.Path; + +namespace UnitystationLauncher.Services; + +public class TTSService : ITTSService +{ + private static string _nameConfig = @"CodeScanList.json"; + + private readonly HttpClient _httpClient; + + private readonly IPreferencesService _preferencesService; + private readonly IEnvironmentService _environmentService; + + private static Process? process; + + public TTSService(HttpClient httpClient, IPreferencesService preferencesService, + IEnvironmentService environmentService) + { + _httpClient = httpClient; + _preferencesService = preferencesService; + _environmentService = environmentService; + } + + public async Task CheckAndDownloadLatestVersion(Download Download) + { + if ((_preferencesService.GetPreferences().TTSEnabled is true) == false) return; + + if (_environmentService.GetCurrentEnvironment() == CurrentEnvironment.MacOsStandalone) + { + Log.Error( + "MAC TTS Is not currently supported, If you would like to add support Join the discord and contribute"); + return; + } + + string jsonData = ""; + try + { + HttpResponseMessage response = await _httpClient.GetAsync(ApiUrls.TTSVersionFile); + if (!response.IsSuccessStatusCode) + { + Log.Error("Unable to download config" + response); + return; + } + + jsonData = await response.Content.ReadAsStringAsync(); + } + catch (Exception e) + { + Log.Error("Unable to download ValidGoodFilesVersionAsync config" + e); + return; + } + + + VersionModel? CurrentVersion = JsonSerializer.Deserialize(jsonData, options: new() + { + IgnoreReadOnlyProperties = true, + PropertyNameCaseInsensitive = true + }); + + if (CurrentVersion == null) + { + return; + } + + string installationBasePath = _preferencesService.GetPreferences().InstallationPath; + + VersionModel? localVersionModel = null; + + try + { + var LocalVersion = System.IO.Path.Combine(installationBasePath, "tts", "version.txt"); + if (System.IO.File.Exists(LocalVersion)) + { + // Read the JSON file content + string jsonContent = System.IO.File.ReadAllText(LocalVersion); + + // Deserialize the JSON content into an object + localVersionModel = JsonSerializer.Deserialize(jsonContent); + } + } + catch (Exception ex) + { + Log.Error($"An error occurred: {ex.Message}"); + } + + + try + { + if (localVersionModel == null || localVersionModel.version != CurrentVersion.version) + { + var LocalVersion = System.IO.Path.Combine(installationBasePath, "tts"); + if (System.IO.Directory.Exists(LocalVersion)) + { + System.IO.Directory.Delete(LocalVersion, true); + } + + + var zip = _environmentService.GetCurrentEnvironment() switch + { + CurrentEnvironment.WindowsStandalone => "win.zip", + CurrentEnvironment.MacOsStandalone => "mac.zip", + CurrentEnvironment.LinuxStandalone or CurrentEnvironment.LinuxFlatpak => "lnx.zip", + _ => null + }; + + Download.Active = true; + Download.DownloadState = DownloadState.InProgress; + HttpResponseMessage request = await _httpClient.GetAsync(ApiUrls.TTSFiles + "/" + zip, + HttpCompletionOption.ResponseHeadersRead); + + Download.Size = request.Content.Headers.ContentLength ?? + throw new ContentLengthNullException(ApiUrls.TTSFiles + "/" + zip); + using Stream responseStream = await request.Content.ReadAsStreamAsync(); + Log.Information("Download connection established"); + await using ProgressStream progressStream = new(responseStream); + using IDisposable logProgressDisposable = InstallationService.LogProgress(progressStream, Download); + + using IDisposable progressDisposable = + progressStream.Progress.Subscribe(p => { Download.Downloaded = p; }); + + await Task.Run(() => ExtractTo(progressStream, LocalVersion, Download)); + } + //Is find no need to update + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } + } + + + private void ExtractTo(Stream progressStream, string LocalVersion, Download Download) + { + Download.DownloadState = DownloadState.Extracting; + switch (_environmentService.GetCurrentEnvironment()) + { + case CurrentEnvironment.WindowsStandalone: + { + ZipArchive archive = new(progressStream); + archive.ExtractToDirectory(LocalVersion, true); + break; + } + case CurrentEnvironment.LinuxStandalone or CurrentEnvironment.LinuxFlatpak: + { + using var decompressedStream = DecompressXz(progressStream); // Decompress XZ stream to get .tar + ExtractTar(decompressedStream, LocalVersion); + break; + } + } + + Download.Active = false; + Download.DownloadState = DownloadState.InProgress; + } + + private static Stream DecompressXz(Stream compressedStream) + { + var decompressedStream = new MemoryStream(); + using (var xzStream = new SharpCompress.Compressors.Xz.XZStream(compressedStream)) + { + xzStream.CopyTo(decompressedStream); + } + + decompressedStream.Seek(0, SeekOrigin.Begin); + return decompressedStream; + } + + + private void ExtractTar(Stream tarStream, string destinationPath) + { + using var archive = TarArchive.Open(tarStream); + foreach (var entry in archive.Entries) + { + if (!entry.IsDirectory) + { + entry.WriteToDirectory(destinationPath, new ExtractionOptions + { + ExtractFullPath = true, + Overwrite = true + }); + } + } + } + + private (string? ,string?) FindExecutable() + { + string installationBasePath = _preferencesService.GetPreferences().InstallationPath; + if (string.IsNullOrWhiteSpace(installationBasePath) || !Directory.Exists(installationBasePath)) + { + return (null, null); + } + + return _environmentService.GetCurrentEnvironment() switch + { + CurrentEnvironment.WindowsStandalone + => (Path.Combine(installationBasePath, "tts", "python-3.10.11.amd64", "python.exe"), Path.Combine(installationBasePath, "tts", "scripts")), + CurrentEnvironment.MacOsStandalone + => throw new NotImplementedException("tts Mac Support not implemented"), + CurrentEnvironment.LinuxStandalone or CurrentEnvironment.LinuxFlatpak + => (Path.Combine(installationBasePath, "tts", "bin", "python"), Path.Combine(installationBasePath, "tts", "bin")), + _ => (null, null) + }; + } + + private void EnsureExecutableFlagOnUnixSystems(string executablePath) + { + if (_environmentService.GetCurrentEnvironment() != CurrentEnvironment.WindowsStandalone) + { + UnixFileInfo fileInfo = new(executablePath); + fileInfo.FileAccessPermissions |= FileAccessPermissions.UserReadWriteExecute; + } + } + + public void StartTTS() + { + var Preference = _preferencesService.GetPreferences(); + if ((Preference.TTSEnabled is true) == false) return; + + if (process != null && process.HasExited == false) + { + return; + } + + string installationBasePath = _preferencesService.GetPreferences().InstallationPath; + var LocalVersion = System.IO.Path.Combine(installationBasePath, "tts"); + if (System.IO.Directory.Exists(LocalVersion) == false) + { + return; //Not installed + } + + (string?, string?) executable = FindExecutable(); + if (string.IsNullOrWhiteSpace(executable.Item1)) + { + const string failureReason = "Couldn't find executable to start."; + Log.Warning(failureReason + $" Installation Path: {executable.Item1 ?? "null"}"); + return; + } + + EnsureExecutableFlagOnUnixSystems(executable.Item1); + + string arguments = "TTS_local_Server.py"; + ProcessStartInfo startInfo = new ProcessStartInfo + { + WorkingDirectory = executable.Item2, + FileName = executable.Item1, + ArgumentList = { arguments }, + UseShellExecute = false, // Don't use the shell + CreateNoWindow = true, // Run without creating a window + RedirectStandardOutput = true, // Optional: Redirect output for logging + RedirectStandardError = true, // Optional: Redirect error output + }; + + if (startInfo == null) + { + const string failureReason = "Unhandled platform."; + Log.Warning(failureReason + $" Platform: {Enum.GetName(_environmentService.GetCurrentEnvironment())}"); + return; + } + + // Start the process + process = new Process(); + + process.StartInfo = startInfo; + process.EnableRaisingEvents = true; + + // Handle process exit to clean up if needed + process.Exited += (sender, e) => { Log.Information($"Subprocess with PID {process.Id} exited."); }; + + // Ensure subprocess ends when the main application exits + AppDomain.CurrentDomain.ProcessExit += (sender, e) => + { + if (process.HasExited == false) + { + process.Kill(); + } + }; + + try + { + process.Start(); + } + catch (Exception ex) + { + Log.Error($"Error starting process: {ex.Message}"); + } + } + + public void StopTTS() + { + if (process != null) + { + if (process.HasExited == false) + { + process.Kill(); + } + } + } +} \ No newline at end of file diff --git a/UnitystationLauncher/StandardModule.cs b/UnitystationLauncher/StandardModule.cs index 0d311d60..a4bfb11a 100644 --- a/UnitystationLauncher/StandardModule.cs +++ b/UnitystationLauncher/StandardModule.cs @@ -21,6 +21,7 @@ protected override void Load(ContainerBuilder builder) builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); + builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); diff --git a/UnitystationLauncher/UnitystationLauncher.csproj b/UnitystationLauncher/UnitystationLauncher.csproj index f387acf3..71281178 100644 --- a/UnitystationLauncher/UnitystationLauncher.csproj +++ b/UnitystationLauncher/UnitystationLauncher.csproj @@ -75,6 +75,7 @@ + @@ -111,6 +112,7 @@ + diff --git a/UnitystationLauncher/ViewModels/InstallationViewModel.cs b/UnitystationLauncher/ViewModels/InstallationViewModel.cs index 3363488a..d7cae379 100644 --- a/UnitystationLauncher/ViewModels/InstallationViewModel.cs +++ b/UnitystationLauncher/ViewModels/InstallationViewModel.cs @@ -1,6 +1,13 @@ using System.Reactive; +using System.Reactive.Concurrency; +using System.Threading.Tasks; +using MsBox.Avalonia.Base; using ReactiveUI; +using UnitystationLauncher.Constants; +using UnitystationLauncher.Infrastructure; using UnitystationLauncher.Models; +using UnitystationLauncher.Models.ConfigFile; +using UnitystationLauncher.Models.Enums; using UnitystationLauncher.Services.Interface; namespace UnitystationLauncher.ViewModels @@ -11,16 +18,14 @@ public class InstallationViewModel : ViewModelBase public ReactiveCommand LaunchCommand { get; set; } public ReactiveCommand UninstallCommand { get; set; } - private readonly IInstallationService _installationService; public InstallationViewModel(Installation installation, IInstallationService installationService) { _installationService = installationService; - Installation = installation; LaunchCommand = ReactiveCommand.Create(LaunchInstallation); - UninstallCommand = ReactiveCommand.Create(DeleteInstallation); + UninstallCommand = ReactiveCommand.Create(DeleteInstallation); ; } private void LaunchInstallation() @@ -37,5 +42,6 @@ public override void Refresh() { // Do nothing } + } } \ No newline at end of file diff --git a/UnitystationLauncher/ViewModels/InstallationsPanelViewModel.cs b/UnitystationLauncher/ViewModels/InstallationsPanelViewModel.cs index 9f8a6428..d899ece4 100644 --- a/UnitystationLauncher/ViewModels/InstallationsPanelViewModel.cs +++ b/UnitystationLauncher/ViewModels/InstallationsPanelViewModel.cs @@ -13,6 +13,7 @@ using UnitystationLauncher.Models; using UnitystationLauncher.Models.ConfigFile; using UnitystationLauncher.Models.Enums; +using UnitystationLauncher.Services; using UnitystationLauncher.Services.Interface; namespace UnitystationLauncher.ViewModels @@ -36,25 +37,49 @@ public bool AutoRemove set => this.RaiseAndSetIfChanged(ref _autoRemove, value); } + private bool? _TTSEnabled; + + public bool? TTSEnabled + { + get => _TTSEnabled; + set => this.RaiseAndSetIfChanged(ref _TTSEnabled, value); + } + public ObservableCollection InstallationViews { get; init; } = new(); private readonly TimeSpan _refreshInterval = TimeSpan.FromSeconds(2); private readonly IPreferencesService _preferencesService; private readonly IInstallationService _installationService; - - public InstallationsPanelViewModel(IInstallationService installationService, IPreferencesService preferencesService) + private readonly IEnvironmentService _environmentService; + private readonly ITTSService _ttsService; + + public InstallationsPanelViewModel(IInstallationService installationService, + IPreferencesService preferencesService, + IEnvironmentService environmentService, + ITTSService ttsService + ) { _installationService = installationService; _preferencesService = preferencesService; + _environmentService = environmentService; + _ttsService = ttsService; + BuildNum = $"Hub Build Num: {AppInfo.CurrentBuild}"; + UpdateFromPreferences(); + this.WhenAnyValue(p => p.AutoRemove) .Select(_ => Observable.FromAsync(OnAutoRemoveChangedAsync)) .Concat() .Subscribe(); - UpdateFromPreferences(); + this.WhenAnyValue(p => p.TTSEnabled) + .Select(_ => Observable.FromAsync(OnTTSChange)) + .Concat() + .Subscribe(); + + InitializeInstallationsList(); } @@ -62,10 +87,13 @@ private void UpdateFromPreferences() { Preferences prefs = _preferencesService.GetPreferences(); AutoRemove = prefs.AutoRemove; + TTSEnabled = prefs.TTSEnabled; } private async Task OnAutoRemoveChangedAsync() { + + if (AutoRemove) { IMsBox msgBox = MessageBoxBuilder.CreateMessageBox(MessageBoxButtons.YesNo, @@ -86,6 +114,41 @@ private async Task OnAutoRemoveChangedAsync() SaveChoice(); } } + + private async Task OnTTSChange() + { + if (_environmentService.GetCurrentEnvironment() == CurrentEnvironment.MacOsStandalone) + { + IMsBox msgBox = MessageBoxBuilder.CreateMessageBox(MessageBoxButtons.Ok, + " Mac Support is sad ", + " Sadly TTS is unsupported on Mac, If you'd like to contribute this, feel free to shoot a message on the Discord. "); + string response = await msgBox.ShowAsync(); + return; + } + + + if (TTSEnabled is false) + { + IMsBox msgBox = MessageBoxBuilder.CreateMessageBox(MessageBoxButtons.YesNo, + "Are you sure?", "This will disable Character voices (TTS). Proceed? (If yes It can take a little bit to delete So be patient)"); + + string response = await msgBox.ShowAsync(); + if (response.Equals(MessageBoxResults.Yes)) + { + TTSEnabled = false; + SaveChoiceTTS(); + } + else + { + TTSEnabled = true; + SaveChoiceTTS(); + } + } + else + { + SaveChoiceTTS(); + } + } private void InitializeInstallationsList() { @@ -145,6 +208,24 @@ private void SaveChoice() prefs.AutoRemove = AutoRemove; } + private void SaveChoiceTTS() + { + Preferences prefs = _preferencesService.GetPreferences(); + prefs.TTSEnabled = TTSEnabled; + + if (TTSEnabled == false) + { + _ttsService.StopTTS(); + string installationBasePath = _preferencesService.GetPreferences().InstallationPath; + var LocalVersion = System.IO.Path.Combine(installationBasePath, "tts"); + if (System.IO.Directory.Exists(LocalVersion)) + { + System.IO.Directory.Delete(LocalVersion, true); + } + } + + } + public override void Refresh() { this.RaisePropertyChanged(nameof(InstallationViews)); diff --git a/UnitystationLauncher/ViewModels/LauncherViewModel.cs b/UnitystationLauncher/ViewModels/LauncherViewModel.cs index ea3d3e2d..7d96784f 100644 --- a/UnitystationLauncher/ViewModels/LauncherViewModel.cs +++ b/UnitystationLauncher/ViewModels/LauncherViewModel.cs @@ -7,8 +7,11 @@ using Serilog; using System.Reactive.Linq; using System.Threading.Tasks; +using MsBox.Avalonia.Base; using UnitystationLauncher.Constants; +using UnitystationLauncher.Infrastructure; using UnitystationLauncher.Models.ConfigFile; +using UnitystationLauncher.Models.Enums; using UnitystationLauncher.Services.Interface; namespace UnitystationLauncher.ViewModels @@ -20,6 +23,8 @@ public class LauncherViewModel : ViewModelBase private readonly IPreferencesService _preferencesService; private readonly IEnvironmentService _environmentService; + private readonly ITTSService _ITTSService; + public ReactiveCommand OpenMainSite { get; } public ReactiveCommand OpenPatreon { get; } public ReactiveCommand OpenDiscordInvite { get; } @@ -49,12 +54,14 @@ public LauncherViewModel( IHubService hubService, IPreferencesService preferencesService, IEnvironmentService environmentService, - IGameCommunicationPipeService gameCommunicationPipeService) + IGameCommunicationPipeService gameCommunicationPipeService, + ITTSService ITTSService) { _hubUpdateVm = hubUpdateVm; _hubService = hubService; _preferencesService = preferencesService; _environmentService = environmentService; + _ITTSService = ITTSService; gameCommunicationPipeService.Init(); OpenMainSite = ReactiveCommand.Create(() => OpenLink(LinkUrls.MainSiteUrl)); @@ -66,6 +73,8 @@ public LauncherViewModel( SelectedPanel = serversPanel; RxApp.MainThreadScheduler.ScheduleAsync((_, _) => ValidateClientVersionAsync()); + RxApp.MainThreadScheduler.ScheduleAsync((_, _) => StartTTSIfInstalled()); + } private static PanelBase[] GetEnabledPanels( @@ -99,8 +108,14 @@ private static PanelBase[] GetEnabledPanels( return panelBases.ToArray(); } + private async Task StartTTSIfInstalled() + { + _ITTSService.StartTTS(); + } + private async Task ValidateClientVersionAsync() { + HubClientConfig? hubClientConfig = await _hubService.GetServerHubClientConfigAsync(); if (hubClientConfig == null) @@ -149,5 +164,6 @@ public override void Refresh() { // Do nothing } + } } diff --git a/UnitystationLauncher/ViewModels/ServersPanelViewModel.cs b/UnitystationLauncher/ViewModels/ServersPanelViewModel.cs index d4c067e2..46e98116 100644 --- a/UnitystationLauncher/ViewModels/ServersPanelViewModel.cs +++ b/UnitystationLauncher/ViewModels/ServersPanelViewModel.cs @@ -5,11 +5,14 @@ using System.Reactive; using System.Reactive.Concurrency; using System.Threading.Tasks; +using MsBox.Avalonia.Base; using ReactiveUI; using Serilog; +using UnitystationLauncher.Constants; using UnitystationLauncher.Infrastructure; using UnitystationLauncher.Models; using UnitystationLauncher.Models.Api; +using UnitystationLauncher.Models.ConfigFile; using UnitystationLauncher.Models.Enums; using UnitystationLauncher.Services.Interface; @@ -31,13 +34,18 @@ public class ServersPanelViewModel : PanelBase private readonly IInstallationService _installationService; private readonly IPingService _pingService; private readonly IServerService _serverService; + private readonly IPreferencesService? _preferencesService; + private readonly IEnvironmentService? _environmentService; public ServersPanelViewModel(IInstallationService installationService, IPingService pingService, - IServerService serverService) + IServerService serverService, IPreferencesService? preferencesService,IEnvironmentService? environmentService ) { _installationService = installationService; _pingService = pingService; _serverService = serverService; + _preferencesService = preferencesService; + _environmentService = environmentService; + DownloadCommand = ReactiveCommand.Create(server => { @@ -46,15 +54,49 @@ public ServersPanelViewModel(IInstallationService installationService, IPingServ }); InitializeServersList(); + } + public async Task CheckNewUser() + { + if (_environmentService == null || _preferencesService == null) return; //is Tests + + if (_environmentService.GetCurrentEnvironment() == CurrentEnvironment.MacOsStandalone) + { + return; + } + + if (_preferencesService.GetPreferences().TTSEnabled == null) + { + IMsBox msgBox = MessageBoxBuilder.CreateMessageBox(MessageBoxButtons.YesNo, + "Local TTS?", " would you like local TTS ( Character voices from other players Will not be present if you say no ) To be installed on your computer (2Gb Storage space and 500mb download)? It will download the first time you download a build It may take awhile to extract "); + + string response = await msgBox.ShowAsync(); + if (response.Equals(MessageBoxResults.Yes)) + { + SaveChoiceTTS(true); + } + else + { + SaveChoiceTTS(false); + } + } + } + + private void SaveChoiceTTS(bool? val) + { + if (_environmentService == null || _preferencesService == null) return; //is Tests + Preferences prefs = _preferencesService.GetPreferences(); + prefs.TTSEnabled = val; + } + private void InitializeServersList() { Log.Information("Initializing servers list..."); RxApp.MainThreadScheduler.ScheduleAsync((_, _) => RefreshServersList()); Log.Information("Scheduling periodic refresh for servers list..."); - + RxApp.MainThreadScheduler.ScheduleAsync((_, _) => CheckNewUser()); // Why can you not just run async methods with this?? Instead we have to do this ugly thing RxApp.TaskpoolScheduler.SchedulePeriodic(_refreshInterval, () => { RxApp.MainThreadScheduler.ScheduleAsync((_, _) => RefreshServersList()); }); diff --git a/UnitystationLauncher/Views/InstallationsPanelView.xaml b/UnitystationLauncher/Views/InstallationsPanelView.xaml index 5ef2550f..a5d1c1a2 100644 --- a/UnitystationLauncher/Views/InstallationsPanelView.xaml +++ b/UnitystationLauncher/Views/InstallationsPanelView.xaml @@ -18,6 +18,9 @@ + + + From 4be8a44c2c8c564ef76a158c95a60de9f31e3a1f Mon Sep 17 00:00:00 2001 From: Bod9001 Date: Mon, 2 Dec 2024 21:07:05 +0000 Subject: [PATCH 2/9] White spaces changes --- UnitystationLauncher/Constants/ApiUrls.cs | 2 +- .../Models/ConfigFile/Preferences.cs | 4 +-- .../Services/InstallationService.cs | 18 +++++------ UnitystationLauncher/Services/TTSService.cs | 32 +++++++++---------- .../ViewModels/InstallationViewModel.cs | 2 +- .../ViewModels/InstallationsPanelViewModel.cs | 26 +++++++-------- .../ViewModels/LauncherViewModel.cs | 12 +++---- .../ViewModels/ServersPanelViewModel.cs | 14 ++++---- 8 files changed, 55 insertions(+), 55 deletions(-) diff --git a/UnitystationLauncher/Constants/ApiUrls.cs b/UnitystationLauncher/Constants/ApiUrls.cs index 51888832..6cd3fb5b 100644 --- a/UnitystationLauncher/Constants/ApiUrls.cs +++ b/UnitystationLauncher/Constants/ApiUrls.cs @@ -20,5 +20,5 @@ public static class ApiUrls public static string CodeScanListUrl => $"{RawGitHubFileBaseUrl}/CodeScanList.json"; public static string TTSFiles => $"{CdnBaseUrl}/STTBundleTTS/TTS"; public static string TTSVersionFile => $"{TTSFiles}/version.txt"; - + } \ No newline at end of file diff --git a/UnitystationLauncher/Models/ConfigFile/Preferences.cs b/UnitystationLauncher/Models/ConfigFile/Preferences.cs index ce1908d4..570363ed 100644 --- a/UnitystationLauncher/Models/ConfigFile/Preferences.cs +++ b/UnitystationLauncher/Models/ConfigFile/Preferences.cs @@ -8,7 +8,7 @@ public class Preferences : ReactiveObject private int _ignoreVersionUpdate; private string _installationPath = string.Empty; private bool? _TTSEnabled = null; - + public bool AutoRemove { get => _autoRemove; @@ -26,7 +26,7 @@ public string InstallationPath get => _installationPath; set => this.RaiseAndSetIfChanged(ref _installationPath, value); } - + public bool? TTSEnabled { get => _TTSEnabled; diff --git a/UnitystationLauncher/Services/InstallationService.cs b/UnitystationLauncher/Services/InstallationService.cs index 6cfa5ee7..06783505 100644 --- a/UnitystationLauncher/Services/InstallationService.cs +++ b/UnitystationLauncher/Services/InstallationService.cs @@ -87,10 +87,10 @@ public List GetInstallations() public async Task<(Download?, string)> DownloadInstallationAsync(Server server) { - - - - + + + + string? downloadUrl = server.GetDownloadUrl(_environmentService); if (string.IsNullOrWhiteSpace(downloadUrl)) { @@ -139,9 +139,9 @@ public List GetInstallations() } _downloads.Add(download); - - - + + + RxApp.MainThreadScheduler.ScheduleAsync((_, _) => StartDownloadAsync(download)); return (download, string.Empty); } @@ -149,7 +149,7 @@ public List GetInstallations() public (bool, string) StartInstallation(Guid installationId, string? server = null, short? port = null) { _TTSVersionService.StartTTS(); - + Installation? installation = GetInstallationById(installationId); if (installation == null) { @@ -435,7 +435,7 @@ private async Task StartDownloadAsync(Download download) { //Update TTS if it's needed await _TTSVersionService.CheckAndDownloadLatestVersion(download); - + Log.Information("Download requested, Installation Path '{Path}', Url '{Url}'", download.InstallPath, download.DownloadUrl); try { diff --git a/UnitystationLauncher/Services/TTSService.cs b/UnitystationLauncher/Services/TTSService.cs index de4aa292..ff2fec44 100644 --- a/UnitystationLauncher/Services/TTSService.cs +++ b/UnitystationLauncher/Services/TTSService.cs @@ -34,7 +34,7 @@ public class TTSService : ITTSService private readonly IEnvironmentService _environmentService; private static Process? process; - + public TTSService(HttpClient httpClient, IPreferencesService preferencesService, IEnvironmentService environmentService) { @@ -46,7 +46,7 @@ public TTSService(HttpClient httpClient, IPreferencesService preferencesService, public async Task CheckAndDownloadLatestVersion(Download Download) { if ((_preferencesService.GetPreferences().TTSEnabled is true) == false) return; - + if (_environmentService.GetCurrentEnvironment() == CurrentEnvironment.MacOsStandalone) { Log.Error( @@ -158,17 +158,17 @@ private void ExtractTo(Stream progressStream, string LocalVersion, Download Down switch (_environmentService.GetCurrentEnvironment()) { case CurrentEnvironment.WindowsStandalone: - { - ZipArchive archive = new(progressStream); - archive.ExtractToDirectory(LocalVersion, true); - break; - } + { + ZipArchive archive = new(progressStream); + archive.ExtractToDirectory(LocalVersion, true); + break; + } case CurrentEnvironment.LinuxStandalone or CurrentEnvironment.LinuxFlatpak: - { - using var decompressedStream = DecompressXz(progressStream); // Decompress XZ stream to get .tar - ExtractTar(decompressedStream, LocalVersion); - break; - } + { + using var decompressedStream = DecompressXz(progressStream); // Decompress XZ stream to get .tar + ExtractTar(decompressedStream, LocalVersion); + break; + } } Download.Active = false; @@ -204,7 +204,7 @@ private void ExtractTar(Stream tarStream, string destinationPath) } } - private (string? ,string?) FindExecutable() + private (string?, string?) FindExecutable() { string installationBasePath = _preferencesService.GetPreferences().InstallationPath; if (string.IsNullOrWhiteSpace(installationBasePath) || !Directory.Exists(installationBasePath)) @@ -237,19 +237,19 @@ public void StartTTS() { var Preference = _preferencesService.GetPreferences(); if ((Preference.TTSEnabled is true) == false) return; - + if (process != null && process.HasExited == false) { return; } - + string installationBasePath = _preferencesService.GetPreferences().InstallationPath; var LocalVersion = System.IO.Path.Combine(installationBasePath, "tts"); if (System.IO.Directory.Exists(LocalVersion) == false) { return; //Not installed } - + (string?, string?) executable = FindExecutable(); if (string.IsNullOrWhiteSpace(executable.Item1)) { diff --git a/UnitystationLauncher/ViewModels/InstallationViewModel.cs b/UnitystationLauncher/ViewModels/InstallationViewModel.cs index d7cae379..8a07b9d2 100644 --- a/UnitystationLauncher/ViewModels/InstallationViewModel.cs +++ b/UnitystationLauncher/ViewModels/InstallationViewModel.cs @@ -42,6 +42,6 @@ public override void Refresh() { // Do nothing } - + } } \ No newline at end of file diff --git a/UnitystationLauncher/ViewModels/InstallationsPanelViewModel.cs b/UnitystationLauncher/ViewModels/InstallationsPanelViewModel.cs index d899ece4..3ad790a9 100644 --- a/UnitystationLauncher/ViewModels/InstallationsPanelViewModel.cs +++ b/UnitystationLauncher/ViewModels/InstallationsPanelViewModel.cs @@ -38,7 +38,7 @@ public bool AutoRemove } private bool? _TTSEnabled; - + public bool? TTSEnabled { get => _TTSEnabled; @@ -52,9 +52,9 @@ public bool? TTSEnabled private readonly IInstallationService _installationService; private readonly IEnvironmentService _environmentService; private readonly ITTSService _ttsService; - + public InstallationsPanelViewModel(IInstallationService installationService, - IPreferencesService preferencesService, + IPreferencesService preferencesService, IEnvironmentService environmentService, ITTSService ttsService ) @@ -64,11 +64,11 @@ ITTSService ttsService _environmentService = environmentService; _ttsService = ttsService; - + BuildNum = $"Hub Build Num: {AppInfo.CurrentBuild}"; UpdateFromPreferences(); - + this.WhenAnyValue(p => p.AutoRemove) .Select(_ => Observable.FromAsync(OnAutoRemoveChangedAsync)) .Concat() @@ -78,8 +78,8 @@ ITTSService ttsService .Select(_ => Observable.FromAsync(OnTTSChange)) .Concat() .Subscribe(); - - + + InitializeInstallationsList(); } @@ -92,8 +92,8 @@ private void UpdateFromPreferences() private async Task OnAutoRemoveChangedAsync() { - - + + if (AutoRemove) { IMsBox msgBox = MessageBoxBuilder.CreateMessageBox(MessageBoxButtons.YesNo, @@ -114,7 +114,7 @@ private async Task OnAutoRemoveChangedAsync() SaveChoice(); } } - + private async Task OnTTSChange() { if (_environmentService.GetCurrentEnvironment() == CurrentEnvironment.MacOsStandalone) @@ -126,7 +126,7 @@ private async Task OnTTSChange() return; } - + if (TTSEnabled is false) { IMsBox msgBox = MessageBoxBuilder.CreateMessageBox(MessageBoxButtons.YesNo, @@ -223,9 +223,9 @@ private void SaveChoiceTTS() System.IO.Directory.Delete(LocalVersion, true); } } - + } - + public override void Refresh() { this.RaisePropertyChanged(nameof(InstallationViews)); diff --git a/UnitystationLauncher/ViewModels/LauncherViewModel.cs b/UnitystationLauncher/ViewModels/LauncherViewModel.cs index 7d96784f..416c136d 100644 --- a/UnitystationLauncher/ViewModels/LauncherViewModel.cs +++ b/UnitystationLauncher/ViewModels/LauncherViewModel.cs @@ -24,7 +24,7 @@ public class LauncherViewModel : ViewModelBase private readonly IEnvironmentService _environmentService; private readonly ITTSService _ITTSService; - + public ReactiveCommand OpenMainSite { get; } public ReactiveCommand OpenPatreon { get; } public ReactiveCommand OpenDiscordInvite { get; } @@ -74,7 +74,7 @@ public LauncherViewModel( RxApp.MainThreadScheduler.ScheduleAsync((_, _) => ValidateClientVersionAsync()); RxApp.MainThreadScheduler.ScheduleAsync((_, _) => StartTTSIfInstalled()); - + } private static PanelBase[] GetEnabledPanels( @@ -109,13 +109,13 @@ private static PanelBase[] GetEnabledPanels( } private async Task StartTTSIfInstalled() - { + { _ITTSService.StartTTS(); } - + private async Task ValidateClientVersionAsync() { - + HubClientConfig? hubClientConfig = await _hubService.GetServerHubClientConfigAsync(); if (hubClientConfig == null) @@ -164,6 +164,6 @@ public override void Refresh() { // Do nothing } - + } } diff --git a/UnitystationLauncher/ViewModels/ServersPanelViewModel.cs b/UnitystationLauncher/ViewModels/ServersPanelViewModel.cs index 46e98116..b1f33dc5 100644 --- a/UnitystationLauncher/ViewModels/ServersPanelViewModel.cs +++ b/UnitystationLauncher/ViewModels/ServersPanelViewModel.cs @@ -38,7 +38,7 @@ public class ServersPanelViewModel : PanelBase private readonly IEnvironmentService? _environmentService; public ServersPanelViewModel(IInstallationService installationService, IPingService pingService, - IServerService serverService, IPreferencesService? preferencesService,IEnvironmentService? environmentService ) + IServerService serverService, IPreferencesService? preferencesService, IEnvironmentService? environmentService) { _installationService = installationService; _pingService = pingService; @@ -54,18 +54,18 @@ public ServersPanelViewModel(IInstallationService installationService, IPingServ }); InitializeServersList(); - + } public async Task CheckNewUser() { if (_environmentService == null || _preferencesService == null) return; //is Tests - + if (_environmentService.GetCurrentEnvironment() == CurrentEnvironment.MacOsStandalone) { return; - } - + } + if (_preferencesService.GetPreferences().TTSEnabled == null) { IMsBox msgBox = MessageBoxBuilder.CreateMessageBox(MessageBoxButtons.YesNo, @@ -82,14 +82,14 @@ public async Task CheckNewUser() } } } - + private void SaveChoiceTTS(bool? val) { if (_environmentService == null || _preferencesService == null) return; //is Tests Preferences prefs = _preferencesService.GetPreferences(); prefs.TTSEnabled = val; } - + private void InitializeServersList() { Log.Information("Initializing servers list..."); From 530c26e90b54a426c8417fd0de2cabbbe5035a81 Mon Sep 17 00:00:00 2001 From: Bod9001 Date: Mon, 2 Dec 2024 21:39:40 +0000 Subject: [PATCH 3/9] quality --- UnitystationLauncher/Services/TTSService.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UnitystationLauncher/Services/TTSService.cs b/UnitystationLauncher/Services/TTSService.cs index ff2fec44..4e50a468 100644 --- a/UnitystationLauncher/Services/TTSService.cs +++ b/UnitystationLauncher/Services/TTSService.cs @@ -169,6 +169,8 @@ private void ExtractTo(Stream progressStream, string LocalVersion, Download Down ExtractTar(decompressedStream, LocalVersion); break; } + default: + throw new Exception("Unsupported OS"); } Download.Active = false; From f864fa85ae15534e5f559df12cadbb225622efed Mon Sep 17 00:00:00 2001 From: Bod9001 Date: Wed, 4 Dec 2024 20:58:06 +0000 Subject: [PATCH 4/9] fix --- UnitystationLauncher/Services/TTSService.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UnitystationLauncher/Services/TTSService.cs b/UnitystationLauncher/Services/TTSService.cs index 4e50a468..21b3ae46 100644 --- a/UnitystationLauncher/Services/TTSService.cs +++ b/UnitystationLauncher/Services/TTSService.cs @@ -120,8 +120,8 @@ public async Task CheckAndDownloadLatestVersion(Download Download) var zip = _environmentService.GetCurrentEnvironment() switch { CurrentEnvironment.WindowsStandalone => "win.zip", - CurrentEnvironment.MacOsStandalone => "mac.zip", - CurrentEnvironment.LinuxStandalone or CurrentEnvironment.LinuxFlatpak => "lnx.zip", + //CurrentEnvironment.MacOsStandalone => "mac.zip", + CurrentEnvironment.LinuxStandalone or CurrentEnvironment.LinuxFlatpak => "lnx.tar.xz", _ => null }; From 3d7c1b2f886a65e06bba9101584b218099b671d4 Mon Sep 17 00:00:00 2001 From: Bod9001 Date: Sun, 8 Dec 2024 17:45:29 +0000 Subject: [PATCH 5/9] Good files --- UnitystationLauncher/Models/Api/Server.cs | 2 +- .../Services/InstallationService.cs | 14 ++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/UnitystationLauncher/Models/Api/Server.cs b/UnitystationLauncher/Models/Api/Server.cs index 6317838f..e2fe22bb 100644 --- a/UnitystationLauncher/Models/Api/Server.cs +++ b/UnitystationLauncher/Models/Api/Server.cs @@ -29,7 +29,7 @@ public Server(string forkName, int buildVersion, string serverIp, int serverPort public string? OsxDownload { get; set; } public string? LinuxDownload { get; set; } - public string ServerGoodFileVersion { get; set; } = string.Empty; + public string GoodFileVersion { get; set; } = string.Empty; public (string, int) ForkAndVersion => (ForkName, BuildVersion); diff --git a/UnitystationLauncher/Services/InstallationService.cs b/UnitystationLauncher/Services/InstallationService.cs index 06783505..bc03fa59 100644 --- a/UnitystationLauncher/Services/InstallationService.cs +++ b/UnitystationLauncher/Services/InstallationService.cs @@ -87,10 +87,6 @@ public List GetInstallations() public async Task<(Download?, string)> DownloadInstallationAsync(Server server) { - - - - string? downloadUrl = server.GetDownloadUrl(_environmentService); if (string.IsNullOrWhiteSpace(downloadUrl)) { @@ -99,14 +95,12 @@ public List GetInstallations() return (null!, failureReason); } - server.ServerGoodFileVersion = "1.0.0"; //TODO - - bool result = await _codeScanConfigService.ValidGoodFilesVersionAsync(server.ServerGoodFileVersion); + bool result = await _codeScanConfigService.ValidGoodFilesVersionAsync(server.GoodFileVersion); if (result == false) { const string failureReason = "server does not have a valid ServerGoodFileVersion "; - Log.Warning(failureReason + $" ServerName: {server.ServerName} ServerGoodFileVersion : {server.ServerGoodFileVersion}"); + Log.Warning(failureReason + $" ServerName: {server.ServerName} ServerGoodFileVersion : {server.GoodFileVersion}"); return (null!, failureReason); } @@ -121,9 +115,9 @@ public List GetInstallations() string installationBasePath = _preferencesService.GetPreferences().InstallationPath; // should be something like {basePath}/{forkName}/{version} - string installationPath = Path.Combine(installationBasePath, server.ForkName.SanitiseStringPath(), server.ServerGoodFileVersion.SanitiseStringPath(), server.BuildVersion.ToString()); + string installationPath = Path.Combine(installationBasePath, server.ForkName.SanitiseStringPath(), server.GoodFileVersion.SanitiseStringPath(), server.BuildVersion.ToString()); - download = new(downloadUrl, installationPath, server.ForkName, server.BuildVersion, server.ServerGoodFileVersion); + download = new(downloadUrl, installationPath, server.ForkName, server.BuildVersion, server.GoodFileVersion); (bool canStartDownload, string cantDownloadReason) = CanStartDownload(download); From b1c6f4845f564fedda34eaa7850555913a50eacc Mon Sep 17 00:00:00 2001 From: Bod9001 Date: Tue, 10 Dec 2024 20:46:05 +0000 Subject: [PATCH 6/9] updatws --- .../Services/CodeScanConfigService.cs | 10 +++++----- UnitystationLauncher/Services/CodeScanService.cs | 6 ++++-- UnitystationLauncher/Services/InstallationService.cs | 11 +++++++++++ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/UnitystationLauncher/Services/CodeScanConfigService.cs b/UnitystationLauncher/Services/CodeScanConfigService.cs index 348c8102..8078c3e0 100644 --- a/UnitystationLauncher/Services/CodeScanConfigService.cs +++ b/UnitystationLauncher/Services/CodeScanConfigService.cs @@ -47,11 +47,11 @@ public CodeScanConfigService(HttpClient httpClient, IPreferencesService preferen string pathBase = _preferencesService.GetPreferences().InstallationPath; string folderName = GetFolderName(version); - string versionPath = Path.Combine(pathBase, version, folderName); + string versionPath = Path.Combine(pathBase, "nonbuild", version, folderName); if (Directory.Exists(versionPath) == false) { - string zipExtractPath = Path.Combine(pathBase, version); + string zipExtractPath = Path.Combine(pathBase, "nonbuild", version); HttpResponseMessage request = await _httpClient.GetAsync($"{ApiUrls.GoodFilesBaseUrl}/{version}/{folderName}.zip", HttpCompletionOption.ResponseHeadersRead); await using Stream responseStream = await request.Content.ReadAsStreamAsync(); ZipArchive archive = new(responseStream); @@ -183,12 +183,12 @@ private string GetZipFolderName() switch (os) { case CurrentEnvironment.WindowsStandalone: - return "Windows"; + return "StandaloneWindows64"; case CurrentEnvironment.LinuxFlatpak: case CurrentEnvironment.LinuxStandalone: - return "Linux"; + return "StandaloneLinux64"; case CurrentEnvironment.MacOsStandalone: - return "Mac"; + return "StandaloneOSX"; default: throw new UnsupportedPlatformException($"Unable to determine OS Version {os}"); } diff --git a/UnitystationLauncher/Services/CodeScanService.cs b/UnitystationLauncher/Services/CodeScanService.cs index b41d462a..ab78d08c 100644 --- a/UnitystationLauncher/Services/CodeScanService.cs +++ b/UnitystationLauncher/Services/CodeScanService.cs @@ -36,8 +36,10 @@ public async Task OnScanAsync(ZipArchive archive, string targetDirectory, // TODO: Enable extraction cancelling DirectoryInfo root = new(_preferencesService.GetPreferences().InstallationPath); - DirectoryInfo stagingDirectory = root.CreateSubdirectory("UnsafeBuildZipDirectory"); - DirectoryInfo processingDirectory = root.CreateSubdirectory("UnsafeBuildProcessing"); + var nonbuild = root.CreateSubdirectory("nonbuild"); + + DirectoryInfo stagingDirectory = nonbuild.CreateSubdirectory("UnsafeBuildZipDirectory"); + DirectoryInfo processingDirectory = nonbuild.CreateSubdirectory("UnsafeBuildProcessing"); DirectoryInfo? dataPath = null; archive.ExtractToDirectory(stagingDirectory.ToString(), true); try diff --git a/UnitystationLauncher/Services/InstallationService.cs b/UnitystationLauncher/Services/InstallationService.cs index bc03fa59..72839a0d 100644 --- a/UnitystationLauncher/Services/InstallationService.cs +++ b/UnitystationLauncher/Services/InstallationService.cs @@ -115,6 +115,17 @@ public List GetInstallations() string installationBasePath = _preferencesService.GetPreferences().InstallationPath; // should be something like {basePath}/{forkName}/{version} + if (server.ForkName.SanitiseStringPath() == "nonbuild") + { + throw new Exception($" bad server.ForkName {server.ForkName.SanitiseStringPath()} Not allowed as save location (nonbuild)"); + } + + if (server.ForkName.SanitiseStringPath() == "tts") + { + throw new Exception($" bad server.ForkName {server.ForkName.SanitiseStringPath()} Not allowed as save location (tts) "); + } + + string installationPath = Path.Combine(installationBasePath, server.ForkName.SanitiseStringPath(), server.GoodFileVersion.SanitiseStringPath(), server.BuildVersion.ToString()); download = new(downloadUrl, installationPath, server.ForkName, server.BuildVersion, server.GoodFileVersion); From 91f9b8617022ec0ad48ff07bb72787b981b94472 Mon Sep 17 00:00:00 2001 From: Bod9001 Date: Thu, 12 Dec 2024 13:19:19 +0000 Subject: [PATCH 7/9] formaatting --- UnitystationLauncher/Services/InstallationService.cs | 4 ++-- UnitystationLauncher/Services/TTSService.cs | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/UnitystationLauncher/Services/InstallationService.cs b/UnitystationLauncher/Services/InstallationService.cs index 72839a0d..befb8638 100644 --- a/UnitystationLauncher/Services/InstallationService.cs +++ b/UnitystationLauncher/Services/InstallationService.cs @@ -117,12 +117,12 @@ public List GetInstallations() // should be something like {basePath}/{forkName}/{version} if (server.ForkName.SanitiseStringPath() == "nonbuild") { - throw new Exception($" bad server.ForkName {server.ForkName.SanitiseStringPath()} Not allowed as save location (nonbuild)"); + throw new Exception($" bad server ForkName {server.ForkName.SanitiseStringPath()} Not allowed as save location (nonbuild)"); } if (server.ForkName.SanitiseStringPath() == "tts") { - throw new Exception($" bad server.ForkName {server.ForkName.SanitiseStringPath()} Not allowed as save location (tts) "); + throw new Exception($" bad server ForkName {server.ForkName.SanitiseStringPath()} Not allowed as save location (tts) "); } diff --git a/UnitystationLauncher/Services/TTSService.cs b/UnitystationLauncher/Services/TTSService.cs index 21b3ae46..e26bc2bc 100644 --- a/UnitystationLauncher/Services/TTSService.cs +++ b/UnitystationLauncher/Services/TTSService.cs @@ -45,7 +45,10 @@ public TTSService(HttpClient httpClient, IPreferencesService preferencesService, public async Task CheckAndDownloadLatestVersion(Download Download) { - if ((_preferencesService.GetPreferences().TTSEnabled is true) == false) return; + if ((_preferencesService.GetPreferences().TTSEnabled is true) == false) + { + return; + } if (_environmentService.GetCurrentEnvironment() == CurrentEnvironment.MacOsStandalone) { @@ -309,6 +312,7 @@ public void StartTTS() } } + public void StopTTS() { if (process != null) From d4a3fc414c62c24da2cb7eab39f7918c25b7dbd7 Mon Sep 17 00:00:00 2001 From: Bod9001 Date: Thu, 12 Dec 2024 13:27:57 +0000 Subject: [PATCH 8/9] format --- UnitystationLauncher/Models/Api/VersionModel.cs | 7 +++++-- UnitystationLauncher/Services/TTSService.cs | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/UnitystationLauncher/Models/Api/VersionModel.cs b/UnitystationLauncher/Models/Api/VersionModel.cs index f7546196..7b7eee22 100644 --- a/UnitystationLauncher/Models/Api/VersionModel.cs +++ b/UnitystationLauncher/Models/Api/VersionModel.cs @@ -1,6 +1,9 @@ -namespace UnitystationLauncher.Models.Api; +using System.Text.Json.Serialization; + +namespace UnitystationLauncher.Models.Api; public class VersionModel { - public string version { get; set; } + [JsonPropertyName("version")] + public required string Version { get; set; } } \ No newline at end of file diff --git a/UnitystationLauncher/Services/TTSService.cs b/UnitystationLauncher/Services/TTSService.cs index e26bc2bc..702a9c2b 100644 --- a/UnitystationLauncher/Services/TTSService.cs +++ b/UnitystationLauncher/Services/TTSService.cs @@ -111,7 +111,7 @@ public async Task CheckAndDownloadLatestVersion(Download Download) try { - if (localVersionModel == null || localVersionModel.version != CurrentVersion.version) + if (localVersionModel == null || localVersionModel.Version != CurrentVersion.Version) { var LocalVersion = System.IO.Path.Combine(installationBasePath, "tts"); if (System.IO.Directory.Exists(LocalVersion)) From 54df2ea3263afbe94e389da72b0b662aac1b2f90 Mon Sep 17 00:00:00 2001 From: Bod9001 Date: Thu, 12 Dec 2024 13:33:46 +0000 Subject: [PATCH 9/9] asynchronous --- UnitystationLauncher/ViewModels/LauncherViewModel.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UnitystationLauncher/ViewModels/LauncherViewModel.cs b/UnitystationLauncher/ViewModels/LauncherViewModel.cs index 416c136d..3367c288 100644 --- a/UnitystationLauncher/ViewModels/LauncherViewModel.cs +++ b/UnitystationLauncher/ViewModels/LauncherViewModel.cs @@ -73,7 +73,7 @@ public LauncherViewModel( SelectedPanel = serversPanel; RxApp.MainThreadScheduler.ScheduleAsync((_, _) => ValidateClientVersionAsync()); - RxApp.MainThreadScheduler.ScheduleAsync((_, _) => StartTTSIfInstalled()); + RxApp.MainThreadScheduler.Schedule((_) => StartTTSIfInstalled()); } @@ -108,7 +108,7 @@ private static PanelBase[] GetEnabledPanels( return panelBases.ToArray(); } - private async Task StartTTSIfInstalled() + private void StartTTSIfInstalled() { _ITTSService.StartTTS(); }