From fad8c9cfebb4ede83433dbcdc712a54d61c1f6cb Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Sun, 10 Apr 2022 11:13:00 +0200 Subject: [PATCH 01/29] Fix small Misstake. Shame on me. --- QModManager/Patching/StoreDetector.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/QModManager/Patching/StoreDetector.cs b/QModManager/Patching/StoreDetector.cs index c642145a..62eb32f0 100644 --- a/QModManager/Patching/StoreDetector.cs +++ b/QModManager/Patching/StoreDetector.cs @@ -29,7 +29,7 @@ internal static string GetUsedGameStore() } else if (IsEpic(directory)) { - return "Eic Games"; + return "Epic Games"; } else if (IsMSStore(directory)) { @@ -88,7 +88,7 @@ internal static bool NonValidStore(string folder) { if (File.Exists(Path.Combine(folder, file))) { - return false; + return true; } } return false; From e4b53e5138cb252ab7e3a5f5bacc11361494582d Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Sun, 10 Apr 2022 14:18:42 +0200 Subject: [PATCH 02/29] Added internal Modlist Tab --- QModManager/OptionsManager.cs | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index be4921ba..0492c26b 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -6,10 +6,13 @@ using QModManager.Utility; using System.Reflection; using UnityEngine.Events; + using System; + using System.IO; internal static class OptionsManager { internal static int ModsTab; + internal static int ModListTab; [HarmonyPatch(typeof(uGUI_OptionsPanel), nameof(uGUI_OptionsPanel.AddTabs))] internal static class OptionsPatch @@ -17,10 +20,10 @@ internal static class OptionsPatch [HarmonyPostfix] internal static void Postfix(uGUI_OptionsPanel __instance) { + #region Mod Config ModsTab = __instance.AddTab("Mods"); __instance.AddHeading(ModsTab, "QModManager"); - MethodInfo AddToggleOption = null; if(Patcher.CurrentlyRunningGame == QModGame.Subnautica) { @@ -60,7 +63,35 @@ internal static void Postfix(uGUI_OptionsPanel __instance) AddToggleOption.Invoke(__instance, new object[] { ModsTab, "Enable debug logs", Config.EnableDebugLogs, new UnityAction(value => Config.EnableDebugLogs = value), null }); AddToggleOption.Invoke(__instance, new object[] { ModsTab, "Enable developer mode", Config.EnableDevMode, new UnityAction(value => Config.EnableDevMode = value), null }); } + #endregion Mod Config + #region Mod List + ModListTab = __instance.AddTab("Loaded Mods List"); + +#if SUBNAUTICA_STABLE + __instance.AddHeading(ModListTab, $"QModManager Stable for Subnautica running version {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}"); +#elif SUBNAUTICA_EXP + __instance.AddHeading(ModListTab, $"QModManager Experimental for Subnautica running version {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}"); +#elif BELOWZERO_STABLE + __instance.AddHeading(ModListTab, $"QModManager Stable for Below Zero running version {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}"); +#elif BELOWZERO_EXP + __instance.AddHeading(ModListTab, $"QModManager Experimental for Below Zero running version {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}"); +#endif + __instance.AddHeading(ModListTab, $"- - List of currently running Mods - -"); + var mods = QModServices.Main.GetAllMods(); + int modsactivecounter = 0; + + //Maybe add algorithm to sort Mods after Name + foreach (var mod in mods) + { + if(mod.Enable) + { + __instance.AddHeading(ModListTab, $"{mod.DisplayName} version {mod.ParsedVersion.ToString()} from {mod.Author}"); + modsactivecounter++; + } + } + __instance.AddHeading(ModListTab, $"Statistics: {modsactivecounter} Mods activated from {mods.Count} loaded"); + #endregion Mod List } } } From 8f203467f7ee8ad2cebebcb6b7acc1eb56a719e5 Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Sun, 10 Apr 2022 18:30:21 +0200 Subject: [PATCH 03/29] Change to alphabetical sorted Mod List Add Statistic entry --- QModManager/OptionsManager.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index 0492c26b..db1ba8f7 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -6,8 +6,8 @@ using QModManager.Utility; using System.Reflection; using UnityEngine.Events; - using System; - using System.IO; + using System.Collections.Generic; + using System.Linq; internal static class OptionsManager { @@ -66,7 +66,7 @@ internal static void Postfix(uGUI_OptionsPanel __instance) #endregion Mod Config #region Mod List - ModListTab = __instance.AddTab("Loaded Mods List"); + ModListTab = __instance.AddTab("QMods List"); #if SUBNAUTICA_STABLE __instance.AddHeading(ModListTab, $"QModManager Stable for Subnautica running version {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}"); @@ -77,11 +77,12 @@ internal static void Postfix(uGUI_OptionsPanel __instance) #elif BELOWZERO_EXP __instance.AddHeading(ModListTab, $"QModManager Experimental for Below Zero running version {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}"); #endif + __instance.AddHeading(ModListTab, $"- - List of currently running Mods - -"); - var mods = QModServices.Main.GetAllMods(); + + IEnumerable mods = QModServices.Main.GetAllMods().OrderBy(mod => mod.Id); int modsactivecounter = 0; - //Maybe add algorithm to sort Mods after Name foreach (var mod in mods) { if(mod.Enable) @@ -90,7 +91,10 @@ internal static void Postfix(uGUI_OptionsPanel __instance) modsactivecounter++; } } - __instance.AddHeading(ModListTab, $"Statistics: {modsactivecounter} Mods activated from {mods.Count} loaded"); + + __instance.AddHeading(ModListTab, $"- - Statistics - -"); + __instance.AddHeading(ModListTab, $"{modsactivecounter} Mods activated from {mods.Count()} loaded"); + __instance.AddHeading(ModListTab, $"{mods.Count() - modsactivecounter} Mods inactive from {mods.Count()} total"); #endregion Mod List } } From 8d11859ddd3b872377f9a9a7a67d10514538345b Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Mon, 11 Apr 2022 19:45:22 +0200 Subject: [PATCH 04/29] integrated deactivated Mod list + improvments --- QModManager/OptionsManager.cs | 42 +++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index db1ba8f7..437e5c9f 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -77,24 +77,48 @@ internal static void Postfix(uGUI_OptionsPanel __instance) #elif BELOWZERO_EXP __instance.AddHeading(ModListTab, $"QModManager Experimental for Below Zero running version {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}"); #endif - - __instance.AddHeading(ModListTab, $"- - List of currently running Mods - -"); + var modprio_sml = QModServices.Main.GetMod("SMLHelper"); + if (modprio_sml != null) + { + __instance.AddHeading(ModListTab, $"{modprio_sml.DisplayName} {(modprio_sml.Enable ? $"v{modprio_sml.ParsedVersion}" : $"")} {(modprio_sml.IsLoaded ? "is activated" : "is deactivated")}"); + } + else + { + __instance.AddHeading(ModListTab, $"SML Helper is not installed"); + } - IEnumerable mods = QModServices.Main.GetAllMods().OrderBy(mod => mod.Id); - int modsactivecounter = 0; + IEnumerable mods = QModServices.Main.GetAllMods().OrderBy(mod => mod.DisplayName); + List activeMods = new List(); + List inactiveMods = new List(); foreach (var mod in mods) { - if(mod.Enable) + if (mod.Enable) + { + activeMods.Add(mod); + } + else { - __instance.AddHeading(ModListTab, $"{mod.DisplayName} version {mod.ParsedVersion.ToString()} from {mod.Author}"); - modsactivecounter++; + inactiveMods.Add(mod); } } __instance.AddHeading(ModListTab, $"- - Statistics - -"); - __instance.AddHeading(ModListTab, $"{modsactivecounter} Mods activated from {mods.Count()} loaded"); - __instance.AddHeading(ModListTab, $"{mods.Count() - modsactivecounter} Mods inactive from {mods.Count()} total"); + __instance.AddHeading(ModListTab, $"{activeMods.Count} Mods activated from {mods.Count()} loaded"); + __instance.AddHeading(ModListTab, $"{inactiveMods.Count} Mods inactive from {mods.Count()} total"); + + __instance.AddHeading(ModListTab, $"- - List of currently running Mods - -"); + foreach (var mod in activeMods) + { + __instance.AddHeading(ModListTab, $"{mod.DisplayName} v{mod.ParsedVersion.ToString()} from {mod.Author}"); + } + + __instance.AddHeading(ModListTab, $"- - List of Disabled Mods - -"); + + foreach (var mod in inactiveMods) + { + __instance.AddHeading(ModListTab, $"{mod.DisplayName} from {mod.Author}"); + } #endregion Mod List } } From 8f2842b755b822db650acc350167cf6e4d93871a Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Mon, 11 Apr 2022 20:11:08 +0200 Subject: [PATCH 05/29] reduce overhead + clearup appearance --- QModManager/OptionsManager.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index 437e5c9f..f276d74e 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -66,17 +66,16 @@ internal static void Postfix(uGUI_OptionsPanel __instance) #endregion Mod Config #region Mod List + //Create new Tab in the Menu ModListTab = __instance.AddTab("QMods List"); -#if SUBNAUTICA_STABLE - __instance.AddHeading(ModListTab, $"QModManager Stable for Subnautica running version {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}"); -#elif SUBNAUTICA_EXP - __instance.AddHeading(ModListTab, $"QModManager Experimental for Subnautica running version {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}"); -#elif BELOWZERO_STABLE - __instance.AddHeading(ModListTab, $"QModManager Stable for Below Zero running version {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}"); -#elif BELOWZERO_EXP - __instance.AddHeading(ModListTab, $"QModManager Experimental for Below Zero running version {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}"); + //Add QMM Informations +#if SUBNAUTICA_EXP || BELOWZERO_EXP + __instance.AddHeading(ModListTab, $"QModManager -Experimental- running version {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}"); +#else + __instance.AddHeading(ModListTab, $"QModManager running version {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}"); #endif + //Add SML Informations var modprio_sml = QModServices.Main.GetMod("SMLHelper"); if (modprio_sml != null) { @@ -104,8 +103,9 @@ internal static void Postfix(uGUI_OptionsPanel __instance) } __instance.AddHeading(ModListTab, $"- - Statistics - -"); - __instance.AddHeading(ModListTab, $"{activeMods.Count} Mods activated from {mods.Count()} loaded"); - __instance.AddHeading(ModListTab, $"{inactiveMods.Count} Mods inactive from {mods.Count()} total"); + __instance.AddHeading(ModListTab, $"{mods.Count()} Mods found"); + __instance.AddHeading(ModListTab, $"{activeMods.Count} Mods enabled"); + __instance.AddHeading(ModListTab, $"{inactiveMods.Count} Mods disabled"); __instance.AddHeading(ModListTab, $"- - List of currently running Mods - -"); foreach (var mod in activeMods) From 0e0c2ab19e5838b45bd832abf37465b6906c6ed2 Mon Sep 17 00:00:00 2001 From: Metious <71298690+Metious@users.noreply.github.com> Date: Thu, 14 Apr 2022 16:35:00 +0430 Subject: [PATCH 06/29] Coding consistency cleanup from previous PR --- QModManager/Checks/PirateCheck.cs | 17 +++++----- QModManager/Patching/StoreDetector.cs | 49 ++++++++++++--------------- 2 files changed, 29 insertions(+), 37 deletions(-) diff --git a/QModManager/Checks/PirateCheck.cs b/QModManager/Checks/PirateCheck.cs index 3ef1e34b..b068a768 100644 --- a/QModManager/Checks/PirateCheck.cs +++ b/QModManager/Checks/PirateCheck.cs @@ -7,13 +7,12 @@ namespace QModManager.Checks { internal static class PirateCheck { - internal static string Steamapi => "steam_api64.dll"; - internal static int Steamapilengh => 220000; - - - internal static string folder = Environment.CurrentDirectory; + internal const string SteamApiName = "steam_api64.dll"; + internal const int SteamApiLength = 220000; internal static bool PirateDetected; + private static readonly string _folder = Environment.CurrentDirectory; + internal static readonly HashSet CrackedFiles = new HashSet() { "steam_api64.cdx", @@ -32,12 +31,12 @@ internal static class PirateCheck internal static void IsPirate() { - string steamDll = Path.Combine(folder, Steamapi); + string steamDll = Path.Combine(_folder, SteamApiName); bool steamStore = File.Exists(steamDll); if (steamStore) { FileInfo fileInfo = new FileInfo(steamDll); - if (fileInfo.Length > Steamapilengh) + if (fileInfo.Length > SteamApiLength) { PirateDetected = true; } @@ -47,7 +46,7 @@ internal static void IsPirate() { foreach (string file in CrackedFiles) { - if (File.Exists(Path.Combine(folder, file))) + if (File.Exists(Path.Combine(_folder, file))) { PirateDetected = true; break; @@ -55,7 +54,7 @@ internal static void IsPirate() } } - Logger.Info(PirateDetected? "Ahoy, matey! Ye be a pirate!":"Seems Legit."); + Logger.Info(PirateDetected ? "Ahoy, matey! Ye be a pirate!" : "Seems legit."); } } } diff --git a/QModManager/Patching/StoreDetector.cs b/QModManager/Patching/StoreDetector.cs index 62eb32f0..3235c0e7 100644 --- a/QModManager/Patching/StoreDetector.cs +++ b/QModManager/Patching/StoreDetector.cs @@ -1,47 +1,40 @@ -namespace QModManager.Patching -{ - using System; - using System.IO; - using Checks; +using System; +using System.IO; +using QModManager.Checks; +namespace QModManager.Patching +{ internal class StoreDetector { internal static string GetUsedGameStore() { - string directory = null; - - try - { - directory ??= Environment.CurrentDirectory; - } - catch - { - return "Error on getting Store"; - } + var directory = Environment.CurrentDirectory;; + if (NonValidStore(directory)) { return "free Store"; } - else if (IsSteam(directory)) + + if (IsSteam(directory)) { return "Steam"; } - else if (IsEpic(directory)) + + if (IsEpic(directory)) { return "Epic Games"; } - else if (IsMSStore(directory)) + + if (IsMSStore(directory)) { return "MSStore"; } - else - { - return "was not able to identify Store"; - } + + return "was not able to identify Store"; } - internal static bool IsSteam(string directory) + private static bool IsSteam(string directory) { string checkfile = Path.Combine(directory, "steam_api64.dll"); if (File.Exists(checkfile)) @@ -51,7 +44,7 @@ internal static bool IsSteam(string directory) return false; } - internal static bool IsEpic(string directory) + private static bool IsEpic(string directory) { string checkfolder = Path.Combine(directory, ".eggstore"); if (Directory.Exists(checkfolder)) @@ -61,7 +54,7 @@ internal static bool IsEpic(string directory) return false; } - internal static bool IsMSStore(string directory) + private static bool IsMSStore(string directory) { string checkfile = Path.Combine(directory, "MicrosoftGame.config"); if (File.Exists(checkfile)) @@ -71,14 +64,14 @@ internal static bool IsMSStore(string directory) return false; } - internal static bool NonValidStore(string folder) + private static bool NonValidStore(string folder) { - string steamDll = Path.Combine(folder, PirateCheck.Steamapi); + string steamDll = Path.Combine(folder, PirateCheck.SteamApiName); if (File.Exists(steamDll)) { FileInfo fileInfo = new FileInfo(steamDll); - if (fileInfo.Length > PirateCheck.Steamapilengh) + if (fileInfo.Length > PirateCheck.SteamApiLength) { return true; } From a125c8df6eb722534312bb6aa67441067f5a1bf8 Mon Sep 17 00:00:00 2001 From: Metious <71298690+Metious@users.noreply.github.com> Date: Thu, 14 Apr 2022 16:42:32 +0430 Subject: [PATCH 07/29] Better game store checks --- QModManager/Patching/StoreDetector.cs | 65 ++++++--------------------- 1 file changed, 14 insertions(+), 51 deletions(-) diff --git a/QModManager/Patching/StoreDetector.cs b/QModManager/Patching/StoreDetector.cs index 3235c0e7..3e03dd0b 100644 --- a/QModManager/Patching/StoreDetector.cs +++ b/QModManager/Patching/StoreDetector.cs @@ -1,5 +1,4 @@ using System; -using System.IO; using QModManager.Checks; namespace QModManager.Patching @@ -8,83 +7,47 @@ internal class StoreDetector { internal static string GetUsedGameStore() { - var directory = Environment.CurrentDirectory;; - - - if (NonValidStore(directory)) + if (NonValidStore()) { - return "free Store"; + return "Invalid store"; } - if (IsSteam(directory)) + if (IsSteam()) { return "Steam"; } - if (IsEpic(directory)) + if (IsEpic()) { return "Epic Games"; } - if (IsMSStore(directory)) + if (IsMSStore()) { return "MSStore"; } - return "was not able to identify Store"; + return "Unable to identify game store."; } - private static bool IsSteam(string directory) + private static bool IsSteam() { - string checkfile = Path.Combine(directory, "steam_api64.dll"); - if (File.Exists(checkfile)) - { - return true; - } - return false; + return PlatformServicesUtils.IsRuntimePluginDllPresent("CSteamworks"); } - private static bool IsEpic(string directory) + private static bool IsEpic() { - string checkfolder = Path.Combine(directory, ".eggstore"); - if (Directory.Exists(checkfolder)) - { - return true; - } - return false; + return Array.IndexOf(Environment.GetCommandLineArgs(), "-EpicPortal") != -1; } - private static bool IsMSStore(string directory) + private static bool IsMSStore() { - string checkfile = Path.Combine(directory, "MicrosoftGame.config"); - if (File.Exists(checkfile)) - { - return true; - } - return false; + return PlatformServicesUtils.IsRuntimePluginDllPresent("XGamingRuntimeThunks"); } - private static bool NonValidStore(string folder) + private static bool NonValidStore() { - string steamDll = Path.Combine(folder, PirateCheck.SteamApiName); - if (File.Exists(steamDll)) - { - FileInfo fileInfo = new FileInfo(steamDll); - - if (fileInfo.Length > PirateCheck.SteamApiLength) - { - return true; - } - } - - foreach (string file in PirateCheck.CrackedFiles) - { - if (File.Exists(Path.Combine(folder, file))) - { - return true; - } - } - return false; + return PirateCheck.PirateDetected; } } } From b33e15d9508fc3c741f4e6d7b4a158c6ccddd7d7 Mon Sep 17 00:00:00 2001 From: desperationfighter <76217485+desperationfighter@users.noreply.github.com> Date: Thu, 14 Apr 2022 16:14:24 +0200 Subject: [PATCH 08/29] Update QModManager/OptionsManager.cs Co-authored-by: Metious <71298690+Metious@users.noreply.github.com> --- QModManager/OptionsManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index f276d74e..6a6c3cc2 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -79,7 +79,7 @@ internal static void Postfix(uGUI_OptionsPanel __instance) var modprio_sml = QModServices.Main.GetMod("SMLHelper"); if (modprio_sml != null) { - __instance.AddHeading(ModListTab, $"{modprio_sml.DisplayName} {(modprio_sml.Enable ? $"v{modprio_sml.ParsedVersion}" : $"")} {(modprio_sml.IsLoaded ? "is activated" : "is deactivated")}"); + __instance.AddHeading(ModListTab, $"{modprio_sml.DisplayName} {(modprio_sml.Enable ? $"v{modprio_sml.ParsedVersion}" : string.Empty)} is {(modprio_sml.IsLoaded ? "enabled" : "disabled")}"); } else { From 12e450305113983f8b157a0f1712fdad112ce79c Mon Sep 17 00:00:00 2001 From: desperationfighter <76217485+desperationfighter@users.noreply.github.com> Date: Thu, 14 Apr 2022 16:14:37 +0200 Subject: [PATCH 09/29] Update QModManager/OptionsManager.cs Co-authored-by: Metious <71298690+Metious@users.noreply.github.com> --- QModManager/OptionsManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index 6a6c3cc2..b1db99a0 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -83,7 +83,7 @@ internal static void Postfix(uGUI_OptionsPanel __instance) } else { - __instance.AddHeading(ModListTab, $"SML Helper is not installed"); + __instance.AddHeading(ModListTab, $"SMLHelper is not installed"); } IEnumerable mods = QModServices.Main.GetAllMods().OrderBy(mod => mod.DisplayName); From 59cd0f698bfbf78c73bb71cd37fe2d4702dae0e6 Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Thu, 14 Apr 2022 23:22:02 +0200 Subject: [PATCH 10/29] First try of getting the enable disable Check box --- QModManager/OptionsManager.cs | 56 +++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index b1db99a0..6d57f6b3 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -13,6 +13,9 @@ internal static class OptionsManager { internal static int ModsTab; internal static int ModListTab; + internal static List modlist; + internal static List modchanges; + [HarmonyPatch(typeof(uGUI_OptionsPanel), nameof(uGUI_OptionsPanel.AddTabs))] internal static class OptionsPatch @@ -92,6 +95,13 @@ internal static void Postfix(uGUI_OptionsPanel __instance) foreach (var mod in mods) { + ModDataTemplate _tmpmod = new ModDataTemplate(); + _tmpmod.ID = mod.Id; + _tmpmod.AssemblyName = mod.AssemblyName; + _tmpmod.LoadedAssembly = mod.LoadedAssembly; + _tmpmod.Enabled = mod.Enable; + modlist.Add(_tmpmod); + if (mod.Enable) { activeMods.Add(mod); @@ -111,6 +121,17 @@ internal static void Postfix(uGUI_OptionsPanel __instance) foreach (var mod in activeMods) { __instance.AddHeading(ModListTab, $"{mod.DisplayName} v{mod.ParsedVersion.ToString()} from {mod.Author}"); + + MethodInfo Modlist_AddToggleOption = null; + Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(Modlist_AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); + //Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", mod.Enable, new UnityAction(value => activeMods[(activeMods.IndexOf(mod))].Enable = value) }); + + //int index = modlist.IndexOf(modlist.Where(mdt => mdt.ID.ToString() == mod.Id.ToString()).FirstOrDefault()); + //Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", modlist[index].Enabled , new UnityAction(value => modlist[index].Enabled = value) }); + //Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", modlist[index].Enabled, MyOnchangeMethode(Mod.id; value) }); + //Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", modlist[index].Enabled, new UnityAction(value => MyOnchangeMethode(modlist[index].ID, value)) }); + + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", mod.Enable, new UnityAction(value => MyOnchangeMethode(mod.Id, value)) }); } __instance.AddHeading(ModListTab, $"- - List of Disabled Mods - -"); @@ -121,6 +142,41 @@ internal static void Postfix(uGUI_OptionsPanel __instance) } #endregion Mod List } + + static void MyOnchangeMethode(string id, bool status) + { + ModDataTemplate _tmpmod = modlist.Where(mdt => mdt.ID.ToString() == id).FirstOrDefault(); + if (_tmpmod == null ) + { + _tmpmod.Enabled = status; + modchanges.Add(_tmpmod); + } + else + { + //theoretical i don't need that if statement because if the Mod is already in the List there is only the possibility of removing it anyway when only 2 status exist ??? + if(_tmpmod.Enabled != status) + { + modchanges.Remove(_tmpmod); + } + } + + if(modchanges.Count == 0) + { + //disable Apply Button + } + else + { + //enable Apply Button + } + } + } + + internal class ModDataTemplate + { + public string ID { get; set; } + public Assembly LoadedAssembly { get; set; } + public string AssemblyName { get; set; } + public bool Enabled { get; set; } } } } From 4f0d5a402d06cb4c449c6877a7e1f287dd631cc7 Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Sun, 17 Apr 2022 16:21:53 +0200 Subject: [PATCH 11/29] First test to implement a List of chaning mods --- QModManager/OptionsManager.cs | 148 ++++++++++++++++++++++++++++------ 1 file changed, 123 insertions(+), 25 deletions(-) diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index 6d57f6b3..fc70cd5f 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -8,18 +8,20 @@ using UnityEngine.Events; using System.Collections.Generic; using System.Linq; + using System; internal static class OptionsManager - { + { internal static int ModsTab; internal static int ModListTab; - internal static List modlist; - internal static List modchanges; - - + [HarmonyPatch(typeof(uGUI_OptionsPanel), nameof(uGUI_OptionsPanel.AddTabs))] internal static class OptionsPatch { + public static List modlist; + public static List modchanges { get; set; } + //internal static bool testbool { get; set; } + [HarmonyPostfix] internal static void Postfix(uGUI_OptionsPanel __instance) { @@ -69,6 +71,10 @@ internal static void Postfix(uGUI_OptionsPanel __instance) #endregion Mod Config #region Mod List + Logger.Log(Logger.Level.Debug, "OptionsMenu - Start creating Modlist"); + modlist = null; + modchanges = null; + //Create new Tab in the Menu ModListTab = __instance.AddTab("QMods List"); @@ -83,6 +89,15 @@ internal static void Postfix(uGUI_OptionsPanel __instance) if (modprio_sml != null) { __instance.AddHeading(ModListTab, $"{modprio_sml.DisplayName} {(modprio_sml.Enable ? $"v{modprio_sml.ParsedVersion}" : string.Empty)} is {(modprio_sml.IsLoaded ? "enabled" : "disabled")}"); + + + //*** Test + //testbool = modprio_sml.Enable; + //MethodInfo SML_AddToggleOption = null; + //SML_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); + //SML_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", testbool, new UnityAction(value => testbool = value ) }); + //SML_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", modprio_sml.Enable , new UnityAction(value => MyOnchangeMethode(modprio_sml.Id, value) ) }); + } else { @@ -93,23 +108,37 @@ internal static void Postfix(uGUI_OptionsPanel __instance) List activeMods = new List(); List inactiveMods = new List(); + ModDataTemplate _tmpmod = new ModDataTemplate(); foreach (var mod in mods) { - ModDataTemplate _tmpmod = new ModDataTemplate(); - _tmpmod.ID = mod.Id; - _tmpmod.AssemblyName = mod.AssemblyName; - _tmpmod.LoadedAssembly = mod.LoadedAssembly; - _tmpmod.Enabled = mod.Enable; - modlist.Add(_tmpmod); - if (mod.Enable) { activeMods.Add(mod); + } else { inactiveMods.Add(mod); } + + try + { + //_tmpmod.ID = mod.Id; + /* + if (mod.LoadedAssembly != null) + { + _tmpmod.AssemblyName = mod.AssemblyName; + _tmpmod.LoadedAssembly = mod.LoadedAssembly; + } + */ + //_tmpmod.Enabled = mod.Enable; + //modlist.Add(_tmpmod); + } + catch + { + Logger.Log(Logger.Level.Debug, "123456789 - Error on adding Temp Mod to Modlist"); + } + } __instance.AddHeading(ModListTab, $"- - Statistics - -"); @@ -123,15 +152,16 @@ internal static void Postfix(uGUI_OptionsPanel __instance) __instance.AddHeading(ModListTab, $"{mod.DisplayName} v{mod.ParsedVersion.ToString()} from {mod.Author}"); MethodInfo Modlist_AddToggleOption = null; - Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(Modlist_AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); - //Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", mod.Enable, new UnityAction(value => activeMods[(activeMods.IndexOf(mod))].Enable = value) }); + Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); + //int index = modlist.IndexOf(modlist.Where(mdt => mdt.ID.ToString() == mod.Id.ToString()).FirstOrDefault()); //Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", modlist[index].Enabled , new UnityAction(value => modlist[index].Enabled = value) }); + //Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", modlist[index].Enabled, MyOnchangeMethode(Mod.id; value) }); //Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", modlist[index].Enabled, new UnityAction(value => MyOnchangeMethode(modlist[index].ID, value)) }); - Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", mod.Enable, new UnityAction(value => MyOnchangeMethode(mod.Id, value)) }); + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", mod.Enable, new UnityAction(value => MyOnChangeMethode(__instance, mod.Id, value)) }); } __instance.AddHeading(ModListTab, $"- - List of Disabled Mods - -"); @@ -140,27 +170,89 @@ internal static void Postfix(uGUI_OptionsPanel __instance) { __instance.AddHeading(ModListTab, $"{mod.DisplayName} from {mod.Author}"); } + + Logger.Log(Logger.Level.Debug, "OptionsMenu - Creating Modlist Ending"); #endregion Mod List } - static void MyOnchangeMethode(string id, bool status) + static void MyOnChangeMethode(uGUI_OptionsPanel __instance, string id, bool status) { - ModDataTemplate _tmpmod = modlist.Where(mdt => mdt.ID.ToString() == id).FirstOrDefault(); - if (_tmpmod == null ) + + Logger.Log(Logger.Level.Debug, "WOLOLOLOLOLO - enter MyOnChangeMethode"); + + Logger.Log(Logger.Level.Debug, $"WOLOLOLOLOLO - the submit id is {id} and the Status is {status}"); + + ModDataTemplate _tmpmod = new ModDataTemplate(); + IEnumerable _tmpmodlist; + + //try + //{ + Logger.Log(Logger.Level.Debug, "WOLOLOLOLOLO - searched Mod"); + try { - _tmpmod.Enabled = status; - modchanges.Add(_tmpmod); + //_tmpmod = modlist.Where(mdt => mdt.ID.ToString() == id).FirstOrDefault(); + + if(modlist.Count == 0) + { + Logger.Log(Logger.Level.Debug, $"modlistcount is Zero"); + _tmpmodlist = null; + } + else + { + Logger.Log(Logger.Level.Debug, $"modlistcount not Zero"); + _tmpmodlist = modlist.Where(mdt => mdt.ID == id); + + foreach (ModDataTemplate test in _tmpmodlist) + { + Logger.Log(Logger.Level.Debug, $"WOLOLOLOLOLO - found mod {test.ID}"); + } + } + + } + catch (Exception e) + { + throw e; + } + /* + catch + { + Logger.Log(Logger.Level.Debug, "WOLOLOLOLOLO - ERROR - searched Mod"); + } + */ + + if (_tmpmod == null) + { + Logger.Log(Logger.Level.Debug, "WOLOLOLOLOLO - Mod is not null"); + try + { + Logger.Log(Logger.Level.Debug, "WOLOLOLOLOLO - Adding mod to change list"); + _tmpmod.Enabled = status; + modchanges.Add(_tmpmod); + } + catch + { + Logger.Log(Logger.Level.Debug, "WOLOLOLOLOLO - ERROR - Adding mod to change list"); + } } else { //theoretical i don't need that if statement because if the Mod is already in the List there is only the possibility of removing it anyway when only 2 status exist ??? - if(_tmpmod.Enabled != status) + if (_tmpmod.Enabled != status) { - modchanges.Remove(_tmpmod); + try + { + Logger.Log(Logger.Level.Debug, "WOLOLOLOLOLO - remove mod from list again."); + modchanges.Remove(_tmpmod); + } + catch + { + Logger.Log(Logger.Level.Debug, "WOLOLOLOLOLO - remove mod from list again."); + } + } } - if(modchanges.Count == 0) + if (modchanges.Count == 0) { //disable Apply Button } @@ -168,14 +260,20 @@ static void MyOnchangeMethode(string id, bool status) { //enable Apply Button } + //} + //catch + //{ + //Logger.Log(Logger.Level.Debug, "123456789 - Error on MyOnChangeMethode"); + //} + } } internal class ModDataTemplate { public string ID { get; set; } - public Assembly LoadedAssembly { get; set; } - public string AssemblyName { get; set; } + //public Assembly LoadedAssembly { get; set; } + //public string AssemblyName { get; set; } public bool Enabled { get; set; } } } From c74fbc7423fb02e9540023a5182d5da8e6ff1450 Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Sun, 17 Apr 2022 17:02:56 +0200 Subject: [PATCH 12/29] backup --- QModManager/OptionsManager.cs | 55 ++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index fc70cd5f..d1592ddf 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -72,8 +72,10 @@ internal static void Postfix(uGUI_OptionsPanel __instance) #region Mod List Logger.Log(Logger.Level.Debug, "OptionsMenu - Start creating Modlist"); - modlist = null; - modchanges = null; + //modlist = null; + modlist = new List(); + //modchanges = null; + modchanges = new List(); //Create new Tab in the Menu ModListTab = __instance.AddTab("QMods List"); @@ -108,7 +110,6 @@ internal static void Postfix(uGUI_OptionsPanel __instance) List activeMods = new List(); List inactiveMods = new List(); - ModDataTemplate _tmpmod = new ModDataTemplate(); foreach (var mod in mods) { if (mod.Enable) @@ -121,22 +122,27 @@ internal static void Postfix(uGUI_OptionsPanel __instance) inactiveMods.Add(mod); } + ModDataTemplate _tmpmod = new ModDataTemplate(); try { - //_tmpmod.ID = mod.Id; - /* + _tmpmod.ID = mod.Id; + if (mod.LoadedAssembly != null) { - _tmpmod.AssemblyName = mod.AssemblyName; - _tmpmod.LoadedAssembly = mod.LoadedAssembly; + Logger.Log(Logger.Level.Debug, $"NANANANANANA - Just checking {mod.DisplayName} ; {mod.AssemblyName} ; {mod.LoadedAssembly.Location}"); + _tmpmod.PathToAssemblyFile = mod.LoadedAssembly.Location; + } + else + { + Logger.Log(Logger.Level.Debug, $"NANANANANANA - Just checking {mod.DisplayName} has no Loaded Assembly"); } - */ - //_tmpmod.Enabled = mod.Enable; - //modlist.Add(_tmpmod); + + _tmpmod.Enabled = mod.Enable; + modlist.Add(_tmpmod); } catch { - Logger.Log(Logger.Level.Debug, "123456789 - Error on adding Temp Mod to Modlist"); + Logger.Log(Logger.Level.Debug, "NANANANANANA - Error on adding Temp Mod to Modlist"); } } @@ -183,7 +189,7 @@ static void MyOnChangeMethode(uGUI_OptionsPanel __instance, string id, bool stat Logger.Log(Logger.Level.Debug, $"WOLOLOLOLOLO - the submit id is {id} and the Status is {status}"); ModDataTemplate _tmpmod = new ModDataTemplate(); - IEnumerable _tmpmodlist; + //IEnumerable _tmpmodlist; //try //{ @@ -191,27 +197,31 @@ static void MyOnChangeMethode(uGUI_OptionsPanel __instance, string id, bool stat try { //_tmpmod = modlist.Where(mdt => mdt.ID.ToString() == id).FirstOrDefault(); - + + //Check if the Modlist contains any Mods if(modlist.Count == 0) { + //If not i do not need to search for Mods already in Logger.Log(Logger.Level.Debug, $"modlistcount is Zero"); - _tmpmodlist = null; + _tmpmod = null; + //_tmpmodlist = null; } else { Logger.Log(Logger.Level.Debug, $"modlistcount not Zero"); - _tmpmodlist = modlist.Where(mdt => mdt.ID == id); + _tmpmod = modlist.Where(mdt => mdt.ID.ToString() == id).FirstOrDefault(); + //_tmpmodlist = modlist.Where(mdt => mdt.ID == id); - foreach (ModDataTemplate test in _tmpmodlist) - { - Logger.Log(Logger.Level.Debug, $"WOLOLOLOLOLO - found mod {test.ID}"); - } + //foreach (ModDataTemplate test in _tmpmodlist) + //{ + //Logger.Log(Logger.Level.Debug, $"WOLOLOLOLOLO - found mod {test.ID}"); + //} } } - catch (Exception e) + catch { - throw e; + } /* catch @@ -272,8 +282,7 @@ static void MyOnChangeMethode(uGUI_OptionsPanel __instance, string id, bool stat internal class ModDataTemplate { public string ID { get; set; } - //public Assembly LoadedAssembly { get; set; } - //public string AssemblyName { get; set; } + public string PathToAssemblyFile { get; set; } public bool Enabled { get; set; } } } From 96c55d8514adf5d2806d9ceab271ae7320722d12 Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Sun, 17 Apr 2022 20:29:27 +0200 Subject: [PATCH 13/29] Onchange Methode cleared up --- .../DataStructures/SimpleModDataTemplate.cs | 9 ++ QModManager/OptionsManager.cs | 148 +++++------------- QModManager/QModManager.csproj | 1 + QModManager/Utility/IOUtilities.cs | 2 + 4 files changed, 53 insertions(+), 107 deletions(-) create mode 100644 QModManager/DataStructures/SimpleModDataTemplate.cs diff --git a/QModManager/DataStructures/SimpleModDataTemplate.cs b/QModManager/DataStructures/SimpleModDataTemplate.cs new file mode 100644 index 00000000..1315a76c --- /dev/null +++ b/QModManager/DataStructures/SimpleModDataTemplate.cs @@ -0,0 +1,9 @@ +namespace QModManager.DataStructures +{ + internal class SimpleModDataTemplate + { + public string ID { get; set; } + public string PathToAssemblyFile { get; set; } + public bool Enabled { get; set; } + } +} diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index d1592ddf..1fc84126 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -18,8 +18,8 @@ internal static class OptionsManager [HarmonyPatch(typeof(uGUI_OptionsPanel), nameof(uGUI_OptionsPanel.AddTabs))] internal static class OptionsPatch { - public static List modlist; - public static List modchanges { get; set; } + internal static List ModList; + public static List ModListPendingChanges; //internal static bool testbool { get; set; } [HarmonyPostfix] @@ -71,11 +71,15 @@ internal static void Postfix(uGUI_OptionsPanel __instance) #endregion Mod Config #region Mod List + //Start creating Ingame Mod List Logger.Log(Logger.Level.Debug, "OptionsMenu - Start creating Modlist"); - //modlist = null; - modlist = new List(); - //modchanges = null; - modchanges = new List(); + + //Reset ModList and Pending Changes on Relead the List Menu - We do not want to save any Data or take over Data from previous time here + ModList = new List(); + ModListPendingChanges = new List(); + IEnumerable mods = QModServices.Main.GetAllMods().OrderBy(mod => mod.DisplayName); + List activeMods = new List(); + List inactiveMods = new List(); //Create new Tab in the Menu ModListTab = __instance.AddTab("QMods List"); @@ -86,30 +90,18 @@ internal static void Postfix(uGUI_OptionsPanel __instance) #else __instance.AddHeading(ModListTab, $"QModManager running version {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}"); #endif - //Add SML Informations + //Add SML Informations to the Top as its pretty Important var modprio_sml = QModServices.Main.GetMod("SMLHelper"); if (modprio_sml != null) { __instance.AddHeading(ModListTab, $"{modprio_sml.DisplayName} {(modprio_sml.Enable ? $"v{modprio_sml.ParsedVersion}" : string.Empty)} is {(modprio_sml.IsLoaded ? "enabled" : "disabled")}"); - - - //*** Test - //testbool = modprio_sml.Enable; - //MethodInfo SML_AddToggleOption = null; - //SML_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); - //SML_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", testbool, new UnityAction(value => testbool = value ) }); - //SML_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", modprio_sml.Enable , new UnityAction(value => MyOnchangeMethode(modprio_sml.Id, value) ) }); - } else { __instance.AddHeading(ModListTab, $"SMLHelper is not installed"); } - IEnumerable mods = QModServices.Main.GetAllMods().OrderBy(mod => mod.DisplayName); - List activeMods = new List(); - List inactiveMods = new List(); - + //Now lets create the Mod List foreach (var mod in mods) { if (mod.Enable) @@ -122,11 +114,11 @@ internal static void Postfix(uGUI_OptionsPanel __instance) inactiveMods.Add(mod); } + //Write down a Temporary reduced Modlist that is interactable (The QMM Modlist is only Readonly and has many information we do not need for now) ModDataTemplate _tmpmod = new ModDataTemplate(); try { _tmpmod.ID = mod.Id; - if (mod.LoadedAssembly != null) { Logger.Log(Logger.Level.Debug, $"NANANANANANA - Just checking {mod.DisplayName} ; {mod.AssemblyName} ; {mod.LoadedAssembly.Location}"); @@ -135,10 +127,9 @@ internal static void Postfix(uGUI_OptionsPanel __instance) else { Logger.Log(Logger.Level.Debug, $"NANANANANANA - Just checking {mod.DisplayName} has no Loaded Assembly"); - } - + } _tmpmod.Enabled = mod.Enable; - modlist.Add(_tmpmod); + ModList.Add(_tmpmod); } catch { @@ -147,122 +138,71 @@ internal static void Postfix(uGUI_OptionsPanel __instance) } + //Now show some Statistics ahead of the List. __instance.AddHeading(ModListTab, $"- - Statistics - -"); __instance.AddHeading(ModListTab, $"{mods.Count()} Mods found"); __instance.AddHeading(ModListTab, $"{activeMods.Count} Mods enabled"); __instance.AddHeading(ModListTab, $"{inactiveMods.Count} Mods disabled"); + //Now we write down the actull List with all Mods. Starting with the Active Mods __instance.AddHeading(ModListTab, $"- - List of currently running Mods - -"); foreach (var mod in activeMods) { + //This is the Header Entry __instance.AddHeading(ModListTab, $"{mod.DisplayName} v{mod.ParsedVersion.ToString()} from {mod.Author}"); + //This is the Collapse SubMenu of the Entry MethodInfo Modlist_AddToggleOption = null; - Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); - - - //int index = modlist.IndexOf(modlist.Where(mdt => mdt.ID.ToString() == mod.Id.ToString()).FirstOrDefault()); - //Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", modlist[index].Enabled , new UnityAction(value => modlist[index].Enabled = value) }); - - //Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", modlist[index].Enabled, MyOnchangeMethode(Mod.id; value) }); - //Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", modlist[index].Enabled, new UnityAction(value => MyOnchangeMethode(modlist[index].ID, value)) }); - - Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", mod.Enable, new UnityAction(value => MyOnChangeMethode(__instance, mod.Id, value)) }); + Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", ModList[ModList.FindIndex(mdt => mdt.ID == mod.Id)].Enabled , new UnityAction(value => OnChangeModStatus(ModList[ModList.FindIndex(mdt => mdt.ID == mod.Id)], value)) }); } + //Continue with Disabled Mods __instance.AddHeading(ModListTab, $"- - List of Disabled Mods - -"); - foreach (var mod in inactiveMods) { + //This is the Header Entry __instance.AddHeading(ModListTab, $"{mod.DisplayName} from {mod.Author}"); + + //This is the Collapse SubMenu of the Entry + MethodInfo Modlist_AddToggleOption = null; + Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", ModList[ModList.FindIndex(mdt => mdt.ID == mod.Id)].Enabled, new UnityAction(value => OnChangeModStatus(ModList[ModList.FindIndex(mdt => mdt.ID == mod.Id)], value)) }); } - Logger.Log(Logger.Level.Debug, "OptionsMenu - Creating Modlist Ending"); + Logger.Log(Logger.Level.Debug, "OptionsMenu - ModList - Creating Modlist Ending"); #endregion Mod List } - static void MyOnChangeMethode(uGUI_OptionsPanel __instance, string id, bool status) + static void OnChangeModStatus(ModDataTemplate ChangedMod,bool status) { - - Logger.Log(Logger.Level.Debug, "WOLOLOLOLOLO - enter MyOnChangeMethode"); - - Logger.Log(Logger.Level.Debug, $"WOLOLOLOLOLO - the submit id is {id} and the Status is {status}"); + Logger.Log(Logger.Level.Debug, $"WOLOLOLOLOLO - the submit id is {ChangedMod.ID} and the Status is {status}"); + ChangedMod.Enabled = status; - ModDataTemplate _tmpmod = new ModDataTemplate(); - //IEnumerable _tmpmodlist; - - //try - //{ - Logger.Log(Logger.Level.Debug, "WOLOLOLOLOLO - searched Mod"); - try + if( string.IsNullOrEmpty(ModListPendingChanges.Find(mdt => mdt.ID == ChangedMod.ID).ID) ) { - //_tmpmod = modlist.Where(mdt => mdt.ID.ToString() == id).FirstOrDefault(); - - //Check if the Modlist contains any Mods - if(modlist.Count == 0) + try { - //If not i do not need to search for Mods already in - Logger.Log(Logger.Level.Debug, $"modlistcount is Zero"); - _tmpmod = null; - //_tmpmodlist = null; + ModListPendingChanges.Add(ChangedMod); } - else + catch { - Logger.Log(Logger.Level.Debug, $"modlistcount not Zero"); - _tmpmod = modlist.Where(mdt => mdt.ID.ToString() == id).FirstOrDefault(); - //_tmpmodlist = modlist.Where(mdt => mdt.ID == id); - - //foreach (ModDataTemplate test in _tmpmodlist) - //{ - //Logger.Log(Logger.Level.Debug, $"WOLOLOLOLOLO - found mod {test.ID}"); - //} + Logger.Log(Logger.Level.Debug, "OptionsMenu - ModList - Error on Adding Mod to Pending Status Change List"); } - } - catch - { - - } - /* - catch - { - Logger.Log(Logger.Level.Debug, "WOLOLOLOLOLO - ERROR - searched Mod"); - } - */ - - if (_tmpmod == null) + else { - Logger.Log(Logger.Level.Debug, "WOLOLOLOLOLO - Mod is not null"); try { - Logger.Log(Logger.Level.Debug, "WOLOLOLOLOLO - Adding mod to change list"); - _tmpmod.Enabled = status; - modchanges.Add(_tmpmod); + ModListPendingChanges.Remove(ChangedMod); } catch { - Logger.Log(Logger.Level.Debug, "WOLOLOLOLOLO - ERROR - Adding mod to change list"); + Logger.Log(Logger.Level.Debug, "OptionsMenu - ModList - Error on Removing Mod to Pending Status Change List"); } } - else - { - //theoretical i don't need that if statement because if the Mod is already in the List there is only the possibility of removing it anyway when only 2 status exist ??? - if (_tmpmod.Enabled != status) - { - try - { - Logger.Log(Logger.Level.Debug, "WOLOLOLOLOLO - remove mod from list again."); - modchanges.Remove(_tmpmod); - } - catch - { - Logger.Log(Logger.Level.Debug, "WOLOLOLOLOLO - remove mod from list again."); - } - } - } - - if (modchanges.Count == 0) + if (ModListPendingChanges.Count == 0) { //disable Apply Button } @@ -270,12 +210,6 @@ static void MyOnChangeMethode(uGUI_OptionsPanel __instance, string id, bool stat { //enable Apply Button } - //} - //catch - //{ - //Logger.Log(Logger.Level.Debug, "123456789 - Error on MyOnChangeMethode"); - //} - } } diff --git a/QModManager/QModManager.csproj b/QModManager/QModManager.csproj index 620039b5..bfc7c8e1 100644 --- a/QModManager/QModManager.csproj +++ b/QModManager/QModManager.csproj @@ -101,6 +101,7 @@ + diff --git a/QModManager/Utility/IOUtilities.cs b/QModManager/Utility/IOUtilities.cs index 382cb8ca..d1900c43 100644 --- a/QModManager/Utility/IOUtilities.cs +++ b/QModManager/Utility/IOUtilities.cs @@ -126,5 +126,7 @@ internal static string GenerateSpaces(int spaces) s += "| "; return s; } + + internal static void ChangeModStatustoFile } } From 1627b322e7e5c866de905c4797060e61432fe386 Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Sun, 17 Apr 2022 22:54:05 +0200 Subject: [PATCH 14/29] Adding Apply Function and false confirm prevention --- QModManager/OptionsManager.cs | 84 +++++++++++++++++++++++------- QModManager/Utility/IOUtilities.cs | 31 ++++++++++- 2 files changed, 94 insertions(+), 21 deletions(-) diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index 1fc84126..bc8d1b05 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -8,20 +8,21 @@ using UnityEngine.Events; using System.Collections.Generic; using System.Linq; - using System; + using QModManager.DataStructures; internal static class OptionsManager - { + { + internal static string ModsListTabName = "QMods List"; internal static int ModsTab; internal static int ModListTab; - + internal static List ModList; + public static List ModListPendingChanges; + //Dedicated Indicator to do not loosing change Status on Modlist + public static bool PendingChangesOnModList; + [HarmonyPatch(typeof(uGUI_OptionsPanel), nameof(uGUI_OptionsPanel.AddTabs))] internal static class OptionsPatch { - internal static List ModList; - public static List ModListPendingChanges; - //internal static bool testbool { get; set; } - [HarmonyPostfix] internal static void Postfix(uGUI_OptionsPanel __instance) { @@ -75,8 +76,9 @@ internal static void Postfix(uGUI_OptionsPanel __instance) Logger.Log(Logger.Level.Debug, "OptionsMenu - Start creating Modlist"); //Reset ModList and Pending Changes on Relead the List Menu - We do not want to save any Data or take over Data from previous time here - ModList = new List(); - ModListPendingChanges = new List(); + ModList = new List(); + ModListPendingChanges = new List(); + PendingChangesOnModList = false; IEnumerable mods = QModServices.Main.GetAllMods().OrderBy(mod => mod.DisplayName); List activeMods = new List(); List inactiveMods = new List(); @@ -115,18 +117,18 @@ internal static void Postfix(uGUI_OptionsPanel __instance) } //Write down a Temporary reduced Modlist that is interactable (The QMM Modlist is only Readonly and has many information we do not need for now) - ModDataTemplate _tmpmod = new ModDataTemplate(); + SimpleModDataTemplate _tmpmod = new SimpleModDataTemplate(); try { _tmpmod.ID = mod.Id; if (mod.LoadedAssembly != null) { - Logger.Log(Logger.Level.Debug, $"NANANANANANA - Just checking {mod.DisplayName} ; {mod.AssemblyName} ; {mod.LoadedAssembly.Location}"); + //Logger.Log(Logger.Level.Debug, $"NANANANANANA - Just checking {mod.DisplayName} ; {mod.AssemblyName} ; {mod.LoadedAssembly.Location}"); _tmpmod.PathToAssemblyFile = mod.LoadedAssembly.Location; } else { - Logger.Log(Logger.Level.Debug, $"NANANANANANA - Just checking {mod.DisplayName} has no Loaded Assembly"); + //Logger.Log(Logger.Level.Debug, $"NANANANANANA - Just checking {mod.DisplayName} has no Loaded Assembly"); } _tmpmod.Enabled = mod.Enable; ModList.Add(_tmpmod); @@ -154,7 +156,7 @@ internal static void Postfix(uGUI_OptionsPanel __instance) //This is the Collapse SubMenu of the Entry MethodInfo Modlist_AddToggleOption = null; Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); - Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", ModList[ModList.FindIndex(mdt => mdt.ID == mod.Id)].Enabled , new UnityAction(value => OnChangeModStatus(ModList[ModList.FindIndex(mdt => mdt.ID == mod.Id)], value)) }); + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", ModList[ModList.FindIndex(mdt => mdt.ID == mod.Id)].Enabled , new UnityAction(value => OnChangeModStatus(ModList[ModList.FindIndex(mdt => mdt.ID == mod.Id)], value, __instance)) }); } //Continue with Disabled Mods @@ -167,14 +169,15 @@ internal static void Postfix(uGUI_OptionsPanel __instance) //This is the Collapse SubMenu of the Entry MethodInfo Modlist_AddToggleOption = null; Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); - Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", ModList[ModList.FindIndex(mdt => mdt.ID == mod.Id)].Enabled, new UnityAction(value => OnChangeModStatus(ModList[ModList.FindIndex(mdt => mdt.ID == mod.Id)], value)) }); + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", ModList[ModList.FindIndex(mdt => mdt.ID == mod.Id)].Enabled, new UnityAction(value => OnChangeModStatus(ModList[ModList.FindIndex(mdt => mdt.ID == mod.Id)], value, __instance)) }); } Logger.Log(Logger.Level.Debug, "OptionsMenu - ModList - Creating Modlist Ending"); + #endregion Mod List } - static void OnChangeModStatus(ModDataTemplate ChangedMod,bool status) + static void OnChangeModStatus(SimpleModDataTemplate ChangedMod,bool status, uGUI_OptionsPanel __instance) { Logger.Log(Logger.Level.Debug, $"WOLOLOLOLOLO - the submit id is {ChangedMod.ID} and the Status is {status}"); ChangedMod.Enabled = status; @@ -205,19 +208,62 @@ static void OnChangeModStatus(ModDataTemplate ChangedMod,bool status) if (ModListPendingChanges.Count == 0) { //disable Apply Button + __instance.applyButton.gameObject.SetActive(false); + PendingChangesOnModList = false; } else { //enable Apply Button + __instance.applyButton.gameObject.SetActive(true); + PendingChangesOnModList = true; + } + } + } + + [HarmonyPatch(typeof(uGUI_OptionsPanel), nameof(uGUI_OptionsPanel.OnApplyButton))] + internal static class OptionsPatch_OnApplyButton + { + [HarmonyPrefix] + internal static bool Prefix(uGUI_OptionsPanel __instance) + { + //Warning Save Button is shared over the hole Option Menu ! + + //Check if Pending Changes exist and only run Save for one Menu and not Both + if(OptionsManager.PendingChangesOnModList) + { + if (OptionsManager.ModListPendingChanges.Count > 0) + { + foreach (SimpleModDataTemplate mod in OptionsManager.ModListPendingChanges) + { + IOUtilities.ChangeModStatustoFile(mod); + } + } + __instance.applyButton.gameObject.SetActive(false); + return false; //run custom + } + else + { + return true; //let the Original Run } } } - internal class ModDataTemplate + [HarmonyPatch(typeof(uGUI_TabbedControlsPanel), nameof(uGUI_TabbedControlsPanel.SelectTab))] + internal static class TabbedControlsPanelPatch_SelectTab { - public string ID { get; set; } - public string PathToAssemblyFile { get; set; } - public bool Enabled { get; set; } + [HarmonyPostfix] + internal static void Postfix(uGUI_TabbedControlsPanel __instance) + { + //To avoid Saving changes made on Modlist reset the Pending Status if not looking at the Modlist Tab + if (__instance.GetComponentInChildren().text == ModsListTabName) + { + OptionsManager.PendingChangesOnModList = true; + } + else + { + OptionsManager.PendingChangesOnModList = false; + } + } } } } diff --git a/QModManager/Utility/IOUtilities.cs b/QModManager/Utility/IOUtilities.cs index d1900c43..e5faa1f5 100644 --- a/QModManager/Utility/IOUtilities.cs +++ b/QModManager/Utility/IOUtilities.cs @@ -1,7 +1,8 @@ using System; using System.Collections.Generic; using System.IO; -using System.Text; +using QModManager.DataStructures; +using Oculus.Newtonsoft.Json; namespace QModManager.Utility { @@ -127,6 +128,32 @@ internal static string GenerateSpaces(int spaces) return s; } - internal static void ChangeModStatustoFile + internal static void ChangeModStatustoFile(SimpleModDataTemplate smdt) + { + //Get the Configfile + string modconfigpath = Path.GetFullPath(Path.GetDirectoryName(smdt.PathToAssemblyFile)); + dynamic modconfigfile = JsonConvert.DeserializeObject(File.ReadAllText(modconfigpath)); + + //Modify the Configfile + Logger.Log(Logger.Level.Debug, $"TESTTESTTESTTESTTEST - {modconfigfile["Enable"]}"); + modconfigfile["Enable"] = smdt.Enabled.ToString(); + Logger.Log(Logger.Level.Debug, $"TESTTESTTESTTESTTEST - {modconfigfile["Enable"]}"); + + /* + //Save it back + Formatting myformat = new Formatting(); + myformat = Formatting.Indented; + string jsonstr= JsonConvert.SerializeObject(modconfigfile, myformat); + try + { + File.WriteAllText(modconfigpath, jsonstr); + Logger.Log(Logger.Level.Info, "Mod Compare List for Savegame was saved to Mod Folder"); + } + catch + { + Logger.Log(Logger.Level.Error, "ErrorID:5713/31A - Saving Changed Mod Configfile failed"); + } + */ + } } } From 9694aa0020264e830fcbbb5338e0ca95cb1948e7 Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Mon, 18 Apr 2022 16:22:55 +0200 Subject: [PATCH 15/29] start writing to disk --- QModManager/OptionsManager.cs | 94 ++++++++++++++++++++++++++++-- QModManager/Utility/IOUtilities.cs | 11 +++- 2 files changed, 96 insertions(+), 9 deletions(-) diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index bc8d1b05..5b8d5d1b 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -9,6 +9,8 @@ using System.Collections.Generic; using System.Linq; using QModManager.DataStructures; + using Oculus.Newtonsoft.Json; + using System.IO; internal static class OptionsManager { @@ -182,7 +184,18 @@ static void OnChangeModStatus(SimpleModDataTemplate ChangedMod,bool status, uGUI Logger.Log(Logger.Level.Debug, $"WOLOLOLOLOLO - the submit id is {ChangedMod.ID} and the Status is {status}"); ChangedMod.Enabled = status; - if( string.IsNullOrEmpty(ModListPendingChanges.Find(mdt => mdt.ID == ChangedMod.ID).ID) ) + SimpleModDataTemplate _modexist = new SimpleModDataTemplate(); + try + { + //Is there a better way than try/catch using Find while determind a null or Empty when no Mod is found ? + _modexist = ModListPendingChanges.Find(mdt => mdt.ID == ChangedMod.ID); + } + catch + { + _modexist = null; + } + + if(_modexist == null) { try { @@ -193,7 +206,7 @@ static void OnChangeModStatus(SimpleModDataTemplate ChangedMod,bool status, uGUI Logger.Log(Logger.Level.Debug, "OptionsMenu - ModList - Error on Adding Mod to Pending Status Change List"); } } - else + else if(_modexist.ID == ChangedMod.ID) { try { @@ -204,11 +217,16 @@ static void OnChangeModStatus(SimpleModDataTemplate ChangedMod,bool status, uGUI Logger.Log(Logger.Level.Debug, "OptionsMenu - ModList - Error on Removing Mod to Pending Status Change List"); } } + else + { + Logger.Log(Logger.Level.Debug, "OptionsMenu - ModList - Error on Adding AND Removing Mod to Pending Status Change List."); + //mhh that should not happen.... + } if (ModListPendingChanges.Count == 0) { - //disable Apply Button - __instance.applyButton.gameObject.SetActive(false); + ////disable Apply Button + //__instance.applyButton.gameObject.SetActive(false); PendingChangesOnModList = false; } else @@ -220,6 +238,7 @@ static void OnChangeModStatus(SimpleModDataTemplate ChangedMod,bool status, uGUI } } + /* [HarmonyPatch(typeof(uGUI_OptionsPanel), nameof(uGUI_OptionsPanel.OnApplyButton))] internal static class OptionsPatch_OnApplyButton { @@ -239,7 +258,7 @@ internal static bool Prefix(uGUI_OptionsPanel __instance) } } __instance.applyButton.gameObject.SetActive(false); - return false; //run custom + return false; //run custom only } else { @@ -247,7 +266,69 @@ internal static bool Prefix(uGUI_OptionsPanel __instance) } } } + */ + + [HarmonyPatch(typeof(uGUI_OptionsPanel), nameof(uGUI_OptionsPanel.OnApplyButton))] + internal static class OptionsPatch_OnApplyButton + { + [HarmonyPostfix] + internal static void Postfix(uGUI_OptionsPanel __instance) + { + //Warning Save Button is shared over the hole Option Menu ! + Logger.Log(Logger.Level.Debug, $"OptionsMenu - OnApplyButton - Mod Count going to Change Status: {OptionsManager.ModListPendingChanges.Count}"); + if (OptionsManager.ModListPendingChanges.Count > 0) + { + foreach (SimpleModDataTemplate _mod in OptionsManager.ModListPendingChanges) + { + Logger.Log(Logger.Level.Debug, $"OptionsMenu - OnApplyButton - {_mod.ID}"); + try + { + ChangeModStatustoFile(_mod); + } + catch + { + Logger.Log(Logger.Level.Debug, $"OptionsMenu - OnApplyButton - erro on pass"); + } + + } + } + //just in case disable to button again + __instance.applyButton.gameObject.SetActive(false); + } + + internal static void ChangeModStatustoFile(SimpleModDataTemplate smdt) + { + Logger.Log(Logger.Level.Debug, $"Welcome to the ChangeModStatustoFile Methode"); + + //Get the Configfile + string modconfigpath = Path.Combine(Path.GetFullPath(Path.GetDirectoryName(smdt.PathToAssemblyFile)), "mod.json"); + Logger.Log(Logger.Level.Debug, $"Path {modconfigpath}"); + dynamic modconfigfile = JsonConvert.DeserializeObject(File.ReadAllText(modconfigpath)); + + //Modify the Configfile + Logger.Log(Logger.Level.Debug, $"TESTTESTTESTTESTTEST - {modconfigfile["Enable"]}"); + modconfigfile["Enable"] = smdt.Enabled.ToString(); + Logger.Log(Logger.Level.Debug, $"TESTTESTTESTTESTTEST - {modconfigfile["Enable"]}"); + + /* + //Save it back + Formatting myformat = new Formatting(); + myformat = Formatting.Indented; + string jsonstr= JsonConvert.SerializeObject(modconfigfile, myformat); + try + { + File.WriteAllText(modconfigpath, jsonstr); + Logger.Log(Logger.Level.Info, "Mod Compare List for Savegame was saved to Mod Folder"); + } + catch + { + Logger.Log(Logger.Level.Error, "ErrorID:5713/31A - Saving Changed Mod Configfile failed"); + } + */ + } + } + /* [HarmonyPatch(typeof(uGUI_TabbedControlsPanel), nameof(uGUI_TabbedControlsPanel.SelectTab))] internal static class TabbedControlsPanelPatch_SelectTab { @@ -255,7 +336,7 @@ internal static class TabbedControlsPanelPatch_SelectTab internal static void Postfix(uGUI_TabbedControlsPanel __instance) { //To avoid Saving changes made on Modlist reset the Pending Status if not looking at the Modlist Tab - if (__instance.GetComponentInChildren().text == ModsListTabName) + if (__instance.GetComponentInChildren().text == ModsListTabName && ModListPendingChanges.Count > 0) { OptionsManager.PendingChangesOnModList = true; } @@ -265,5 +346,6 @@ internal static void Postfix(uGUI_TabbedControlsPanel __instance) } } } + */ } } diff --git a/QModManager/Utility/IOUtilities.cs b/QModManager/Utility/IOUtilities.cs index e5faa1f5..ba94bffc 100644 --- a/QModManager/Utility/IOUtilities.cs +++ b/QModManager/Utility/IOUtilities.cs @@ -128,10 +128,14 @@ internal static string GenerateSpaces(int spaces) return s; } + /* internal static void ChangeModStatustoFile(SimpleModDataTemplate smdt) { + Logger.Log(Logger.Level.Debug, $"Welcome to the ChangeModStatustoFile Methode"); + //Get the Configfile - string modconfigpath = Path.GetFullPath(Path.GetDirectoryName(smdt.PathToAssemblyFile)); + string modconfigpath = Path.Combine(Path.GetFullPath(Path.GetDirectoryName(smdt.PathToAssemblyFile)),"mod.json"); + Logger.Log(Logger.Level.Debug, $"Path {modconfigpath}"); dynamic modconfigfile = JsonConvert.DeserializeObject(File.ReadAllText(modconfigpath)); //Modify the Configfile @@ -139,7 +143,7 @@ internal static void ChangeModStatustoFile(SimpleModDataTemplate smdt) modconfigfile["Enable"] = smdt.Enabled.ToString(); Logger.Log(Logger.Level.Debug, $"TESTTESTTESTTESTTEST - {modconfigfile["Enable"]}"); - /* + //Save it back Formatting myformat = new Formatting(); myformat = Formatting.Indented; @@ -153,7 +157,8 @@ internal static void ChangeModStatustoFile(SimpleModDataTemplate smdt) { Logger.Log(Logger.Level.Error, "ErrorID:5713/31A - Saving Changed Mod Configfile failed"); } - */ + } + */ } } From a33d1ef0d7d57e6bb6534dcb9396f329ceaf69f0 Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Mon, 18 Apr 2022 18:38:22 +0200 Subject: [PATCH 16/29] Save to Mod.json first time working fine --- QModManager/OptionsManager.cs | 39 +++++++++++++++-------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index 5b8d5d1b..5af8bc35 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -280,41 +280,35 @@ internal static void Postfix(uGUI_OptionsPanel __instance) { foreach (SimpleModDataTemplate _mod in OptionsManager.ModListPendingChanges) { - Logger.Log(Logger.Level.Debug, $"OptionsMenu - OnApplyButton - {_mod.ID}"); - try - { - ChangeModStatustoFile(_mod); - } - catch - { - Logger.Log(Logger.Level.Debug, $"OptionsMenu - OnApplyButton - erro on pass"); - } - + ChangeModStatustoFile(_mod); } } //just in case disable to button again __instance.applyButton.gameObject.SetActive(false); } - + internal static void ChangeModStatustoFile(SimpleModDataTemplate smdt) { - Logger.Log(Logger.Level.Debug, $"Welcome to the ChangeModStatustoFile Methode"); - //Get the Configfile string modconfigpath = Path.Combine(Path.GetFullPath(Path.GetDirectoryName(smdt.PathToAssemblyFile)), "mod.json"); - Logger.Log(Logger.Level.Debug, $"Path {modconfigpath}"); - dynamic modconfigfile = JsonConvert.DeserializeObject(File.ReadAllText(modconfigpath)); + var modconfig = JsonConvert.DeserializeObject>(File.ReadAllText(modconfigpath)); //Modify the Configfile - Logger.Log(Logger.Level.Debug, $"TESTTESTTESTTESTTEST - {modconfigfile["Enable"]}"); - modconfigfile["Enable"] = smdt.Enabled.ToString(); - Logger.Log(Logger.Level.Debug, $"TESTTESTTESTTESTTEST - {modconfigfile["Enable"]}"); - - /* + foreach (var kvp in modconfig) + { + if (kvp.Key.ToLower() == "enable") + { + Logger.Log(Logger.Level.Debug, $"TESTTESTTEST - json thing - {modconfig[kvp.Key]}"); + modconfig[kvp.Key] = smdt.Enabled; + Logger.Log(Logger.Level.Debug, $"TESTTESTTEST - json thing - {modconfig[kvp.Key]}"); + break; + } + } + //Save it back Formatting myformat = new Formatting(); myformat = Formatting.Indented; - string jsonstr= JsonConvert.SerializeObject(modconfigfile, myformat); + string jsonstr= JsonConvert.SerializeObject(modconfig, myformat); try { File.WriteAllText(modconfigpath, jsonstr); @@ -324,8 +318,9 @@ internal static void ChangeModStatustoFile(SimpleModDataTemplate smdt) { Logger.Log(Logger.Level.Error, "ErrorID:5713/31A - Saving Changed Mod Configfile failed"); } - */ + } + } /* From a88324c9378798a49ff505ecb66c0b7f090f5195 Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Mon, 18 Apr 2022 19:58:27 +0200 Subject: [PATCH 17/29] backup --- QModManager/OptionsManager.cs | 131 +++++++++-------------------- QModManager/Utility/IOUtilities.cs | 27 +++--- 2 files changed, 53 insertions(+), 105 deletions(-) diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index 5af8bc35..686db402 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -9,8 +9,7 @@ using System.Collections.Generic; using System.Linq; using QModManager.DataStructures; - using Oculus.Newtonsoft.Json; - using System.IO; + using System; internal static class OptionsManager { @@ -82,6 +81,42 @@ internal static void Postfix(uGUI_OptionsPanel __instance) ModListPendingChanges = new List(); PendingChangesOnModList = false; IEnumerable mods = QModServices.Main.GetAllMods().OrderBy(mod => mod.DisplayName); + + //test + Logger.Log(Logger.Level.Debug, $"NANANANANANA1 - Mods - test1"); + try + { + List testmods = new List(); + foreach (var iQMod in QModServices.Main.GetAllMods()) + if (iQMod is QMod qMod) + testmods.Add(qMod); + + foreach (var _mod in testmods) + { + Logger.Log(Logger.Level.Debug, $"NANANANANANA1 - Mods - {_mod.Id} , {_mod.Enable} , {_mod.SubDirectory}"); + } + } + catch + { + + } + Logger.Log(Logger.Level.Debug, $"NANANANANANA1 - Mods - test2"); + try + { + List testmods2 = QModServices.Main.GetAllMods().OrderBy(mod => mod.DisplayName) as List; + + foreach (var _mod in testmods2) + { + Logger.Log(Logger.Level.Debug, $"NANANANANANA2 - Mods - {_mod.Id} , {_mod.Enable} , {_mod.SubDirectory}"); + } + + } + catch + { + + } + // ENDE TEST + List activeMods = new List(); List inactiveMods = new List(); @@ -108,6 +143,7 @@ internal static void Postfix(uGUI_OptionsPanel __instance) //Now lets create the Mod List foreach (var mod in mods) { + if (mod.Enable) { activeMods.Add(mod); @@ -195,7 +231,7 @@ static void OnChangeModStatus(SimpleModDataTemplate ChangedMod,bool status, uGUI _modexist = null; } - if(_modexist == null) + if (_modexist == null) { try { @@ -226,7 +262,6 @@ static void OnChangeModStatus(SimpleModDataTemplate ChangedMod,bool status, uGUI if (ModListPendingChanges.Count == 0) { ////disable Apply Button - //__instance.applyButton.gameObject.SetActive(false); PendingChangesOnModList = false; } else @@ -238,36 +273,6 @@ static void OnChangeModStatus(SimpleModDataTemplate ChangedMod,bool status, uGUI } } - /* - [HarmonyPatch(typeof(uGUI_OptionsPanel), nameof(uGUI_OptionsPanel.OnApplyButton))] - internal static class OptionsPatch_OnApplyButton - { - [HarmonyPrefix] - internal static bool Prefix(uGUI_OptionsPanel __instance) - { - //Warning Save Button is shared over the hole Option Menu ! - - //Check if Pending Changes exist and only run Save for one Menu and not Both - if(OptionsManager.PendingChangesOnModList) - { - if (OptionsManager.ModListPendingChanges.Count > 0) - { - foreach (SimpleModDataTemplate mod in OptionsManager.ModListPendingChanges) - { - IOUtilities.ChangeModStatustoFile(mod); - } - } - __instance.applyButton.gameObject.SetActive(false); - return false; //run custom only - } - else - { - return true; //let the Original Run - } - } - } - */ - [HarmonyPatch(typeof(uGUI_OptionsPanel), nameof(uGUI_OptionsPanel.OnApplyButton))] internal static class OptionsPatch_OnApplyButton { @@ -275,72 +280,16 @@ internal static class OptionsPatch_OnApplyButton internal static void Postfix(uGUI_OptionsPanel __instance) { //Warning Save Button is shared over the hole Option Menu ! - Logger.Log(Logger.Level.Debug, $"OptionsMenu - OnApplyButton - Mod Count going to Change Status: {OptionsManager.ModListPendingChanges.Count}"); if (OptionsManager.ModListPendingChanges.Count > 0) { foreach (SimpleModDataTemplate _mod in OptionsManager.ModListPendingChanges) { - ChangeModStatustoFile(_mod); + IOUtilities.ChangeModStatustoFile(_mod); } } //just in case disable to button again __instance.applyButton.gameObject.SetActive(false); } - - internal static void ChangeModStatustoFile(SimpleModDataTemplate smdt) - { - //Get the Configfile - string modconfigpath = Path.Combine(Path.GetFullPath(Path.GetDirectoryName(smdt.PathToAssemblyFile)), "mod.json"); - var modconfig = JsonConvert.DeserializeObject>(File.ReadAllText(modconfigpath)); - - //Modify the Configfile - foreach (var kvp in modconfig) - { - if (kvp.Key.ToLower() == "enable") - { - Logger.Log(Logger.Level.Debug, $"TESTTESTTEST - json thing - {modconfig[kvp.Key]}"); - modconfig[kvp.Key] = smdt.Enabled; - Logger.Log(Logger.Level.Debug, $"TESTTESTTEST - json thing - {modconfig[kvp.Key]}"); - break; - } - } - - //Save it back - Formatting myformat = new Formatting(); - myformat = Formatting.Indented; - string jsonstr= JsonConvert.SerializeObject(modconfig, myformat); - try - { - File.WriteAllText(modconfigpath, jsonstr); - Logger.Log(Logger.Level.Info, "Mod Compare List for Savegame was saved to Mod Folder"); - } - catch - { - Logger.Log(Logger.Level.Error, "ErrorID:5713/31A - Saving Changed Mod Configfile failed"); - } - - } - - } - - /* - [HarmonyPatch(typeof(uGUI_TabbedControlsPanel), nameof(uGUI_TabbedControlsPanel.SelectTab))] - internal static class TabbedControlsPanelPatch_SelectTab - { - [HarmonyPostfix] - internal static void Postfix(uGUI_TabbedControlsPanel __instance) - { - //To avoid Saving changes made on Modlist reset the Pending Status if not looking at the Modlist Tab - if (__instance.GetComponentInChildren().text == ModsListTabName && ModListPendingChanges.Count > 0) - { - OptionsManager.PendingChangesOnModList = true; - } - else - { - OptionsManager.PendingChangesOnModList = false; - } - } } - */ } } diff --git a/QModManager/Utility/IOUtilities.cs b/QModManager/Utility/IOUtilities.cs index ba94bffc..a6caf80b 100644 --- a/QModManager/Utility/IOUtilities.cs +++ b/QModManager/Utility/IOUtilities.cs @@ -128,37 +128,36 @@ internal static string GenerateSpaces(int spaces) return s; } - /* internal static void ChangeModStatustoFile(SimpleModDataTemplate smdt) { - Logger.Log(Logger.Level.Debug, $"Welcome to the ChangeModStatustoFile Methode"); - //Get the Configfile - string modconfigpath = Path.Combine(Path.GetFullPath(Path.GetDirectoryName(smdt.PathToAssemblyFile)),"mod.json"); - Logger.Log(Logger.Level.Debug, $"Path {modconfigpath}"); - dynamic modconfigfile = JsonConvert.DeserializeObject(File.ReadAllText(modconfigpath)); + string modconfigpath = Path.Combine(Path.GetFullPath(Path.GetDirectoryName(smdt.PathToAssemblyFile)), "mod.json"); + var modconfig = JsonConvert.DeserializeObject>(File.ReadAllText(modconfigpath)); //Modify the Configfile - Logger.Log(Logger.Level.Debug, $"TESTTESTTESTTESTTEST - {modconfigfile["Enable"]}"); - modconfigfile["Enable"] = smdt.Enabled.ToString(); - Logger.Log(Logger.Level.Debug, $"TESTTESTTESTTESTTEST - {modconfigfile["Enable"]}"); + foreach (var kvp in modconfig) + { + if (kvp.Key.ToLower() == "enable") + { + modconfig[kvp.Key] = smdt.Enabled; + break; + } + } - //Save it back Formatting myformat = new Formatting(); myformat = Formatting.Indented; - string jsonstr= JsonConvert.SerializeObject(modconfigfile, myformat); + string jsonstr = JsonConvert.SerializeObject(modconfig, myformat); try { File.WriteAllText(modconfigpath, jsonstr); - Logger.Log(Logger.Level.Info, "Mod Compare List for Savegame was saved to Mod Folder"); + Logger.Log(Logger.Level.Info, $"IOUtilities - ChangeModStatustoFile - mod.json Update for {smdt.ID} was succesful saved to Mod Folder"); } catch { Logger.Log(Logger.Level.Error, "ErrorID:5713/31A - Saving Changed Mod Configfile failed"); } - + } - */ } } From 9cd1e8813c57b0f903b63264e9acde175e220da9 Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Mon, 18 Apr 2022 20:44:06 +0200 Subject: [PATCH 18/29] Rework Code + Deactivated Mods can now be changed too --- .../DataStructures/SimpleModDataTemplate.cs | 9 -- QModManager/OptionsManager.cs | 123 +++++------------- QModManager/QModManager.csproj | 1 - QModManager/Utility/IOUtilities.cs | 55 ++++---- 4 files changed, 61 insertions(+), 127 deletions(-) delete mode 100644 QModManager/DataStructures/SimpleModDataTemplate.cs diff --git a/QModManager/DataStructures/SimpleModDataTemplate.cs b/QModManager/DataStructures/SimpleModDataTemplate.cs deleted file mode 100644 index 1315a76c..00000000 --- a/QModManager/DataStructures/SimpleModDataTemplate.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace QModManager.DataStructures -{ - internal class SimpleModDataTemplate - { - public string ID { get; set; } - public string PathToAssemblyFile { get; set; } - public bool Enabled { get; set; } - } -} diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index 686db402..dbbaaf94 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -8,18 +8,13 @@ using UnityEngine.Events; using System.Collections.Generic; using System.Linq; - using QModManager.DataStructures; - using System; internal static class OptionsManager { - internal static string ModsListTabName = "QMods List"; internal static int ModsTab; + internal static string ModsListTabName = "QMods List"; internal static int ModListTab; - internal static List ModList; - public static List ModListPendingChanges; - //Dedicated Indicator to do not loosing change Status on Modlist - public static bool PendingChangesOnModList; + public static List ModListPendingChanges; [HarmonyPatch(typeof(uGUI_OptionsPanel), nameof(uGUI_OptionsPanel.AddTabs))] internal static class OptionsPatch @@ -75,50 +70,15 @@ internal static void Postfix(uGUI_OptionsPanel __instance) #region Mod List //Start creating Ingame Mod List Logger.Log(Logger.Level.Debug, "OptionsMenu - Start creating Modlist"); - - //Reset ModList and Pending Changes on Relead the List Menu - We do not want to save any Data or take over Data from previous time here - ModList = new List(); - ModListPendingChanges = new List(); - PendingChangesOnModList = false; - IEnumerable mods = QModServices.Main.GetAllMods().OrderBy(mod => mod.DisplayName); - - //test - Logger.Log(Logger.Level.Debug, $"NANANANANANA1 - Mods - test1"); - try - { - List testmods = new List(); - foreach (var iQMod in QModServices.Main.GetAllMods()) - if (iQMod is QMod qMod) - testmods.Add(qMod); - - foreach (var _mod in testmods) - { - Logger.Log(Logger.Level.Debug, $"NANANANANANA1 - Mods - {_mod.Id} , {_mod.Enable} , {_mod.SubDirectory}"); - } - } - catch - { - - } - Logger.Log(Logger.Level.Debug, $"NANANANANANA1 - Mods - test2"); - try - { - List testmods2 = QModServices.Main.GetAllMods().OrderBy(mod => mod.DisplayName) as List; - - foreach (var _mod in testmods2) - { - Logger.Log(Logger.Level.Debug, $"NANANANANANA2 - Mods - {_mod.Id} , {_mod.Enable} , {_mod.SubDirectory}"); - } - } - catch - { - - } - // ENDE TEST - - List activeMods = new List(); - List inactiveMods = new List(); + //Reset ModList and Pending Changes on Relead the List Menu - We do not want to save any Data or take over Data from previous time here + ModListPendingChanges = new List(); + List mods = new List(); + foreach (var iQMod in QModServices.Main.GetAllMods().OrderBy(mod => mod.DisplayName)) + if (iQMod is QMod qMod) + mods.Add(qMod); + List activeMods = new List(); + List inactiveMods = new List(); //Create new Tab in the Menu ModListTab = __instance.AddTab("QMods List"); @@ -143,7 +103,6 @@ internal static void Postfix(uGUI_OptionsPanel __instance) //Now lets create the Mod List foreach (var mod in mods) { - if (mod.Enable) { activeMods.Add(mod); @@ -153,29 +112,6 @@ internal static void Postfix(uGUI_OptionsPanel __instance) { inactiveMods.Add(mod); } - - //Write down a Temporary reduced Modlist that is interactable (The QMM Modlist is only Readonly and has many information we do not need for now) - SimpleModDataTemplate _tmpmod = new SimpleModDataTemplate(); - try - { - _tmpmod.ID = mod.Id; - if (mod.LoadedAssembly != null) - { - //Logger.Log(Logger.Level.Debug, $"NANANANANANA - Just checking {mod.DisplayName} ; {mod.AssemblyName} ; {mod.LoadedAssembly.Location}"); - _tmpmod.PathToAssemblyFile = mod.LoadedAssembly.Location; - } - else - { - //Logger.Log(Logger.Level.Debug, $"NANANANANANA - Just checking {mod.DisplayName} has no Loaded Assembly"); - } - _tmpmod.Enabled = mod.Enable; - ModList.Add(_tmpmod); - } - catch - { - Logger.Log(Logger.Level.Debug, "NANANANANANA - Error on adding Temp Mod to Modlist"); - } - } //Now show some Statistics ahead of the List. @@ -194,7 +130,7 @@ internal static void Postfix(uGUI_OptionsPanel __instance) //This is the Collapse SubMenu of the Entry MethodInfo Modlist_AddToggleOption = null; Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); - Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", ModList[ModList.FindIndex(mdt => mdt.ID == mod.Id)].Enabled , new UnityAction(value => OnChangeModStatus(ModList[ModList.FindIndex(mdt => mdt.ID == mod.Id)], value, __instance)) }); + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", mod.Enable , new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); } //Continue with Disabled Mods @@ -207,7 +143,7 @@ internal static void Postfix(uGUI_OptionsPanel __instance) //This is the Collapse SubMenu of the Entry MethodInfo Modlist_AddToggleOption = null; Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); - Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", ModList[ModList.FindIndex(mdt => mdt.ID == mod.Id)].Enabled, new UnityAction(value => OnChangeModStatus(ModList[ModList.FindIndex(mdt => mdt.ID == mod.Id)], value, __instance)) }); + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", mod.Enable , new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); } Logger.Log(Logger.Level.Debug, "OptionsMenu - ModList - Creating Modlist Ending"); @@ -215,60 +151,58 @@ internal static void Postfix(uGUI_OptionsPanel __instance) #endregion Mod List } - static void OnChangeModStatus(SimpleModDataTemplate ChangedMod,bool status, uGUI_OptionsPanel __instance) - { - Logger.Log(Logger.Level.Debug, $"WOLOLOLOLOLO - the submit id is {ChangedMod.ID} and the Status is {status}"); - ChangedMod.Enabled = status; + static void OnChangeModStatus(QMod ChangedMod,bool status, uGUI_OptionsPanel __instance) + { + //write the new Status to the Mod Variable + ChangedMod.Enable = status; - SimpleModDataTemplate _modexist = new SimpleModDataTemplate(); + QMod _modexist = new QMod(); + //Now check if the Mod is already in the Pending list try { //Is there a better way than try/catch using Find while determind a null or Empty when no Mod is found ? - _modexist = ModListPendingChanges.Find(mdt => mdt.ID == ChangedMod.ID); + _modexist = ModListPendingChanges.Find(mdt => mdt.Id == ChangedMod.Id); } catch { + //if not it will result in an exception so i can set it to null _modexist = null; } if (_modexist == null) { + //if the Mod is not in list add it to pending try { ModListPendingChanges.Add(ChangedMod); } catch { - Logger.Log(Logger.Level.Debug, "OptionsMenu - ModList - Error on Adding Mod to Pending Status Change List"); + Logger.Log(Logger.Level.Warn, "OptionsMenu - ModList - Error on Adding Mod to Pending Status Change List"); } } - else if(_modexist.ID == ChangedMod.ID) + else if(_modexist.Id == ChangedMod.Id) { + //if the Mod is already in the List the user revert the change. Remove it try { ModListPendingChanges.Remove(ChangedMod); } catch { - Logger.Log(Logger.Level.Debug, "OptionsMenu - ModList - Error on Removing Mod to Pending Status Change List"); + Logger.Log(Logger.Level.Warn, "OptionsMenu - ModList - Error on Removing Mod to Pending Status Change List"); } } else { - Logger.Log(Logger.Level.Debug, "OptionsMenu - ModList - Error on Adding AND Removing Mod to Pending Status Change List."); + Logger.Log(Logger.Level.Warn, "OptionsMenu - ModList - Error on Adding AND Removing Mod to Pending Status Change List."); //mhh that should not happen.... } - if (ModListPendingChanges.Count == 0) - { - ////disable Apply Button - PendingChangesOnModList = false; - } - else + if (ModListPendingChanges.Count != 0) { //enable Apply Button __instance.applyButton.gameObject.SetActive(true); - PendingChangesOnModList = true; } } } @@ -282,7 +216,8 @@ internal static void Postfix(uGUI_OptionsPanel __instance) //Warning Save Button is shared over the hole Option Menu ! if (OptionsManager.ModListPendingChanges.Count > 0) { - foreach (SimpleModDataTemplate _mod in OptionsManager.ModListPendingChanges) + //if the List Contains Pending entries send every change to the File Writer + foreach (QMod _mod in OptionsManager.ModListPendingChanges) { IOUtilities.ChangeModStatustoFile(_mod); } diff --git a/QModManager/QModManager.csproj b/QModManager/QModManager.csproj index bfc7c8e1..620039b5 100644 --- a/QModManager/QModManager.csproj +++ b/QModManager/QModManager.csproj @@ -101,7 +101,6 @@ - diff --git a/QModManager/Utility/IOUtilities.cs b/QModManager/Utility/IOUtilities.cs index a6caf80b..04a9aee5 100644 --- a/QModManager/Utility/IOUtilities.cs +++ b/QModManager/Utility/IOUtilities.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.IO; -using QModManager.DataStructures; +using QModManager.Patching; using Oculus.Newtonsoft.Json; namespace QModManager.Utility @@ -128,36 +128,45 @@ internal static string GenerateSpaces(int spaces) return s; } - internal static void ChangeModStatustoFile(SimpleModDataTemplate smdt) + internal static void ChangeModStatustoFile(QMod qmod) { - //Get the Configfile - string modconfigpath = Path.Combine(Path.GetFullPath(Path.GetDirectoryName(smdt.PathToAssemblyFile)), "mod.json"); - var modconfig = JsonConvert.DeserializeObject>(File.ReadAllText(modconfigpath)); - - //Modify the Configfile - foreach (var kvp in modconfig) + //Get the Configfile (The mod.json in the Mod Directory) + string modconfigpath = Path.Combine(Path.GetFullPath(qmod.SubDirectory), "mod.json"); + if (File.Exists(modconfigpath)) { - if (kvp.Key.ToLower() == "enable") + //we doing it with a Dictionary instead of because we have Data in the File that is NOT handles by QMM we would loose this information and that is bad. + var modconfig = JsonConvert.DeserializeObject>(File.ReadAllText(modconfigpath)); + + //Modify the Configfile + foreach (var kvp in modconfig) { - modconfig[kvp.Key] = smdt.Enabled; - break; + if (kvp.Key.ToLower() == "enable") + { + modconfig[kvp.Key] = qmod.Enable; + break; + } } - } - //Save it back - Formatting myformat = new Formatting(); - myformat = Formatting.Indented; - string jsonstr = JsonConvert.SerializeObject(modconfig, myformat); - try - { - File.WriteAllText(modconfigpath, jsonstr); - Logger.Log(Logger.Level.Info, $"IOUtilities - ChangeModStatustoFile - mod.json Update for {smdt.ID} was succesful saved to Mod Folder"); + //Create a JSON Format so it will be Readable by User in a Text Editor + Formatting myformat = new Formatting(); + myformat = Formatting.Indented; + + //Save it back to File + string jsonstr = JsonConvert.SerializeObject(modconfig, myformat); + try + { + File.WriteAllText(modconfigpath, jsonstr); + Logger.Log(Logger.Level.Info, $"IOUtilities - ChangeModStatustoFile - Enabled Status Update for {qmod.Id} was succesful written to: {modconfigpath}"); + } + catch + { + Logger.Log(Logger.Level.Error, $"ErrorID:5713/36B - Saving mod.json for Mod {qmod.Id} to {modconfigpath} failed. - Was the File open in a other Program ? Permission Error ?"); + } } - catch + else { - Logger.Log(Logger.Level.Error, "ErrorID:5713/31A - Saving Changed Mod Configfile failed"); + Logger.Log(Logger.Level.Error, $"ErrorID:5713/17A - File {modconfigpath} does not exist! - Mod {qmod.Id}"); } - } } } From 32c377d3329217e45165d6608a5c83ea781de026 Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Tue, 19 Apr 2022 23:46:46 +0200 Subject: [PATCH 19/29] Update Pirate Check --- QModManager/Checks/PirateCheck.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/QModManager/Checks/PirateCheck.cs b/QModManager/Checks/PirateCheck.cs index b068a768..241318ca 100644 --- a/QModManager/Checks/PirateCheck.cs +++ b/QModManager/Checks/PirateCheck.cs @@ -25,6 +25,8 @@ internal static class PirateCheck "Subnautica_Data/Plugins/steam_emu.ini", "Profile/SteamUserID.cfg", "Profile/Stats/Achievements.Bin", + "Profile/VALVE/SteamUserID.cfg", + "Profile/VALVE/Stats/Achievements.Bin", "launcher.bat", "chuj.cdx", }; From 23320556044ba11ec6c4cd465e89af12b791ea90 Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Sun, 24 Apr 2022 21:31:00 +0200 Subject: [PATCH 20/29] added cancel changes function --- QModManager/OptionsManager.cs | 129 +++++++++++++++++++++++------ QModManager/Utility/Dialog.cs | 26 +++++- QModManager/Utility/IOUtilities.cs | 7 +- 3 files changed, 134 insertions(+), 28 deletions(-) diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index dbbaaf94..092dad93 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -77,6 +77,8 @@ internal static void Postfix(uGUI_OptionsPanel __instance) foreach (var iQMod in QModServices.Main.GetAllMods().OrderBy(mod => mod.DisplayName)) if (iQMod is QMod qMod) mods.Add(qMod); + List erroredMods = mods.FindAll(m => !m.IsLoaded && m.Status > 0); + int erroredModscount = erroredMods.Count; List activeMods = new List(); List inactiveMods = new List(); @@ -84,11 +86,16 @@ internal static void Postfix(uGUI_OptionsPanel __instance) ModListTab = __instance.AddTab("QMods List"); //Add QMM Informations -#if SUBNAUTICA_EXP || BELOWZERO_EXP - __instance.AddHeading(ModListTab, $"QModManager -Experimental- running version {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}"); -#else - __instance.AddHeading(ModListTab, $"QModManager running version {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}"); +#if SUBNAUTICA_STABLE + __instance.AddHeading(ModListTab, $"Running QModManager {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} for Subnautica"); +#elif SUBNAUTICA_EXP + __instance.AddHeading(ModListTab, $"Running QModManager -Experimental- {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} for Subnautica"); +#elif BELOWZERO_STABLE + __instance.AddHeading(ModListTab, $"Running QModManager {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} for Below Zero"); +#elif BELOWZERO_EXP + __instance.AddHeading(ModListTab, $"Running QModManager -Experimental- {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} for Below Zero"); #endif + //Add SML Informations to the Top as its pretty Important var modprio_sml = QModServices.Main.GetMod("SMLHelper"); if (modprio_sml != null) @@ -103,34 +110,84 @@ internal static void Postfix(uGUI_OptionsPanel __instance) //Now lets create the Mod List foreach (var mod in mods) { - if (mod.Enable) + if (mod.Id != "SMLHelper") { - activeMods.Add(mod); + if (mod.Enable) + { + activeMods.Add(mod); - } - else - { - inactiveMods.Add(mod); + } + else + { + inactiveMods.Add(mod); + } } } //Now show some Statistics ahead of the List. __instance.AddHeading(ModListTab, $"- - Statistics - -"); __instance.AddHeading(ModListTab, $"{mods.Count()} Mods found"); + if (erroredModscount != 0) + { + __instance.AddHeading(ModListTab, $"WARNING: {erroredModscount} Mods failed to load"); + } __instance.AddHeading(ModListTab, $"{activeMods.Count} Mods enabled"); __instance.AddHeading(ModListTab, $"{inactiveMods.Count} Mods disabled"); + + //At first show the Mods with errors. But show it only, when Mod errors exist + if (erroredModscount != 0) + { + __instance.AddHeading(ModListTab, $"- - List of Error Mods, You need to take Actions on them ! - -"); + foreach (var mod in erroredMods) + { + //This is the Header Entry + //__instance.AddHeading(ModListTab, $"{mod.DisplayName} from {mod.Author}"); + + //This is the Collapse SubMenu of the Entry + if (Patcher.CurrentlyRunningGame == QModGame.Subnautica) + { + MethodInfo Modlist_AddToggleOption = null; + Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); +#if SUBNAUTICA_STABLE + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); +#else + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); +#endif + } + else + { + MethodInfo Modlist_AddToggleOption = null; + Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction), typeof(string) }); + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)), null }); + } + } + } + //Now we write down the actull List with all Mods. Starting with the Active Mods __instance.AddHeading(ModListTab, $"- - List of currently running Mods - -"); foreach (var mod in activeMods) { //This is the Header Entry - __instance.AddHeading(ModListTab, $"{mod.DisplayName} v{mod.ParsedVersion.ToString()} from {mod.Author}"); + //__instance.AddHeading(ModListTab, $"{mod.DisplayName} v{mod.ParsedVersion.ToString()} from {mod.Author}"); //This is the Collapse SubMenu of the Entry - MethodInfo Modlist_AddToggleOption = null; - Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); - Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", mod.Enable , new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); + if (Patcher.CurrentlyRunningGame == QModGame.Subnautica) + { + MethodInfo Modlist_AddToggleOption = null; + Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); +#if SUBNAUTICA_STABLE + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); +#else + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} v{mod.ParsedVersion.ToString()} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); +#endif + } + else + { + MethodInfo Modlist_AddToggleOption = null; + Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction), typeof(string) }); + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} v{mod.ParsedVersion.ToString()} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)), null }); + } } //Continue with Disabled Mods @@ -138,17 +195,30 @@ internal static void Postfix(uGUI_OptionsPanel __instance) foreach (var mod in inactiveMods) { //This is the Header Entry - __instance.AddHeading(ModListTab, $"{mod.DisplayName} from {mod.Author}"); + //__instance.AddHeading(ModListTab, $"{mod.DisplayName} from {mod.Author}"); //This is the Collapse SubMenu of the Entry - MethodInfo Modlist_AddToggleOption = null; - Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); - Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, "Enable Mod", mod.Enable , new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); + if (Patcher.CurrentlyRunningGame == QModGame.Subnautica) + { + MethodInfo Modlist_AddToggleOption = null; + Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); +#if SUBNAUTICA_STABLE + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); +#else + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); +#endif + } + else + { + MethodInfo Modlist_AddToggleOption = null; + Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction), typeof(string) }); + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)), null }); + } } Logger.Log(Logger.Level.Debug, "OptionsMenu - ModList - Creating Modlist Ending"); - #endregion Mod List +#endregion Mod List } static void OnChangeModStatus(QMod ChangedMod,bool status, uGUI_OptionsPanel __instance) @@ -216,14 +286,21 @@ internal static void Postfix(uGUI_OptionsPanel __instance) //Warning Save Button is shared over the hole Option Menu ! if (OptionsManager.ModListPendingChanges.Count > 0) { - //if the List Contains Pending entries send every change to the File Writer - foreach (QMod _mod in OptionsManager.ModListPendingChanges) - { - IOUtilities.ChangeModStatustoFile(_mod); - } + //if the List Contains Pending entries show Info Box + Dialog dialog = new Dialog(); + //dialog.message = "Important ! Changes on Mods will enforce a Game Reboot after all changes are saved to system. Please wait until next notice"; + dialog.message = "Important ! Changes on Mods will enforce a Game Reboot after all changes are saved to system."; + dialog.color = Dialog.DialogColor.Red; + dialog.rightButton = Dialog.Button.CancelModChanges; + dialog.leftButton = Dialog.Button.ApplyModChanges; + dialog.Show(); + } + //Disbale the button if all Changes got applied + if (OptionsManager.ModListPendingChanges.Count != 0) + { + //As the Original Methode would be disable the Button anyway. We need to Enable it again. + __instance.applyButton.gameObject.SetActive(false); } - //just in case disable to button again - __instance.applyButton.gameObject.SetActive(false); } } } diff --git a/QModManager/Utility/Dialog.cs b/QModManager/Utility/Dialog.cs index 289c060e..03f9b9ef 100644 --- a/QModManager/Utility/Dialog.cs +++ b/QModManager/Utility/Dialog.cs @@ -10,6 +10,7 @@ using QModManager.Patching; using UnityEngine; using UnityEngine.UI; + using UWE; internal class Dialog { @@ -43,6 +44,7 @@ internal class Button } }); internal static readonly Button Close = new Button("Close", () => { }); + internal static readonly Button CancelModChanges = new Button("Cancel", () => { }); internal static readonly Button Download = new Button("Download", () => { if (Patcher.CurrentlyRunningGame == QModGame.Subnautica) @@ -50,12 +52,21 @@ internal class Button else Process.Start(VersionCheck.bzNexus); }); - internal static readonly Button Pirate = new Button("Close", () => { Process.Start("https://www.youtube.com/watch?v=dQw4w9WgXcQ"); Application.Quit(); }); + internal static readonly Button ExitGame = new Button("Exit Game", () => + { + Application.Quit(); + } + ); + internal static readonly Button ApplyModChanges = new Button("Apply", () => + { + CoroutineHost.StartCoroutine(ApplychangesandExit()); + } + ); internal Button() { } internal Button(string text, Action action) @@ -65,6 +76,19 @@ internal Button(string text, Action action) } } + public static IEnumerator ApplychangesandExit() + { + foreach (QMod _mod in OptionsManager.ModListPendingChanges) + { + IOUtilities.ChangeModStatustoFile(_mod); + } + OptionsManager.ModListPendingChanges.Clear(); + + yield return new WaitForSecondsRealtime(1); + + Application.Quit(); + } + internal enum DialogColor { Red, diff --git a/QModManager/Utility/IOUtilities.cs b/QModManager/Utility/IOUtilities.cs index 04a9aee5..f16941b5 100644 --- a/QModManager/Utility/IOUtilities.cs +++ b/QModManager/Utility/IOUtilities.cs @@ -2,7 +2,12 @@ using System.Collections.Generic; using System.IO; using QModManager.Patching; -using Oculus.Newtonsoft.Json; + +#if SUBNAUTICA_STABLE + using Oculus.Newtonsoft.Json; +#else +using Newtonsoft.Json; +#endif namespace QModManager.Utility { From 54a8500043826d534664cd2a760f5aa7e9bda371 Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Sun, 24 Apr 2022 21:46:58 +0200 Subject: [PATCH 21/29] code Cleanup --- QModManager/OptionsManager.cs | 6 +++--- QModManager/Utility/Dialog.cs | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index 092dad93..3ff85f57 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -288,18 +288,18 @@ internal static void Postfix(uGUI_OptionsPanel __instance) { //if the List Contains Pending entries show Info Box Dialog dialog = new Dialog(); - //dialog.message = "Important ! Changes on Mods will enforce a Game Reboot after all changes are saved to system. Please wait until next notice"; dialog.message = "Important ! Changes on Mods will enforce a Game Reboot after all changes are saved to system."; dialog.color = Dialog.DialogColor.Red; dialog.rightButton = Dialog.Button.CancelModChanges; dialog.leftButton = Dialog.Button.ApplyModChanges; dialog.Show(); } - //Disbale the button if all Changes got applied + + //In case User Canceled or the Quit was not executed properly if (OptionsManager.ModListPendingChanges.Count != 0) { //As the Original Methode would be disable the Button anyway. We need to Enable it again. - __instance.applyButton.gameObject.SetActive(false); + __instance.applyButton.gameObject.SetActive(true); } } } diff --git a/QModManager/Utility/Dialog.cs b/QModManager/Utility/Dialog.cs index 03f9b9ef..6d5e5ad1 100644 --- a/QModManager/Utility/Dialog.cs +++ b/QModManager/Utility/Dialog.cs @@ -78,14 +78,18 @@ internal Button(string text, Action action) public static IEnumerator ApplychangesandExit() { + //Apply every pending Mod Change foreach (QMod _mod in OptionsManager.ModListPendingChanges) { IOUtilities.ChangeModStatustoFile(_mod); } + //Clear the List to make sure the Check after the Button works valid when the User Canceled or the Quit Game didn't executed correct. OptionsManager.ModListPendingChanges.Clear(); + //It seems that the Filewriter Process need some time after saving. Otherwise the Game crashes. yield return new WaitForSecondsRealtime(1); + //Close the Game now. Application.Quit(); } From acba05c5097c52c85b99556e0e10ea0f2f9fdf2d Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Mon, 25 Apr 2022 14:11:20 +0200 Subject: [PATCH 22/29] Added QMM Option Entry to make Mod List Menu optional --- QModManager/OptionsManager.cs | 256 ++++++++++++++++++---------------- QModManager/Utility/Config.cs | 6 + 2 files changed, 143 insertions(+), 119 deletions(-) diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index 3ff85f57..721503b2 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -45,6 +45,7 @@ internal static void Postfix(uGUI_OptionsPanel __instance) AddToggleOption.Invoke(__instance, new object[] { ModsTab, "Enable debug logs", Config.EnableDebugLogs, new UnityAction(value => Config.EnableDebugLogs = value) }); AddToggleOption.Invoke(__instance, new object[] { ModsTab, "Enable developer mode", Config.EnableDevMode, new UnityAction(value => Config.EnableDevMode = value) }); + AddToggleOption.Invoke(__instance, new object[] { ModsTab, "Enable Mod List Menu", Config.EnableModListMenu, new UnityAction(value => Config.EnableModListMenu = value) }); } else { @@ -64,85 +65,120 @@ internal static void Postfix(uGUI_OptionsPanel __instance) AddToggleOption.Invoke(__instance, new object[] { ModsTab, "Enable debug logs", Config.EnableDebugLogs, new UnityAction(value => Config.EnableDebugLogs = value), null }); AddToggleOption.Invoke(__instance, new object[] { ModsTab, "Enable developer mode", Config.EnableDevMode, new UnityAction(value => Config.EnableDevMode = value), null }); + AddToggleOption.Invoke(__instance, new object[] { ModsTab, "Enable Mod List Menu", Config.EnableModListMenu, new UnityAction(value => Config.EnableModListMenu = value), null }); } #endregion Mod Config #region Mod List - //Start creating Ingame Mod List - Logger.Log(Logger.Level.Debug, "OptionsMenu - Start creating Modlist"); + Logger.Log(Logger.Level.Debug, "OptionsMenu - Reset Mod List Menu"); - //Reset ModList and Pending Changes on Relead the List Menu - We do not want to save any Data or take over Data from previous time here + //Reset ModList and Pending Changes on Reload the List Menu - We do not want to save any Data or take over Data from previous time here + //Part 1 things we should reset anyway ModListPendingChanges = new List(); - List mods = new List(); - foreach (var iQMod in QModServices.Main.GetAllMods().OrderBy(mod => mod.DisplayName)) - if (iQMod is QMod qMod) - mods.Add(qMod); - List erroredMods = mods.FindAll(m => !m.IsLoaded && m.Status > 0); - int erroredModscount = erroredMods.Count; - List activeMods = new List(); - List inactiveMods = new List(); - - //Create new Tab in the Menu - ModListTab = __instance.AddTab("QMods List"); - - //Add QMM Informations + + if (Config.EnableModListMenu) + { + //Part 2 things we only need to reset when activly using the Mod List Menu + List mods = new List(); + List activeMods = new List(); + List inactiveMods = new List(); + foreach (var iQMod in QModServices.Main.GetAllMods().OrderBy(mod => mod.DisplayName)) + if (iQMod is QMod qMod) + mods.Add(qMod); + List erroredMods = mods.FindAll(m => !m.IsLoaded && m.Status > 0); + int erroredModscount = erroredMods.Count; + + //Start creating Ingame Mod List + Logger.Log(Logger.Level.Debug, "OptionsMenu - Start creating Modlist"); + + //Create new Tab in the Menu + ModListTab = __instance.AddTab("QMods List"); + + //Add QMM Informations #if SUBNAUTICA_STABLE - __instance.AddHeading(ModListTab, $"Running QModManager {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} for Subnautica"); + __instance.AddHeading(ModListTab, $"Running QModManager {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} for Subnautica"); #elif SUBNAUTICA_EXP - __instance.AddHeading(ModListTab, $"Running QModManager -Experimental- {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} for Subnautica"); + __instance.AddHeading(ModListTab, $"Running QModManager -Experimental- {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} for Subnautica"); #elif BELOWZERO_STABLE - __instance.AddHeading(ModListTab, $"Running QModManager {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} for Below Zero"); + __instance.AddHeading(ModListTab, $"Running QModManager {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} for Below Zero"); #elif BELOWZERO_EXP - __instance.AddHeading(ModListTab, $"Running QModManager -Experimental- {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} for Below Zero"); + __instance.AddHeading(ModListTab, $"Running QModManager -Experimental- {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} for Below Zero"); #endif - //Add SML Informations to the Top as its pretty Important - var modprio_sml = QModServices.Main.GetMod("SMLHelper"); - if (modprio_sml != null) - { - __instance.AddHeading(ModListTab, $"{modprio_sml.DisplayName} {(modprio_sml.Enable ? $"v{modprio_sml.ParsedVersion}" : string.Empty)} is {(modprio_sml.IsLoaded ? "enabled" : "disabled")}"); - } - else - { - __instance.AddHeading(ModListTab, $"SMLHelper is not installed"); - } + //Add SML Informations to the Top as its pretty Important + var modprio_sml = QModServices.Main.GetMod("SMLHelper"); + if (modprio_sml != null) + { + __instance.AddHeading(ModListTab, $"{modprio_sml.DisplayName} {(modprio_sml.Enable ? $"v{modprio_sml.ParsedVersion}" : string.Empty)} is {(modprio_sml.IsLoaded ? "enabled" : "disabled")}"); + } + else + { + __instance.AddHeading(ModListTab, $"SMLHelper is not installed"); + } - //Now lets create the Mod List - foreach (var mod in mods) - { - if (mod.Id != "SMLHelper") + //Now lets create the enable and disable Mod Lists + foreach (var mod in mods) { - if (mod.Enable) + if (mod.Id != "SMLHelper") { - activeMods.Add(mod); + if (mod.Enable) + { + activeMods.Add(mod); - } - else - { - inactiveMods.Add(mod); + } + else + { + inactiveMods.Add(mod); + } } } - } - //Now show some Statistics ahead of the List. - __instance.AddHeading(ModListTab, $"- - Statistics - -"); - __instance.AddHeading(ModListTab, $"{mods.Count()} Mods found"); - if (erroredModscount != 0) - { - __instance.AddHeading(ModListTab, $"WARNING: {erroredModscount} Mods failed to load"); - } - __instance.AddHeading(ModListTab, $"{activeMods.Count} Mods enabled"); - __instance.AddHeading(ModListTab, $"{inactiveMods.Count} Mods disabled"); + //Now show some Statistics ahead of the List. + __instance.AddHeading(ModListTab, $"- - Statistics - -"); + __instance.AddHeading(ModListTab, $"{mods.Count()} Mods found"); + if (erroredModscount != 0) + { + __instance.AddHeading(ModListTab, $"WARNING: {erroredModscount} Mods failed to load"); + } + __instance.AddHeading(ModListTab, $"{activeMods.Count} Mods enabled"); + __instance.AddHeading(ModListTab, $"{inactiveMods.Count} Mods disabled"); - //At first show the Mods with errors. But show it only, when Mod errors exist - if (erroredModscount != 0) - { - __instance.AddHeading(ModListTab, $"- - List of Error Mods, You need to take Actions on them ! - -"); - foreach (var mod in erroredMods) + //At first show the Mods with errors. But show it only, when Mod errors exist + if (erroredModscount != 0) + { + __instance.AddHeading(ModListTab, $"- - List of Mods wit Loading Errors. You need to take Actions on them ! - -"); + foreach (var mod in erroredMods) + { + //This is the Header Entry + //__instance.AddHeading(ModListTab, $"{mod.DisplayName} from {mod.Author}"); + + //This is the Collapse SubMenu of the Entry + if (Patcher.CurrentlyRunningGame == QModGame.Subnautica) + { + MethodInfo Modlist_AddToggleOption = null; + Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); +#if SUBNAUTICA_STABLE + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); +#else + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); +#endif + } + else + { + MethodInfo Modlist_AddToggleOption = null; + Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction), typeof(string) }); + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)), null }); + } + } + } + + //Now we write down the actull List with all Mods. Starting with the Active Mods + __instance.AddHeading(ModListTab, $"- - List of currently running Mods - -"); + foreach (var mod in activeMods) { //This is the Header Entry - //__instance.AddHeading(ModListTab, $"{mod.DisplayName} from {mod.Author}"); + //__instance.AddHeading(ModListTab, $"{mod.DisplayName} v{mod.ParsedVersion.ToString()} from {mod.Author}"); //This is the Collapse SubMenu of the Entry if (Patcher.CurrentlyRunningGame == QModGame.Subnautica) @@ -152,73 +188,52 @@ internal static void Postfix(uGUI_OptionsPanel __instance) #if SUBNAUTICA_STABLE Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); #else - Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} v{mod.ParsedVersion.ToString()} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); #endif } else { MethodInfo Modlist_AddToggleOption = null; Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction), typeof(string) }); - Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)), null }); + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} v{mod.ParsedVersion.ToString()} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)), null }); } } - } - - //Now we write down the actull List with all Mods. Starting with the Active Mods - __instance.AddHeading(ModListTab, $"- - List of currently running Mods - -"); - foreach (var mod in activeMods) - { - //This is the Header Entry - //__instance.AddHeading(ModListTab, $"{mod.DisplayName} v{mod.ParsedVersion.ToString()} from {mod.Author}"); - //This is the Collapse SubMenu of the Entry - if (Patcher.CurrentlyRunningGame == QModGame.Subnautica) + //Continue with Disabled Mods + __instance.AddHeading(ModListTab, $"- - List of Disabled Mods - -"); + foreach (var mod in inactiveMods) { - MethodInfo Modlist_AddToggleOption = null; - Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); + //This is the Header Entry + //__instance.AddHeading(ModListTab, $"{mod.DisplayName} from {mod.Author}"); + + //This is the Collapse SubMenu of the Entry + if (Patcher.CurrentlyRunningGame == QModGame.Subnautica) + { + MethodInfo Modlist_AddToggleOption = null; + Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); #if SUBNAUTICA_STABLE - Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); #else - Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} v{mod.ParsedVersion.ToString()} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); #endif + } + else + { + MethodInfo Modlist_AddToggleOption = null; + Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction), typeof(string) }); + Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)), null }); + } } - else - { - MethodInfo Modlist_AddToggleOption = null; - Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction), typeof(string) }); - Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} v{mod.ParsedVersion.ToString()} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)), null }); - } - } - //Continue with Disabled Mods - __instance.AddHeading(ModListTab, $"- - List of Disabled Mods - -"); - foreach (var mod in inactiveMods) + Logger.Log(Logger.Level.Debug, "OptionsMenu - ModList - Creating Modlist Ending"); + } + else { - //This is the Header Entry - //__instance.AddHeading(ModListTab, $"{mod.DisplayName} from {mod.Author}"); - - //This is the Collapse SubMenu of the Entry - if (Patcher.CurrentlyRunningGame == QModGame.Subnautica) - { - MethodInfo Modlist_AddToggleOption = null; - Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction) }); -#if SUBNAUTICA_STABLE - Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); -#else - Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)) }); -#endif - } - else - { - MethodInfo Modlist_AddToggleOption = null; - Modlist_AddToggleOption = typeof(uGUI_OptionsPanel).GetMethod(nameof(AddToggleOption), new System.Type[] { typeof(int), typeof(string), typeof(bool), typeof(UnityAction), typeof(string) }); - Modlist_AddToggleOption.Invoke(__instance, new object[] { ModListTab, $"{mod.DisplayName} from {mod.Author}", mod.Enable, new UnityAction(value => OnChangeModStatus(mod, value, __instance)), null }); - } + Logger.Log(Logger.Level.Info, "OptionsMenu - ModList - No Mod List Menu was created due to User wish."); } - Logger.Log(Logger.Level.Debug, "OptionsMenu - ModList - Creating Modlist Ending"); - #endregion Mod List + } static void OnChangeModStatus(QMod ChangedMod,bool status, uGUI_OptionsPanel __instance) @@ -283,23 +298,26 @@ internal static class OptionsPatch_OnApplyButton [HarmonyPostfix] internal static void Postfix(uGUI_OptionsPanel __instance) { - //Warning Save Button is shared over the hole Option Menu ! - if (OptionsManager.ModListPendingChanges.Count > 0) + if (Config.EnableModListMenu) { - //if the List Contains Pending entries show Info Box - Dialog dialog = new Dialog(); - dialog.message = "Important ! Changes on Mods will enforce a Game Reboot after all changes are saved to system."; - dialog.color = Dialog.DialogColor.Red; - dialog.rightButton = Dialog.Button.CancelModChanges; - dialog.leftButton = Dialog.Button.ApplyModChanges; - dialog.Show(); - } + //Warning Save Button is shared over the hole Option Menu ! + if (OptionsManager.ModListPendingChanges.Count > 0) + { + //if the List Contains Pending entries show Info Box + Dialog dialog = new Dialog(); + dialog.message = "Important ! Changes on Mods will enforce a Game Reboot after all changes are saved to system."; + dialog.color = Dialog.DialogColor.Red; + dialog.rightButton = Dialog.Button.CancelModChanges; + dialog.leftButton = Dialog.Button.ApplyModChanges; + dialog.Show(); + } - //In case User Canceled or the Quit was not executed properly - if (OptionsManager.ModListPendingChanges.Count != 0) - { - //As the Original Methode would be disable the Button anyway. We need to Enable it again. - __instance.applyButton.gameObject.SetActive(true); + //In case User Canceled or the Quit was not executed properly + if (OptionsManager.ModListPendingChanges.Count != 0) + { + //As the Original Methode would be disable the Button anyway. We need to Enable it again. + __instance.applyButton.gameObject.SetActive(true); + } } } } diff --git a/QModManager/Utility/Config.cs b/QModManager/Utility/Config.cs index 2153a8b9..b0f350f1 100644 --- a/QModManager/Utility/Config.cs +++ b/QModManager/Utility/Config.cs @@ -35,6 +35,12 @@ internal static bool EnableDevMode set => Set("Enable developer mode", value); } + internal static bool EnableModListMenu + { + get => Get("Enable Mod List Menu", true); + set => Set("Enable Mod List Menu", value); + } + private static readonly string ConfigPath = Path.Combine(Environment.CurrentDirectory, "qmodmanager-config.json"); private static Dictionary Cfg = new Dictionary(); From 1c526f443927aedfa2130b73dcf456927b92e445 Mon Sep 17 00:00:00 2001 From: desperationfighter <76217485+desperationfighter@users.noreply.github.com> Date: Sun, 8 May 2022 00:41:41 +0200 Subject: [PATCH 23/29] Fix for QMM Versionchecker parsing + Fix Gameversion Logger (#5) * Helper got confused when getting the "wrong Game detection" line in the Logfile while the top says this QMM version was build for the Game X. As this make no sense to display the "running" game version when saying it is build for. I changed that to hardcoded even its look a bit bloated. * Fixed issue when a not Full Qualified Version is provided by the QMM Latest Version file. --- QModManager/Checks/VersionCheck.cs | 28 ++++++++++++++++++---------- QModManager/Patching/GameDetector.cs | 11 ++++++++++- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/QModManager/Checks/VersionCheck.cs b/QModManager/Checks/VersionCheck.cs index 612f23dc..3d90a815 100644 --- a/QModManager/Checks/VersionCheck.cs +++ b/QModManager/Checks/VersionCheck.cs @@ -19,13 +19,13 @@ internal static void Check() { if (!Config.CheckForUpdates) { - Logger.Info("Update check disabled"); + Logger.Info("QMM Internal Versionchecker: Update check disabled"); return; } if (!NetworkUtilities.CheckConnection()) { - Logger.Info("Cannot check for updates, internet disabled"); + Logger.Info("QMM Internal Versionchecker: Cannot check for updates, internet disabled"); return; } @@ -37,14 +37,14 @@ internal static void Check() { if (e.Error != null) { - Logger.Error("There was an error retrieving the latest version from GitHub!"); + Logger.Error("QMM Internal Versionchecker: There was an error retrieving the latest version from GitHub!"); Logger.Exception(e.Error); return; } Parse(e.Result); }; - Logger.Debug("Getting the latest version..."); + Logger.Debug("QMM Internal Versionchecker: Getting the latest version..."); client.DownloadStringAsync(new Uri(VersionURL)); } } @@ -56,15 +56,23 @@ internal static void Parse(string versionStr) Version currentVersion = Assembly.GetExecutingAssembly().GetName().Version; if (versionStr == null) { - Logger.Error("There was an error retrieving the latest version from GitHub!"); + Logger.Error("QMM Internal Versionchecker: There was an error retrieving the latest version from GitHub!"); return; } - var latestVersion = new Version(versionStr); + + string[] versionStr_splittet = versionStr.Split('.'); + string version_builder = $"{versionStr_splittet[0]}.{(versionStr_splittet.Length >= 2 ? $"{versionStr_splittet[1]}" : "0")}.{(versionStr_splittet.Length >= 3 ? $"{versionStr_splittet[2]}" : "0")}.{(versionStr_splittet.Length >= 4 ? $"{versionStr_splittet[3]}" : "0")}"; + var latestVersion = new Version(version_builder); + if (latestVersion == null) { - Logger.Error("There was an error retrieving the latest version from GitHub!"); + Logger.Error("QMM Internal Versionchecker: There was an error retrieving the latest version from GitHub!"); return; } + + //Logger.Debug($"QMM Version Checker - Parse - current Version value: {currentVersion}"); + //Logger.Debug($"QMM Version Checker - Parse - latest Version value: {latestVersion}"); + if (latestVersion > currentVersion) { Logger.Info($"Newer version found: {latestVersion.ToStringParsed()} (current version: {currentVersion.ToStringParsed()})"); @@ -72,16 +80,16 @@ internal static void Parse(string versionStr) } else if (latestVersion < currentVersion) { - Logger.Info($"Received latest version from GitHub. We're ahead. This is probably a development build."); + Logger.Info($"QMM Internal Versionchecker: Received latest version from GitHub. We're ahead. This is probably a development build."); } else { - Logger.Info($"Received latest version from GitHub. We are up to date!"); + Logger.Info($"QMM Internal Versionchecker: Received latest version from GitHub. We are up to date!"); } } catch (Exception e) { - Logger.Error("There was an error retrieving the latest version from GitHub!"); + Logger.Error("QMM Internal Versionchecker: There was an error retrieving the latest version from GitHub!"); Logger.Exception(e); return; } diff --git a/QModManager/Patching/GameDetector.cs b/QModManager/Patching/GameDetector.cs index 83c8d010..47b541fd 100644 --- a/QModManager/Patching/GameDetector.cs +++ b/QModManager/Patching/GameDetector.cs @@ -61,7 +61,16 @@ internal GameDetector() CurrentGameVersion = SNUtils.GetPlasticChangeSetOfBuild(-1); Logger.Info($"Game Version: {CurrentGameVersion} Build Date: {SNUtils.GetDateTimeOfBuild():dd-MMMM-yyyy} Store: {StoreDetector.GetUsedGameStore()}"); - Logger.Info($"Loading QModManager v{Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()}{(IsValidGameRunning && MinimumBuildVersion != 0 ? $" built for {CurrentlyRunningGame} v{MinimumBuildVersion}" : string.Empty)}..."); + +#if SUBNAUTICA_STABLE + Logger.Info($"Loading QModManager v{Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} built for Subnautica v{SupportedGameVersions[QModGame.Subnautica]}..."); +#elif SUBNAUTICA_EXP + Logger.Info($"Loading QModManager -Experimental- v{Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} built for Subnautica v{SupportedGameVersions[QModGame.Subnautica]}..."); +#elif BELOWZERO_STABLE + Logger.Info($"Loading QModManager v{Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} built for Below Zero v{SupportedGameVersions[QModGame.BelowZero]}..."); +#elif BELOWZERO_EXP + Logger.Info($"Loading QModManager -Experimental- v{Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} built for Below Zero v{SupportedGameVersions[QModGame.BelowZero]}..."); +#endif Logger.Info($"Today is {DateTime.Now:dd-MMMM-yyyy_HH:mm:ss}"); if (!IsValidGameVersion) From 642d68477ac256b37eb4cb6e2b794eb656b20d03 Mon Sep 17 00:00:00 2001 From: desperationfighter <76217485+desperationfighter@users.noreply.github.com> Date: Sun, 15 May 2022 09:42:22 +0200 Subject: [PATCH 24/29] Adding API for Mods to get current running QMM Version. (#6) For example in case the Mod depence on a QMM Feature release with a special build. --- QModManager/API/IQModServices.cs | 9 +++++++++ QModManager/API/QModServices.cs | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/QModManager/API/IQModServices.cs b/QModManager/API/IQModServices.cs index 6aee2d35..5c5ec7c7 100644 --- a/QModManager/API/IQModServices.cs +++ b/QModManager/API/IQModServices.cs @@ -1,5 +1,6 @@ namespace QModManager.API { + using System; using System.Reflection; using QModManager.Utility; @@ -56,5 +57,13 @@ public interface IQModServices : IQModAPI /// true if Piracy was detected; otherwise, false. /// bool PirateDetected { get; } + + /// + /// Gets the current Q Mod Manager Version. + /// + /// + /// Return Running QMM Version. + /// + Version QMMrunningVersion { get; } } } \ No newline at end of file diff --git a/QModManager/API/QModServices.cs b/QModManager/API/QModServices.cs index c44518a5..c485ea83 100644 --- a/QModManager/API/QModServices.cs +++ b/QModManager/API/QModServices.cs @@ -2,6 +2,7 @@ namespace QModManager.API { + using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Reflection; @@ -165,5 +166,13 @@ public void AddCriticalMessage(string msg, int size = MainMenuMessages.defaultSi /// true if Piracy was detected; otherwise, false. /// public bool PirateDetected => PirateCheck.PirateDetected; + + /// + /// Gets the current Q Mod Manager Version. + /// + /// + /// Return Running QMM Version. + /// + public Version QMMrunningVersion => Assembly.GetExecutingAssembly().GetName().Version; } } From 5214db2ce08fe12e38c45dd17d4d7c1c45833b31 Mon Sep 17 00:00:00 2001 From: desperationfighter <76217485+desperationfighter@users.noreply.github.com> Date: Wed, 25 May 2022 22:12:57 +0200 Subject: [PATCH 25/29] Added detailed Error Catch for Folder Tree Logger (#7) Added detailed Error Catch for specific File to prevent stopping the hole File Tree logging on a single error. This should help helpers to still see all the Files. This idea was initially because a Mod had a ".rar" File in it that caused a IO Exception. --- QModManager/Utility/IOUtilities.cs | 38 ++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/QModManager/Utility/IOUtilities.cs b/QModManager/Utility/IOUtilities.cs index f16941b5..e6e96cbb 100644 --- a/QModManager/Utility/IOUtilities.cs +++ b/QModManager/Utility/IOUtilities.cs @@ -60,22 +60,29 @@ internal static void WriteFolderStructure(string directory) string[] files = Directory.GetFiles(directory); for (int i = 1; i <= files.Length; i++) { - FileInfo fileinfo = new FileInfo(files[i - 1]); - if (i != files.Length) - Console.WriteLine($"{GenerateSpaces(0)}|---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})"); - else - Console.WriteLine($"{GenerateSpaces(0)}|---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})"); + try + { + FileInfo fileinfo = new FileInfo(files[i - 1]); + if (i != files.Length) + Console.WriteLine($"{GenerateSpaces(0)}|---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})"); + else + Console.WriteLine($"{GenerateSpaces(0)}|---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})"); + } + catch (Exception e) + { + Console.WriteLine($"{GenerateSpaces(0)}|---- ERROR ON GETTING FILE INFORMATION - {e.Message}"); + } } } catch (Exception e) { throw e; } - } +} internal static void WriteFolderStructureRecursively(string directory, int spaces = 0) { try - { + { DirectoryInfo dirInfo = new DirectoryInfo(directory); Console.WriteLine($"{GenerateSpaces(spaces)}|---+ {dirInfo.Name}"); @@ -93,11 +100,18 @@ internal static void WriteFolderStructureRecursively(string directory, int space string[] files = Directory.GetFiles(directory); for (int i = 1; i <= files.Length; i++) { - FileInfo fileinfo = new FileInfo(files[i - 1]); - if (i != files.Length) - Console.WriteLine($"{GenerateSpaces(spaces + 4)}|---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})"); - else - Console.WriteLine($"{GenerateSpaces(spaces + 4)}`---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})"); + try + { + FileInfo fileinfo = new FileInfo(files[i - 1]); + if (i != files.Length) + Console.WriteLine($"{GenerateSpaces(spaces + 4)}|---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})"); + else + Console.WriteLine($"{GenerateSpaces(spaces + 4)}`---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})"); + } + catch (Exception e) + { + Console.WriteLine($"{GenerateSpaces(spaces + 4)}|---- ERROR ON GETTING FILE INFORMATION -> {e.Message}"); + } } } catch (Exception e) From dc389ec2dc6944b4b449f819be18534595df6837 Mon Sep 17 00:00:00 2001 From: desperationfighter <76217485+desperationfighter@users.noreply.github.com> Date: Thu, 16 Jun 2022 17:47:27 +0200 Subject: [PATCH 26/29] additional Error Catching + Mod.json Information on Filetree (#8) * added mod.json information on FileTree * adding additional Error Catching for bad Files on Filetree Adding additional Error Catching on Filetree generation to prevent a single file from breaking the complete process. this helps Supporter to find the error file while beeing still able to help on all other topics. Secondary added a Mod.json information parser to read Data directly from file. This should help to indicate what mod you are looking for when user messed up with the folders or installing multiple versions of the same mod. (Happens with SML Helper sometimes) --- .../plugins/QModManager/QModInstaller.xml | 21 +++++++++++ QModManager/Checks/VersionCheck.cs | 2 +- QModManager/OptionsManager.cs | 5 +++ QModManager/Utility/IOUtilities.cs | 36 +++++++++++++++---- 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/BepinexPackages/Subnautica_Packages/QModManager/plugins/QModManager/QModInstaller.xml b/BepinexPackages/Subnautica_Packages/QModManager/plugins/QModManager/QModInstaller.xml index 04a0010e..42e18a49 100644 --- a/BepinexPackages/Subnautica_Packages/QModManager/plugins/QModManager/QModInstaller.xml +++ b/BepinexPackages/Subnautica_Packages/QModManager/plugins/QModManager/QModInstaller.xml @@ -152,6 +152,14 @@ true if Nitrox is being used; otherwise, false. + + + Gets a value indicating whether Piracy was detected. + + + true if Piracy was detected; otherwise, false. + + Identifies the patching class for your QMod. @@ -354,6 +362,14 @@ true if Nitrox is being used; otherwise, false. + + + Gets a value indicating whether Piracy was detected. + + + true if Piracy was detected; otherwise, false. + + Identifies a required mod and an optional minimum version. @@ -597,6 +613,11 @@ QMMLoader - simply fires up the QModManager entry point. + + + "Only for use by Bepinex" + + Prevents a default instance of the class from being created diff --git a/QModManager/Checks/VersionCheck.cs b/QModManager/Checks/VersionCheck.cs index 3d90a815..b615256f 100644 --- a/QModManager/Checks/VersionCheck.cs +++ b/QModManager/Checks/VersionCheck.cs @@ -80,7 +80,7 @@ internal static void Parse(string versionStr) } else if (latestVersion < currentVersion) { - Logger.Info($"QMM Internal Versionchecker: Received latest version from GitHub. We're ahead. This is probably a development build."); + Logger.Info($"QMM Internal Versionchecker: Received latest version ({latestVersion.ToStringParsed()}) from GitHub. We're ahead. This is probably a development build (current version: {currentVersion.ToStringParsed()})."); } else { diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index 721503b2..1eba2f00 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -94,6 +94,11 @@ internal static void Postfix(uGUI_OptionsPanel __instance) //Create new Tab in the Menu ModListTab = __instance.AddTab("QMods List"); + if(QModServices.Main.PirateDetected) + { + __instance.AddHeading(ModListTab, $"If you like the Game, please Support it and buy it. Thanks."); + } + //Add QMM Informations #if SUBNAUTICA_STABLE __instance.AddHeading(ModListTab, $"Running QModManager {Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} for Subnautica"); diff --git a/QModManager/Utility/IOUtilities.cs b/QModManager/Utility/IOUtilities.cs index e6e96cbb..86169927 100644 --- a/QModManager/Utility/IOUtilities.cs +++ b/QModManager/Utility/IOUtilities.cs @@ -4,7 +4,7 @@ using QModManager.Patching; #if SUBNAUTICA_STABLE - using Oculus.Newtonsoft.Json; +using Oculus.Newtonsoft.Json; #else using Newtonsoft.Json; #endif @@ -66,11 +66,14 @@ internal static void WriteFolderStructure(string directory) if (i != files.Length) Console.WriteLine($"{GenerateSpaces(0)}|---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})"); else - Console.WriteLine($"{GenerateSpaces(0)}|---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})"); + Console.WriteLine($"{GenerateSpaces(0)}`---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})"); } catch (Exception e) { - Console.WriteLine($"{GenerateSpaces(0)}|---- ERROR ON GETTING FILE INFORMATION - {e.Message}"); + if (i != files.Length) + Console.WriteLine($"{GenerateSpaces(0)}|---- ERROR ON GETTING FILE INFORMATIONS - {e.Message}"); + else + Console.WriteLine($"{GenerateSpaces(0)}`---- ERROR ON GETTING FILE INFORMATIONS - {e.Message}"); } } } @@ -103,14 +106,33 @@ internal static void WriteFolderStructureRecursively(string directory, int space try { FileInfo fileinfo = new FileInfo(files[i - 1]); - if (i != files.Length) - Console.WriteLine($"{GenerateSpaces(spaces + 4)}|---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})"); + if (fileinfo.Name == "mod.json") + { + var modjson = JsonConvert.DeserializeObject(File.ReadAllText(fileinfo.FullName)); + if (i != files.Length) + { + + Console.WriteLine($"{GenerateSpaces(spaces + 4)}|---- {fileinfo.Name} [{modjson.Id} v{modjson.Version} by {modjson.Author} for {modjson.Game}] ({ParseSize(fileinfo.Length)})"); + } + else + { + Console.WriteLine($"{GenerateSpaces(spaces + 4)}`---- {fileinfo.Name} [{modjson.Id} v{modjson.Version} by {modjson.Author} for {modjson.Game}] ({ParseSize(fileinfo.Length)})"); + } + } else - Console.WriteLine($"{GenerateSpaces(spaces + 4)}`---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})"); + { + if (i != files.Length) + Console.WriteLine($"{GenerateSpaces(spaces + 4)}|---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})"); + else + Console.WriteLine($"{GenerateSpaces(spaces + 4)}`---- {fileinfo.Name} ({ParseSize(fileinfo.Length)})"); + } } catch (Exception e) { - Console.WriteLine($"{GenerateSpaces(spaces + 4)}|---- ERROR ON GETTING FILE INFORMATION -> {e.Message}"); + if (i != files.Length) + Console.WriteLine($"{GenerateSpaces(spaces + 4)}|---- ERROR ON GETTING FILE INFORMATIONS - {e.Message}"); + else + Console.WriteLine($"{GenerateSpaces(spaces + 4)}`---- ERROR ON GETTING FILE INFORMATIONS - {e.Message}"); } } } From 374f0ecfe0e6014a07ebb33c554f37e6b9483c8a Mon Sep 17 00:00:00 2001 From: desperationfighter <76217485+desperationfighter@users.noreply.github.com> Date: Thu, 16 Jun 2022 17:53:55 +0200 Subject: [PATCH 27/29] returnfrom save game warning (#9) * Adding Warnings when already played a Savegame --- QModManager/API/IQModServices.cs | 11 +++- QModManager/API/QModServices.cs | 8 +++ .../ReturnfromSavegameWarning.cs | 58 +++++++++++++++++++ QModManager/OptionsManager.cs | 2 + QModManager/QModManager.csproj | 1 + QModManager/Utility/Config.cs | 5 ++ 6 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 QModManager/HarmonyPatches/ReturnfromSavegameWarning.cs diff --git a/QModManager/API/IQModServices.cs b/QModManager/API/IQModServices.cs index 5c5ec7c7..9e90d1f0 100644 --- a/QModManager/API/IQModServices.cs +++ b/QModManager/API/IQModServices.cs @@ -49,7 +49,6 @@ public interface IQModServices : IQModAPI /// bool NitroxRunning { get; } - /// /// Gets a value indicating whether Piracy was detected. /// @@ -57,7 +56,7 @@ public interface IQModServices : IQModAPI /// true if Piracy was detected; otherwise, false. /// bool PirateDetected { get; } - + /// /// Gets the current Q Mod Manager Version. /// @@ -65,5 +64,13 @@ public interface IQModServices : IQModAPI /// Return Running QMM Version. /// Version QMMrunningVersion { get; } + + /// + /// Gets a value indicating when a Savegame was already loaded. (Turns true when entering the Mainmenu again.) + /// + /// + /// true Mainmenu is entered AFTER a Savegame was loaded already; otherwise, false. + /// + bool AnySavegamewasalreadyloaded { get; } } } \ No newline at end of file diff --git a/QModManager/API/QModServices.cs b/QModManager/API/QModServices.cs index c485ea83..7d1eeb92 100644 --- a/QModManager/API/QModServices.cs +++ b/QModManager/API/QModServices.cs @@ -174,5 +174,13 @@ public void AddCriticalMessage(string msg, int size = MainMenuMessages.defaultSi /// Return Running QMM Version. /// public Version QMMrunningVersion => Assembly.GetExecutingAssembly().GetName().Version; + + /// + /// Gets a value indicating when a Savegame was already loaded (Turn true when entering the Mainmenu again. + /// + /// + /// true Mainmenu is entered AFTER a Savegame was loaded already; otherwise, false. + /// + public bool AnySavegamewasalreadyloaded => ReturnfromSavegameWarning.AnySavegamewasloaded; } } diff --git a/QModManager/HarmonyPatches/ReturnfromSavegameWarning.cs b/QModManager/HarmonyPatches/ReturnfromSavegameWarning.cs new file mode 100644 index 00000000..efd9ad18 --- /dev/null +++ b/QModManager/HarmonyPatches/ReturnfromSavegameWarning.cs @@ -0,0 +1,58 @@ +namespace QModManager.Patching +{ + using HarmonyLib; + using QModManager.API; + using MyLogger = Utility; + using UWE; + using System.Collections; + using UnityEngine; + + internal static class ReturnfromSavegameWarning + { + public static bool AnySavegamewasloaded = false; + } + + [HarmonyPatch(typeof(Player), nameof(Player.Awake))] + internal static class ReturnfromSavegameWarningPlayerAwake + { + [HarmonyPostfix] + internal static void Postfix(Player __instance) + { + if (ReturnfromSavegameWarning.AnySavegamewasloaded) + { + MyLogger.Logger.Error("Entering a Savegame after playing a other one without restarting the Game. Modders do not recommend that. Restart the Game to prevent errors or unexpected behaviour"); + if (Utility.Config.ShowWarnOnLoadSecondSave) + { + CoroutineHost.StartCoroutine(ShowIngameMessage_async("Modders do not recommend loading multiple savegames without restarting the game.")); + } + } + else + { + ReturnfromSavegameWarning.AnySavegamewasloaded = true; + } + } + public static IEnumerator ShowIngameMessage_async(string Message) + { + yield return new WaitForSecondsRealtime(2); + yield return new WaitForSeconds(3); + ErrorMessage.AddMessage(Message); + } + } + + [HarmonyPatch(typeof(uGUI_MainMenu), nameof(uGUI_MainMenu.Awake))] + internal static class ReturnfromSavegameWarninguGUI_MainMenuAwake + { + [HarmonyPostfix] + internal static void Postfix(uGUI_OptionsPanel __instance) + { + if (ReturnfromSavegameWarning.AnySavegamewasloaded) + { + MyLogger.Logger.Error("Entering Main Menu after playing a Savegame. Modders do not recommend to start or load a Savegame now. Restart the Game to prevent errors or unexpected behaviour"); + if (Utility.Config.ShowWarnOnLoadSecondSave) + { + //QModServices.Main.AddCriticalMessage("Note that Modders recommend to restart the Game before loading the next Savegame", 15, "orange"); + } + } + } + } +} diff --git a/QModManager/OptionsManager.cs b/QModManager/OptionsManager.cs index 1eba2f00..b26ffde4 100644 --- a/QModManager/OptionsManager.cs +++ b/QModManager/OptionsManager.cs @@ -46,6 +46,7 @@ internal static void Postfix(uGUI_OptionsPanel __instance) AddToggleOption.Invoke(__instance, new object[] { ModsTab, "Enable debug logs", Config.EnableDebugLogs, new UnityAction(value => Config.EnableDebugLogs = value) }); AddToggleOption.Invoke(__instance, new object[] { ModsTab, "Enable developer mode", Config.EnableDevMode, new UnityAction(value => Config.EnableDevMode = value) }); AddToggleOption.Invoke(__instance, new object[] { ModsTab, "Enable Mod List Menu", Config.EnableModListMenu, new UnityAction(value => Config.EnableModListMenu = value) }); + AddToggleOption.Invoke(__instance, new object[] { ModsTab, "Show Warning on Loading Second Save", Config.ShowWarnOnLoadSecondSave, new UnityAction(value => Config.ShowWarnOnLoadSecondSave = value) }); } else { @@ -66,6 +67,7 @@ internal static void Postfix(uGUI_OptionsPanel __instance) AddToggleOption.Invoke(__instance, new object[] { ModsTab, "Enable debug logs", Config.EnableDebugLogs, new UnityAction(value => Config.EnableDebugLogs = value), null }); AddToggleOption.Invoke(__instance, new object[] { ModsTab, "Enable developer mode", Config.EnableDevMode, new UnityAction(value => Config.EnableDevMode = value), null }); AddToggleOption.Invoke(__instance, new object[] { ModsTab, "Enable Mod List Menu", Config.EnableModListMenu, new UnityAction(value => Config.EnableModListMenu = value), null }); + AddToggleOption.Invoke(__instance, new object[] { ModsTab, "Show Warning on Loading Second Save", Config.ShowWarnOnLoadSecondSave, new UnityAction(value => Config.ShowWarnOnLoadSecondSave = value), null }); } #endregion Mod Config diff --git a/QModManager/QModManager.csproj b/QModManager/QModManager.csproj index 620039b5..e630c5d9 100644 --- a/QModManager/QModManager.csproj +++ b/QModManager/QModManager.csproj @@ -137,6 +137,7 @@ + diff --git a/QModManager/Utility/Config.cs b/QModManager/Utility/Config.cs index b0f350f1..45dbd681 100644 --- a/QModManager/Utility/Config.cs +++ b/QModManager/Utility/Config.cs @@ -40,6 +40,11 @@ internal static bool EnableModListMenu get => Get("Enable Mod List Menu", true); set => Set("Enable Mod List Menu", value); } + internal static bool ShowWarnOnLoadSecondSave + { + get => Get("Show Warning on Loading Second Save", false); + set => Set("Show Warning on Loading Second Save", value); + } private static readonly string ConfigPath = Path.Combine(Environment.CurrentDirectory, "qmodmanager-config.json"); From 41ff30722119aa1ba691aa46e33321fa02019648 Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Wed, 20 Jul 2022 13:51:03 +0200 Subject: [PATCH 28/29] Error Catching for Date and Time Logging. As its not critical there is no reason to stop QMM from running. --- QModManager/Patching/GameDetector.cs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/QModManager/Patching/GameDetector.cs b/QModManager/Patching/GameDetector.cs index 47b541fd..669b5bfe 100644 --- a/QModManager/Patching/GameDetector.cs +++ b/QModManager/Patching/GameDetector.cs @@ -60,7 +60,14 @@ internal GameDetector() CurrentGameVersion = SNUtils.GetPlasticChangeSetOfBuild(-1); - Logger.Info($"Game Version: {CurrentGameVersion} Build Date: {SNUtils.GetDateTimeOfBuild():dd-MMMM-yyyy} Store: {StoreDetector.GetUsedGameStore()}"); + try + { + Logger.Info($"Game Version: {CurrentGameVersion} Build Date: {SNUtils.GetDateTimeOfBuild():dd-MMMM-yyyy} Store: {StoreDetector.GetUsedGameStore()}"); + } + catch + { + Logger.Warn($"Game Version: {CurrentGameVersion} Build Date: [Error in displaying Time and Date] Store: {StoreDetector.GetUsedGameStore()}"); + } #if SUBNAUTICA_STABLE Logger.Info($"Loading QModManager v{Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} built for Subnautica v{SupportedGameVersions[QModGame.Subnautica]}..."); @@ -71,7 +78,21 @@ internal GameDetector() #elif BELOWZERO_EXP Logger.Info($"Loading QModManager -Experimental- v{Assembly.GetExecutingAssembly().GetName().Version.ToStringParsed()} built for Below Zero v{SupportedGameVersions[QModGame.BelowZero]}..."); #endif - Logger.Info($"Today is {DateTime.Now:dd-MMMM-yyyy_HH:mm:ss}"); + try + { + Logger.Info($"Today is {DateTime.Now:dd-MMMM-yyyy_HH:mm:ss}"); + } + catch + { + try + { + Logger.Warn($"Today is: Unable to format Time here is the raw Version - {DateTime.Now}"); + } + catch + { + Logger.Error($"Today is: Unable to Read Time and Date. Possible due to unsupported Calender settings."); + } + } if (!IsValidGameVersion) { From d5f74708eeb03e2f51444a6859e4d40f34dfb3cf Mon Sep 17 00:00:00 2001 From: desperationfighter Date: Mon, 15 Aug 2022 18:35:16 +0200 Subject: [PATCH 29/29] pass through Exception Message --- QModManager/Utility/IOUtilities.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/QModManager/Utility/IOUtilities.cs b/QModManager/Utility/IOUtilities.cs index 86169927..e031057f 100644 --- a/QModManager/Utility/IOUtilities.cs +++ b/QModManager/Utility/IOUtilities.cs @@ -199,9 +199,9 @@ internal static void ChangeModStatustoFile(QMod qmod) File.WriteAllText(modconfigpath, jsonstr); Logger.Log(Logger.Level.Info, $"IOUtilities - ChangeModStatustoFile - Enabled Status Update for {qmod.Id} was succesful written to: {modconfigpath}"); } - catch + catch (Exception ex) { - Logger.Log(Logger.Level.Error, $"ErrorID:5713/36B - Saving mod.json for Mod {qmod.Id} to {modconfigpath} failed. - Was the File open in a other Program ? Permission Error ?"); + Logger.Log(Logger.Level.Error, $"ErrorID:5713/36B - Saving mod.json for Mod {qmod.Id} to {modconfigpath} failed. - Was the File open in a other Program ? Permission Error ? Original Message:\n {ex.Message}"); } } else