diff --git a/CHANGELOG.md b/CHANGELOG.md index cfee58159..28e7cf1e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## Version 2.21.0 +* Added ConfigManagerUtils for soft access to common ConfigurationManager functionality * Added PieceManager.AddPieceCategory(string name) and PieceManager.RemovePieceCategory(string name) * Deprecated PieceManager.AddPieceCategory(string table, string name) and PieceManager.RemovePieceCategory(string table, string name), use the new overloads without the table parameter diff --git a/JotunnLib/Managers/SynchronizationManager.cs b/JotunnLib/Managers/SynchronizationManager.cs index 7c277d235..a6c657995 100644 --- a/JotunnLib/Managers/SynchronizationManager.cs +++ b/JotunnLib/Managers/SynchronizationManager.cs @@ -28,7 +28,6 @@ public class SynchronizationManager : IManager private readonly Dictionary CustomConfigs = new Dictionary(); private List> CachedConfigValues = new List>(); private readonly Dictionary CachedCustomConfigGUIDs = new Dictionary(); - private BaseUnityPlugin ConfigurationManager; private bool ConfigurationManagerWindowShown; /// @@ -89,20 +88,15 @@ void IManager.Init() // Hook start scene to reset config SceneManager.sceneLoaded += SceneManager_sceneLoaded; - // Find Configuration manager plugin and add to DisplayingWindowChanged event - const string configManagerGuid = "com.bepis.bepinex.configurationmanager"; - if (Chainloader.PluginInfos.TryGetValue(configManagerGuid, out var configManagerInfo) && configManagerInfo.Instance) + if (ConfigManagerUtils.Plugin) { - ConfigurationManager = configManagerInfo.Instance; - - Logger.LogDebug("Configuration manager found, trying to hook DisplayingWindowChanged"); - var eventinfo = ConfigurationManager.GetType().GetEvent("DisplayingWindowChanged"); + var eventinfo = ConfigManagerUtils.Plugin.GetType().GetEvent("DisplayingWindowChanged"); if (eventinfo != null) { Action local = ConfigurationManager_DisplayingWindowChanged; var converted = Delegate.CreateDelegate(eventinfo.EventHandlerType, local.Target, local.Method); - eventinfo.AddEventHandler(ConfigurationManager, converted); + eventinfo.AddEventHandler(ConfigManagerUtils.Plugin, converted); } } @@ -573,9 +567,7 @@ private void Menu_IsVisible(ref bool result) /// private void ConfigurationManager_DisplayingWindowChanged(object sender, object e) { - // Read configuration manager's DisplayingWindow property - var pi = ConfigurationManager.GetType().GetProperty("DisplayingWindow"); - ConfigurationManagerWindowShown = (bool)pi.GetValue(ConfigurationManager, null); + ConfigurationManagerWindowShown = ConfigManagerUtils.DisplayingWindow; if (!ConfigurationManagerWindowShown) { diff --git a/JotunnLib/Utils/ConfigManagerUtils.cs b/JotunnLib/Utils/ConfigManagerUtils.cs new file mode 100644 index 000000000..f6b5d10bd --- /dev/null +++ b/JotunnLib/Utils/ConfigManagerUtils.cs @@ -0,0 +1,54 @@ +using System; +using System.Reflection; +using BepInEx; +using BepInEx.Bootstrap; +using HarmonyLib; + +namespace Jotunn.Utils +{ + /// + /// Utility class for the BepInEx ConfigurationManager plugin, without requiring a hard dependency + /// + public static class ConfigManagerUtils + { + /// + /// The ConfigurationManager plugin instance if installed, otherwise null + /// + public static BaseUnityPlugin Plugin { get; private set; } + + private static PropertyInfo displayingWindowInfo; + private static MethodInfo buildSettingListMethodInfo; + + static ConfigManagerUtils() + { + if (Chainloader.PluginInfos.TryGetValue("com.bepis.bepinex.configurationmanager", out var configManagerInfo) && configManagerInfo.Instance) + { + Plugin = configManagerInfo.Instance; + displayingWindowInfo = AccessTools.Property(Plugin.GetType(), "DisplayingWindow"); + buildSettingListMethodInfo = AccessTools.Method(Plugin.GetType(), "BuildSettingList"); + } + } + + /// + /// Is the config manager main window displayed on screen
+ /// Safe to use even if ConfigurationManager is not installed. + ///
+ public static bool DisplayingWindow + { + get => Plugin && (bool)displayingWindowInfo.GetValue(Plugin); + set => displayingWindowInfo?.SetValue(Plugin, value); + } + + /// + /// Rebuild the setting list. Use to update the config manager window if config settings were removed or added while it was open.
+ /// Safe to call even if ConfigurationManager is not installed. + ///
+ public static void BuildSettingList() + { + if (Plugin) + { + buildSettingListMethodInfo.Invoke(Plugin, null); + } + } + } +}