From bb2d25b0e194de7d85d6d95e978f99f9ff9e9ec5 Mon Sep 17 00:00:00 2001 From: CryoTechnic Date: Mon, 10 Aug 2026 17:11:18 -0400 Subject: [PATCH 1/6] Update submodules --- ColorThief | 2 +- H.NotifyIcon | 2 +- Hi3Helper.EncTool | 2 +- Hi3Helper.Http | 2 +- Hi3Helper.Plugin.Core | 2 +- Hi3Helper.SharpDiscordRPC | 2 +- Hi3Helper.Sophon | 2 +- Hi3Helper.Win32 | 2 +- ImageEx | 2 +- SevenZipExtractor | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ColorThief b/ColorThief index cfd412a69..1146cb157 160000 --- a/ColorThief +++ b/ColorThief @@ -1 +1 @@ -Subproject commit cfd412a6958cfaf37bf3c4882ef1524d91c3ab31 +Subproject commit 1146cb157182d2bd821f6494efc317b98534cb36 diff --git a/H.NotifyIcon b/H.NotifyIcon index 414b1f9e3..64c54ae95 160000 --- a/H.NotifyIcon +++ b/H.NotifyIcon @@ -1 +1 @@ -Subproject commit 414b1f9e3b43905c5436ecc9efcbc97418f8fe18 +Subproject commit 64c54ae95aeae6925c8a8c2b6416a60dbabd180e diff --git a/Hi3Helper.EncTool b/Hi3Helper.EncTool index 52c06228d..2fbbc4b3b 160000 --- a/Hi3Helper.EncTool +++ b/Hi3Helper.EncTool @@ -1 +1 @@ -Subproject commit 52c06228df34ddae82dcc9f4173c518cca0973dd +Subproject commit 2fbbc4b3b42ed98b9d0bea1d5d1bc1c7f28d7469 diff --git a/Hi3Helper.Http b/Hi3Helper.Http index 2d4c209d4..8cb746cb3 160000 --- a/Hi3Helper.Http +++ b/Hi3Helper.Http @@ -1 +1 @@ -Subproject commit 2d4c209d4d462ee94a5e6a13e3c45abcfbca848e +Subproject commit 8cb746cb32bf391df06189fbb961091722420368 diff --git a/Hi3Helper.Plugin.Core b/Hi3Helper.Plugin.Core index 5811f4e7a..3613d20b4 160000 --- a/Hi3Helper.Plugin.Core +++ b/Hi3Helper.Plugin.Core @@ -1 +1 @@ -Subproject commit 5811f4e7a81c79374d32becce6d90e3a63b5a259 +Subproject commit 3613d20b405626e694f78793ac0d5f1626a37ff1 diff --git a/Hi3Helper.SharpDiscordRPC b/Hi3Helper.SharpDiscordRPC index e80e57c3e..0a8cf69ec 160000 --- a/Hi3Helper.SharpDiscordRPC +++ b/Hi3Helper.SharpDiscordRPC @@ -1 +1 @@ -Subproject commit e80e57c3e758bc7a28f9c69fb266019e977d1a1a +Subproject commit 0a8cf69ec4996ea985848c011e362203cac92b44 diff --git a/Hi3Helper.Sophon b/Hi3Helper.Sophon index 2c0868e34..6fbbcdf74 160000 --- a/Hi3Helper.Sophon +++ b/Hi3Helper.Sophon @@ -1 +1 @@ -Subproject commit 2c0868e34d2fd8d11099eb83e88e0476d28bf871 +Subproject commit 6fbbcdf74fa59348f7a316d4b1d1f344a5a411bc diff --git a/Hi3Helper.Win32 b/Hi3Helper.Win32 index 9478014fd..10be369e1 160000 --- a/Hi3Helper.Win32 +++ b/Hi3Helper.Win32 @@ -1 +1 @@ -Subproject commit 9478014fdce9a1b42f38e17145fb8c8d173190fc +Subproject commit 10be369e176e0127a886d89d3a6edb491911da31 diff --git a/ImageEx b/ImageEx index d599a35cc..c0eb31a4a 160000 --- a/ImageEx +++ b/ImageEx @@ -1 +1 @@ -Subproject commit d599a35cc1f9362f4ca0c2e346620301a7fe4cea +Subproject commit c0eb31a4aa726d0cb4598d1ee9a55b4823e8b11f diff --git a/SevenZipExtractor b/SevenZipExtractor index 5e0f4de32..8c4399bb3 160000 --- a/SevenZipExtractor +++ b/SevenZipExtractor @@ -1 +1 @@ -Subproject commit 5e0f4de32a5da3ae441fdd5c95d3951ef703480e +Subproject commit 8c4399bb372c14898847a6cf08cc495acfc67a34 From 9f71529ae482ef43bea64bae8526ddc89ee0dd6e Mon Sep 17 00:00:00 2001 From: CryoTechnic Date: Mon, 10 Aug 2026 17:51:53 -0400 Subject: [PATCH 2/6] feat(settings): render plugin game settings pages --- .../Plugins/PluginPresetConfigWrapper.cs | 2 + .../XAMLs/MainApp/MainPage.Navigation.cs | 4 +- .../PluginGameSettingsPage.cs | 283 ++++++++++++++++++ 3 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 CollapseLauncher/XAMLs/MainApp/Pages/GameSettingsPages/PluginGameSettingsPage.cs diff --git a/CollapseLauncher/Classes/Plugins/PluginPresetConfigWrapper.cs b/CollapseLauncher/Classes/Plugins/PluginPresetConfigWrapper.cs index bd0578c38..6c8a77d52 100644 --- a/CollapseLauncher/Classes/Plugins/PluginPresetConfigWrapper.cs +++ b/CollapseLauncher/Classes/Plugins/PluginPresetConfigWrapper.cs @@ -25,6 +25,7 @@ public partial class PluginPresetConfigWrapper : PresetConfig, IDisposable { public DiscordPresenceExtension.DiscordPresenceContext DiscordPresenceContext { get; } public GameManagerExtension.RunGameFromGameManagerContext RunGameContext { get; } + public GameSettingsExtension.GameSettingsContext GameSettingsContext { get; } public readonly PluginInfo PluginInfo; public readonly IPlugin Plugin; private readonly IPluginPresetConfig _config; @@ -50,6 +51,7 @@ private unsafe PluginPresetConfigWrapper(PluginInfo pluginInfo, IPluginPresetCon }; DiscordPresenceContext = new DiscordPresenceExtension.DiscordPresenceContext(pluginInfo.Handle, config); + GameSettingsContext = new GameSettingsExtension.GameSettingsContext(pluginInfo.Handle, config); } public unsafe GameManagerExtension.RunGameFromGameManagerContext UseToggledGameLaunchContext() diff --git a/CollapseLauncher/XAMLs/MainApp/MainPage.Navigation.cs b/CollapseLauncher/XAMLs/MainApp/MainPage.Navigation.cs index fb8913904..ad9a7a1cf 100644 --- a/CollapseLauncher/XAMLs/MainApp/MainPage.Navigation.cs +++ b/CollapseLauncher/XAMLs/MainApp/MainPage.Navigation.cs @@ -203,11 +203,13 @@ void Impl() GameNameType.StarRail => typeof(StarRailGameSettingsPage), GameNameType.Genshin => typeof(GenshinGameSettingsPage), GameNameType.Zenless => typeof(ZenlessGameSettingsPage), + GameNameType.Plugin when presetConfig is PluginPresetConfigWrapper + { GameSettingsContext.HasPage: true } => typeof(PluginGameSettingsPage), _ => null }; NavigationViewItemsContext.GameSettingsPage.Item.Tag = gspPageType; - NavigationViewItemsContext.GameSettingsPage.Item.Visibility = isPluginGame ? Visibility.Collapsed : Visibility.Visible; + NavigationViewItemsContext.GameSettingsPage.Item.Visibility = gspPageType == null ? Visibility.Collapsed : Visibility.Visible; NavigationViewItemsContext.FileCleanupPage.Item.Visibility = isPluginGame ? Visibility.Collapsed : Visibility.Visible; } } diff --git a/CollapseLauncher/XAMLs/MainApp/Pages/GameSettingsPages/PluginGameSettingsPage.cs b/CollapseLauncher/XAMLs/MainApp/Pages/GameSettingsPages/PluginGameSettingsPage.cs new file mode 100644 index 000000000..31d9f03a3 --- /dev/null +++ b/CollapseLauncher/XAMLs/MainApp/Pages/GameSettingsPages/PluginGameSettingsPage.cs @@ -0,0 +1,283 @@ +using CollapseLauncher.Plugins; +using CollapseLauncher.Helper; +using Hi3Helper.Plugin.Core.UI.Settings; +using Hi3Helper.Plugin.Core.Utility; +using Microsoft.UI; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Media; +using System; +using System.Globalization; +using static CollapseLauncher.Statics.GamePropertyVault; + +#nullable enable +namespace CollapseLauncher.Pages; + +/// +/// Renders the declarative game settings page exposed by a v0.1.6 plugin. +/// +public sealed class PluginGameSettingsPage : Page +{ + private readonly GameSettingsExtension.GameSettingsContext _context; + private readonly TextBlock _statusText = new() + { + Margin = new Thickness(16, 0, 0, 0), + VerticalAlignment = VerticalAlignment.Center, + TextWrapping = TextWrapping.Wrap + }; + + public PluginGameSettingsPage() + { + NavigationCacheMode = Microsoft.UI.Xaml.Navigation.NavigationCacheMode.Disabled; + + if (GetCurrentGameProperty().GameVersion.GamePreset is not PluginPresetConfigWrapper preset) + { + throw new InvalidOperationException("The current game preset is not provided by a plugin"); + } + + _context = preset.GameSettingsContext; + Content = CreateContent(); + } + + private UIElement CreateContent() + { + if (!_context.TryGetPage(out GameSettingsPage? page, out Exception? error) || page == null) + { + return new TextBlock + { + Margin = new Thickness(32, 40, 32, 32), + Text = error?.Message ?? "This plugin did not provide a game settings page.", + TextWrapping = TextWrapping.Wrap + }; + } + + Grid root = new(); + root.RowDefinitions.Add(new RowDefinition()); + root.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); + + StackPanel sectionsPanel = new() { Margin = new Thickness(32, 40, 32, 32), Spacing = 24 }; + if (!string.IsNullOrWhiteSpace(page.Title)) + { + sectionsPanel.Children.Add(new TextBlock + { + Text = page.Title, + Style = Application.Current.Resources["TitleLargeTextBlockStyle"] as Style, + TextWrapping = TextWrapping.Wrap + }); + } + + foreach (GameSettingsSection section in page.Sections) + { + sectionsPanel.Children.Add(CreateSection(section)); + } + + ScrollViewer scrollViewer = new() + { + Content = sectionsPanel, + VerticalScrollBarVisibility = ScrollBarVisibility.Auto + }; + root.Children.Add(scrollViewer); + + Grid applyPanel = new() + { + Padding = new Thickness(32, 16, 32, 16), + Background = Application.Current.Resources["GameSettingsApplyGridBrush"] as Brush + }; + applyPanel.ColumnDefinitions.Add(new ColumnDefinition()); + applyPanel.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); + applyPanel.Children.Add(_statusText); + + Button applyButton = new() + { + Content = Locale.Current.Lang?._GameSettingsPage?.ApplyBtn ?? "Apply settings", + MinWidth = 144, + CornerRadius = new CornerRadius(16), + Style = Application.Current.Resources["AccentButtonStyle"] as Style + }; + applyButton.Click += OnApply; + Grid.SetColumn(applyButton, 1); + applyPanel.Children.Add(applyButton); + Grid.SetRow(applyPanel, 1); + root.Children.Add(applyPanel); + + return root; + } + + private FrameworkElement CreateSection(GameSettingsSection section) + { + StackPanel panel = new() { Spacing = 8 }; + panel.Children.Add(new TextBlock + { + Text = section.Title, + Style = Application.Current.Resources["SubtitleTextBlockStyle"] as Style, + TextWrapping = TextWrapping.Wrap + }); + + if (!string.IsNullOrWhiteSpace(section.Description)) + { + panel.Children.Add(new TextBlock + { + Text = section.Description, + Opacity = 0.72, + TextWrapping = TextWrapping.Wrap + }); + } + + foreach (GameSettingEntry entry in section.Entries) + { + panel.Children.Add(CreateEntry(entry)); + } + + return panel; + } + + private FrameworkElement CreateEntry(GameSettingEntry entry) + { + Grid card = new() + { + Padding = new Thickness(16, 12, 16, 12), + ColumnSpacing = 24, + Background = Application.Current.Resources["CardBackgroundFillColorDefaultBrush"] as Brush, + CornerRadius = new CornerRadius(8) + }; + card.ColumnDefinitions.Add(new ColumnDefinition()); + card.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); + + StackPanel text = new() { VerticalAlignment = VerticalAlignment.Center, Spacing = 2 }; + text.Children.Add(new TextBlock { Text = entry.Title, TextWrapping = TextWrapping.Wrap }); + if (!string.IsNullOrWhiteSpace(entry.Description)) + { + text.Children.Add(new TextBlock + { + Text = entry.Description, + Opacity = 0.72, + TextWrapping = TextWrapping.Wrap + }); + } + card.Children.Add(text); + + FrameworkElement editor = CreateEditor(entry); + editor.MinWidth = entry.Kind is GameSettingKind.Toggle ? 0 : 180; + editor.VerticalAlignment = VerticalAlignment.Center; + Grid.SetColumn(editor, 1); + card.Children.Add(editor); + return card; + } + + private FrameworkElement CreateEditor(GameSettingEntry entry) => entry.Kind switch + { + GameSettingKind.Toggle => CreateToggle(entry), + GameSettingKind.Text => CreateText(entry), + GameSettingKind.Number => CreateNumber(entry), + GameSettingKind.Slider => CreateSlider(entry), + GameSettingKind.Choice => CreateChoice(entry), + _ => throw new ArgumentOutOfRangeException(nameof(entry.Kind)) + }; + + private ToggleSwitch CreateToggle(GameSettingEntry entry) + { + ToggleSwitch control = new() { IsOn = bool.TryParse(entry.Value, out bool value) && value }; + control.Toggled += (_, _) => SetValue(entry.Key, control.IsOn ? bool.TrueString : bool.FalseString); + return control; + } + + private TextBox CreateText(GameSettingEntry entry) + { + TextBox control = new() { Text = entry.Value, PlaceholderText = entry.Placeholder }; + control.TextChanged += (_, _) => SetValue(entry.Key, control.Text); + return control; + } + + private NumberBox CreateNumber(GameSettingEntry entry) + { + NumberBox control = new() + { + Minimum = entry.Minimum, + Maximum = entry.Maximum, + SmallChange = entry.Step, + SpinButtonPlacementMode = NumberBoxSpinButtonPlacementMode.Compact, + Value = ParseNumber(entry.Value, entry.Minimum) + }; + control.ValueChanged += (_, args) => + { + if (!double.IsNaN(args.NewValue)) + { + SetValue(entry.Key, args.NewValue.ToString(CultureInfo.InvariantCulture)); + } + }; + return control; + } + + private Slider CreateSlider(GameSettingEntry entry) + { + Slider control = new() + { + Minimum = entry.Minimum, + Maximum = entry.Maximum, + StepFrequency = entry.Step, + Value = ParseNumber(entry.Value, entry.Minimum), + Width = 220 + }; + control.ValueChanged += (_, args) => + SetValue(entry.Key, args.NewValue.ToString(CultureInfo.InvariantCulture)); + return control; + } + + private ComboBox CreateChoice(GameSettingEntry entry) + { + ComboBox control = new(); + foreach (GameSettingChoice choice in entry.Choices ?? []) + { + ComboBoxItem item = new() { Content = choice.Title, Tag = choice.Value }; + control.Items.Add(item); + if (string.Equals(choice.Value, entry.Value, StringComparison.Ordinal)) + { + control.SelectedItem = item; + } + } + + control.SelectionChanged += (_, _) => + { + if (control.SelectedItem is ComboBoxItem { Tag: string value }) + { + SetValue(entry.Key, value); + } + }; + return control; + } + + private static double ParseNumber(string value, double fallback) => + double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out double result) ? result : fallback; + + private void SetValue(string key, string value) + { + try + { + _context.SetValue(key, value); + SetStatus(null); + } + catch (Exception ex) + { + SetStatus(ex.Message, true); + } + } + + private void OnApply(object sender, RoutedEventArgs args) + { + try + { + _context.Apply(); + SetStatus(Locale.Current.Lang?._GameSettingsPage?.SettingsApplied ?? "Settings applied."); + } + catch (Exception ex) + { + SetStatus(ex.Message, true); + } + } + + private void SetStatus(string? text, bool isError = false) + { + _statusText.Text = text ?? string.Empty; + _statusText.Foreground = isError ? new SolidColorBrush(Colors.IndianRed) : null; + } +} From 150f2d3cdd42eb8e58b4465ab3fdc162f974f3c4 Mon Sep 17 00:00:00 2001 From: CryoTechnic Date: Tue, 18 Aug 2026 02:39:05 -0400 Subject: [PATCH 3/6] Hydrate background activity notification state Expose `Progress` and `Status` on `IBackgroundActivity` and use them when wiring notification handlers in `BackgroundActivityManager`. This immediately initializes notification text/progress for already-running activities instead of waiting for the next event, preventing placeholder content from lingering. --- .../Classes/EventsManagement/BackgroundActivityManager.cs | 6 ++++++ CollapseLauncher/Classes/Interfaces/IBackgroundActivity.cs | 2 ++ 2 files changed, 8 insertions(+) diff --git a/CollapseLauncher/Classes/EventsManagement/BackgroundActivityManager.cs b/CollapseLauncher/Classes/EventsManagement/BackgroundActivityManager.cs index 2ec01077c..d1d83fc86 100644 --- a/CollapseLauncher/Classes/EventsManagement/BackgroundActivityManager.cs +++ b/CollapseLauncher/Classes/EventsManagement/BackgroundActivityManager.cs @@ -259,6 +259,12 @@ private static void AttachEventToNotification(PresetConfig presetConfig, IBackgr activity!.ProgressChanged += progressChangedEventHandler; activity!.StatusChanged += statusChangedEventHandler; + // The notification can be attached after the operation has already + // started. Hydrate it immediately instead of waiting for another + // progress/status event and leaving the placeholder text visible. + progressChangedEventHandler(activity, activity.Progress); + statusChangedEventHandler(activity, activity.Status); + activity.FlushingTrigger += (_, _) => { activity.ProgressChanged -= progressChangedEventHandler; diff --git a/CollapseLauncher/Classes/Interfaces/IBackgroundActivity.cs b/CollapseLauncher/Classes/Interfaces/IBackgroundActivity.cs index 3eeda615b..ba378bf23 100644 --- a/CollapseLauncher/Classes/Interfaces/IBackgroundActivity.cs +++ b/CollapseLauncher/Classes/Interfaces/IBackgroundActivity.cs @@ -11,6 +11,8 @@ internal interface IBackgroundActivity event EventHandler StatusChanged; event EventHandler FlushingTrigger; + TotalPerFileProgress Progress { get; } + TotalPerFileStatus Status { get; } bool IsRunning { get; } UIElement ParentUI { get; } void CancelRoutine(); From f46f26bb35702f18822e38ad49ff1bede9950f5a Mon Sep 17 00:00:00 2001 From: CryoTechnic Date: Wed, 19 Aug 2026 16:05:37 -0400 Subject: [PATCH 4/6] Reset install speed baseline on state changes Add a reusable speed-calculator reset helper in `ProgressBase` and use it in plugin install progress updates to avoid bogus speed deltas after state transitions. The wrapper now resets its download baseline when install state changes, computes per-tick bytes only from monotonic progress, and clears speed/time-left values appropriately. It also ensures completed installs report zero time left and clamp per-file progress to 100%. --- .../Classes/Interfaces/Class/ProgressBase.cs | 7 ++++ .../Plugins/PluginGameInstallWrapper.cs | 37 +++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/CollapseLauncher/Classes/Interfaces/Class/ProgressBase.cs b/CollapseLauncher/Classes/Interfaces/Class/ProgressBase.cs index f344db39f..17134e599 100644 --- a/CollapseLauncher/Classes/Interfaces/Class/ProgressBase.cs +++ b/CollapseLauncher/Classes/Interfaces/Class/ProgressBase.cs @@ -467,6 +467,13 @@ protected virtual void UpdateProgressCopyStream(long currentPosition, int read, protected double CalculateSpeed(long receivedBytes) => CalculateSpeed(receivedBytes, ref _scLastSpeed, ref _scLastReceivedBytes, ref _scLastTick); + protected void ResetSpeedCalculator() + { + Interlocked.Exchange(ref _scLastReceivedBytes, 0); + Interlocked.Exchange(ref _scLastTick, Environment.TickCount64); + _scLastSpeed = 0; + } + protected static double CalculateSpeed(long receivedBytes, ref double lastSpeedToUse, ref long lastReceivedBytesToUse, ref long lastTickToUse) { long currentTick = Environment.TickCount64 - lastTickToUse + 1; diff --git a/CollapseLauncher/Classes/Plugins/PluginGameInstallWrapper.cs b/CollapseLauncher/Classes/Plugins/PluginGameInstallWrapper.cs index 4d59a69b6..0d043a837 100644 --- a/CollapseLauncher/Classes/Plugins/PluginGameInstallWrapper.cs +++ b/CollapseLauncher/Classes/Plugins/PluginGameInstallWrapper.cs @@ -73,6 +73,7 @@ public override string GamePath private InstallProgressState _currentInstallState = InstallProgressState.Idle; private string _lastActivityStatus = string.Empty; private float _lastLoggedPercentage = -1f; + private bool _resetSpeedBaseline = true; private PerFileProgressCallbackNative? _perFileProgressDelegate; private GCHandle _perFileProgressGcHandle; @@ -558,7 +559,18 @@ private void UpdateProgressCallback(in InstallProgress delegateProgress) long downloadedBytes = delegateProgress.DownloadedBytes; long downloadedBytesTotal = delegateProgress.TotalBytesToDownload; - long readDownload = delegateProgress.DownloadedBytes - _updateProgressProperty.LastDownloaded; + long readDownload = 0; + if (_resetSpeedBaseline) + { + _resetSpeedBaseline = false; + _updateProgressProperty.LastDownloaded = downloadedBytes; + } + else if (downloadedBytes >= _updateProgressProperty.LastDownloaded) + { + readDownload = downloadedBytes - _updateProgressProperty.LastDownloaded; + _updateProgressProperty.LastDownloaded = downloadedBytes; + } + double currentSpeed = CalculateSpeed(readDownload); Progress.ProgressAllSizeCurrent = downloadedBytes; @@ -605,8 +617,6 @@ or InstallProgressState.Verify : 0; } - _updateProgressProperty.LastDownloaded = downloadedBytes; - PublishProgressUi(updateProgressBar: true); } } @@ -623,7 +633,26 @@ private void UpdateStatusCallback(InstallProgressState delegateState) { using (_updateStatusLock.EnterScope()) { - _currentInstallState = delegateState; + if (_currentInstallState != delegateState) + { + _currentInstallState = delegateState; + _resetSpeedBaseline = true; + ResetSpeedCalculator(); + Progress.ProgressAllSpeed = 0; + } + + if (delegateState == InstallProgressState.Completed) + { + Progress.ProgressAllTimeLeft = TimeSpan.Zero; + if (Progress.ProgressPerFileSizeTotal > 0) + { + Progress.ProgressPerFilePercentage = Math.Min(100d, + ConverterTool.ToPercentage( + Progress.ProgressPerFileSizeTotal, + Progress.ProgressPerFileSizeCurrent)); + } + } + ApplyActivityStatusFromProperty(); PublishProgressUi(updateProgressBar: true); } From ecee77930ca16603bb86cf7abe6d6dbece918bae Mon Sep 17 00:00:00 2001 From: CryoTechnic Date: Wed, 19 Aug 2026 16:46:00 -0400 Subject: [PATCH 5/6] Bump submodules --- CollapseLauncher/packages.lock.json | 10 +++++----- ColorThief | 2 +- H.NotifyIcon | 2 +- Hi3Helper.Core/Hi3Helper.Core.csproj | 2 +- Hi3Helper.Core/packages.lock.json | 6 +++--- Hi3Helper.EncTool | 2 +- Hi3Helper.Http | 2 +- Hi3Helper.Plugin.Core | 2 +- Hi3Helper.SharpDiscordRPC | 2 +- Hi3Helper.Sophon | 2 +- Hi3Helper.TaskScheduler/packages.lock.json | 14 ++++++++++++++ Hi3Helper.Win32 | 2 +- ImageEx | 2 +- SevenZipExtractor | 2 +- 14 files changed, 33 insertions(+), 19 deletions(-) diff --git a/CollapseLauncher/packages.lock.json b/CollapseLauncher/packages.lock.json index 3c108b17a..0f957bdef 100644 --- a/CollapseLauncher/packages.lock.json +++ b/CollapseLauncher/packages.lock.json @@ -456,8 +456,8 @@ }, "Sentry": { "type": "Transitive", - "resolved": "6.8.0", - "contentHash": "amUjwslDtdx1p8r6z4APCxM8vHCKG4CBamPpSTwxmTMoBQ2CLwx2m3CaIttJXRT/hw9S5rNfXgjol2OqADytLQ==" + "resolved": "6.9.0", + "contentHash": "qQIvEwuvjAB6fDLVLLcDj/5f8n5jOyPyHjj3a/GQ1ogTLLQqsSxgQj1fEEquNT9HQuj4ZTyCg3c1DCBMUIvJGQ==" }, "SharpHDiffPatch.Core": { "type": "Transitive", @@ -494,7 +494,7 @@ "colorthief": { "type": "Project", "dependencies": { - "System.Drawing.Common": "[10.0.10, )" + "System.Drawing.Common": "[10.0.11, )" } }, "discordrpc": { @@ -529,7 +529,7 @@ "Hi3Helper.EncTool": "[1.0.0, )", "Hi3Helper.Win32": "[1.0.0, )", "Microsoft.Windows.CsWinRT": "[2.3.1, )", - "Sentry": "[6.8.0, )" + "Sentry": "[6.9.0, )" } }, "hi3helper.enctool": { @@ -554,7 +554,7 @@ "hi3helper.plugin.core": { "type": "Project", "dependencies": { - "Microsoft.Extensions.Logging.Abstractions": "[10.0.11, )" + "Microsoft.Extensions.Logging.Abstractions": "[10.0.10, )" } }, "hi3helper.simpleziparchivereader": { diff --git a/ColorThief b/ColorThief index 1146cb157..b568f2973 160000 --- a/ColorThief +++ b/ColorThief @@ -1 +1 @@ -Subproject commit 1146cb157182d2bd821f6494efc317b98534cb36 +Subproject commit b568f2973aa050c4a5665362da665c71945da2bb diff --git a/H.NotifyIcon b/H.NotifyIcon index 64c54ae95..fe2c3647a 160000 --- a/H.NotifyIcon +++ b/H.NotifyIcon @@ -1 +1 @@ -Subproject commit 64c54ae95aeae6925c8a8c2b6416a60dbabd180e +Subproject commit fe2c3647a3de1d2534ff3cf4c9ccfd6401543f10 diff --git a/Hi3Helper.Core/Hi3Helper.Core.csproj b/Hi3Helper.Core/Hi3Helper.Core.csproj index ce07c81b0..f2285a8bf 100644 --- a/Hi3Helper.Core/Hi3Helper.Core.csproj +++ b/Hi3Helper.Core/Hi3Helper.Core.csproj @@ -45,7 +45,7 @@ - + diff --git a/Hi3Helper.Core/packages.lock.json b/Hi3Helper.Core/packages.lock.json index a618be123..1e60b5fad 100644 --- a/Hi3Helper.Core/packages.lock.json +++ b/Hi3Helper.Core/packages.lock.json @@ -16,9 +16,9 @@ }, "Sentry": { "type": "Direct", - "requested": "[6.8.0, )", - "resolved": "6.8.0", - "contentHash": "amUjwslDtdx1p8r6z4APCxM8vHCKG4CBamPpSTwxmTMoBQ2CLwx2m3CaIttJXRT/hw9S5rNfXgjol2OqADytLQ==" + "requested": "[6.9.0, )", + "resolved": "6.9.0", + "contentHash": "qQIvEwuvjAB6fDLVLLcDj/5f8n5jOyPyHjj3a/GQ1ogTLLQqsSxgQj1fEEquNT9HQuj4ZTyCg3c1DCBMUIvJGQ==" }, "Google.Protobuf": { "type": "Transitive", diff --git a/Hi3Helper.EncTool b/Hi3Helper.EncTool index 2fbbc4b3b..52c06228d 160000 --- a/Hi3Helper.EncTool +++ b/Hi3Helper.EncTool @@ -1 +1 @@ -Subproject commit 2fbbc4b3b42ed98b9d0bea1d5d1bc1c7f28d7469 +Subproject commit 52c06228df34ddae82dcc9f4173c518cca0973dd diff --git a/Hi3Helper.Http b/Hi3Helper.Http index 8cb746cb3..2d4c209d4 160000 --- a/Hi3Helper.Http +++ b/Hi3Helper.Http @@ -1 +1 @@ -Subproject commit 8cb746cb32bf391df06189fbb961091722420368 +Subproject commit 2d4c209d4d462ee94a5e6a13e3c45abcfbca848e diff --git a/Hi3Helper.Plugin.Core b/Hi3Helper.Plugin.Core index 3613d20b4..cff6f3a4d 160000 --- a/Hi3Helper.Plugin.Core +++ b/Hi3Helper.Plugin.Core @@ -1 +1 @@ -Subproject commit 3613d20b405626e694f78793ac0d5f1626a37ff1 +Subproject commit cff6f3a4d303cc11907295ad51053bbc1c659a74 diff --git a/Hi3Helper.SharpDiscordRPC b/Hi3Helper.SharpDiscordRPC index 0a8cf69ec..e80e57c3e 160000 --- a/Hi3Helper.SharpDiscordRPC +++ b/Hi3Helper.SharpDiscordRPC @@ -1 +1 @@ -Subproject commit 0a8cf69ec4996ea985848c011e362203cac92b44 +Subproject commit e80e57c3e758bc7a28f9c69fb266019e977d1a1a diff --git a/Hi3Helper.Sophon b/Hi3Helper.Sophon index 6fbbcdf74..2c0868e34 160000 --- a/Hi3Helper.Sophon +++ b/Hi3Helper.Sophon @@ -1 +1 @@ -Subproject commit 6fbbcdf74fa59348f7a316d4b1d1f344a5a411bc +Subproject commit 2c0868e34d2fd8d11099eb83e88e0476d28bf871 diff --git a/Hi3Helper.TaskScheduler/packages.lock.json b/Hi3Helper.TaskScheduler/packages.lock.json index dd14c88fc..24f3fdee7 100644 --- a/Hi3Helper.TaskScheduler/packages.lock.json +++ b/Hi3Helper.TaskScheduler/packages.lock.json @@ -17,6 +17,15 @@ "resolved": "6.9.3", "contentHash": "1CUGgFdyECDKgi5HaUBhdv6k+VG9Iy4OCforGfHyar3xQXAJypZkzymgKtWj/4SPd6nSG0Qi7NH71qHrDSZLaA==" }, + "Microsoft.NETFramework.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", + "dependencies": { + "Microsoft.NETFramework.ReferenceAssemblies.net462": "1.0.3" + } + }, "System.Net.Http": { "type": "Direct", "requested": "[4.3.4, )", @@ -38,6 +47,11 @@ "resolved": "2.12.2", "contentHash": "glpAb3VrwfdAofp6PIyAzL0ZeTV7XUJ8muu0oZoTeyU5jtk2sMJ6QAMRRuFbovcaj+SBJiEUGklxIWOqQoxshA==" }, + "Microsoft.NETFramework.ReferenceAssemblies.net462": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "IzAV30z22ESCeQfxP29oVf4qEo8fBGXLXSU6oacv/9Iqe6PzgHDKCaWfwMBak7bSJQM0F5boXWoZS+kChztRIQ==" + }, "System.Security.Cryptography.Algorithms": { "type": "Transitive", "resolved": "4.3.0", diff --git a/Hi3Helper.Win32 b/Hi3Helper.Win32 index 10be369e1..9478014fd 160000 --- a/Hi3Helper.Win32 +++ b/Hi3Helper.Win32 @@ -1 +1 @@ -Subproject commit 10be369e176e0127a886d89d3a6edb491911da31 +Subproject commit 9478014fdce9a1b42f38e17145fb8c8d173190fc diff --git a/ImageEx b/ImageEx index c0eb31a4a..d599a35cc 160000 --- a/ImageEx +++ b/ImageEx @@ -1 +1 @@ -Subproject commit c0eb31a4aa726d0cb4598d1ee9a55b4823e8b11f +Subproject commit d599a35cc1f9362f4ca0c2e346620301a7fe4cea diff --git a/SevenZipExtractor b/SevenZipExtractor index 8c4399bb3..5e0f4de32 160000 --- a/SevenZipExtractor +++ b/SevenZipExtractor @@ -1 +1 @@ -Subproject commit 8c4399bb372c14898847a6cf08cc495acfc67a34 +Subproject commit 5e0f4de32a5da3ae441fdd5c95d3951ef703480e From 792fc882ffb710d13324c59058d9521c3edce303 Mon Sep 17 00:00:00 2001 From: CryoTechnic Date: Wed, 19 Aug 2026 18:29:16 -0400 Subject: [PATCH 6/6] Fix opacity causing elements not to render correctly --- .../Pages/GameSettingsPages/PluginGameSettingsPage.cs | 9 ++++++++- .../Pages/GameSettingsPages/PluginGameSettingsPage.xaml | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 CollapseLauncher/XAMLs/MainApp/Pages/GameSettingsPages/PluginGameSettingsPage.xaml diff --git a/CollapseLauncher/XAMLs/MainApp/Pages/GameSettingsPages/PluginGameSettingsPage.cs b/CollapseLauncher/XAMLs/MainApp/Pages/GameSettingsPages/PluginGameSettingsPage.cs index 31d9f03a3..8778c0e9c 100644 --- a/CollapseLauncher/XAMLs/MainApp/Pages/GameSettingsPages/PluginGameSettingsPage.cs +++ b/CollapseLauncher/XAMLs/MainApp/Pages/GameSettingsPages/PluginGameSettingsPage.cs @@ -1,5 +1,6 @@ using CollapseLauncher.Plugins; using CollapseLauncher.Helper; +using CollapseLauncher.GameManagement.ImageBackground; using Hi3Helper.Plugin.Core.UI.Settings; using Hi3Helper.Plugin.Core.Utility; using Microsoft.UI; @@ -16,7 +17,7 @@ namespace CollapseLauncher.Pages; /// /// Renders the declarative game settings page exposed by a v0.1.6 plugin. /// -public sealed class PluginGameSettingsPage : Page +public sealed partial class PluginGameSettingsPage : Page { private readonly GameSettingsExtension.GameSettingsContext _context; private readonly TextBlock _statusText = new() @@ -28,6 +29,12 @@ public sealed class PluginGameSettingsPage : Page public PluginGameSettingsPage() { + InitializeComponent(); + + ImageBackgroundManager.Shared.IsBackgroundElevated = true; + ImageBackgroundManager.Shared.ForegroundOpacity = 0d; + ImageBackgroundManager.Shared.SmokeOpacity = 1d; + NavigationCacheMode = Microsoft.UI.Xaml.Navigation.NavigationCacheMode.Disabled; if (GetCurrentGameProperty().GameVersion.GamePreset is not PluginPresetConfigWrapper preset) diff --git a/CollapseLauncher/XAMLs/MainApp/Pages/GameSettingsPages/PluginGameSettingsPage.xaml b/CollapseLauncher/XAMLs/MainApp/Pages/GameSettingsPages/PluginGameSettingsPage.xaml new file mode 100644 index 000000000..9b59cc711 --- /dev/null +++ b/CollapseLauncher/XAMLs/MainApp/Pages/GameSettingsPages/PluginGameSettingsPage.xaml @@ -0,0 +1,5 @@ + +