Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ public EditModCommand(PathTuple<ModConfig>? modTuple, object? parent)
public bool CanExecute(object? parameter) => _modTuple != null;

/// <inheritdoc />
public void Execute(object? parameter) => Actions.EditModDialog(new EditModDialogViewModel(_modTuple!, IoC.Get<ApplicationConfigService>(), IoC.Get<ModConfigService>()), _parent);
public void Execute(object? parameter) => Actions.EditModDialog(new EditModDialogViewModel(_modTuple!, IoC.Get<ApplicationConfigService>().Items, IoC.Get<ModConfigService>().Items), _parent);
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,30 +67,28 @@ public class EditModDialogViewModel : ObservableObject, IDisposable
/// </summary>
public ObservableCollection<ResolverFactoryConfiguration> Updates { get; set; } = new ObservableCollection<ResolverFactoryConfiguration>();

private readonly ApplicationConfigService _applicationConfigService;
private SetModImageCommand _setModImageCommand;
private Action? _close;

/// <inheritdoc />
public EditModDialogViewModel(PathTuple<ModConfig> modTuple, ApplicationConfigService applicationConfigService, ModConfigService modConfigService)
public EditModDialogViewModel(PathTuple<ModConfig> modTuple, ObservableCollection<PathTuple<ApplicationConfig>> appItems, ObservableCollection<PathTuple<ModConfig>> modsItems)
{
_applicationConfigService = applicationConfigService;
ConfigTuple = modTuple;
Config = modTuple.Config;

// Add Tags
Tags.AddRange(Config.Tags);

// Add Known Apps
var apps = applicationConfigService.Items;
var apps = appItems;
foreach (var app in apps)
{
bool isAppEnabled = modTuple.Config.SupportedAppId.Contains(app.Config.AppId, StringComparer.OrdinalIgnoreCase);
Applications.Add(new BooleanGenericTuple<IApplicationConfig>(isAppEnabled, app.Config));
}

// Build Dependencies
var mods = modConfigService.Items; // In case collection changes during window open.
var mods = modsItems; // In case collection changes during window open.
foreach (var mod in mods)
{
bool isModEnabled = modTuple.Config.ModDependencies.Contains(mod.Config.ModId, StringComparer.OrdinalIgnoreCase);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ public void Execute(object? parameter)
_viewModel.DownloadPackageStatus = DownloadPackageStatus.Downloading;
try
{
var modConfigService = IoC.GetConstant<ModConfigService>();
var modsBefore = new Dictionary<string, PathTuple<ModConfig>>(modConfigService.ItemsById);
_canExecute = false;
RaiseCanExecute(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));

Expand All @@ -307,6 +309,40 @@ public void Execute(object? parameter)
await Update.ResolveMissingPackagesAsync();
});

modConfigService.ForceRefresh();
var newConfigs = new List<ModConfig>();
foreach (var item in modConfigService.ItemsById.ToArray())
{
if (!modsBefore.ContainsKey(item.Key))
{
newConfigs.Add(item.Value.Config);
if (item.Value.Config.IsUniversalMod || item.Value.Config.SupportedAppId.Length > 0)
{
var match = IoC.Get<ApplicationConfigService>().Items.FirstOrDefault(app => item.Value.Config.SupportedAppId.Contains(app.Config.AppId));
if (match == null)
{
bool loadAppPage = Actions.DisplayResourceMessageBoxOkCancel!.Invoke(Resources.NoCompatibleAppsInConfigTitle.Get(), $"{Resources.NoCompatibleAppsInConfigDescription.Get()}\n{Resources.AppSelectionQuestion.Get()}", Resources.Yes.Get(), Resources.No.Get());
if (loadAppPage)
{
var viewmodel = new EditModDialogViewModel(item.Value, IoC.Get<ApplicationConfigService>().Items, modConfigService.Items);
viewmodel.Page = EditModPage.Special;
var createModDialog = Actions.EditModDialog(viewmodel, null);
}
}
}
else
{
bool loadAppPage = Actions.DisplayResourceMessageBoxOkCancel!.Invoke(Resources.NoAppsInConfigTitle.Get(), $"{Resources.NoAppsInConfigDescription.Get()}\n{Resources.AppSelectionQuestion.Get()}", Resources.Yes.Get(), Resources.No.Get());
if (loadAppPage)
{
var viewmodel = new EditModDialogViewModel(item.Value, IoC.Get<ApplicationConfigService>().Items, modConfigService.Items);
viewmodel.Page = EditModPage.Special;
var createModDialog = Actions.EditModDialog(viewmodel, null);
}
}
}
}

_canExecute = true;
RaiseCanExecute(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
Expand Down
47 changes: 47 additions & 0 deletions source/Reloaded.Mod.Launcher.Lib/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,17 @@ private static void LaunchApplicationAndExit(string applicationToLaunch, bool fo
[MethodImpl(MethodImplOptions.NoInlining)]
private static void DownloadModAndExit(string downloadUrl)
{
var loaderConfig = IoC.Get<LoaderConfig>();
var modConfigDir = loaderConfig.GetModConfigDirectory();
var modConfig = ModConfig.GetAllMods(modConfigDir);
var allAppsList = ApplicationConfig.GetAllApplications(loaderConfig.GetApplicationConfigDirectory());
var allApps = new ObservableCollection<PathTuple<ApplicationConfig>>(allAppsList);
var oldItemsById = modConfig.ToDictionary(
x => x.Config.ModId,
x => x,
StringComparer.OrdinalIgnoreCase
);

if (downloadUrl.StartsWith($"{Constants.ReloadedProtocol}:", StringComparison.InvariantCultureIgnoreCase))
downloadUrl = downloadUrl.Substring(Constants.ReloadedProtocol.Length + 1);

Expand All @@ -119,6 +130,42 @@ private static void DownloadModAndExit(string downloadUrl)

Actions.ShowFetchPackageDialog(viewModel);
Update.ResolveMissingPackages();

modConfig = ModConfig.GetAllMods(modConfigDir);
var itemsById = modConfig.ToDictionary(x => x.Config.ModId, x => x, StringComparer.OrdinalIgnoreCase);
var items = new ObservableCollection<PathTuple<ModConfig>>(modConfig);
foreach (var item in itemsById.ToArray())
{
if (!oldItemsById.ContainsKey(item.Key))
{
if (item.Value.Config.IsUniversalMod || item.Value.Config.SupportedAppId.Length > 0)
{
var match = IoC.Get<ApplicationConfigService>().Items.FirstOrDefault(app => item.Value.Config.SupportedAppId.Contains(app.Config.AppId));
if (match == null)
{
bool loadAppPage = Actions.DisplayResourceMessageBoxOkCancel(Resources.NoCompatibleAppsInConfigTitle.Get(), $"{Resources.NoCompatibleAppsInConfigDescription.Get()}\n{Resources.AppSelectionQuestion.Get()}", Resources.Yes.Get(), Resources.No.Get());
if (loadAppPage)
{
var viewmodel = new EditModDialogViewModel(item.Value, allApps, items);
viewmodel.Page = EditModPage.Special;
var createModDialog = Actions.EditModDialog(viewmodel, null);
}
}
}
else
{
bool loadAppPage = Actions.DisplayResourceMessageBoxOkCancel(Resources.NoAppsInConfigTitle.Get(), $"{Resources.NoAppsInConfigDescription.Get()}\n{Resources.AppSelectionQuestion.Get()}", Resources.Yes.Get(), Resources.No.Get());
if (loadAppPage)
{
var viewmodel = new EditModDialogViewModel(item.Value, allApps, items);
viewmodel.Page = EditModPage.Special;
var createModDialog = Actions.EditModDialog(viewmodel, null);
}
}
}

}

Actions.DisplayMessagebox(Resources.PackageDownloaderDownloadCompleteTitle.Get(), Resources.PackageDownloaderDownloadCompleteDescription.Get(), new Actions.DisplayMessageBoxParams()
{
Type = Actions.MessageBoxType.Ok,
Expand Down
13 changes: 11 additions & 2 deletions source/Reloaded.Mod.Launcher.Lib/Static/Resources.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,18 @@ public static void Init(IDictionaryResourceProvider provider)
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)
// Update 1.29.3: New Progress Window for Local Mod Installation
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; }
}

// Update 1.XX.XX: Add warning during installation of mods with no apps in their supported apps list or when no compatible app is installed (UPDATE LAUNCHER VER BEFORE RELEASE)
public static IDictionaryResource<string> NoAppsInConfigTitle { get; set; }
public static IDictionaryResource<string> NoAppsInConfigDescription { get; set; }
public static IDictionaryResource<string> NoCompatibleAppsInConfigTitle { get; set; }
public static IDictionaryResource<string> NoCompatibleAppsInConfigDescription { get; set; }
public static IDictionaryResource<string> AppSelectionQuestion { get; set; }
public static IDictionaryResource<string> Yes { get; set; }
public static IDictionaryResource<string> No { get; set; }
}
12 changes: 12 additions & 0 deletions source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,13 @@
<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>

<!-- App Resolution Failure Message-->
<sys:String x:Key="NoAppsInConfigTitle">Unable to find any supported app</sys:String>
<sys:String x:Key="NoAppsInConfigDescription">Reloaded-II was unable to find any supported apps in the mod's config.</sys:String>
<sys:String x:Key="NoCompatibleAppsInConfigTitle">Unable to find a compatible app</sys:String>
<sys:String x:Key="NoCompatibleAppsInConfigDescription">Reloaded-II was unable to find an installed app which is compatible with this mod.</sys:String>
<sys:String x:Key="AppSelectionQuestion">Do you want to select a supported app manually?</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 Expand Up @@ -739,4 +746,9 @@ For more info, refer to the tutorial. Don't forget to set correct Publish target

<!-- Update 1.30.1: Missing Dependencies using same code as Installer -->
<sys:String x:Key="MissingDependenciesText3">Please download the requirements above by using the button below. You may need administrator permissions.</sys:String>

<!-- Update 1.XX.X: Uhh no strings for Yes and No? -->
<sys:String x:Key="Yes">Yes</sys:String>
<sys:String x:Key="No">No</sys:String>

</ResourceDictionary>
30 changes: 30 additions & 0 deletions source/Reloaded.Mod.Launcher/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using NuGet.Common;
using Reloaded.Mod.Launcher.Pages.BaseSubpages.Dialogs;
using Reloaded.Mod.Loader.Update.Providers.Web;
using Sewer56.DeltaPatchGenerator.Lib.Utility;
using Sewer56.Update.Extractors.SevenZipSharp;
Expand Down Expand Up @@ -132,7 +133,36 @@ private async void InstallMod_Drop(object sender, DragEventArgs e)
foreach (var item in modConfigService.ItemsById.ToArray())
{
if (!modsBefore.ContainsKey(item.Key))
{
newConfigs.Add(item.Value.Config);
if(item.Value.Config.IsUniversalMod || item.Value.Config.SupportedAppId.Length > 0)
{
var match = Lib.IoC.Get<ApplicationConfigService>().Items.FirstOrDefault(app => item.Value.Config.SupportedAppId.Contains(app.Config.AppId));
if(match == null)
{
bool loadAppPage = Actions.DisplayResourceMessageBoxOkCancel!.Invoke(NoCompatibleAppsInConfigTitle.Get(), $"{NoCompatibleAppsInConfigDescription.Get()}\n{AppSelectionQuestion.Get()}", Yes.Get(), No.Get());
if (loadAppPage)
{
var createModDialog = new EditModDialog(new EditModDialogViewModel(item.Value, Lib.IoC.Get<ApplicationConfigService>().Items, modConfigService.Items));
createModDialog.Owner = System.Windows.Window.GetWindow(this);
createModDialog.RealViewModel.Page = EditModPage.Special;
createModDialog.ShowDialog();
}
}
}
else
{
bool loadAppPage = Actions.DisplayResourceMessageBoxOkCancel!.Invoke(NoAppsInConfigTitle.Get(), $"{NoAppsInConfigDescription.Get()}\n{AppSelectionQuestion.Get()}" , Yes.Get(), No.Get());
if (loadAppPage)
{
var createModDialog = new EditModDialog(new EditModDialogViewModel(item.Value, Lib.IoC.Get<ApplicationConfigService>().Items, modConfigService.Items));
createModDialog.Owner = System.Windows.Window.GetWindow(this);
createModDialog.RealViewModel.Page = EditModPage.Special;
createModDialog.ShowDialog();
}
}
}

}

if (newConfigs.Count <= 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public async Task Save()
var mod = await ActionWrappers.TryGetValueAsync(() => modConfigService.ItemsById[createdMod.Config.ModId], 5000, 32);
if (mod != null)
{
var createModDialog = new EditModDialog(new EditModDialogViewModel(mod, Lib.IoC.Get<ApplicationConfigService>(), modConfigService));
var createModDialog = new EditModDialog(new EditModDialogViewModel(mod, Lib.IoC.Get<ApplicationConfigService>().Items, modConfigService.Items));
createModDialog.Owner = Window.GetWindow(this);
createModDialog.ShowDialog();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ public class XamlResourceMessageBoxOkCancel : MessageBoxOkCancel

}

public XamlResourceMessageBoxOkCancel(string titleResourceName, string descriptionResourceName, string okButtonTextResourceName, string cancelButtonTextResourceName) : base(new XamlResource<string>(titleResourceName).Get(), new XamlResource<string>(descriptionResourceName).Get())
public XamlResourceMessageBoxOkCancel(string title, string message, string okText, string cancelText) : base(title, message)
{
this.CancelBtn.Content = Lib.Static.Resources.ResourceProvider.Get<string>(cancelButtonTextResourceName);
this.OKBtn.Content = Lib.Static.Resources.ResourceProvider.Get<string>(okButtonTextResourceName);
Comment on lines -13 to -16
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I'm missing something, wouldn't this replace every instance of Ok/Cancel to Yes/No?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uhh no? You are passing the text every time you call it. Plus other message boxes use another delegate to display their text. Only I'm using this one.

this.OKBtn.Content = okText;
this.CancelBtn.Content = cancelText;
}
}
Loading