From 2c7c7080e3d590ce13e72c83822e2ac7754a24be Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Wed, 7 Aug 2024 08:36:00 +0300 Subject: [PATCH 01/12] #46 Remove redundant command execution in GmlButton The `Command.Execute` call within the button click event handler was redundant since the command is already executed elsewhere. This change improves code readability and prevents potential double execution of the command. --- src/Gml.Launcher/Views/Components/GmlButton.axaml.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Gml.Launcher/Views/Components/GmlButton.axaml.cs b/src/Gml.Launcher/Views/Components/GmlButton.axaml.cs index a7d267a..700eae4 100644 --- a/src/Gml.Launcher/Views/Components/GmlButton.axaml.cs +++ b/src/Gml.Launcher/Views/Components/GmlButton.axaml.cs @@ -89,10 +89,6 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e) base.OnApplyTemplate(e); if (this.GetTemplateChildren().First() is Button button) - button.Click += (sender, args) => - { - RaiseEvent(new RoutedEventArgs(ClickEvent)); - Command?.Execute(CommandParameter); - }; + button.Click += (_, _) => RaiseEvent(new RoutedEventArgs(ClickEvent));; } } From 8e3748163e8e439517c91d62ed797c54dc4aad50 Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Wed, 7 Aug 2024 11:02:37 +0300 Subject: [PATCH 02/12] Handle disk full errors with new localized messages. Added a new IsDiskFull resource string in multiple languages to display an error message when the disk is full. Updated the SystemService and OverviewPageViewModel to catch IOException and check for disk full errors using the new IsDiskFull method in SystemService. --- .../Assets/Resources/ResourceKeysDictionary.Template.cs | 1 + .../Assets/Resources/ResourceKeysDictionary.cs | 3 +-- src/Gml.Launcher/Assets/Resources/Resources.Designer.cs | 8 ++++++++ src/Gml.Launcher/Assets/Resources/Resources.en.resx | 3 +++ src/Gml.Launcher/Assets/Resources/Resources.resx | 3 +++ src/Gml.Launcher/Assets/Resources/Resources.ru.resx | 3 +++ src/Gml.Launcher/Core/Services/ISystemService.cs | 3 +++ src/Gml.Launcher/Core/Services/SystemService.cs | 8 ++++++++ .../ViewModels/Pages/OverviewPageViewModel.cs | 7 +++++++ 9 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs index 35085dc..2d15214 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs @@ -24,6 +24,7 @@ public static class ResourceKeysDictionary public const string InstallingUpdates = "InstallingUpdates"; public const string FailedOs = "FailedOs"; public const string JavaNotFound = "JavaNotFound"; + public const string IsDiskFull = "IsDiskFull"; public const string Host = "{{HOST}}"; public const string FolderName = "{{FOLDER_NAME}}"; } diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs index e10bcee..813e8a2 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs @@ -23,9 +23,8 @@ public static class ResourceKeysDictionary public const string CheckUpdates = "CheckUpdates"; public const string InstallingUpdates = "InstallingUpdates"; public const string FailedOs = "FailedOs"; - public const string JavaNotFound = "JavaNotFound"; - + public const string IsDiskFull = "IsDiskFull"; // public const string Host = "https://gmlb.recloud.tech"; public const string Host = "https://gmlb-test.recloud.tech"; public const string FolderName = "GamerVIILacunerhV2"; diff --git a/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs b/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs index 649e671..4c757e8 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs +++ b/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs @@ -258,5 +258,13 @@ public static string InvalidFolder { return ResourceManager.GetString("InvalidFolder", resourceCulture); } } + /// + /// Ищет локализованную строку, похожую на ProfileNotConfigured. + /// + public static string IsDiskFull { + get { + return ResourceManager.GetString("IsDiskFull", resourceCulture); + } + } } } diff --git a/src/Gml.Launcher/Assets/Resources/Resources.en.resx b/src/Gml.Launcher/Assets/Resources/Resources.en.resx index 3441c25..aa1771b 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.en.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.en.resx @@ -135,4 +135,7 @@ Failed to change the installation folder or an error occurred while changing the folder. + + Not enough disk space + diff --git a/src/Gml.Launcher/Assets/Resources/Resources.resx b/src/Gml.Launcher/Assets/Resources/Resources.resx index 32ad5b3..0fdd2b3 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.resx @@ -143,4 +143,7 @@ Failed to change the installation folder or an error occurred while changing the folder. + + Not enough disk space + diff --git a/src/Gml.Launcher/Assets/Resources/Resources.ru.resx b/src/Gml.Launcher/Assets/Resources/Resources.ru.resx index b1a4814..f12a6b3 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.ru.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.ru.resx @@ -135,4 +135,7 @@ Не получилось сменить папку установки или произошла ошибка при смене папки + + Недостаточно места на диске + diff --git a/src/Gml.Launcher/Core/Services/ISystemService.cs b/src/Gml.Launcher/Core/Services/ISystemService.cs index 3f15683..445fd4d 100644 --- a/src/Gml.Launcher/Core/Services/ISystemService.cs +++ b/src/Gml.Launcher/Core/Services/ISystemService.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.IO; using System.Threading.Tasks; using Gml.Launcher.Models; using Gml.Web.Api.Domains.System; @@ -52,4 +53,6 @@ public interface ISystemService /// /// A task representing the asynchronous operation. Task LoadSystemData(); + + bool IsDiskFull(IOException ioException); } diff --git a/src/Gml.Launcher/Core/Services/SystemService.cs b/src/Gml.Launcher/Core/Services/SystemService.cs index 00e96d9..b55c811 100644 --- a/src/Gml.Launcher/Core/Services/SystemService.cs +++ b/src/Gml.Launcher/Core/Services/SystemService.cs @@ -3,6 +3,7 @@ using System.Globalization; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Threading.Tasks; using Gml.Launcher.Models; using Gml.Web.Api.Domains.System; @@ -15,6 +16,7 @@ public class SystemService : ISystemService { private const string NotSupportedMessage = "The operating system is not supported."; private readonly HardwareInfo _hardwareInfo = new(); + const int ERROR_DISK_FULL = 0x70; public ulong GetMaxRam() { @@ -63,6 +65,12 @@ public async Task LoadSystemData() await Task.WhenAll(refreshDriveListTask, refreshMotherboardListTask, refreshCpuListTask); } + public bool IsDiskFull(IOException ioException) + { + int hr = Marshal.GetHRForException(ioException); + return (hr & 0xFFFF) == ERROR_DISK_FULL; + } + public OsType GetOsType() { if (IsWindows()) return OsType.Windows; diff --git a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs index 007ea90..84bd365 100644 --- a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs @@ -178,6 +178,13 @@ await ExecuteFromNewThread(async () => Console.WriteLine(exception); } + catch (IOException ioException) when (_systemService.IsDiskFull(ioException)) + { + ShowError(ResourceKeysDictionary.Error, + LocalizationService.GetString(ResourceKeysDictionary.IsDiskFull)); + + Console.WriteLine(ioException); + } catch (Exception exception) { ShowError(ResourceKeysDictionary.Error, string.Join(". ", exception.Message)); From 1a6a890ed0d55e7b64f1b58b30784eb8a407b35f Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Wed, 7 Aug 2024 11:53:06 +0300 Subject: [PATCH 03/12] Add error handling for game profile initialization Introduce a new error message "GameProfileError" in resource files. Implement logic to capture and display this error when initializing game profiles, ensuring errors are properly logged and displayed to the user. --- .../Resources/ResourceKeysDictionary.cs | 1 + .../Assets/Resources/Resources.Designer.cs | 8 +++++++ .../Assets/Resources/Resources.en.resx | 3 +++ .../Assets/Resources/Resources.resx | 3 +++ .../Assets/Resources/Resources.ru.resx | 3 +++ .../ViewModels/Pages/OverviewPageViewModel.cs | 21 ++++++++++++++++++- 6 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs index 813e8a2..b641583 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs @@ -5,6 +5,7 @@ public static class ResourceKeysDictionary public const string MainPageTitle = "DefaultPageTitle"; public const string DefaultPageTitle = "DefaultPageTitle"; public const string Error = "Error"; + public const string GameProfileError = "GameProfileError"; public const string InvalidFolder = "InvalidFolder"; public const string NotSetting = "NotSetting"; public const string Updating = "Updating"; diff --git a/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs b/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs index 4c757e8..916933e 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs +++ b/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs @@ -266,5 +266,13 @@ public static string IsDiskFull { return ResourceManager.GetString("IsDiskFull", resourceCulture); } } + /// + /// Ищет локализованную строку, похожую на ProfileNotConfigured. + /// + public static string GameProfileError { + get { + return ResourceManager.GetString("GameProfileError", resourceCulture); + } + } } } diff --git a/src/Gml.Launcher/Assets/Resources/Resources.en.resx b/src/Gml.Launcher/Assets/Resources/Resources.en.resx index aa1771b..ba38ddd 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.en.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.en.resx @@ -138,4 +138,7 @@ Not enough disk space + + Error initializing the game profile. + diff --git a/src/Gml.Launcher/Assets/Resources/Resources.resx b/src/Gml.Launcher/Assets/Resources/Resources.resx index 0fdd2b3..52adde4 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.resx @@ -146,4 +146,7 @@ Not enough disk space + + Error initializing the game profile. + diff --git a/src/Gml.Launcher/Assets/Resources/Resources.ru.resx b/src/Gml.Launcher/Assets/Resources/Resources.ru.resx index f12a6b3..0be8cae 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.ru.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.ru.resx @@ -138,4 +138,7 @@ Недостаточно места на диске + + Ошибка инициализации игрового профиля. + diff --git a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs index 84bd365..7e1e8c0 100644 --- a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs @@ -161,6 +161,9 @@ await ExecuteFromNewThread(async () => _gameProcess?.Close(); _gameProcess = await GenerateProcess(cancellationToken, profileInfo); _gameProcess.Start(); + _gameProcess.BeginOutputReadLine(); + _gameProcess.BeginErrorReadLine(); + await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); Dispatcher.UIThread.Invoke(() => _mainViewModel._gameLaunched.OnNext(true)); UpdateProgress(string.Empty, string.Empty, false); @@ -214,7 +217,23 @@ private async Task GenerateProcess(CancellationToken cancellationToken, await _gmlManager.DownloadNotInstalledFiles(profileInfo.Data, cancellationToken); - var process = await _gmlManager.GetProcess(profileInfo.Data, _systemService.GetOsType()); + Process process = await _gmlManager.GetProcess(profileInfo.Data, _systemService.GetOsType()); + + process.OutputDataReceived += (sender, e) => + { + if (!string.IsNullOrEmpty(e.Data)) + { + Console.WriteLine(e.Data); + } + }; + + process.ErrorDataReceived += (sender, e) => + { + if (!string.IsNullOrEmpty(e.Data) && !e.Data.Contains("[gml-patch]")) + { + ShowError(ResourceKeysDictionary.GameProfileError, e.Data); + } + }; await _gmlManager.ClearFiles(profileInfo.Data); From 21cea5a7f0a062ca5d986736b76366e221b6424f Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Wed, 7 Aug 2024 12:06:00 +0300 Subject: [PATCH 04/12] Add placeholder for Sentry Java logging Commented-out code added as a placeholder for future Sentry logging implementation. This will facilitate capturing Java log4j-related exceptions once the actual logging code is integrated. --- src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs index 7e1e8c0..ffb8221 100644 --- a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs @@ -224,6 +224,12 @@ private async Task GenerateProcess(CancellationToken cancellationToken, if (!string.IsNullOrEmpty(e.Data)) { Console.WriteLine(e.Data); + + // ToDo: Add sentry java logging + // if (e.Data.Contains("log4j:Throwable")) + // { + // + // } } }; From 57981898f9a5b962240a30a8835553dae1b7252d Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sun, 11 Aug 2024 09:45:29 +0300 Subject: [PATCH 05/12] Update submodule link Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index 0d334ab..9fa59a1 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit 0d334abe23f13b2fe361a7444d5df6e9924eb6e8 +Subproject commit 9fa59a165af6e33ca04193ea990e40c86c2e584e From 381684da9219e2ca750d9088c6a92dcc2d3df34e Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sun, 11 Aug 2024 10:01:40 +0300 Subject: [PATCH 06/12] Add GameProfileError constant to ResourceKeysDictionary This new constant will be used to provide an error message for issues related to game profiles. It ensures that error handling for game profiles is more robust and maintainable. --- .../Assets/Resources/ResourceKeysDictionary.Template.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs index 2d15214..5724bce 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs @@ -14,6 +14,7 @@ public static class ResourceKeysDictionary public const string PlayDRpcText = "PlayDRpcText"; public const string Launching = "Launching"; public const string PreparingLaunch = "PreparingLaunch"; + public const string GameProfileError = "GameProfileError"; public const string CheckingFileIntegrity = "CheckingFileIntegrity"; public const string ProfileNotConfigured = "ProfileNotConfigured"; public const string UpdatingDescription = "UpdatingDescription"; From 3964872e763d373a998ee574df64526595cabb24 Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sun, 11 Aug 2024 10:42:45 +0300 Subject: [PATCH 07/12] Update submodule link Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index 9fa59a1..23e0443 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit 9fa59a165af6e33ca04193ea990e40c86c2e584e +Subproject commit 23e04439a5770dac99457b3ce1197737bf59a92b From 5eb6e56d1c06484ece5b8495e06c798acd339f48 Mon Sep 17 00:00:00 2001 From: dirold2 Date: Fri, 16 Aug 2024 17:01:08 +0300 Subject: [PATCH 08/12] Solving the error for folders that have UTF-8 characters or spaces in the name --- src/Gml.Launcher/Core/Services/SystemService.cs | 10 +++++----- .../Views/Pages/SettingsPageView.axaml.cs | 13 +++++++++++-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/Gml.Launcher/Core/Services/SystemService.cs b/src/Gml.Launcher/Core/Services/SystemService.cs index b55c811..eed6417 100644 --- a/src/Gml.Launcher/Core/Services/SystemService.cs +++ b/src/Gml.Launcher/Core/Services/SystemService.cs @@ -29,9 +29,9 @@ public ulong GetMaxRam() public string GetApplicationFolder() { - if (IsWindows()) return GetFolderPath(Environment.SpecialFolder.ApplicationData); + if (IsWindows()) return Path.GetFullPath(GetFolderPath(Environment.SpecialFolder.ApplicationData)); - if (IsLinux() || IsMacOS()) return GetFolderPath(Environment.SpecialFolder.UserProfile); + if (IsLinux() || IsMacOS()) return Path.GetFullPath(GetFolderPath(Environment.SpecialFolder.UserProfile)); throw new NotSupportedException(NotSupportedMessage); } @@ -84,11 +84,11 @@ public OsType GetOsType() public IEnumerable GetAvailableLanguages() { - return new List - { + return + [ new() { IconPath = "/Assets/Images/lang-ru.svg", Name = "Русский", Culture = new CultureInfo("ru-RU") }, new() { IconPath = "/Assets/Images/lang-us.svg", Name = "English", Culture = new CultureInfo("en-US") } - }; + ]; } private static string GetFolderPath(Environment.SpecialFolder folder) diff --git a/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml.cs b/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml.cs index 327fdf0..fb8bd0e 100644 --- a/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml.cs +++ b/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.IO; using Avalonia; using Avalonia.Controls; using Avalonia.Interactivity; @@ -11,6 +12,7 @@ using Gml.Launcher.Assets; using Gml.Launcher.ViewModels.Pages; using ReactiveUI; +// using Sentry; namespace Gml.Launcher.Views.Pages; @@ -46,13 +48,20 @@ private async void OpenFileDialog(object? sender, RoutedEventArgs e) if (folders.Count != 1) return; - ViewModel!.InstallationFolder = folders[0].Path.AbsolutePath; + ViewModel!.InstallationFolder = Path.GetFullPath(folders[0].Path.AbsolutePath); ViewModel!.ChangeFolder(); } } catch (Exception exception) { - //ToDo: Sentry send + // Log the exception details to Sentry + // SentrySdk.CaptureException(exception); + // TODO Sentry send + + // Existing log statement + Console.WriteLine(exception.ToString()); + + // Show error notification ViewModel?.MainViewModel.Manager .CreateMessage(true, "#D03E3E", ViewModel.LocalizationService.GetString(ResourceKeysDictionary.Error), From bce788024efb7adcf70fdbdec07bebc4a440db76 Mon Sep 17 00:00:00 2001 From: dirold2 Date: Fri, 16 Aug 2024 18:45:38 +0300 Subject: [PATCH 09/12] Fixing warnings and updating the license string in Gml.Launcher.csproj to address the NETSDK1206 warning. Also adding RuntimeIdentifiers for faster builds. --- src/Gml.Launcher/App.axaml.cs | 8 ++--- src/Gml.Launcher/Core/Services/SkinService.cs | 2 +- src/Gml.Launcher/Gml.Launcher.csproj | 3 ++ src/L1.Avalonia.Gif/Decoding/GifDecoder.cs | 33 +++++++++---------- src/L1.Avalonia.Gif/Decoding/GifFrame.cs | 2 +- src/L1.Avalonia.Gif/Decoding/GifHeader.cs | 5 ++- src/L1.Avalonia.Gif/Decoding/GifRect.cs | 4 ++- .../Decoding/InvalidGifStreamException.cs | 7 ++-- .../Decoding/LzwDecompressionException.cs | 7 ++-- src/L1.Avalonia.Gif/GifImage.cs | 14 ++++---- src/L1.Avalonia.Gif/GifInstance.cs | 5 +-- .../InvalidGifStreamException.cs | 7 ++-- 12 files changed, 53 insertions(+), 44 deletions(-) diff --git a/src/Gml.Launcher/App.axaml.cs b/src/Gml.Launcher/App.axaml.cs index 2a8c430..0ed154a 100644 --- a/src/Gml.Launcher/App.axaml.cs +++ b/src/Gml.Launcher/App.axaml.cs @@ -3,25 +3,25 @@ using Avalonia.Markup.Xaml; using Gml.Launcher.ViewModels; using Gml.Launcher.Views; -using Gml.Launcher.Views.SplashScreen; namespace Gml.Launcher; -public class App : Application +public partial class App : Application { public override void Initialize() { AvaloniaXamlLoader.Load(this); } - public override async void OnFrameworkInitializationCompleted() + public override void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { + #if DEBUG desktop.MainWindow = new MainWindow { - DataContext = new MainWindowViewModel() + DataContext = new MainWindowViewModel(), }; #else var splashViewModel = new SplashScreenViewModel(); diff --git a/src/Gml.Launcher/Core/Services/SkinService.cs b/src/Gml.Launcher/Core/Services/SkinService.cs index 2982797..a799184 100644 --- a/src/Gml.Launcher/Core/Services/SkinService.cs +++ b/src/Gml.Launcher/Core/Services/SkinService.cs @@ -140,7 +140,7 @@ public static byte[] GetBack(string skinPath, int size, bool includeCloak = fals var croppedRightArm = croppedLeftArm.Clone(x => x.Flip(FlipMode.Horizontal)); - Image croppedCloak = null; + Image? croppedCloak = null; if (includeCloak && cloakImage != null) croppedCloak = cloakImage.Clone(ctx => diff --git a/src/Gml.Launcher/Gml.Launcher.csproj b/src/Gml.Launcher/Gml.Launcher.csproj index dbb153e..e914f83 100644 --- a/src/Gml.Launcher/Gml.Launcher.csproj +++ b/src/Gml.Launcher/Gml.Launcher.csproj @@ -9,6 +9,9 @@ Assets\Images\logo.ico 2.1.0.0 2.1.0.0 + Apache-2.0 + win-x86;win-x64;win-arm64;linux-x64;osx-x64;osx-arm64;linux-musl-x64;linux-musl-arm64 + $(NoWarn);NETSDK1206 diff --git a/src/L1.Avalonia.Gif/Decoding/GifDecoder.cs b/src/L1.Avalonia.Gif/Decoding/GifDecoder.cs index 9eb920e..68a5d40 100644 --- a/src/L1.Avalonia.Gif/Decoding/GifDecoder.cs +++ b/src/L1.Avalonia.Gif/Decoding/GifDecoder.cs @@ -41,8 +41,8 @@ private static readonly (int Start, int Step)[] Pass = private readonly Stream _fileStream; private readonly bool _hasFrameBackups; - public readonly List Frames = new(); - private byte[] _backupFrameIndexBuf; + public readonly List Frames = []; + private byte[]? _backupFrameIndexBuf; private GifColor[] _bitmapBackBuffer; private int _gctSize, _bgIndex, _prevFrame = -1, _backupFrame = -1; @@ -64,7 +64,7 @@ public GifDecoder(Stream fileStream, CancellationToken currentCtsToken) ProcessHeaderData(); ProcessFrameData(); - Header.IterationCount = Header.Iterations switch + Header!.IterationCount = Header.Iterations switch { -1 => new GifRepeatBehavior { Count = 1 }, 0 => new GifRepeatBehavior { LoopForever = true }, @@ -98,12 +98,12 @@ public void Dispose() { Frames.Clear(); - _bitmapBackBuffer = null; - _prefixBuf = null; - _suffixBuf = null; - _pixelStack = null; - _indexBuf = null; - _backupFrameIndexBuf = null; + _bitmapBackBuffer = []; + _prefixBuf = []; + _suffixBuf = []; + _pixelStack = []; + _indexBuf = []; + _backupFrameIndexBuf = []; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -169,7 +169,7 @@ private void RenderFrameAt(int idx, WriteableBitmap writeableBitmap) if (_hasFrameBackups & curFrame.ShouldBackup) { - Buffer.BlockCopy(_indexBuf, 0, _backupFrameIndexBuf, 0, curFrame.Dimensions.TotalPixels); + Buffer.BlockCopy(_indexBuf, 0, _backupFrameIndexBuf!, 0, curFrame.Dimensions.TotalPixels); _backupFrame = idx; } @@ -417,15 +417,14 @@ private void WriteBackBufToFb(IntPtr targetPointer) if (!(_hasNewFrame & (_bitmapBackBuffer != null))) return; unsafe - { - fixed (void* src = &_bitmapBackBuffer[0]) { - Buffer.MemoryCopy(src, targetPointer.ToPointer(), (uint)_backBufferBytes, - (uint)_backBufferBytes); + fixed (void* src = _bitmapBackBuffer) // Use the null-forgiving post-fix to assure the compiler `_bitmapBackBuffer` is not null. + { + Buffer.MemoryCopy(src, targetPointer.ToPointer(), (uint)_backBufferBytes, (uint)_backBufferBytes); + }; } - _hasNewFrame = false; - } + _hasNewFrame = false; } public static bool IsGifStream(Stream stream) @@ -466,7 +465,7 @@ private void ProcessHeaderData() HasGlobalColorTable = _gctUsed, // GlobalColorTableCacheID = _globalColorTable, GlobarColorTable = - _gctUsed ? ProcessColorTable(ref str, tmpB, _gctSize) : Array.Empty(), + _gctUsed ? ProcessColorTable(ref str, tmpB, _gctSize) : [], GlobalColorTableSize = _gctSize, BackgroundColorIndex = _bgIndex, HeaderSize = _fileStream.Position diff --git a/src/L1.Avalonia.Gif/Decoding/GifFrame.cs b/src/L1.Avalonia.Gif/Decoding/GifFrame.cs index 5b504dc..265844b 100644 --- a/src/L1.Avalonia.Gif/Decoding/GifFrame.cs +++ b/src/L1.Avalonia.Gif/Decoding/GifFrame.cs @@ -6,7 +6,7 @@ public class GifFrame public TimeSpan FrameDelay; public FrameDisposal FrameDisposalMethod; public bool HasTransparency, IsInterlaced, IsLocalColorTableUsed; - public GifColor[] LocalColorTable; + public GifColor[]? LocalColorTable; public int LZWMinCodeSize, LocalColorTableSize; public long LZWStreamPosition; public bool ShouldBackup; diff --git a/src/L1.Avalonia.Gif/Decoding/GifHeader.cs b/src/L1.Avalonia.Gif/Decoding/GifHeader.cs index cc2c5fa..674f6c0 100644 --- a/src/L1.Avalonia.Gif/Decoding/GifHeader.cs +++ b/src/L1.Avalonia.Gif/Decoding/GifHeader.cs @@ -2,14 +2,13 @@ namespace L1.Avalonia.Gif.Decoding; public class GifHeader { - private GifColor[] _globarColorTable; public int BackgroundColorIndex; public GifRect Dimensions; public ulong GlobalColorTableCacheID; public int GlobalColorTableSize; - public GifColor[] GlobarColorTable; + public GifColor[]? GlobarColorTable; // Default to empty array public bool HasGlobalColorTable; public long HeaderSize; - public GifRepeatBehavior IterationCount; + public GifRepeatBehavior? IterationCount; internal int Iterations = -1; } diff --git a/src/L1.Avalonia.Gif/Decoding/GifRect.cs b/src/L1.Avalonia.Gif/Decoding/GifRect.cs index 2a42737..1d40fb4 100644 --- a/src/L1.Avalonia.Gif/Decoding/GifRect.cs +++ b/src/L1.Avalonia.Gif/Decoding/GifRect.cs @@ -1,3 +1,5 @@ +using System.Diagnostics.CodeAnalysis; + namespace L1.Avalonia.Gif.Decoding; public readonly struct GifRect @@ -30,7 +32,7 @@ public GifRect(int x, int y, int width, int height) return !(a == b); } - public override bool Equals(object obj) + public override bool Equals([AllowNull] object obj) { if (obj == null || GetType() != obj.GetType()) return false; diff --git a/src/L1.Avalonia.Gif/Decoding/InvalidGifStreamException.cs b/src/L1.Avalonia.Gif/Decoding/InvalidGifStreamException.cs index fddcdd2..20a85be 100644 --- a/src/L1.Avalonia.Gif/Decoding/InvalidGifStreamException.cs +++ b/src/L1.Avalonia.Gif/Decoding/InvalidGifStreamException.cs @@ -17,7 +17,8 @@ public InvalidGifStreamException(string message, Exception innerException) : bas { } - protected InvalidGifStreamException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } + // protected InvalidGifStreamException(SerializationInfo info, StreamingContext context) : base(info, context) + // { + // } + // TODO } diff --git a/src/L1.Avalonia.Gif/Decoding/LzwDecompressionException.cs b/src/L1.Avalonia.Gif/Decoding/LzwDecompressionException.cs index 1453bda..148d035 100644 --- a/src/L1.Avalonia.Gif/Decoding/LzwDecompressionException.cs +++ b/src/L1.Avalonia.Gif/Decoding/LzwDecompressionException.cs @@ -17,7 +17,8 @@ public LzwDecompressionException(string message, Exception innerException) : bas { } - protected LzwDecompressionException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } + // protected LzwDecompressionException(SerializationInfo info, StreamingContext context) : base(info, context) + // { + // } + // TODO } diff --git a/src/L1.Avalonia.Gif/GifImage.cs b/src/L1.Avalonia.Gif/GifImage.cs index bbc6a77..3d63f46 100644 --- a/src/L1.Avalonia.Gif/GifImage.cs +++ b/src/L1.Avalonia.Gif/GifImage.cs @@ -33,11 +33,11 @@ public class GifImage : Control private bool _hasNewSource; private object? _newSource; - private Stopwatch _stopwatch; + private Stopwatch? _stopwatch; - private RenderTargetBitmap backingRTB; + private RenderTargetBitmap? backingRTB; - private GifInstance gifInstance; + private GifInstance? gifInstance; static GifImage() { @@ -117,8 +117,10 @@ public override void Render(DrawingContext context) if (_hasNewSource) { StopAndDispose(); - gifInstance = new GifInstance(_newSource); - gifInstance.IterationCount = IterationCount; + gifInstance = new GifInstance(_newSource!) + { + IterationCount = IterationCount + }; backingRTB = new RenderTargetBitmap(gifInstance.GifPixelSize, new Vector(96, 96)); _hasNewSource = false; @@ -131,7 +133,7 @@ public override void Render(DrawingContext context) if (gifInstance is null || (gifInstance.CurrentCts?.IsCancellationRequested ?? true)) return; - if (!_stopwatch.IsRunning) _stopwatch.Start(); + if (!_stopwatch!.IsRunning) _stopwatch.Start(); var currentFrame = gifInstance.ProcessFrameTime(_stopwatch.Elapsed); diff --git a/src/L1.Avalonia.Gif/GifInstance.cs b/src/L1.Avalonia.Gif/GifInstance.cs index 9351759..2e8044d 100644 --- a/src/L1.Avalonia.Gif/GifInstance.cs +++ b/src/L1.Avalonia.Gif/GifInstance.cs @@ -8,7 +8,8 @@ namespace L1.Avalonia.Gif { public class GifInstance : IDisposable { - private readonly List _colorTableIdList; + // TODO + // private readonly List _colorTableIdList; private readonly List _frameTimes; private readonly GifDecoder _gifDecoder; private readonly WriteableBitmap _targetBitmap; @@ -114,7 +115,7 @@ private static Stream GetStreamFromUri(Uri uri) } [CanBeNull] - public WriteableBitmap ProcessFrameTime(TimeSpan stopwatchElapsed) + public WriteableBitmap? ProcessFrameTime(TimeSpan stopwatchElapsed) { if (!IterationCount.IsInfinite && _iterationCount > IterationCount.Value) return null; diff --git a/src/L1.Avalonia.Gif/InvalidGifStreamException.cs b/src/L1.Avalonia.Gif/InvalidGifStreamException.cs index 0e1c9e4..1f45765 100644 --- a/src/L1.Avalonia.Gif/InvalidGifStreamException.cs +++ b/src/L1.Avalonia.Gif/InvalidGifStreamException.cs @@ -17,7 +17,8 @@ public InvalidGifStreamException(string message, Exception innerException) : bas { } - protected InvalidGifStreamException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } + // protected InvalidGifStreamException(SerializationInfo info, StreamingContext context) : base(info, context) + // { + // } + // TODO } From 4359dd68d69ebefdc4df734b2731650cf9c27bd7 Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sun, 1 Sep 2024 12:56:19 +0300 Subject: [PATCH 10/12] Add GameProfileError constant to ResourceKeysDictionary Re-add the GameProfileError constant to ensure error handling for game profiles is defined. This change corrects its previous removal and maintains consistency in the dictionary. --- .../Assets/Resources/ResourceKeysDictionary.Template.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs index 5724bce..a81d364 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs @@ -5,6 +5,7 @@ public static class ResourceKeysDictionary public const string MainPageTitle = "DefaultPageTitle"; public const string DefaultPageTitle = "DefaultPageTitle"; public const string Error = "Error"; + public const string GameProfileError = "GameProfileError"; public const string InvalidFolder = "InvalidFolder"; public const string NotSetting = "NotSetting"; public const string Updating = "Updating"; @@ -14,7 +15,6 @@ public static class ResourceKeysDictionary public const string PlayDRpcText = "PlayDRpcText"; public const string Launching = "Launching"; public const string PreparingLaunch = "PreparingLaunch"; - public const string GameProfileError = "GameProfileError"; public const string CheckingFileIntegrity = "CheckingFileIntegrity"; public const string ProfileNotConfigured = "ProfileNotConfigured"; public const string UpdatingDescription = "UpdatingDescription"; From 3b64970451b0c36ba1cc375cb193648756fc21cc Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sun, 1 Sep 2024 13:50:59 +0300 Subject: [PATCH 11/12] Log error output from process data receiver Add a Console.WriteLine statement to log error data from the process. This helps in debugging by providing immediate visibility of any error output that is not filtered by the existing conditions. --- src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs index ffb8221..eda94d8 100644 --- a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs @@ -235,6 +235,7 @@ private async Task GenerateProcess(CancellationToken cancellationToken, process.ErrorDataReceived += (sender, e) => { + Console.WriteLine(e?.Data); if (!string.IsNullOrEmpty(e.Data) && !e.Data.Contains("[gml-patch]")) { ShowError(ResourceKeysDictionary.GameProfileError, e.Data); From 9c221d38a013a4a664b7692968b9bfb6ceb2de3e Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sun, 1 Sep 2024 15:34:01 +0300 Subject: [PATCH 12/12] Add SplashScreen view import and update initialization Importing the SplashScreen view allows the application to display a splash screen during launch. Additionally, updating the OnFrameworkInitializationCompleted method to be asynchronous supports potential future asynchronous operations. --- src/Gml.Launcher/App.axaml.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Gml.Launcher/App.axaml.cs b/src/Gml.Launcher/App.axaml.cs index 0ed154a..1714673 100644 --- a/src/Gml.Launcher/App.axaml.cs +++ b/src/Gml.Launcher/App.axaml.cs @@ -3,6 +3,7 @@ using Avalonia.Markup.Xaml; using Gml.Launcher.ViewModels; using Gml.Launcher.Views; +using Gml.Launcher.Views.SplashScreen; namespace Gml.Launcher; @@ -13,7 +14,7 @@ public override void Initialize() AvaloniaXamlLoader.Load(this); } - public override void OnFrameworkInitializationCompleted() + public override async void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) {