diff --git a/source/Reloaded.Mod.Launcher.Lib/Commands/Mod/EditModCommand.cs b/source/Reloaded.Mod.Launcher.Lib/Commands/Mod/EditModCommand.cs index 7098ca18..65189c27 100644 --- a/source/Reloaded.Mod.Launcher.Lib/Commands/Mod/EditModCommand.cs +++ b/source/Reloaded.Mod.Launcher.Lib/Commands/Mod/EditModCommand.cs @@ -23,5 +23,5 @@ public EditModCommand(PathTuple? modTuple, object? parent) public bool CanExecute(object? parameter) => _modTuple != null; /// - public void Execute(object? parameter) => Actions.EditModDialog(new EditModDialogViewModel(_modTuple!, IoC.Get(), IoC.Get()), _parent); + public void Execute(object? parameter) => Actions.EditModDialog(new EditModDialogViewModel(_modTuple!, IoC.Get().Items, IoC.Get().Items), _parent); } \ No newline at end of file diff --git a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/EditModDialogViewModel.cs b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/EditModDialogViewModel.cs index df7097a0..41cf46d2 100644 --- a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/EditModDialogViewModel.cs +++ b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/Dialog/EditModDialogViewModel.cs @@ -67,14 +67,12 @@ public class EditModDialogViewModel : ObservableObject, IDisposable /// public ObservableCollection Updates { get; set; } = new ObservableCollection(); - private readonly ApplicationConfigService _applicationConfigService; private SetModImageCommand _setModImageCommand; private Action? _close; /// - public EditModDialogViewModel(PathTuple modTuple, ApplicationConfigService applicationConfigService, ModConfigService modConfigService) + public EditModDialogViewModel(PathTuple modTuple, ObservableCollection> appItems, ObservableCollection> modsItems) { - _applicationConfigService = applicationConfigService; ConfigTuple = modTuple; Config = modTuple.Config; @@ -82,7 +80,7 @@ public EditModDialogViewModel(PathTuple modTuple, ApplicationConfigSe 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); @@ -90,7 +88,7 @@ public EditModDialogViewModel(PathTuple modTuple, ApplicationConfigSe } // 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); diff --git a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/DownloadPackagesViewModel.cs b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/DownloadPackagesViewModel.cs index 4d946b2e..16bf6357 100644 --- a/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/DownloadPackagesViewModel.cs +++ b/source/Reloaded.Mod.Launcher.Lib/Models/ViewModel/DownloadPackagesViewModel.cs @@ -294,6 +294,8 @@ public void Execute(object? parameter) _viewModel.DownloadPackageStatus = DownloadPackageStatus.Downloading; try { + var modConfigService = IoC.GetConstant(); + var modsBefore = new Dictionary>(modConfigService.ItemsById); _canExecute = false; RaiseCanExecute(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); @@ -307,6 +309,40 @@ public void Execute(object? parameter) await Update.ResolveMissingPackagesAsync(); }); + modConfigService.ForceRefresh(); + var newConfigs = new List(); + 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().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().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().Items, modConfigService.Items); + viewmodel.Page = EditModPage.Special; + var createModDialog = Actions.EditModDialog(viewmodel, null); + } + } + } + } + _canExecute = true; RaiseCanExecute(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } diff --git a/source/Reloaded.Mod.Launcher.Lib/Startup.cs b/source/Reloaded.Mod.Launcher.Lib/Startup.cs index 091edd40..bd1dd4a2 100644 --- a/source/Reloaded.Mod.Launcher.Lib/Startup.cs +++ b/source/Reloaded.Mod.Launcher.Lib/Startup.cs @@ -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(); + var modConfigDir = loaderConfig.GetModConfigDirectory(); + var modConfig = ModConfig.GetAllMods(modConfigDir); + var allAppsList = ApplicationConfig.GetAllApplications(loaderConfig.GetApplicationConfigDirectory()); + var allApps = new ObservableCollection>(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); @@ -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>(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().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, diff --git a/source/Reloaded.Mod.Launcher.Lib/Static/Resources.cs b/source/Reloaded.Mod.Launcher.Lib/Static/Resources.cs index 00014d0b..126c547f 100644 --- a/source/Reloaded.Mod.Launcher.Lib/Static/Resources.cs +++ b/source/Reloaded.Mod.Launcher.Lib/Static/Resources.cs @@ -220,9 +220,18 @@ public static void Init(IDictionaryResourceProvider provider) 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) + // Update 1.29.3: New Progress Window for Local Mod Installation 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 + + // 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 NoAppsInConfigTitle { get; set; } + public static IDictionaryResource NoAppsInConfigDescription { get; set; } + public static IDictionaryResource NoCompatibleAppsInConfigTitle { get; set; } + public static IDictionaryResource NoCompatibleAppsInConfigDescription { get; set; } + public static IDictionaryResource AppSelectionQuestion { get; set; } + public static IDictionaryResource Yes { get; set; } + public static IDictionaryResource No { get; set; } +} diff --git a/source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml b/source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml index 7318188a..6d2d8852 100644 --- a/source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml +++ b/source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml @@ -203,6 +203,13 @@ Mod Name Please wait while we install the mod! Extracting a local mod, please wait! + + + Unable to find any supported app + Reloaded-II was unable to find any supported apps in the mod's config. + Unable to find a compatible app + Reloaded-II was unable to find an installed app which is compatible with this mod. + Do you want to select a supported app manually? 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. @@ -739,4 +746,9 @@ For more info, refer to the tutorial. Don't forget to set correct Publish target Please download the requirements above by using the button below. You may need administrator permissions. + + + Yes + No + \ 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 1bb80223..626f5318 100644 --- a/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs +++ b/source/Reloaded.Mod.Launcher/MainWindow.xaml.cs @@ -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; @@ -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().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().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().Items, modConfigService.Items)); + createModDialog.Owner = System.Windows.Window.GetWindow(this); + createModDialog.RealViewModel.Page = EditModPage.Special; + createModDialog.ShowDialog(); + } + } + } + } if (newConfigs.Count <= 0) diff --git a/source/Reloaded.Mod.Launcher/Pages/BaseSubpages/Dialogs/CreateModDialog.xaml.cs b/source/Reloaded.Mod.Launcher/Pages/BaseSubpages/Dialogs/CreateModDialog.xaml.cs index 526922fa..43c0cbd9 100644 --- a/source/Reloaded.Mod.Launcher/Pages/BaseSubpages/Dialogs/CreateModDialog.xaml.cs +++ b/source/Reloaded.Mod.Launcher/Pages/BaseSubpages/Dialogs/CreateModDialog.xaml.cs @@ -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(), modConfigService)); + var createModDialog = new EditModDialog(new EditModDialogViewModel(mod, Lib.IoC.Get().Items, modConfigService.Items)); createModDialog.Owner = Window.GetWindow(this); createModDialog.ShowDialog(); } diff --git a/source/Reloaded.Mod.Launcher/Pages/Dialogs/XamlResourceMessageBoxOkCancel.xaml.cs b/source/Reloaded.Mod.Launcher/Pages/Dialogs/XamlResourceMessageBoxOkCancel.xaml.cs index 3c87b4af..5565b341 100644 --- a/source/Reloaded.Mod.Launcher/Pages/Dialogs/XamlResourceMessageBoxOkCancel.xaml.cs +++ b/source/Reloaded.Mod.Launcher/Pages/Dialogs/XamlResourceMessageBoxOkCancel.xaml.cs @@ -10,9 +10,9 @@ public class XamlResourceMessageBoxOkCancel : MessageBoxOkCancel } - public XamlResourceMessageBoxOkCancel(string titleResourceName, string descriptionResourceName, string okButtonTextResourceName, string cancelButtonTextResourceName) : base(new XamlResource(titleResourceName).Get(), new XamlResource(descriptionResourceName).Get()) + public XamlResourceMessageBoxOkCancel(string title, string message, string okText, string cancelText) : base(title, message) { - this.CancelBtn.Content = Lib.Static.Resources.ResourceProvider.Get(cancelButtonTextResourceName); - this.OKBtn.Content = Lib.Static.Resources.ResourceProvider.Get(okButtonTextResourceName); + this.OKBtn.Content = okText; + this.CancelBtn.Content = cancelText; } } \ No newline at end of file