From bfd7cd0dac245c489e901994a2aaf77c85dbbb89 Mon Sep 17 00:00:00 2001
From: TheBestAstroNOT <139786546+TheBestAstroNOT@users.noreply.github.com>
Date: Fri, 8 Aug 2025 00:22:06 +0530
Subject: [PATCH 01/15] Save included and excluded regex to modconfig for
publishing
---
.../Dialog/PublishModDialogViewModel.cs | 46 ++++++++++---------
.../Config/ModConfig.cs | 5 ++
2 files changed, 29 insertions(+), 22 deletions(-)
diff --git a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
index 5373ada0..13704104 100644
--- a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
+++ b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
@@ -100,23 +100,17 @@ public class PublishModDialogViewModel : ObservableObject
///
public PublishModDialogViewModel(PathTuple modTuple)
{
- _modTuple = modTuple;
- PackageName = IOEx.ForceValidFilePath(_modTuple.Config.ModName.Replace(' ', '_'));
- OutputFolder = Path.Combine(Path.GetTempPath(), $"{IOEx.ForceValidFilePath(_modTuple.Config.ModId)}.Publish");
-
- // Set default Regexes.
- IgnoreRegexes = new ObservableCollection()
+ _modTuple = modTuple;
+ if (!_modTuple.Config.IgnoreRegexes.Contains($"{Regex.Escape($@"{_modTuple.Config.ModId}.nuspec")}"))
{
- @".*\.json", // Config files
- $"{Regex.Escape($@"{_modTuple.Config.ModId}.nuspec")}"
- };
-
- IncludeRegexes = new ObservableCollection()
+ _modTuple.Config.IgnoreRegexes.Add($"{Regex.Escape($@"{_modTuple.Config.ModId}.nuspec")}");
+ }
+ if (!_modTuple.Config.IncludeRegexes.Contains(Regex.Escape(ModConfig.ConfigFileName)))
{
- Regex.Escape(ModConfig.ConfigFileName),
- @"\.deps\.json",
- @"\.runtimeconfig\.json",
- };
+ _modTuple.Config.IncludeRegexes.Add(Regex.Escape(ModConfig.ConfigFileName));
+ }
+ PackageName = IOEx.ForceValidFilePath(_modTuple.Config.ModName.Replace(' ', '_'));
+ OutputFolder = Path.Combine(Path.GetTempPath(), $"{IOEx.ForceValidFilePath(_modTuple.Config.ModId)}.Publish");
// Set notifications
PropertyChanged += ChangeUiVisbilityOnPropertyChanged;
@@ -148,8 +142,8 @@ await PublishAsync(new PublishArgs()
PublishTarget = PublishTarget,
OutputFolder = OutputFolder,
ModTuple = _modTuple,
- IgnoreRegexes = IgnoreRegexes.Select(x => x.Value).ToList(),
- IncludeRegexes = IncludeRegexes.Select(x => x.Value).ToList(),
+ IgnoreRegexes = _modTuple.Config.IgnoreRegexes,
+ IncludeRegexes = _modTuple.Config.IncludeRegexes,
Progress = new Progress(d => BuildProgress = d * 100),
AutomaticDelta = AutomaticDelta,
CompressionLevel = CompressionLevel,
@@ -227,22 +221,22 @@ public void AddNewVersionFolder()
///
/// Removes the selected ignore regex.
///
- public void RemoveSelectedIgnoreRegex() => RemoveSelectedOrLastItem(SelectedIgnoreRegex, IgnoreRegexes);
+ public void RemoveSelectedIgnoreRegex() => RemoveSelectedOrLastItemRegex(_modTuple.Config.IgnoreRegexes);
///
/// Removes the selected include regex.
///
- public void RemoveSelectedIncludeRegex() => RemoveSelectedOrLastItem(SelectedIncludeRegex, IncludeRegexes);
+ public void RemoveSelectedIncludeRegex() => RemoveSelectedOrLastItemRegex(_modTuple.Config.IncludeRegexes);
///
/// Adds a regular expression for ignoring files.
///
- public void AddIgnoreRegex() => IgnoreRegexes.Add("New Ignore Regex");
+ public void AddIgnoreRegex() => _modTuple.Config.IgnoreRegexes.Add("New Ignore Regex");
///
/// Adds a regular expression for including files.
///
- public void AddIncludeRegex() => IncludeRegexes.Add("New Include Regex");
+ public void AddIncludeRegex() => _modTuple.Config.IncludeRegexes.Add("New Include Regex");
///
/// Calculates all files that will be removed from the final archive and displays them to the user.
@@ -296,7 +290,15 @@ private void RemoveSelectedOrLastItem(StringWrapper? item, ObservableCollection<
else if (allItems.Count > 0)
allItems.RemoveAt(allItems.Count - 1);
}
-
+
+ private void RemoveSelectedOrLastItemRegex(List allItems)
+ {
+ if (allItems.Count() > 0)
+ {
+ allItems.RemoveAt(allItems.Count - 1);
+ }
+ }
+
private void ChangeUiVisbilityOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(PublishTarget))
diff --git a/source/Reloaded.Mod.Loader.IO/Config/ModConfig.cs b/source/Reloaded.Mod.Loader.IO/Config/ModConfig.cs
index b63e36b7..f583de42 100644
--- a/source/Reloaded.Mod.Loader.IO/Config/ModConfig.cs
+++ b/source/Reloaded.Mod.Loader.IO/Config/ModConfig.cs
@@ -1,4 +1,5 @@
using Reloaded.Memory.Extensions;
+using System.Text.RegularExpressions;
namespace Reloaded.Mod.Loader.IO.Config;
@@ -36,6 +37,10 @@ public class ModConfig : ObservableObject, IConfig, IModConfig
public bool IsLibrary { get; set; } = false;
public string ReleaseMetadataFileName { get; set; } = "Sewer56.Update.ReleaseMetadata.json";
+ /// Publishing
+ public List IgnoreRegexes { get; set; } = [@".*\.json"];
+ public List IncludeRegexes { get; set; } = [@"\.deps\.json", @"\.runtimeconfig\.json"];
+
[JsonIgnore]
public string ModSubDirs { get; set; } = string.Empty;
From 49b3e1e66b744fdef659d47501abf3c9d11fc727 Mon Sep 17 00:00:00 2001
From: TheBestAstroNOT <139786546+TheBestAstroNOT@users.noreply.github.com>
Date: Fri, 8 Aug 2025 12:40:37 +0530
Subject: [PATCH 02/15] Persist ignore/include regexes across sessions
---
.../Dialog/PublishModDialogViewModel.cs | 46 +++++++++++--------
1 file changed, 28 insertions(+), 18 deletions(-)
diff --git a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
index 13704104..1c99c4fb 100644
--- a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
+++ b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
@@ -100,7 +100,9 @@ public class PublishModDialogViewModel : ObservableObject
///
public PublishModDialogViewModel(PathTuple modTuple)
{
- _modTuple = modTuple;
+ _modTuple = modTuple;
+ PackageName = IOEx.ForceValidFilePath(_modTuple.Config.ModName.Replace(' ', '_'));
+ OutputFolder = Path.Combine(Path.GetTempPath(), $"{IOEx.ForceValidFilePath(_modTuple.Config.ModId)}.Publish");
if (!_modTuple.Config.IgnoreRegexes.Contains($"{Regex.Escape($@"{_modTuple.Config.ModId}.nuspec")}"))
{
_modTuple.Config.IgnoreRegexes.Add($"{Regex.Escape($@"{_modTuple.Config.ModId}.nuspec")}");
@@ -109,11 +111,27 @@ public PublishModDialogViewModel(PathTuple modTuple)
{
_modTuple.Config.IncludeRegexes.Add(Regex.Escape(ModConfig.ConfigFileName));
}
- PackageName = IOEx.ForceValidFilePath(_modTuple.Config.ModName.Replace(' ', '_'));
- OutputFolder = Path.Combine(Path.GetTempPath(), $"{IOEx.ForceValidFilePath(_modTuple.Config.ModId)}.Publish");
+ IgnoreRegexes = new ObservableCollection(
+ _modTuple.Config.IgnoreRegexes.Select(x => new StringWrapper { Value = x })
+ );
+ IgnoreRegexes.CollectionChanged += (s, e) =>
+ {
+ _modTuple.Config.IgnoreRegexes.Clear();
+ _modTuple.Config.IgnoreRegexes.AddRange(IgnoreRegexes.Select(x => x.Value));
+ _modTuple.Save();
+ };
+
+ // IncludeRegexes
+ IncludeRegexes = new ObservableCollection(
+ _modTuple.Config.IncludeRegexes.Select(x => new StringWrapper { Value = x })
+ );
+ IncludeRegexes.CollectionChanged += (s, e) =>
+ {
+ _modTuple.Config.IncludeRegexes.Clear();
+ _modTuple.Config.IncludeRegexes.AddRange(IncludeRegexes.Select(x => x.Value));
+ _modTuple.Save();
+ };
- // Set notifications
- PropertyChanged += ChangeUiVisbilityOnPropertyChanged;
}
///
@@ -221,22 +239,22 @@ public void AddNewVersionFolder()
///
/// Removes the selected ignore regex.
///
- public void RemoveSelectedIgnoreRegex() => RemoveSelectedOrLastItemRegex(_modTuple.Config.IgnoreRegexes);
+ public void RemoveSelectedIgnoreRegex() => RemoveSelectedOrLastItem(SelectedIgnoreRegex, IgnoreRegexes);
///
/// Removes the selected include regex.
///
- public void RemoveSelectedIncludeRegex() => RemoveSelectedOrLastItemRegex(_modTuple.Config.IncludeRegexes);
+ public void RemoveSelectedIncludeRegex() => RemoveSelectedOrLastItem(SelectedIncludeRegex, IncludeRegexes);
///
/// Adds a regular expression for ignoring files.
///
- public void AddIgnoreRegex() => _modTuple.Config.IgnoreRegexes.Add("New Ignore Regex");
+ public void AddIgnoreRegex() => IgnoreRegexes.Add("New Ignore Regex");
///
/// Adds a regular expression for including files.
///
- public void AddIncludeRegex() => _modTuple.Config.IncludeRegexes.Add("New Include Regex");
+ public void AddIncludeRegex() => IncludeRegexes.Add("New Include Regex");
///
/// Calculates all files that will be removed from the final archive and displays them to the user.
@@ -290,15 +308,7 @@ private void RemoveSelectedOrLastItem(StringWrapper? item, ObservableCollection<
else if (allItems.Count > 0)
allItems.RemoveAt(allItems.Count - 1);
}
-
- private void RemoveSelectedOrLastItemRegex(List allItems)
- {
- if (allItems.Count() > 0)
- {
- allItems.RemoveAt(allItems.Count - 1);
- }
- }
-
+
private void ChangeUiVisbilityOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(PublishTarget))
From 0cf29386872cd6386fa2318c97fc3c149861dbd2 Mon Sep 17 00:00:00 2001
From: TheBestAstroNOT <139786546+TheBestAstroNOT@users.noreply.github.com>
Date: Fri, 8 Aug 2025 12:46:17 +0530
Subject: [PATCH 03/15] Remove old comment
---
.../Models/ViewModel/Dialog/PublishModDialogViewModel.cs | 2 --
1 file changed, 2 deletions(-)
diff --git a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
index 1c99c4fb..5824407a 100644
--- a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
+++ b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
@@ -120,8 +120,6 @@ public PublishModDialogViewModel(PathTuple modTuple)
_modTuple.Config.IgnoreRegexes.AddRange(IgnoreRegexes.Select(x => x.Value));
_modTuple.Save();
};
-
- // IncludeRegexes
IncludeRegexes = new ObservableCollection(
_modTuple.Config.IncludeRegexes.Select(x => new StringWrapper { Value = x })
);
From bdff39682268b15ac7654de6419613b4c15f6558 Mon Sep 17 00:00:00 2001
From: TheBestAstroNOT <139786546+TheBestAstroNOT@users.noreply.github.com>
Date: Fri, 8 Aug 2025 16:16:00 +0530
Subject: [PATCH 04/15] Update PublishModDialogViewModel.cs
---
.../Models/ViewModel/Dialog/PublishModDialogViewModel.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
index 5824407a..85d28b3c 100644
--- a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
+++ b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
@@ -118,7 +118,7 @@ public PublishModDialogViewModel(PathTuple modTuple)
{
_modTuple.Config.IgnoreRegexes.Clear();
_modTuple.Config.IgnoreRegexes.AddRange(IgnoreRegexes.Select(x => x.Value));
- _modTuple.Save();
+ _modTuple.SaveAsync();
};
IncludeRegexes = new ObservableCollection(
_modTuple.Config.IncludeRegexes.Select(x => new StringWrapper { Value = x })
@@ -127,7 +127,7 @@ public PublishModDialogViewModel(PathTuple modTuple)
{
_modTuple.Config.IncludeRegexes.Clear();
_modTuple.Config.IncludeRegexes.AddRange(IncludeRegexes.Select(x => x.Value));
- _modTuple.Save();
+ _modTuple.SaveAsync();
};
}
From f70880fa90fedaf85de52dc032a712d33348dd2c Mon Sep 17 00:00:00 2001
From: TheBestAstroNOT <139786546+TheBestAstroNOT@users.noreply.github.com>
Date: Sun, 10 Aug 2025 00:47:59 +0530
Subject: [PATCH 05/15] Added a progress bar for mod installation (large mods
only), made CopyPackagesFromExtractFolderToTargetDir async to stop UI freezes
for larger mods.
---
source/Reloaded.Mod.Launcher.Lib/Lib.cs | 3 +-
.../Dialog/InstallPackageViewModel.cs | 51 +++++++++++++++++++
.../Static/Actions.cs | 9 ++++
.../Assets/Languages/en-GB.xaml | 4 ++
.../Reloaded.Mod.Launcher/LibraryBindings.cs | 2 +
.../Reloaded.Mod.Launcher/MainWindow.xaml.cs | 38 ++++++++++++--
.../Pages/Dialogs/InstallPackageDialog.xaml | 44 ++++++++++++++++
.../Dialogs/InstallPackageDialog.xaml.cs | 25 +++++++++
.../Update/UpdateDownloadablePackage.cs | 2 +-
.../Providers/Web/WebDownloadablePackage.cs | 4 +-
10 files changed, 175 insertions(+), 7 deletions(-)
create mode 100644 source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/InstallPackageViewModel.cs
create mode 100644 source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml
create mode 100644 source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml.cs
diff --git a/source/Reloaded.Mod.Launcher.Lib/Lib.cs b/source/Reloaded.Mod.Launcher.Lib/Lib.cs
index cd6255df..2194ed2e 100644
--- a/source/Reloaded.Mod.Launcher.Lib/Lib.cs
+++ b/source/Reloaded.Mod.Launcher.Lib/Lib.cs
@@ -62,7 +62,7 @@ public static void Init(IDictionaryResourceProvider provider, SynchronizationCon
Actions.ShowModLoaderUpdateDialogDelegate showModLoaderUpdate, Actions.ShowModUpdateDialogDelegate showModUpdate, Actions.ConfigureNuGetFeedsDialogDelegate configureNuGetFeeds,
Actions.ConfigureModDialogDelegate configureModDialog, Actions.ShowMissingCoreDependencyDialogDelegate showMissingCoreDependency,
Actions.EditModDialogDelegate editModDialog, Actions.PublishModDialogDelegate publishModDialog,
- Actions.ShowEditModUserConfigDialogDelegate showEditModUserConfig, Actions.ShowFetchPackageDialogDelegate showFetchPackageDialog,
+ Actions.ShowEditModUserConfigDialogDelegate showEditModUserConfig, Actions.ShowFetchPackageDialogDelegate showFetchPackageDialog, Actions.ShowInstallPackageDialogDelegate showInstallPackageDialog,
Actions.ShowSelectAddedGameDialogDelegate showSelectAddedGameDialog, Actions.ShowAddAppHashMismatchDialogDelegate showAddAppMismatchDialog,
Actions.ShowApplicationWarningDialogDelegate showApplicationWarningDialog, Actions.ShowRunAppViaWineDialogDelegate showRunAppViaWineDialog,
Actions.ShowEditPackDialogDelegate showEditPackDialog, Actions.ShowInstallModPackDialogDelegate showInstallModPackDialog, Action initControllerSupport)
@@ -85,6 +85,7 @@ public static void Init(IDictionaryResourceProvider provider, SynchronizationCon
Actions.PublishModDialog = publishModDialog;
Actions.ShowEditModUserConfig = showEditModUserConfig;
Actions.ShowFetchPackageDialog = showFetchPackageDialog;
+ Actions.ShowInstallPackageDialog = showInstallPackageDialog;
Actions.ShowSelectAddedGameDialog = showSelectAddedGameDialog;
Actions.ShowAddAppHashMismatchDialog = showAddAppMismatchDialog;
Actions.ShowApplicationWarningDialog = showApplicationWarningDialog;
diff --git a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/InstallPackageViewModel.cs b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/InstallPackageViewModel.cs
new file mode 100644
index 00000000..3375f2b1
--- /dev/null
+++ b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/InstallPackageViewModel.cs
@@ -0,0 +1,51 @@
+namespace Reloaded.Mod.Launcher.Lib.Models.ViewModel.Dialog;
+
+///
+/// ViewModel for downloading an individual package.
+///
+public class InstallPackageViewModel : INotifyPropertyChanged
+{
+ private string _text;
+ public string Text
+ {
+ get => _text;
+ set
+ {
+ if (_text != value)
+ {
+ _text = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Text)));
+ }
+ }
+ }
+
+ private double _progress;
+ public double Progress
+ {
+ get => _progress;
+ set
+ {
+ if (_progress != value)
+ {
+ _progress = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Progress)));
+ }
+ }
+ }
+
+ private bool _isComplete;
+ public bool IsComplete
+ {
+ get => _isComplete;
+ set
+ {
+ if (_isComplete != value)
+ {
+ _isComplete = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsComplete)));
+ }
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+}
\ No newline at end of file
diff --git a/source/Reloaded.Mod.Launcher.Lib/Static/Actions.cs b/source/Reloaded.Mod.Launcher.Lib/Static/Actions.cs
index ca952f98..af850eb0 100644
--- a/source/Reloaded.Mod.Launcher.Lib/Static/Actions.cs
+++ b/source/Reloaded.Mod.Launcher.Lib/Static/Actions.cs
@@ -77,6 +77,9 @@ public static class Actions
///
public static ShowFetchPackageDialogDelegate ShowFetchPackageDialog { get; set; } = null!;
+ public static ShowInstallPackageDialogDelegate ShowInstallPackageDialog { get; set; } = null!;
+
+
///
/// Shows a dialog that can be used to select the added game.
///
@@ -254,6 +257,12 @@ public enum MessageBoxType
/// The ViewModel used for downloading the individual package.
public delegate bool ShowFetchPackageDialogDelegate(DownloadPackageViewModel viewModel);
+ ///
+ /// Shows a dialog that can be used to download an individual package.
+ ///
+ /// The ViewModel used for downloading the individual package.
+ public delegate bool ShowInstallPackageDialogDelegate(InstallPackageViewModel viewModel);
+
///
/// Shows a dialog that can be used to select the added game.
///
diff --git a/source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml b/source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml
index bdce0f65..9028169c 100644
--- a/source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml
+++ b/source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml
@@ -197,6 +197,10 @@
Download Mod Archive
File Name
+
+
+ Installing Mod Archive
+ Mod Name
You need to run this application as administrator.
Administrative privileges are needed to receive application launch/exit events from Windows Management Instrumentation (WMI).
Developers: Run your favourite IDE e.g. Visual Studio as Admin.
diff --git a/source/Reloaded.Mod.Launcher/LibraryBindings.cs b/source/Reloaded.Mod.Launcher/LibraryBindings.cs
index 2b623ef9..638db1b4 100644
--- a/source/Reloaded.Mod.Launcher/LibraryBindings.cs
+++ b/source/Reloaded.Mod.Launcher/LibraryBindings.cs
@@ -27,6 +27,7 @@ public static void Init(IResourceFileSelector? languageSelector, IResourceFileSe
publishModDialog: PublishModDialog,
showEditModUserConfig: ShowEditModUserConfig,
showFetchPackageDialog: ShowFetchPackageDialog,
+ showInstallPackageDialog: ShowInstallPackageDialog,
showSelectAddedGameDialog: ShowSelectAddedGameDialog,
showAddAppMismatchDialog: ShowAddAppMismatchDialog,
showApplicationWarningDialog: ShowApplicationWarningDialog,
@@ -106,6 +107,7 @@ private static bool EditModDialog(EditModDialogViewModel viewmodel, object? owne
private static bool ShowEditModUserConfig(EditModUserConfigDialogViewModel viewmodel) => ShowDialogAndGetResult(new EditModUserConfigDialog(viewmodel));
private static bool PublishModDialog(PublishModDialogViewModel viewmodel) => ShowDialogAndGetResult(new PublishModDialog(viewmodel));
private static bool ShowFetchPackageDialog(DownloadPackageViewModel viewmodel) => ShowDialogAndGetResult(new DownloadPackageDialog(viewmodel));
+ private static bool ShowInstallPackageDialog(InstallPackageViewModel viewmodel) => ShowDialogAndGetResult(new InstallPackageDialog(viewmodel));
private static bool ShowAddAppMismatchDialog(AddAppHashMismatchDialogViewModel viewmodel) => ShowDialogAndGetResult(new AddAppHashMismatchDialog(viewmodel));
private static bool ShowApplicationWarningDialog(AddApplicationWarningDialogViewModel viewmodel) => ShowDialogAndGetResult(new ShowApplicationWarningDialog(viewmodel));
private static bool ShowInstallModPackDialog(InstallModPackDialogViewModel viewmodel) => ShowDialogAndGetResult(new InstallModPackDialog(viewmodel));
diff --git a/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs b/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs
index eb9c0816..4db3ed38 100644
--- a/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs
+++ b/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs
@@ -1,7 +1,9 @@
-using System.Text;
+using NuGet.Common;
using Reloaded.Mod.Loader.Update.Providers.Web;
using Sewer56.DeltaPatchGenerator.Lib.Utility;
using Sewer56.Update.Extractors.SevenZipSharp;
+using System.Text;
+using System.Windows.Threading;
using static Reloaded.Mod.Launcher.Lib.Static.Resources;
namespace Reloaded.Mod.Launcher;
@@ -88,10 +90,40 @@ private async void InstallMod_Drop(object sender, DragEventArgs e)
/* Extract to Temp Directory */
using var tempFolder = new TemporaryFolderAllocation();
var archiveExtractor = new SevenZipSharpExtractor();
- await archiveExtractor.ExtractPackageAsync(file, tempFolder.FolderPath, new Progress(), default);
+
+ var installVM = new InstallPackageViewModel
+ {
+ Text = "Extracting a local mod, please wait!",
+ Progress = 0
+ };
+
+ var progress = new Progress(value =>
+ {
+ installVM.Progress = value * 100;
+ });
+
+ var timer = new DispatcherTimer
+ {
+ Interval = TimeSpan.FromSeconds(3)
+ };
+
+ timer.Tick += (s, e) =>
+ {
+ timer.Stop();
+ if (installVM.Progress != 100)
+ {
+ Actions.ShowInstallPackageDialog.Invoke(installVM);
+ }
+ };
+
+ timer.Start();
+
+ await archiveExtractor.ExtractPackageAsync(file, tempFolder.FolderPath, progress, default);
/* Get name of package. */
- WebDownloadablePackage.CopyPackagesFromExtractFolderToTargetDir(modsFolder!, tempFolder.FolderPath, default);
+ installVM.Text = "Please wait while we install the mod!";
+ await WebDownloadablePackage.CopyPackagesFromExtractFolderToTargetDir(modsFolder!, tempFolder.FolderPath, default);
+ installVM.IsComplete = true;
}
// Find the new mods
diff --git a/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml b/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml
new file mode 100644
index 00000000..7e4a2b3d
--- /dev/null
+++ b/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml.cs b/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml.cs
new file mode 100644
index 00000000..232b745f
--- /dev/null
+++ b/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml.cs
@@ -0,0 +1,25 @@
+using Button = System.Windows.Controls.Button;
+
+namespace Reloaded.Mod.Launcher.Pages.Dialogs;
+
+///
+/// Interaction logic for DownloadPackageDialog.xaml
+///
+public partial class InstallPackageDialog : ReloadedWindow
+{
+ public new InstallPackageViewModel ViewModel { get; set; }
+
+ ///
+ public InstallPackageDialog(InstallPackageViewModel viewModel)
+ {
+ InitializeComponent();
+ ViewModel = viewModel;
+ viewModel.PropertyChanged += (s, e) =>
+ {
+ if (e.PropertyName == nameof(InstallPackageViewModel.IsComplete) && viewModel.IsComplete)
+ {
+ ActionWrappers.ExecuteWithApplicationDispatcher(this.Close);
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/source/Reloaded.Mod.Loader.Update/Providers/Update/UpdateDownloadablePackage.cs b/source/Reloaded.Mod.Loader.Update/Providers/Update/UpdateDownloadablePackage.cs
index 17a743ea..e22b2013 100644
--- a/source/Reloaded.Mod.Loader.Update/Providers/Update/UpdateDownloadablePackage.cs
+++ b/source/Reloaded.Mod.Loader.Update/Providers/Update/UpdateDownloadablePackage.cs
@@ -116,7 +116,7 @@ await retryPolicy.ExecuteAsync(async () =>
await archiveExtractor.ExtractPackageAsync(tempDownloadPath, tempExtractDir.FolderPath, extractSlice, token);
// Copy all packages from download.
- return WebDownloadablePackage.CopyPackagesFromExtractFolderToTargetDir(packageFolder, tempExtractDir.FolderPath, token);
+ return await WebDownloadablePackage.CopyPackagesFromExtractFolderToTargetDir(packageFolder, tempExtractDir.FolderPath, token);
}
#pragma warning disable CS0067 // Event never used
diff --git a/source/Reloaded.Mod.Loader.Update/Providers/Web/WebDownloadablePackage.cs b/source/Reloaded.Mod.Loader.Update/Providers/Web/WebDownloadablePackage.cs
index 679ab373..d254934b 100644
--- a/source/Reloaded.Mod.Loader.Update/Providers/Web/WebDownloadablePackage.cs
+++ b/source/Reloaded.Mod.Loader.Update/Providers/Web/WebDownloadablePackage.cs
@@ -129,7 +129,7 @@ await retryPolicy.ExecuteAsync(async () =>
await archiveExtractor.ExtractPackageAsync(tempFilePath, tempExtractDirectory.FolderPath, extractProgress, token);
/* Get name of package. */
- return CopyPackagesFromExtractFolderToTargetDir(packageFolder, tempExtractDirectory.FolderPath, token);
+ return await CopyPackagesFromExtractFolderToTargetDir(packageFolder, tempExtractDirectory.FolderPath, token);
}
///
@@ -139,7 +139,7 @@ await retryPolicy.ExecuteAsync(async () =>
/// Finds all mods in and copies them to appropriate subfolders in .
///
/// Path to last folder copied.
- public static string CopyPackagesFromExtractFolderToTargetDir(string packageFolder, string tempExtractDir, CancellationToken token)
+ public async static Task CopyPackagesFromExtractFolderToTargetDir(string packageFolder, string tempExtractDir, CancellationToken token)
{
var configs = ConfigReader.ReadConfigurations(tempExtractDir, ModConfig.ConfigFileName, token, int.MaxValue, 0);
var returnResult = "";
From 0966c60cca812d72397b5217fe5d1262f1e8ceb5 Mon Sep 17 00:00:00 2001
From: TheBestAstroNOT <139786546+TheBestAstroNOT@users.noreply.github.com>
Date: Mon, 11 Aug 2025 12:50:45 +0530
Subject: [PATCH 06/15] Fixed bug where the config was not updated if the value
in the StringWrapper was modified
The config used to only be updated once an item was added or deleted.
---
.../Dialog/PublishModDialogViewModel.cs | 26 +++++++++++++++++++
.../Utilities/StringWrapper.cs | 14 +++++++++-
2 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
index 85d28b3c..69f226f7 100644
--- a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
+++ b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
@@ -106,16 +106,27 @@ public PublishModDialogViewModel(PathTuple modTuple)
if (!_modTuple.Config.IgnoreRegexes.Contains($"{Regex.Escape($@"{_modTuple.Config.ModId}.nuspec")}"))
{
_modTuple.Config.IgnoreRegexes.Add($"{Regex.Escape($@"{_modTuple.Config.ModId}.nuspec")}");
+ _modTuple.SaveAsync();
}
if (!_modTuple.Config.IncludeRegexes.Contains(Regex.Escape(ModConfig.ConfigFileName)))
{
_modTuple.Config.IncludeRegexes.Add(Regex.Escape(ModConfig.ConfigFileName));
+ _modTuple.SaveAsync();
}
IgnoreRegexes = new ObservableCollection(
_modTuple.Config.IgnoreRegexes.Select(x => new StringWrapper { Value = x })
);
+ foreach (StringWrapper item in IgnoreRegexes)
+ item.PropertyChanged += (_, __) => UpdateConfig(_modTuple.Config.IgnoreRegexes, IgnoreRegexes);
IgnoreRegexes.CollectionChanged += (s, e) =>
{
+ if (e.NewItems != null)
+ foreach (StringWrapper item in e.NewItems)
+ item.PropertyChanged += (_, __) => UpdateConfig(_modTuple.Config.IgnoreRegexes, IgnoreRegexes);
+
+ if (e.OldItems != null)
+ foreach (StringWrapper item in e.OldItems)
+ item.PropertyChanged -= (_, __) => UpdateConfig(_modTuple.Config.IgnoreRegexes, IgnoreRegexes);
_modTuple.Config.IgnoreRegexes.Clear();
_modTuple.Config.IgnoreRegexes.AddRange(IgnoreRegexes.Select(x => x.Value));
_modTuple.SaveAsync();
@@ -123,13 +134,28 @@ public PublishModDialogViewModel(PathTuple modTuple)
IncludeRegexes = new ObservableCollection(
_modTuple.Config.IncludeRegexes.Select(x => new StringWrapper { Value = x })
);
+ foreach (StringWrapper item in IncludeRegexes)
+ item.PropertyChanged += (_, __) => UpdateConfig(_modTuple.Config.IncludeRegexes, IncludeRegexes);
IncludeRegexes.CollectionChanged += (s, e) =>
{
+ if (e.NewItems != null)
+ foreach (StringWrapper item in e.NewItems)
+ item.PropertyChanged += (_, __) => UpdateConfig(_modTuple.Config.IncludeRegexes, IncludeRegexes);
+
+ if (e.OldItems != null)
+ foreach (StringWrapper item in e.OldItems)
+ item.PropertyChanged -= (_, __) => UpdateConfig(_modTuple.Config.IncludeRegexes, IncludeRegexes);
_modTuple.Config.IncludeRegexes.Clear();
_modTuple.Config.IncludeRegexes.AddRange(IncludeRegexes.Select(x => x.Value));
_modTuple.SaveAsync();
};
+ }
+ void UpdateConfig(List list, ObservableCollection collection)
+ {
+ list.Clear();
+ list.AddRange(collection.Select(x => x.Value));
+ _modTuple.SaveAsync();
}
///
diff --git a/source/Reloaded.Mod.Loader.Update/Utilities/StringWrapper.cs b/source/Reloaded.Mod.Loader.Update/Utilities/StringWrapper.cs
index 65689ee8..30b2c342 100644
--- a/source/Reloaded.Mod.Loader.Update/Utilities/StringWrapper.cs
+++ b/source/Reloaded.Mod.Loader.Update/Utilities/StringWrapper.cs
@@ -6,10 +6,22 @@ namespace Reloaded.Mod.Loader.Update.Utilities;
[JsonConverter(typeof(StringWrapperConverter))]
public class StringWrapper : ObservableObject
{
+ private string _value = "";
///
/// Value of the string wrapper.
///
- public string Value { get; set; } = "";
+ public string Value
+ {
+ get => _value;
+ set
+ {
+ if (_value != value)
+ {
+ _value = value;
+ RaisePropertyChangedEvent(nameof(Value));
+ }
+ }
+ }
///
public static implicit operator string(StringWrapper wrapper) => wrapper.Value;
From a00d75103aec6f8fe3c995c851c689073864f2e6 Mon Sep 17 00:00:00 2001
From: TheBestAstroNOT <139786546+TheBestAstroNOT@users.noreply.github.com>
Date: Mon, 29 Sep 2025 21:53:13 +0530
Subject: [PATCH 07/15] Make suggested changes
---
source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml | 4 +++-
source/Reloaded.Mod.Launcher/MainWindow.xaml.cs | 6 ++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml b/source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml
index 9028169c..7318188a 100644
--- a/source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml
+++ b/source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml
@@ -198,9 +198,11 @@
Download Mod Archive
File Name
-
+
Installing Mod Archive
Mod Name
+ Please wait while we install the mod!
+ Extracting a local mod, please wait!
You need to run this application as administrator.
Administrative privileges are needed to receive application launch/exit events from Windows Management Instrumentation (WMI).
Developers: Run your favourite IDE e.g. Visual Studio as Admin.
diff --git a/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs b/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs
index 4db3ed38..6b2c6e90 100644
--- a/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs
+++ b/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs
@@ -93,7 +93,7 @@ private async void InstallMod_Drop(object sender, DragEventArgs e)
var installVM = new InstallPackageViewModel
{
- Text = "Extracting a local mod, please wait!",
+ Text = (string)Application.Current.Resources["ExtractingLocalModArchive"],
Progress = 0
};
@@ -115,13 +115,11 @@ private async void InstallMod_Drop(object sender, DragEventArgs e)
Actions.ShowInstallPackageDialog.Invoke(installVM);
}
};
-
timer.Start();
await archiveExtractor.ExtractPackageAsync(file, tempFolder.FolderPath, progress, default);
- /* Get name of package. */
- installVM.Text = "Please wait while we install the mod!";
+ installVM.Text = (string)Application.Current.Resources["InstallingModWait"];
await WebDownloadablePackage.CopyPackagesFromExtractFolderToTargetDir(modsFolder!, tempFolder.FolderPath, default);
installVM.IsComplete = true;
}
From e8e5498a39d7a0485724e3f6f6c139a3251bcd7e Mon Sep 17 00:00:00 2001
From: TheBestAstroNOT <139786546+TheBestAstroNOT@users.noreply.github.com>
Date: Mon, 29 Sep 2025 22:05:11 +0530
Subject: [PATCH 08/15] Only add default regexes when creating the mod
Makes it so they don't come back everytime you open the publish window if you remove them (though I have no idea why anyone would remove these regexes)
---
.../Models/ViewModel/Dialog/CreateModViewModel.cs | 2 ++
.../ViewModel/Dialog/PublishModDialogViewModel.cs | 10 ----------
2 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/CreateModViewModel.cs b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/CreateModViewModel.cs
index 4ed5187d..2f239cdb 100644
--- a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/CreateModViewModel.cs
+++ b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/CreateModViewModel.cs
@@ -33,6 +33,8 @@ public CreateModViewModel(ModConfigService modConfigService)
ReleaseMetadataFileName = $"{ModId}.ReleaseMetadata.json"
};
+ config.IgnoreRegexes.Add($"{Regex.Escape($@"{config.ModId}.nuspec")}");
+ config.IncludeRegexes.Add(Regex.Escape(ModConfig.ConfigFileName));
var modDirectory = Path.Combine(IoC.Get().GetModConfigDirectory(), IOEx.ForceValidFilePath(ModId));
var filePath = Path.Combine(modDirectory, ModConfig.ConfigFileName);
await IConfig.ToPathAsync(config, filePath);
diff --git a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
index 69f226f7..ff1c8f60 100644
--- a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
+++ b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
@@ -103,16 +103,6 @@ public PublishModDialogViewModel(PathTuple modTuple)
_modTuple = modTuple;
PackageName = IOEx.ForceValidFilePath(_modTuple.Config.ModName.Replace(' ', '_'));
OutputFolder = Path.Combine(Path.GetTempPath(), $"{IOEx.ForceValidFilePath(_modTuple.Config.ModId)}.Publish");
- if (!_modTuple.Config.IgnoreRegexes.Contains($"{Regex.Escape($@"{_modTuple.Config.ModId}.nuspec")}"))
- {
- _modTuple.Config.IgnoreRegexes.Add($"{Regex.Escape($@"{_modTuple.Config.ModId}.nuspec")}");
- _modTuple.SaveAsync();
- }
- if (!_modTuple.Config.IncludeRegexes.Contains(Regex.Escape(ModConfig.ConfigFileName)))
- {
- _modTuple.Config.IncludeRegexes.Add(Regex.Escape(ModConfig.ConfigFileName));
- _modTuple.SaveAsync();
- }
IgnoreRegexes = new ObservableCollection(
_modTuple.Config.IgnoreRegexes.Select(x => new StringWrapper { Value = x })
);
From 1f7c0613e8a12e81e3b9d13951ee116a06afa1f5 Mon Sep 17 00:00:00 2001
From: TheBestAstroNOT <139786546+TheBestAstroNOT@users.noreply.github.com>
Date: Tue, 30 Sep 2025 22:20:28 +0530
Subject: [PATCH 09/15] Make suggested changes again
---
.../ViewModel/Dialog/InstallPackageViewModel.cs | 14 ++++++++++++++
.../Reloaded.Mod.Launcher.Lib/Static/Resources.cs | 8 +++++++-
source/Reloaded.Mod.Launcher/MainWindow.xaml.cs | 5 +++--
.../Pages/Dialogs/InstallPackageDialog.xaml | 2 +-
.../Pages/Dialogs/InstallPackageDialog.xaml.cs | 1 +
5 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/InstallPackageViewModel.cs b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/InstallPackageViewModel.cs
index 3375f2b1..cad23f70 100644
--- a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/InstallPackageViewModel.cs
+++ b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/InstallPackageViewModel.cs
@@ -19,6 +19,20 @@ public string Text
}
}
+ private string _title;
+ public string Title
+ {
+ get => _title;
+ set
+ {
+ if (_title != value)
+ {
+ _title = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Title)));
+ }
+ }
+ }
+
private double _progress;
public double Progress
{
diff --git a/source/Reloaded.Mod.Launcher.Lib/Static/Resources.cs b/source/Reloaded.Mod.Launcher.Lib/Static/Resources.cs
index 1b329244..00014d0b 100644
--- a/source/Reloaded.Mod.Launcher.Lib/Static/Resources.cs
+++ b/source/Reloaded.Mod.Launcher.Lib/Static/Resources.cs
@@ -181,7 +181,7 @@ public static void Init(IDictionaryResourceProvider provider)
// Update 1.21.0: Mod Packs Install
public static IDictionaryResource InstallModPackDownloading { get; set; }
public static IDictionaryResource InstallModPackErrorDownloadFail { get; set; }
-
+
// Update 1.21.6: Mod Packs Install
public static IDictionaryResource ErrorAddApplicationGeneral { get; set; }
public static IDictionaryResource ErrorAddApplicationCantReadSymlink { get; set; }
@@ -219,4 +219,10 @@ public static void Init(IDictionaryResourceProvider provider)
public static IDictionaryResource ErrorViewDetails { get; set; }
public static IDictionaryResource ErrorStacktraceTitle { get; set; }
public static IDictionaryResource ErrorStacktraceSubtitle { get; set; }
+
+ // Update 1.X.X: New Progress Window for Local Mod Installation (UPDATE LAUNCHER VER BEFORE RELEASE)
+ public static IDictionaryResource InstallModArchiveTitle { get; set; }
+ public static IDictionaryResource InstalledModName { get; set; }
+ public static IDictionaryResource InstallingModWait { get; set; }
+ public static IDictionaryResource ExtractingLocalModArchive { get; set; }
}
\ No newline at end of file
diff --git a/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs b/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs
index 6b2c6e90..ff29f00f 100644
--- a/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs
+++ b/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs
@@ -93,7 +93,8 @@ private async void InstallMod_Drop(object sender, DragEventArgs e)
var installVM = new InstallPackageViewModel
{
- Text = (string)Application.Current.Resources["ExtractingLocalModArchive"],
+ Title = InstallModArchiveTitle.Get(),
+ Text = ExtractingLocalModArchive.Get(),
Progress = 0
};
@@ -119,7 +120,7 @@ private async void InstallMod_Drop(object sender, DragEventArgs e)
await archiveExtractor.ExtractPackageAsync(file, tempFolder.FolderPath, progress, default);
- installVM.Text = (string)Application.Current.Resources["InstallingModWait"];
+ installVM.Text = InstallingModWait.Get();
await WebDownloadablePackage.CopyPackagesFromExtractFolderToTargetDir(modsFolder!, tempFolder.FolderPath, default);
installVM.IsComplete = true;
}
diff --git a/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml b/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml
index 7e4a2b3d..f9cb59b1 100644
--- a/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml
+++ b/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml
@@ -9,7 +9,7 @@
mc:Ignorable="d"
SizeToContent="Height"
Width="500"
- Title="{DynamicResource InstallModArchiveTitle}"
+ Title="{Binding Title}"
Style="{DynamicResource ReloadedWindow}">
diff --git a/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml.cs b/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml.cs
index 232b745f..3de571cb 100644
--- a/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml.cs
+++ b/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml.cs
@@ -14,6 +14,7 @@ public InstallPackageDialog(InstallPackageViewModel viewModel)
{
InitializeComponent();
ViewModel = viewModel;
+ DataContext = viewModel;
viewModel.PropertyChanged += (s, e) =>
{
if (e.PropertyName == nameof(InstallPackageViewModel.IsComplete) && viewModel.IsComplete)
From 626aceff2ccf6494ee41a593ac278dec4d138b5a Mon Sep 17 00:00:00 2001
From: TheBestAstroNOT <139786546+TheBestAstroNOT@users.noreply.github.com>
Date: Tue, 30 Sep 2025 22:43:53 +0530
Subject: [PATCH 10/15] Make suggested changes again again
Sorry for the bad commit names, it's a bit late for me rn
---
.../Dialog/InstallPackageViewModel.cs | 60 ++-----------------
.../Dialog/PublishModDialogViewModel.cs | 7 ++-
.../Reloaded.Mod.Launcher/MainWindow.xaml.cs | 1 +
.../Pages/Dialogs/PublishModDialog.xaml.cs | 5 +-
.../Utilities/StringWrapper.cs | 17 ++----
5 files changed, 19 insertions(+), 71 deletions(-)
diff --git a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/InstallPackageViewModel.cs b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/InstallPackageViewModel.cs
index cad23f70..dbc6bd12 100644
--- a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/InstallPackageViewModel.cs
+++ b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/InstallPackageViewModel.cs
@@ -3,63 +3,13 @@ namespace Reloaded.Mod.Launcher.Lib.Models.ViewModel.Dialog;
///
/// ViewModel for downloading an individual package.
///
+[AddINotifyPropertyChangedInterface]
public class InstallPackageViewModel : INotifyPropertyChanged
{
- private string _text;
- public string Text
- {
- get => _text;
- set
- {
- if (_text != value)
- {
- _text = value;
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Text)));
- }
- }
- }
-
- private string _title;
- public string Title
- {
- get => _title;
- set
- {
- if (_title != value)
- {
- _title = value;
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Title)));
- }
- }
- }
-
- private double _progress;
- public double Progress
- {
- get => _progress;
- set
- {
- if (_progress != value)
- {
- _progress = value;
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Progress)));
- }
- }
- }
-
- private bool _isComplete;
- public bool IsComplete
- {
- get => _isComplete;
- set
- {
- if (_isComplete != value)
- {
- _isComplete = value;
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsComplete)));
- }
- }
- }
+ public string Text { get; set; }
+ public string Title { get; set; }
+ public double Progress { get; set; }
+ public bool IsComplete { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
\ No newline at end of file
diff --git a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
index ff1c8f60..e19e7c94 100644
--- a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
+++ b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
@@ -119,7 +119,6 @@ public PublishModDialogViewModel(PathTuple modTuple)
item.PropertyChanged -= (_, __) => UpdateConfig(_modTuple.Config.IgnoreRegexes, IgnoreRegexes);
_modTuple.Config.IgnoreRegexes.Clear();
_modTuple.Config.IgnoreRegexes.AddRange(IgnoreRegexes.Select(x => x.Value));
- _modTuple.SaveAsync();
};
IncludeRegexes = new ObservableCollection(
_modTuple.Config.IncludeRegexes.Select(x => new StringWrapper { Value = x })
@@ -137,7 +136,6 @@ public PublishModDialogViewModel(PathTuple modTuple)
item.PropertyChanged -= (_, __) => UpdateConfig(_modTuple.Config.IncludeRegexes, IncludeRegexes);
_modTuple.Config.IncludeRegexes.Clear();
_modTuple.Config.IncludeRegexes.AddRange(IncludeRegexes.Select(x => x.Value));
- _modTuple.SaveAsync();
};
}
@@ -312,6 +310,11 @@ public void SetOutputFolder()
///
public void SetReadmePath() => ReadmePath = FileSelectors.SelectMarkdownFile();
+ ///
+ /// Lets the user save all changes to the mod config.
+ ///
+ public Task SaveAsync() => _modTuple.SaveAsync();
+
private string GetModFolder() => Path.GetDirectoryName(_modTuple.Path)!;
diff --git a/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs b/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs
index ff29f00f..1bb80223 100644
--- a/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs
+++ b/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs
@@ -103,6 +103,7 @@ private async void InstallMod_Drop(object sender, DragEventArgs e)
installVM.Progress = value * 100;
});
+ //Waits for 3 seconds before showing the install dialog, if the installation is not complete by then.
var timer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(3)
diff --git a/source/Reloaded.Mod.Launcher/Pages/Dialogs/PublishModDialog.xaml.cs b/source/Reloaded.Mod.Launcher/Pages/Dialogs/PublishModDialog.xaml.cs
index 6901ade2..235ac004 100644
--- a/source/Reloaded.Mod.Launcher/Pages/Dialogs/PublishModDialog.xaml.cs
+++ b/source/Reloaded.Mod.Launcher/Pages/Dialogs/PublishModDialog.xaml.cs
@@ -20,7 +20,10 @@ public PublishModDialog(PublishModDialogViewModel viewModel)
this.Closing += OnClosing;
}
- private void OnClosing(object? sender, CancelEventArgs e) => _cancellationTokenSource.Cancel();
+ private async void OnClosing(object? sender, CancelEventArgs e) {
+ await ViewModel.SaveAsync();
+ _cancellationTokenSource.Cancel();
+ }
private async void Publish_Click(object sender, System.Windows.RoutedEventArgs e)
{
diff --git a/source/Reloaded.Mod.Loader.Update/Utilities/StringWrapper.cs b/source/Reloaded.Mod.Loader.Update/Utilities/StringWrapper.cs
index 30b2c342..8d2c2331 100644
--- a/source/Reloaded.Mod.Loader.Update/Utilities/StringWrapper.cs
+++ b/source/Reloaded.Mod.Loader.Update/Utilities/StringWrapper.cs
@@ -1,27 +1,18 @@
+using PropertyChanged;
+
namespace Reloaded.Mod.Loader.Update.Utilities;
///
/// Class that wraps a string. Used for data binding.
///
+[AddINotifyPropertyChangedInterface]
[JsonConverter(typeof(StringWrapperConverter))]
public class StringWrapper : ObservableObject
{
- private string _value = "";
///
/// Value of the string wrapper.
///
- public string Value
- {
- get => _value;
- set
- {
- if (_value != value)
- {
- _value = value;
- RaisePropertyChangedEvent(nameof(Value));
- }
- }
- }
+ public string Value { get; set; } = "";
///
public static implicit operator string(StringWrapper wrapper) => wrapper.Value;
From fbc6dd0d077b3a9233f4ac13fd9441c224235146 Mon Sep 17 00:00:00 2001
From: Sewer56
Date: Sat, 15 Nov 2025 01:23:52 +0000
Subject: [PATCH 11/15] Changed: Follow Fody Weaving Pattern from rest of
source.
---
.../Dialog/InstallPackageViewModel.cs | 25 ++++++++++++++-----
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/InstallPackageViewModel.cs b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/InstallPackageViewModel.cs
index dbc6bd12..149604c5 100644
--- a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/InstallPackageViewModel.cs
+++ b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/InstallPackageViewModel.cs
@@ -3,13 +3,26 @@ namespace Reloaded.Mod.Launcher.Lib.Models.ViewModel.Dialog;
///
/// ViewModel for downloading an individual package.
///
-[AddINotifyPropertyChangedInterface]
-public class InstallPackageViewModel : INotifyPropertyChanged
+public class InstallPackageViewModel : ObservableObject
{
- public string Text { get; set; }
- public string Title { get; set; }
+ ///
+ /// The display text for the package installation.
+ ///
+ public string Text { get; set; } = "";
+
+ ///
+ /// The title for the package installation.
+ ///
+ public string Title { get; set; } = "";
+
+ ///
+ /// The current progress of the installation operation.
+ /// Range 0-100.
+ ///
public double Progress { get; set; }
- public bool IsComplete { get; set; }
- public event PropertyChangedEventHandler PropertyChanged;
+ ///
+ /// True if the installation is complete, else false.
+ ///
+ public bool IsComplete { get; set; }
}
\ No newline at end of file
From 53be43b1eb9710fac9012b90089201222cf52384 Mon Sep 17 00:00:00 2001
From: Sewer56
Date: Sat, 15 Nov 2025 01:43:49 +0000
Subject: [PATCH 12/15] Improve: Center InstallPackageDialog to the screen
---
.../Pages/Dialogs/InstallPackageDialog.xaml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml b/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml
index f9cb59b1..19230053 100644
--- a/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml
+++ b/source/Reloaded.Mod.Launcher/Pages/Dialogs/InstallPackageDialog.xaml
@@ -1,4 +1,4 @@
-
From e3f34998916ed8222c65c10affaec4880b2af9bf Mon Sep 17 00:00:00 2001
From: Sewer56
Date: Sat, 15 Nov 2025 01:49:45 +0000
Subject: [PATCH 13/15] Removed: Redundant AddINotifyPropertyChangedInterface
from StringWrapper
---
source/Reloaded.Mod.Loader.Update/Utilities/StringWrapper.cs | 3 ---
1 file changed, 3 deletions(-)
diff --git a/source/Reloaded.Mod.Loader.Update/Utilities/StringWrapper.cs b/source/Reloaded.Mod.Loader.Update/Utilities/StringWrapper.cs
index 8d2c2331..65689ee8 100644
--- a/source/Reloaded.Mod.Loader.Update/Utilities/StringWrapper.cs
+++ b/source/Reloaded.Mod.Loader.Update/Utilities/StringWrapper.cs
@@ -1,11 +1,8 @@
-using PropertyChanged;
-
namespace Reloaded.Mod.Loader.Update.Utilities;
///
/// Class that wraps a string. Used for data binding.
///
-[AddINotifyPropertyChangedInterface]
[JsonConverter(typeof(StringWrapperConverter))]
public class StringWrapper : ObservableObject
{
From 966abe1c936c280e4384dea0cedf7bb9eb02f3e4 Mon Sep 17 00:00:00 2001
From: Sewer56
Date: Sat, 15 Nov 2025 02:18:41 +0000
Subject: [PATCH 14/15] Changed: Updated IgnoreRegexes & IncludeRegexes to only
update on save in publish menu.
Not in real time, too expensive.
---
.../Dialog/PublishModDialogViewModel.cs | 60 ++++++-------------
1 file changed, 17 insertions(+), 43 deletions(-)
diff --git a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
index e19e7c94..71f58796 100644
--- a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
+++ b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs
@@ -106,44 +106,9 @@ public PublishModDialogViewModel(PathTuple modTuple)
IgnoreRegexes = new ObservableCollection(
_modTuple.Config.IgnoreRegexes.Select(x => new StringWrapper { Value = x })
);
- foreach (StringWrapper item in IgnoreRegexes)
- item.PropertyChanged += (_, __) => UpdateConfig(_modTuple.Config.IgnoreRegexes, IgnoreRegexes);
- IgnoreRegexes.CollectionChanged += (s, e) =>
- {
- if (e.NewItems != null)
- foreach (StringWrapper item in e.NewItems)
- item.PropertyChanged += (_, __) => UpdateConfig(_modTuple.Config.IgnoreRegexes, IgnoreRegexes);
-
- if (e.OldItems != null)
- foreach (StringWrapper item in e.OldItems)
- item.PropertyChanged -= (_, __) => UpdateConfig(_modTuple.Config.IgnoreRegexes, IgnoreRegexes);
- _modTuple.Config.IgnoreRegexes.Clear();
- _modTuple.Config.IgnoreRegexes.AddRange(IgnoreRegexes.Select(x => x.Value));
- };
IncludeRegexes = new ObservableCollection(
_modTuple.Config.IncludeRegexes.Select(x => new StringWrapper { Value = x })
);
- foreach (StringWrapper item in IncludeRegexes)
- item.PropertyChanged += (_, __) => UpdateConfig(_modTuple.Config.IncludeRegexes, IncludeRegexes);
- IncludeRegexes.CollectionChanged += (s, e) =>
- {
- if (e.NewItems != null)
- foreach (StringWrapper item in e.NewItems)
- item.PropertyChanged += (_, __) => UpdateConfig(_modTuple.Config.IncludeRegexes, IncludeRegexes);
-
- if (e.OldItems != null)
- foreach (StringWrapper item in e.OldItems)
- item.PropertyChanged -= (_, __) => UpdateConfig(_modTuple.Config.IncludeRegexes, IncludeRegexes);
- _modTuple.Config.IncludeRegexes.Clear();
- _modTuple.Config.IncludeRegexes.AddRange(IncludeRegexes.Select(x => x.Value));
- };
- }
-
- void UpdateConfig(List list, ObservableCollection collection)
- {
- list.Clear();
- list.AddRange(collection.Select(x => x.Value));
- _modTuple.SaveAsync();
}
///
@@ -153,6 +118,9 @@ void UpdateConfig(List list, ObservableCollection collect
/// True if a build has started and the operation completed, else false.
public async Task BuildAsync(CancellationToken cancellationToken = default)
{
+ // Save all changes before building to ensure config is current
+ await SaveAsync();
+
// Check if Auto Delta can be performed.
if (AutomaticDelta && !Singleton.Instance.CanReadFromDirectory(OutputFolder, null, out _, out _))
{
@@ -311,9 +279,21 @@ public void SetOutputFolder()
public void SetReadmePath() => ReadmePath = FileSelectors.SelectMarkdownFile();
///
- /// Lets the user save all changes to the mod config.
+ /// Saves all changes to the mod config.
+ /// Automatically syncs collections before saving to ensure all in-memory edits are persisted.
///
- public Task SaveAsync() => _modTuple.SaveAsync();
+ public async Task SaveAsync()
+ {
+ UpdateConfig(_modTuple.Config.IgnoreRegexes, IgnoreRegexes);
+ UpdateConfig(_modTuple.Config.IncludeRegexes, IncludeRegexes);
+ await _modTuple.SaveAsync();
+
+ void UpdateConfig(List list, ObservableCollection collection)
+ {
+ list.Clear();
+ list.AddRange(collection.Select(x => x.Value));
+ }
+ }
private string GetModFolder() => Path.GetDirectoryName(_modTuple.Path)!;
@@ -325,10 +305,4 @@ private void RemoveSelectedOrLastItem(StringWrapper? item, ObservableCollection<
else if (allItems.Count > 0)
allItems.RemoveAt(allItems.Count - 1);
}
-
- private void ChangeUiVisbilityOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
- {
- if (e.PropertyName == nameof(PublishTarget))
- ShowLastVersionUiItems = PublishTarget != PublishTarget.NuGet;
- }
}
\ No newline at end of file
From 78a2e013825cb335216daea29916447a78420c7d Mon Sep 17 00:00:00 2001
From: Sewer56
Date: Sat, 15 Nov 2025 23:40:31 +0000
Subject: [PATCH 15/15] Updated: Template of Changelog Update(s)
---
changelog-template.hbs | 31 +++++++++++++------------------
1 file changed, 13 insertions(+), 18 deletions(-)
diff --git a/changelog-template.hbs b/changelog-template.hbs
index c3cb6790..cde787d3 100644
--- a/changelog-template.hbs
+++ b/changelog-template.hbs
@@ -1,34 +1,29 @@
[Read and Discuss in a Browser](https://github.com/Reloaded-Project/Reloaded-II/discussions/473).
-[Previous Changelog](https://github.com/Reloaded-Project/Reloaded-II/releases/tag/1.29.1).
-
-# 1.29.2: Miscellaneous Things
+[Previous Changelog](https://github.com/Reloaded-Project/Reloaded-II/releases/tag/1.29.2).
Just a few low effort fixes and miscellany. As usual, Reloaded-II is on life support while I spend
the next years building the next best thing - if you want features, please contribute!
-## Fix: Better Error Handling for Bad Update Files
-
-Previously, if someone uploaded a corrupted `Sewer56.Update.Metadata.json` file to GameBanana or GitHub,
-Reloaded would crash. Now it handles these errors gracefully instead of crashing.
+# vNext: Miscellaneous Improvements
-Might add UI in future.
+No update to .NET 10 as of current.
-## Fix: Unnecessary Runtime Downloads
+According to 3rd party reports I got thus far, `Proton` needs updating to receive some upstream fixes from `Wine` for .NET 10, which may take a while.
-
+## Added Progress Bar for Mod Installation
-Fixed an issue where the dependency installer was requesting unnecessary .NET runtime downloads.
-The problem was that the installer wasn't filtering out the `Mods` folder, so it tried to install
-runtimes that mods were built with, even though all mods use the loader's runtime.
+
-Now it only installs truly needed dependencies.
+If a mod takes longer than 3 seconds to install via Drag & Drop, a simple progress bar will display on the screen now.
+In practice you should only see this if you install large mods (think >500MB); on a typical CPU.
-[This happened because in the last release the in-launcher dependency installer was updated to use
-the same code as `Setup.exe`; and this was a small oversight in the migration.]
+## Save Mod Config on Publish, Including `IncludeFiles` and `ExcludeFiles` by @TheBestAstroNOT , @Sewer56
-## Updated French Localization by @dysfunctionalriot
+When you `Publish` a mod you have an option to exclude certain files from the released project via `File Inclusions & Exclusions`.
+By default, that is all `.json` files except `.deps.json` and `.runtimeconfig.json` ones.
-🇫🇷 Updated translations for version 1.29.1.
+Previously, changes on this menu didn't save; as barely anyone ever changed the defaults.
+Now they do.
------------------------------------