From 77a93b585a919058287b215296aa22133b4b3d14 Mon Sep 17 00:00:00 2001 From: Pascal Date: Fri, 27 Jun 2025 11:24:53 +0200 Subject: [PATCH] manager: add proper support for options --- ModpackUpdater.Manager/ModpackInstaller.cs | 45 ++++++++++++++++--- ModpackUpdater.Manager/UpdateCheckOptions.cs | 1 + ModpackUpdater.Manager/UpdateCheckResult.cs | 2 + ModpackUpdater/InstallOption.cs | 3 ++ ModpackUpdater/InstallOptionSet.cs | 2 - .../InstallOptionValueDictionary.cs | 28 ++++++++++++ ModpackUpdater/ModpackInfo.cs | 1 + ModpackUpdater/ModpackUpdater.csproj | 1 + 8 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 ModpackUpdater/InstallOptionValueDictionary.cs diff --git a/ModpackUpdater.Manager/ModpackInstaller.cs b/ModpackUpdater.Manager/ModpackInstaller.cs index 034a466..09863ce 100644 --- a/ModpackUpdater.Manager/ModpackInstaller.cs +++ b/ModpackUpdater.Manager/ModpackInstaller.cs @@ -1,5 +1,6 @@ using Castle.Core.Logging; using Newtonsoft.Json; +using Pilz.Extensions.Collections; using System.IO.Compression; using FileMode = System.IO.FileMode; @@ -76,7 +77,7 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf if (installInfos is not null && installInfos.IsPublic && installInfos.Actions.Count != 0) { - var actions = installInfos.Actions.Where(n => n.Side.IsSide(options.Side) && (!n.IsExtra || options.IncludeExtras)); + var actions = installInfos.Actions.Where(n => n.Side.IsSide(options.Side) && (!n.IsExtra || options.IncludeExtras) && GetOptionValue(options, installInfos, n.TargetOption)); if (actions.Any()) { result.Actions.AddRange(actions); @@ -101,7 +102,7 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf var updatesOrderes = updateInfos.Updates.Where(n => n.IsPublic || options.IncludeNonPublic).OrderByDescending(n => n.Version); var checkingVersionIndex = 0; var checkingVersion = updatesOrderes.ElementAtOrDefault(checkingVersionIndex); - var actionsZeroIndex = result.Actions.Count; // Ensure we insert update actions behind install actions + var actionsZeroIndex = result.Actions.Count; // Ensure we insert update actions BEHIND install actions while (checkingVersion is not null && checkingVersion.Version > result.CurrentVersion) { @@ -113,10 +114,8 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf ResolveInherit(action, installInfos); // Check & add - if (action.Side.IsSide(options.Side) && (!action.IsExtra || options.IncludeExtras) && !result.Actions.Any(n => n.DestPath == action.DestPath)) - { + if (action.Side.IsSide(options.Side) && (!action.IsExtra || options.IncludeExtras) && GetOptionValue(options, installInfos, action.TargetOption) && !result.Actions.Any(n => n.DestPath == action.DestPath)) actionsToAdd.Add(action); - } } result.Actions.InsertRange(actionsZeroIndex, actionsToAdd); @@ -132,6 +131,22 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf result.HasError = true; } + // Check option uninstall actions + result.OptionsAvailable.AddRange(installInfos.OptionSets); // Find used options + result.OptionsEnabled.AddRange(installInfos.OptionSets + .Where(set => set.Side.IsSide(options.Side)) + .SelectMany(set => set.Options + .Where(opt => opt.Side.IsSide(options.Side) && options.Options.GetOptionValue(set, opt)) + .Select(opt => $"{set.Id}.{opt.Id}"))); // Find used options + var uninstallOptionActions = installInfos.OptionSets + .Where(set => set.Side.IsSide(options.Side)) + .SelectMany(set => set.Options + .Where(opt => opt.Side.IsSide(options.Side) && !result.OptionsEnabled.Contains($"{set.Id}.{opt.Id}") && modpackInfo.Options.ContainsKey($"{set.Id}.{opt.Id}")) + .SelectMany(opt => opt.UninstallActions)) + .ForEach(action => ResolveInherit(action, installInfos)) + .Where(action => !result.Actions.Any(n => n.DestPath == action.DestPath)); // Find actions that are not already there + result.Actions.InsertRange(0, uninstallOptionActions); // Add uninstall update actions BEFORE install actions + return result; } @@ -217,6 +232,7 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf } // Save new modpack info + modpackInfo.Options.Clear(); modpackInfo.Version = checkResult.LatestVersion; modpackInfo.ConfigUrl = updateConfig.ConfigUrl; modpackInfo.Save(); @@ -293,4 +309,23 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf return true; } + + private static bool GetOptionValue(UpdateCheckOptions options, InstallInfos installInfos, string optionStr) + { + var optionsStr = optionStr.Split(','); + + foreach (var set in installInfos.OptionSets) + { + if (!set.Side.IsSide(options.Side)) + continue; + + foreach (var opt in set.Options) + { + if (opt.Side.IsSide(options.Side) && optionsStr.Contains($"{set.Id}.{opt.Id}") && options.Options.GetOptionValue(set, opt)) + return true; + } + } + + return false; + } } \ No newline at end of file diff --git a/ModpackUpdater.Manager/UpdateCheckOptions.cs b/ModpackUpdater.Manager/UpdateCheckOptions.cs index 66c3dcc..166bf46 100644 --- a/ModpackUpdater.Manager/UpdateCheckOptions.cs +++ b/ModpackUpdater.Manager/UpdateCheckOptions.cs @@ -8,4 +8,5 @@ public class UpdateCheckOptions public Side Side { get; set; } = Side.Client; public bool IncludeExtras { get; set; } public bool IgnoreInstalledVersion { get; set; } + public InstallOptionValueDictionary Options { get; } = []; } diff --git a/ModpackUpdater.Manager/UpdateCheckResult.cs b/ModpackUpdater.Manager/UpdateCheckResult.cs index 91a155b..1fa00f4 100644 --- a/ModpackUpdater.Manager/UpdateCheckResult.cs +++ b/ModpackUpdater.Manager/UpdateCheckResult.cs @@ -5,6 +5,8 @@ public class UpdateCheckResult public Version CurrentVersion { get; set; } public Version LatestVersion { get; set; } public List Actions { get; private set; } = []; + public List OptionsAvailable { get; } = []; + public List OptionsEnabled { get; } = []; public bool IsInstalled { get; set; } public bool HasError { get; set; } public bool IsInMaintenance { get; set; } diff --git a/ModpackUpdater/InstallOption.cs b/ModpackUpdater/InstallOption.cs index 380fae4..524c27b 100644 --- a/ModpackUpdater/InstallOption.cs +++ b/ModpackUpdater/InstallOption.cs @@ -15,6 +15,9 @@ public class InstallOption : IActionSet [JsonConverter(typeof(StringEnumConverter))] public Side Side { get; set; } = Side.Both; + [DefaultValue(false)] + public bool Default { get; } + public List UninstallActions { get; } = []; IEnumerable IActionSet.Actions => UninstallActions.Cast(); diff --git a/ModpackUpdater/InstallOptionSet.cs b/ModpackUpdater/InstallOptionSet.cs index 9b21af8..a0d98b2 100644 --- a/ModpackUpdater/InstallOptionSet.cs +++ b/ModpackUpdater/InstallOptionSet.cs @@ -18,7 +18,5 @@ public class InstallOptionSet [DefaultValue(false)] public bool Multiselect { get; set; } - public List Defaults { get; } = []; - public List Options { get; } = []; } diff --git a/ModpackUpdater/InstallOptionValueDictionary.cs b/ModpackUpdater/InstallOptionValueDictionary.cs new file mode 100644 index 0000000..fee5690 --- /dev/null +++ b/ModpackUpdater/InstallOptionValueDictionary.cs @@ -0,0 +1,28 @@ +namespace ModpackUpdater; + +public class InstallOptionValueDictionary : Dictionary +{ + public void SetOption(InstallOptionSet set, InstallOption option, bool value) + { + if (!set.Options.Contains(option)) + throw new KeyNotFoundException("Options seems to be not a part of the option set."); + if (option.Default == value) + UnsetOption(set, option); + else + this[$"{set.Id}.{option.Id}"] = value; + } + + public void UnsetOption(InstallOptionSet set, InstallOption option) + { + if (!set.Options.Contains(option)) + throw new KeyNotFoundException("Options seems to be not a part of the option set."); + Remove($"{set.Id}.{option.Id}"); + } + + public bool GetOptionValue(InstallOptionSet set, InstallOption option) + { + if (TryGetValue($"{set.Id}.{option.Id}", out var value)) + return value; + return option.Default; + } +} diff --git a/ModpackUpdater/ModpackInfo.cs b/ModpackUpdater/ModpackInfo.cs index de0c903..bfa9a80 100644 --- a/ModpackUpdater/ModpackInfo.cs +++ b/ModpackUpdater/ModpackInfo.cs @@ -12,6 +12,7 @@ public class ModpackInfo public Version Version { get; set; } public string ConfigUrl { get; set; } public string ExtrasKey { get; set; } + public InstallOptionValueDictionary Options { get; } = []; [JsonIgnore] public string LocaLPath { get; private set; } diff --git a/ModpackUpdater/ModpackUpdater.csproj b/ModpackUpdater/ModpackUpdater.csproj index 8691efb..6d0136d 100644 --- a/ModpackUpdater/ModpackUpdater.csproj +++ b/ModpackUpdater/ModpackUpdater.csproj @@ -7,6 +7,7 @@ + \ No newline at end of file