Skip to content

Commit 6d51c3b

Browse files
committed
Merge branch 'preserve-exclusion-list'
2 parents b1fd82a + 78a2e01 commit 6d51c3b

16 files changed

Lines changed: 216 additions & 53 deletions

File tree

changelog-template.hbs

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,29 @@
11
[Read and Discuss in a Browser](https://github.com/Reloaded-Project/Reloaded-II/discussions/473).
2-
[Previous Changelog](https://github.com/Reloaded-Project/Reloaded-II/releases/tag/1.29.1).
3-
4-
# 1.29.2: Miscellaneous Things
2+
[Previous Changelog](https://github.com/Reloaded-Project/Reloaded-II/releases/tag/1.29.2).
53

64
Just a few low effort fixes and miscellany. As usual, Reloaded-II is on life support while I spend
75
the next years building the next best thing - if you want features, please contribute!
86

9-
## Fix: Better Error Handling for Bad Update Files
10-
11-
Previously, if someone uploaded a corrupted `Sewer56.Update.Metadata.json` file to GameBanana or GitHub,
12-
Reloaded would crash. Now it handles these errors gracefully instead of crashing.
7+
# vNext: Miscellaneous Improvements
138

14-
Might add UI in future.
9+
No update to .NET 10 as of current.
1510

16-
## Fix: Unnecessary Runtime Downloads
11+
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.
1712

18-
![](https://github.com/user-attachments/assets/45795e1b-c922-44e9-9134-60fe18b27f29)
13+
## Added Progress Bar for Mod Installation
1914

20-
Fixed an issue where the dependency installer was requesting unnecessary .NET runtime downloads.
21-
The problem was that the installer wasn't filtering out the `Mods` folder, so it tried to install
22-
runtimes that mods were built with, even though all mods use the loader's runtime.
15+
![Image](https://github.com/user-attachments/assets/9f09ccad-f036-4856-806c-3c75f281307a)
2316

24-
Now it only installs truly needed dependencies.
17+
If a mod takes longer than 3 seconds to install via Drag & Drop, a simple progress bar will display on the screen now.
18+
In practice you should only see this if you install large mods (think >500MB); on a typical CPU.
2519

26-
[This happened because in the last release the in-launcher dependency installer was updated to use
27-
the same code as `Setup.exe`; and this was a small oversight in the migration.]
20+
## Save Mod Config on Publish, Including `IncludeFiles` and `ExcludeFiles` by @TheBestAstroNOT , @Sewer56
2821

29-
## Updated French Localization by @dysfunctionalriot
22+
When you `Publish` a mod you have an option to exclude certain files from the released project via `File Inclusions & Exclusions`.
23+
By default, that is all `.json` files except `.deps.json` and `.runtimeconfig.json` ones.
3024

31-
🇫🇷 Updated translations for version 1.29.1.
25+
Previously, changes on this menu didn't save; as barely anyone ever changed the defaults.
26+
Now they do.
3227

3328
------------------------------------
3429

source/Reloaded.Mod.Launcher.Lib/Lib.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public static void Init(IDictionaryResourceProvider provider, SynchronizationCon
6262
Actions.ShowModLoaderUpdateDialogDelegate showModLoaderUpdate, Actions.ShowModUpdateDialogDelegate showModUpdate, Actions.ConfigureNuGetFeedsDialogDelegate configureNuGetFeeds,
6363
Actions.ConfigureModDialogDelegate configureModDialog, Actions.ShowMissingCoreDependencyDialogDelegate showMissingCoreDependency,
6464
Actions.EditModDialogDelegate editModDialog, Actions.PublishModDialogDelegate publishModDialog,
65-
Actions.ShowEditModUserConfigDialogDelegate showEditModUserConfig, Actions.ShowFetchPackageDialogDelegate showFetchPackageDialog,
65+
Actions.ShowEditModUserConfigDialogDelegate showEditModUserConfig, Actions.ShowFetchPackageDialogDelegate showFetchPackageDialog, Actions.ShowInstallPackageDialogDelegate showInstallPackageDialog,
6666
Actions.ShowSelectAddedGameDialogDelegate showSelectAddedGameDialog, Actions.ShowAddAppHashMismatchDialogDelegate showAddAppMismatchDialog,
6767
Actions.ShowApplicationWarningDialogDelegate showApplicationWarningDialog, Actions.ShowRunAppViaWineDialogDelegate showRunAppViaWineDialog,
6868
Actions.ShowEditPackDialogDelegate showEditPackDialog, Actions.ShowInstallModPackDialogDelegate showInstallModPackDialog, Action initControllerSupport)
@@ -85,6 +85,7 @@ public static void Init(IDictionaryResourceProvider provider, SynchronizationCon
8585
Actions.PublishModDialog = publishModDialog;
8686
Actions.ShowEditModUserConfig = showEditModUserConfig;
8787
Actions.ShowFetchPackageDialog = showFetchPackageDialog;
88+
Actions.ShowInstallPackageDialog = showInstallPackageDialog;
8889
Actions.ShowSelectAddedGameDialog = showSelectAddedGameDialog;
8990
Actions.ShowAddAppHashMismatchDialog = showAddAppMismatchDialog;
9091
Actions.ShowApplicationWarningDialog = showApplicationWarningDialog;

source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/CreateModViewModel.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public CreateModViewModel(ModConfigService modConfigService)
3333
ReleaseMetadataFileName = $"{ModId}.ReleaseMetadata.json"
3434
};
3535

36+
config.IgnoreRegexes.Add($"{Regex.Escape($@"{config.ModId}.nuspec")}");
37+
config.IncludeRegexes.Add(Regex.Escape(ModConfig.ConfigFileName));
3638
var modDirectory = Path.Combine(IoC.Get<LoaderConfig>().GetModConfigDirectory(), IOEx.ForceValidFilePath(ModId));
3739
var filePath = Path.Combine(modDirectory, ModConfig.ConfigFileName);
3840
await IConfig<ModConfig>.ToPathAsync(config, filePath);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
namespace Reloaded.Mod.Launcher.Lib.Models.ViewModel.Dialog;
2+
3+
/// <summary>
4+
/// ViewModel for downloading an individual package.
5+
/// </summary>
6+
public class InstallPackageViewModel : ObservableObject
7+
{
8+
/// <summary>
9+
/// The display text for the package installation.
10+
/// </summary>
11+
public string Text { get; set; } = "";
12+
13+
/// <summary>
14+
/// The title for the package installation.
15+
/// </summary>
16+
public string Title { get; set; } = "";
17+
18+
/// <summary>
19+
/// The current progress of the installation operation.
20+
/// Range 0-100.
21+
/// </summary>
22+
public double Progress { get; set; }
23+
24+
/// <summary>
25+
/// True if the installation is complete, else false.
26+
/// </summary>
27+
public bool IsComplete { get; set; }
28+
}

source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/PublishModDialogViewModel.cs

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -103,23 +103,12 @@ public PublishModDialogViewModel(PathTuple<ModConfig> modTuple)
103103
_modTuple = modTuple;
104104
PackageName = IOEx.ForceValidFilePath(_modTuple.Config.ModName.Replace(' ', '_'));
105105
OutputFolder = Path.Combine(Path.GetTempPath(), $"{IOEx.ForceValidFilePath(_modTuple.Config.ModId)}.Publish");
106-
107-
// Set default Regexes.
108-
IgnoreRegexes = new ObservableCollection<StringWrapper>()
109-
{
110-
@".*\.json", // Config files
111-
$"{Regex.Escape($@"{_modTuple.Config.ModId}.nuspec")}"
112-
};
113-
114-
IncludeRegexes = new ObservableCollection<StringWrapper>()
115-
{
116-
Regex.Escape(ModConfig.ConfigFileName),
117-
@"\.deps\.json",
118-
@"\.runtimeconfig\.json",
119-
};
120-
121-
// Set notifications
122-
PropertyChanged += ChangeUiVisbilityOnPropertyChanged;
106+
IgnoreRegexes = new ObservableCollection<StringWrapper>(
107+
_modTuple.Config.IgnoreRegexes.Select(x => new StringWrapper { Value = x })
108+
);
109+
IncludeRegexes = new ObservableCollection<StringWrapper>(
110+
_modTuple.Config.IncludeRegexes.Select(x => new StringWrapper { Value = x })
111+
);
123112
}
124113

125114
/// <summary>
@@ -129,6 +118,9 @@ public PublishModDialogViewModel(PathTuple<ModConfig> modTuple)
129118
/// <returns>True if a build has started and the operation completed, else false.</returns>
130119
public async Task<bool> BuildAsync(CancellationToken cancellationToken = default)
131120
{
121+
// Save all changes before building to ensure config is current
122+
await SaveAsync();
123+
132124
// Check if Auto Delta can be performed.
133125
if (AutomaticDelta && !Singleton<ReleaseMetadata>.Instance.CanReadFromDirectory(OutputFolder, null, out _, out _))
134126
{
@@ -148,8 +140,8 @@ await PublishAsync(new PublishArgs()
148140
PublishTarget = PublishTarget,
149141
OutputFolder = OutputFolder,
150142
ModTuple = _modTuple,
151-
IgnoreRegexes = IgnoreRegexes.Select(x => x.Value).ToList(),
152-
IncludeRegexes = IncludeRegexes.Select(x => x.Value).ToList(),
143+
IgnoreRegexes = _modTuple.Config.IgnoreRegexes,
144+
IncludeRegexes = _modTuple.Config.IncludeRegexes,
153145
Progress = new Progress<double>(d => BuildProgress = d * 100),
154146
AutomaticDelta = AutomaticDelta,
155147
CompressionLevel = CompressionLevel,
@@ -286,6 +278,23 @@ public void SetOutputFolder()
286278
/// </summary>
287279
public void SetReadmePath() => ReadmePath = FileSelectors.SelectMarkdownFile();
288280

281+
/// <summary>
282+
/// Saves all changes to the mod config.
283+
/// Automatically syncs collections before saving to ensure all in-memory edits are persisted.
284+
/// </summary>
285+
public async Task SaveAsync()
286+
{
287+
UpdateConfig(_modTuple.Config.IgnoreRegexes, IgnoreRegexes);
288+
UpdateConfig(_modTuple.Config.IncludeRegexes, IncludeRegexes);
289+
await _modTuple.SaveAsync();
290+
291+
void UpdateConfig(List<string> list, ObservableCollection<StringWrapper> collection)
292+
{
293+
list.Clear();
294+
list.AddRange(collection.Select(x => x.Value));
295+
}
296+
}
297+
289298
private string GetModFolder() => Path.GetDirectoryName(_modTuple.Path)!;
290299

291300

@@ -296,10 +305,4 @@ private void RemoveSelectedOrLastItem(StringWrapper? item, ObservableCollection<
296305
else if (allItems.Count > 0)
297306
allItems.RemoveAt(allItems.Count - 1);
298307
}
299-
300-
private void ChangeUiVisbilityOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
301-
{
302-
if (e.PropertyName == nameof(PublishTarget))
303-
ShowLastVersionUiItems = PublishTarget != PublishTarget.NuGet;
304-
}
305308
}

source/Reloaded.Mod.Launcher.Lib/Static/Actions.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ public static class Actions
7777
/// </summary>
7878
public static ShowFetchPackageDialogDelegate ShowFetchPackageDialog { get; set; } = null!;
7979

80+
public static ShowInstallPackageDialogDelegate ShowInstallPackageDialog { get; set; } = null!;
81+
82+
8083
/// <summary>
8184
/// Shows a dialog that can be used to select the added game.
8285
/// </summary>
@@ -254,6 +257,12 @@ public enum MessageBoxType
254257
/// <param name="viewModel">The ViewModel used for downloading the individual package.</param>
255258
public delegate bool ShowFetchPackageDialogDelegate(DownloadPackageViewModel viewModel);
256259

260+
/// <summary>
261+
/// Shows a dialog that can be used to download an individual package.
262+
/// </summary>
263+
/// <param name="viewModel">The ViewModel used for downloading the individual package.</param>
264+
public delegate bool ShowInstallPackageDialogDelegate(InstallPackageViewModel viewModel);
265+
257266
/// <summary>
258267
/// Shows a dialog that can be used to select the added game.
259268
/// </summary>

source/Reloaded.Mod.Launcher.Lib/Static/Resources.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ public static void Init(IDictionaryResourceProvider provider)
181181
// Update 1.21.0: Mod Packs Install
182182
public static IDictionaryResource<string> InstallModPackDownloading { get; set; }
183183
public static IDictionaryResource<string> InstallModPackErrorDownloadFail { get; set; }
184-
184+
185185
// Update 1.21.6: Mod Packs Install
186186
public static IDictionaryResource<string> ErrorAddApplicationGeneral { get; set; }
187187
public static IDictionaryResource<string> ErrorAddApplicationCantReadSymlink { get; set; }
@@ -219,4 +219,10 @@ public static void Init(IDictionaryResourceProvider provider)
219219
public static IDictionaryResource<string> ErrorViewDetails { get; set; }
220220
public static IDictionaryResource<string> ErrorStacktraceTitle { get; set; }
221221
public static IDictionaryResource<string> ErrorStacktraceSubtitle { get; set; }
222+
223+
// Update 1.X.X: New Progress Window for Local Mod Installation (UPDATE LAUNCHER VER BEFORE RELEASE)
224+
public static IDictionaryResource<string> InstallModArchiveTitle { get; set; }
225+
public static IDictionaryResource<string> InstalledModName { get; set; }
226+
public static IDictionaryResource<string> InstallingModWait { get; set; }
227+
public static IDictionaryResource<string> ExtractingLocalModArchive { get; set; }
222228
}

source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,12 @@
197197
<!-- Download Mod Archive -->
198198
<sys:String x:Key="DownloadModArchiveTitle">Download Mod Archive</sys:String>
199199
<sys:String x:Key="DownloadModArchiveName">File Name</sys:String>
200+
201+
<!-- Install Mod Archive -->
202+
<sys:String x:Key="InstallModArchiveTitle">Installing Mod Archive</sys:String>
203+
<sys:String x:Key="InstalledModName">Mod Name</sys:String>
204+
<sys:String x:Key="InstallingModWait">Please wait while we install the mod!</sys:String>
205+
<sys:String x:Key="ExtractingLocalModArchive">Extracting a local mod, please wait!</sys:String>
200206

201207
<!-- WMI Administrator Message -->
202208
<sys:String x:Key="RunAsAdminMessage">You need to run this application as administrator.&#x0a;Administrative privileges are needed to receive application launch/exit events from Windows Management Instrumentation (WMI).&#x0a;Developers: Run your favourite IDE e.g. Visual Studio as Admin.</sys:String>

source/Reloaded.Mod.Launcher/LibraryBindings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public static void Init(IResourceFileSelector? languageSelector, IResourceFileSe
2727
publishModDialog: PublishModDialog,
2828
showEditModUserConfig: ShowEditModUserConfig,
2929
showFetchPackageDialog: ShowFetchPackageDialog,
30+
showInstallPackageDialog: ShowInstallPackageDialog,
3031
showSelectAddedGameDialog: ShowSelectAddedGameDialog,
3132
showAddAppMismatchDialog: ShowAddAppMismatchDialog,
3233
showApplicationWarningDialog: ShowApplicationWarningDialog,
@@ -106,6 +107,7 @@ private static bool EditModDialog(EditModDialogViewModel viewmodel, object? owne
106107
private static bool ShowEditModUserConfig(EditModUserConfigDialogViewModel viewmodel) => ShowDialogAndGetResult(new EditModUserConfigDialog(viewmodel));
107108
private static bool PublishModDialog(PublishModDialogViewModel viewmodel) => ShowDialogAndGetResult(new PublishModDialog(viewmodel));
108109
private static bool ShowFetchPackageDialog(DownloadPackageViewModel viewmodel) => ShowDialogAndGetResult(new DownloadPackageDialog(viewmodel));
110+
private static bool ShowInstallPackageDialog(InstallPackageViewModel viewmodel) => ShowDialogAndGetResult(new InstallPackageDialog(viewmodel));
109111
private static bool ShowAddAppMismatchDialog(AddAppHashMismatchDialogViewModel viewmodel) => ShowDialogAndGetResult(new AddAppHashMismatchDialog(viewmodel));
110112
private static bool ShowApplicationWarningDialog(AddApplicationWarningDialogViewModel viewmodel) => ShowDialogAndGetResult(new ShowApplicationWarningDialog(viewmodel));
111113
private static bool ShowInstallModPackDialog(InstallModPackDialogViewModel viewmodel) => ShowDialogAndGetResult(new InstallModPackDialog(viewmodel));

source/Reloaded.Mod.Launcher/MainWindow.xaml.cs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
using System.Text;
1+
using NuGet.Common;
22
using Reloaded.Mod.Loader.Update.Providers.Web;
33
using Sewer56.DeltaPatchGenerator.Lib.Utility;
44
using Sewer56.Update.Extractors.SevenZipSharp;
5+
using System.Text;
6+
using System.Windows.Threading;
57
using static Reloaded.Mod.Launcher.Lib.Static.Resources;
68

79
namespace Reloaded.Mod.Launcher;
@@ -88,10 +90,40 @@ private async void InstallMod_Drop(object sender, DragEventArgs e)
8890
/* Extract to Temp Directory */
8991
using var tempFolder = new TemporaryFolderAllocation();
9092
var archiveExtractor = new SevenZipSharpExtractor();
91-
await archiveExtractor.ExtractPackageAsync(file, tempFolder.FolderPath, new Progress<double>(), default);
9293

93-
/* Get name of package. */
94-
WebDownloadablePackage.CopyPackagesFromExtractFolderToTargetDir(modsFolder!, tempFolder.FolderPath, default);
94+
var installVM = new InstallPackageViewModel
95+
{
96+
Title = InstallModArchiveTitle.Get(),
97+
Text = ExtractingLocalModArchive.Get(),
98+
Progress = 0
99+
};
100+
101+
var progress = new Progress<double>(value =>
102+
{
103+
installVM.Progress = value * 100;
104+
});
105+
106+
//Waits for 3 seconds before showing the install dialog, if the installation is not complete by then.
107+
var timer = new DispatcherTimer
108+
{
109+
Interval = TimeSpan.FromSeconds(3)
110+
};
111+
112+
timer.Tick += (s, e) =>
113+
{
114+
timer.Stop();
115+
if (installVM.Progress != 100)
116+
{
117+
Actions.ShowInstallPackageDialog.Invoke(installVM);
118+
}
119+
};
120+
timer.Start();
121+
122+
await archiveExtractor.ExtractPackageAsync(file, tempFolder.FolderPath, progress, default);
123+
124+
installVM.Text = InstallingModWait.Get();
125+
await WebDownloadablePackage.CopyPackagesFromExtractFolderToTargetDir(modsFolder!, tempFolder.FolderPath, default);
126+
installVM.IsComplete = true;
95127
}
96128

97129
// Find the new mods

0 commit comments

Comments
 (0)