Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 13 additions & 18 deletions changelog-template.hbs
Original file line number Diff line number Diff line change
@@ -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.

![](https://github.com/user-attachments/assets/45795e1b-c922-44e9-9134-60fe18b27f29)
## 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.
![Image](https://github.com/user-attachments/assets/9f09ccad-f036-4856-806c-3c75f281307a)

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.

------------------------------------

Expand Down
3 changes: 2 additions & 1 deletion source/Reloaded.Mod.Launcher.Lib/Lib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<LoaderConfig>().GetModConfigDirectory(), IOEx.ForceValidFilePath(ModId));
var filePath = Path.Combine(modDirectory, ModConfig.ConfigFileName);
await IConfig<ModConfig>.ToPathAsync(config, filePath);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace Reloaded.Mod.Launcher.Lib.Models.ViewModel.Dialog;

/// <summary>
/// ViewModel for downloading an individual package.
/// </summary>
public class InstallPackageViewModel : ObservableObject
{
/// <summary>
/// The display text for the package installation.
/// </summary>
public string Text { get; set; } = "";

/// <summary>
/// The title for the package installation.
/// </summary>
public string Title { get; set; } = "";

/// <summary>
/// The current progress of the installation operation.
/// Range 0-100.
/// </summary>
public double Progress { get; set; }

/// <summary>
/// True if the installation is complete, else false.
/// </summary>
public bool IsComplete { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,23 +103,12 @@ public PublishModDialogViewModel(PathTuple<ModConfig> 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<StringWrapper>()
{
@".*\.json", // Config files
$"{Regex.Escape($@"{_modTuple.Config.ModId}.nuspec")}"
};

IncludeRegexes = new ObservableCollection<StringWrapper>()
{
Regex.Escape(ModConfig.ConfigFileName),
@"\.deps\.json",
@"\.runtimeconfig\.json",
};

// Set notifications
PropertyChanged += ChangeUiVisbilityOnPropertyChanged;
IgnoreRegexes = new ObservableCollection<StringWrapper>(
_modTuple.Config.IgnoreRegexes.Select(x => new StringWrapper { Value = x })
);
IncludeRegexes = new ObservableCollection<StringWrapper>(
_modTuple.Config.IncludeRegexes.Select(x => new StringWrapper { Value = x })
);
}

/// <summary>
Expand All @@ -129,6 +118,9 @@ public PublishModDialogViewModel(PathTuple<ModConfig> modTuple)
/// <returns>True if a build has started and the operation completed, else false.</returns>
public async Task<bool> 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<ReleaseMetadata>.Instance.CanReadFromDirectory(OutputFolder, null, out _, out _))
{
Expand All @@ -148,8 +140,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<double>(d => BuildProgress = d * 100),
AutomaticDelta = AutomaticDelta,
CompressionLevel = CompressionLevel,
Expand Down Expand Up @@ -286,6 +278,23 @@ public void SetOutputFolder()
/// </summary>
public void SetReadmePath() => ReadmePath = FileSelectors.SelectMarkdownFile();

/// <summary>
/// Saves all changes to the mod config.
/// Automatically syncs collections before saving to ensure all in-memory edits are persisted.
/// </summary>
public async Task SaveAsync()
{
UpdateConfig(_modTuple.Config.IgnoreRegexes, IgnoreRegexes);
UpdateConfig(_modTuple.Config.IncludeRegexes, IncludeRegexes);
await _modTuple.SaveAsync();

void UpdateConfig(List<string> list, ObservableCollection<StringWrapper> collection)
{
list.Clear();
list.AddRange(collection.Select(x => x.Value));
}
}

private string GetModFolder() => Path.GetDirectoryName(_modTuple.Path)!;


Expand All @@ -296,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;
}
}
9 changes: 9 additions & 0 deletions source/Reloaded.Mod.Launcher.Lib/Static/Actions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ public static class Actions
/// </summary>
public static ShowFetchPackageDialogDelegate ShowFetchPackageDialog { get; set; } = null!;

public static ShowInstallPackageDialogDelegate ShowInstallPackageDialog { get; set; } = null!;


/// <summary>
/// Shows a dialog that can be used to select the added game.
/// </summary>
Expand Down Expand Up @@ -254,6 +257,12 @@ public enum MessageBoxType
/// <param name="viewModel">The ViewModel used for downloading the individual package.</param>
public delegate bool ShowFetchPackageDialogDelegate(DownloadPackageViewModel viewModel);

/// <summary>
/// Shows a dialog that can be used to download an individual package.
/// </summary>
/// <param name="viewModel">The ViewModel used for downloading the individual package.</param>
public delegate bool ShowInstallPackageDialogDelegate(InstallPackageViewModel viewModel);

/// <summary>
/// Shows a dialog that can be used to select the added game.
/// </summary>
Expand Down
8 changes: 7 additions & 1 deletion source/Reloaded.Mod.Launcher.Lib/Static/Resources.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ public static void Init(IDictionaryResourceProvider provider)
// Update 1.21.0: Mod Packs Install
public static IDictionaryResource<string> InstallModPackDownloading { get; set; }
public static IDictionaryResource<string> InstallModPackErrorDownloadFail { get; set; }

// Update 1.21.6: Mod Packs Install
public static IDictionaryResource<string> ErrorAddApplicationGeneral { get; set; }
public static IDictionaryResource<string> ErrorAddApplicationCantReadSymlink { get; set; }
Expand Down Expand Up @@ -219,4 +219,10 @@ public static void Init(IDictionaryResourceProvider provider)
public static IDictionaryResource<string> ErrorViewDetails { get; set; }
public static IDictionaryResource<string> ErrorStacktraceTitle { get; set; }
public static IDictionaryResource<string> ErrorStacktraceSubtitle { get; set; }

// Update 1.X.X: New Progress Window for Local Mod Installation (UPDATE LAUNCHER VER BEFORE RELEASE)
public static IDictionaryResource<string> InstallModArchiveTitle { get; set; }
public static IDictionaryResource<string> InstalledModName { get; set; }
public static IDictionaryResource<string> InstallingModWait { get; set; }
public static IDictionaryResource<string> ExtractingLocalModArchive { get; set; }
}
6 changes: 6 additions & 0 deletions source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,12 @@
<!-- Download Mod Archive -->
<sys:String x:Key="DownloadModArchiveTitle">Download Mod Archive</sys:String>
<sys:String x:Key="DownloadModArchiveName">File Name</sys:String>

<!-- Install Mod Archive -->
<sys:String x:Key="InstallModArchiveTitle">Installing Mod Archive</sys:String>
<sys:String x:Key="InstalledModName">Mod Name</sys:String>
<sys:String x:Key="InstallingModWait">Please wait while we install the mod!</sys:String>
<sys:String x:Key="ExtractingLocalModArchive">Extracting a local mod, please wait!</sys:String>

<!-- WMI Administrator Message -->
<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>
Expand Down
2 changes: 2 additions & 0 deletions source/Reloaded.Mod.Launcher/LibraryBindings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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));
Expand Down
40 changes: 36 additions & 4 deletions source/Reloaded.Mod.Launcher/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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<double>(), default);

/* Get name of package. */
WebDownloadablePackage.CopyPackagesFromExtractFolderToTargetDir(modsFolder!, tempFolder.FolderPath, default);
var installVM = new InstallPackageViewModel
{
Title = InstallModArchiveTitle.Get(),
Text = ExtractingLocalModArchive.Get(),
Progress = 0
};

var progress = new Progress<double>(value =>
{
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)
};

timer.Tick += (s, e) =>
{
timer.Stop();
if (installVM.Progress != 100)
{
Actions.ShowInstallPackageDialog.Invoke(installVM);
}
};
timer.Start();

await archiveExtractor.ExtractPackageAsync(file, tempFolder.FolderPath, progress, default);

installVM.Text = InstallingModWait.Get();
await WebDownloadablePackage.CopyPackagesFromExtractFolderToTargetDir(modsFolder!, tempFolder.FolderPath, default);
installVM.IsComplete = true;
}

// Find the new mods
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<default:ReloadedWindow x:Class="Reloaded.Mod.Launcher.Pages.Dialogs.InstallPackageDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Reloaded.Mod.Launcher.Pages.Dialogs"
xmlns:converters="clr-namespace:Reloaded.Mod.Launcher.Converters"
xmlns:default="clr-namespace:Reloaded.WPF.Theme.Default;assembly=Reloaded.WPF.Theme.Default"
mc:Ignorable="d"
SizeToContent="Height"
Width="500"
Title="{Binding Title}"
WindowStartupLocation="CenterScreen"
Style="{DynamicResource ReloadedWindow}">
<Grid Margin="{DynamicResource PageMarginSmall}" DataContext="{Binding Path=ViewModel, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}">

<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>

<TextBlock HorizontalAlignment="Center"
Grid.Row="0"
Text="{Binding Text}"
Visibility="{Binding Text, Converter={x:Static converters:StringToVisibilityConverter.Instance}}"
Style="{DynamicResource DefaultTextBlock}" />

<Grid Margin="{DynamicResource PanelMargin}"
Grid.Row="1"/>

<Grid Margin="{DynamicResource PanelMargin}" Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="{DynamicResource GridInterPanelMargin}" />
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>

<ProgressBar Grid.Column="0"
Height="25"
Value="{Binding Progress, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Maximum="100" />
</Grid>
</Grid>
</default:ReloadedWindow>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Button = System.Windows.Controls.Button;

namespace Reloaded.Mod.Launcher.Pages.Dialogs;

/// <summary>
/// Interaction logic for DownloadPackageDialog.xaml
/// </summary>
public partial class InstallPackageDialog : ReloadedWindow
{
public new InstallPackageViewModel ViewModel { get; set; }

/// <inheritdoc />
public InstallPackageDialog(InstallPackageViewModel viewModel)
{
InitializeComponent();
ViewModel = viewModel;
DataContext = viewModel;
viewModel.PropertyChanged += (s, e) =>
{
if (e.PropertyName == nameof(InstallPackageViewModel.IsComplete) && viewModel.IsComplete)
{
ActionWrappers.ExecuteWithApplicationDispatcher(this.Close);
}
};
}
}
Loading
Loading