Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ModConfigs v1.0.6
ModConfigs.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GUIFramework; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; using Valheim.SettingsGui; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: IgnoresAccessChecksTo("assembly_guiutils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: AssemblyCompany("ModConfigs")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.6.0")] [assembly: AssemblyInformationalVersion("1.0.6")] [assembly: AssemblyProduct("ModConfigs")] [assembly: AssemblyTitle("ModConfigs")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.6.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ModdedWolfsConfigs { public static class ModdedWolfsConfigsAPI { public static void OpenConfigPanel() { ConfigPanelOpener.Open(); } } public sealed class ConfigurationManagerAttributes { public bool? Browsable; public bool? IsAdminOnly; public bool? IsAdvanced; public int? Order; public string DispName; public string Description; public string Category; public bool? ReadOnly; public bool? HideDefaultButton; public object DefaultValue; public bool? ShowRangeAsPercent; public bool? HideSettingName; } internal static class ClientLocalBindings { internal static bool IsBinding(ConfigEntryBase entry) { if (entry == null) { return false; } Type settingType = entry.SettingType; if (settingType == null) { return false; } if (settingType == typeof(KeyCode) || settingType == typeof(KeyboardShortcut)) { return true; } return (settingType.FullName ?? string.Empty).IndexOf("KeyboardShortcut", StringComparison.OrdinalIgnoreCase) >= 0; } } internal static class ConfigApply { internal static void PersistAfterLocalChange(ConfigEntryBase entry) { if (entry == null) { return; } try { ConfigFile configFile = entry.ConfigFile; if (configFile != null) { configFile.Save(); } } catch (Exception ex) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)("Failed to save config: " + ex.Message)); } } } internal sealed class DiscoveredPlugin { public string Guid; public string Name; public string Version; public BaseUnityPlugin Plugin; public List<DiscoveredSection> Sections = new List<DiscoveredSection>(); } internal sealed class DiscoveredSection { public string Name; public List<ConfigEntryBase> Entries = new List<ConfigEntryBase>(); } internal static class ConfigDiscovery { private static readonly HashSet<string> HiddenConfigKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "LastSelectedModGuid", "ShowMenuButton" }; private static bool _loggedHiddenKeyFilter; internal static bool IsHiddenConfigKey(string key) { if (!string.IsNullOrEmpty(key)) { return HiddenConfigKeys.Contains(key); } return false; } internal static bool ShouldRenderEntry(ConfigEntryBase entry) { if (((entry != null) ? entry.Definition : null) == (ConfigDefinition)null) { return false; } return !IsHiddenConfigKey(entry.Definition.Key); } internal static List<DiscoveredPlugin> Discover() { List<DiscoveredPlugin> list = new List<DiscoveredPlugin>(); IEnumerable<KeyValuePair<string, PluginInfo>> enumerable; try { enumerable = Chainloader.PluginInfos.Where(delegate(KeyValuePair<string, PluginInfo> p) { PluginInfo value3 = p.Value; return ((value3 != null) ? value3.Metadata : null) != null; }).OrderBy<KeyValuePair<string, PluginInfo>, string>((KeyValuePair<string, PluginInfo> p) => p.Value.Metadata.Name ?? p.Value.Metadata.GUID ?? p.Key ?? string.Empty, StringComparer.OrdinalIgnoreCase); } catch (Exception ex) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)("ConfigDiscovery: failed to enumerate plugins: " + ex.Message)); return list; } foreach (KeyValuePair<string, PluginInfo> item in enumerable) { PluginInfo value = item.Value; string text = item.Key ?? "(unknown)"; try { if (((value != null) ? value.Metadata : null) == null) { continue; } text = ((!string.IsNullOrEmpty(value.Metadata.Name)) ? (value.Metadata.Name + " (" + value.Metadata.GUID + ")") : (value.Metadata.GUID ?? item.Key ?? "(unknown)")); BaseUnityPlugin instance = value.Instance; if ((Object)(object)instance == (Object)null || (ModdedWolfsConfigsPlugin.HideSelfFromList.Value && value.Metadata.GUID == "ModdedWolf.ModConfigs")) { continue; } ConfigFile config = instance.Config; if (config == null) { continue; } Dictionary<string, DiscoveredSection> dictionary = new Dictionary<string, DiscoveredSection>(StringComparer.OrdinalIgnoreCase); foreach (ConfigDefinition key in config.Keys) { if (key == (ConfigDefinition)null) { continue; } if (IsHiddenConfigKey(key.Key)) { if (!_loggedHiddenKeyFilter && value.Metadata.GUID == "ModdedWolf.ModConfigs") { _loggedHiddenKeyFilter = true; ModdedWolfsConfigsPlugin.Log.LogInfo((object)("ConfigDiscovery: hiding internal key '" + key.Key + "' from UI (still stored in cfg).")); } continue; } ConfigEntryBase val = config[key]; if (!(((val != null) ? val.Definition : null) == (ConfigDefinition)null) && IsBrowsable(val)) { string text2 = key.Section ?? string.Empty; if (!dictionary.TryGetValue(text2, out var value2)) { value2 = (dictionary[text2] = new DiscoveredSection { Name = text2 }); } value2.Entries.Add(val); } } if (dictionary.Count == 0) { continue; } DiscoveredPlugin discoveredPlugin = new DiscoveredPlugin { Guid = (value.Metadata.GUID ?? item.Key ?? string.Empty), Name = (value.Metadata.Name ?? value.Metadata.GUID ?? item.Key ?? "Unknown"), Version = (value.Metadata.Version?.ToString() ?? ""), Plugin = instance }; foreach (DiscoveredSection item2 in dictionary.Values.OrderByDescending(SectionHasBinding).ThenByDescending((DiscoveredSection s) => string.Equals(s.Name, "General", StringComparison.OrdinalIgnoreCase)).ThenBy<DiscoveredSection, string>((DiscoveredSection s) => s.Name ?? string.Empty, StringComparer.OrdinalIgnoreCase)) { item2.Entries = item2.Entries.OrderByDescending(ClientLocalBindings.IsBinding).ThenByDescending(GetOrder).ThenBy<ConfigEntryBase, string>(delegate(ConfigEntryBase e) { ConfigDefinition definition = e.Definition; return ((definition != null) ? definition.Key : null) ?? string.Empty; }, StringComparer.OrdinalIgnoreCase) .ToList(); discoveredPlugin.Sections.Add(item2); } list.Add(discoveredPlugin); } catch (Exception ex2) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)("ConfigDiscovery: skipped plugin '" + text + "': " + ex2.Message)); } } return list; } private static bool IsBrowsable(ConfigEntryBase entry) { if (((entry != null) ? entry.Definition : null) == (ConfigDefinition)null) { return false; } if (IsHiddenConfigKey(entry.Definition.Key)) { return false; } ConfigDescription description = entry.Description; object[] array = ((description != null) ? description.Tags : null); if (array == null) { return true; } foreach (object obj in array) { if (obj == null) { continue; } if (obj is ConfigurationManagerAttributes { Browsable: var browsable } configurationManagerAttributes) { if (browsable == false) { return false; } if (configurationManagerAttributes.IsAdvanced == true && !ModdedWolfsConfigsPlugin.ShowAdvancedSettings.Value) { return false; } continue; } PropertyInfo property = obj.GetType().GetProperty("Browsable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.PropertyType == typeof(bool?) && (bool?)property.GetValue(obj, null) == false) { return false; } PropertyInfo property2 = obj.GetType().GetProperty("IsAdvanced", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property2 != null && property2.PropertyType == typeof(bool?) && (bool?)property2.GetValue(obj, null) == true && !ModdedWolfsConfigsPlugin.ShowAdvancedSettings.Value) { return false; } } return true; } private static bool SectionHasBinding(DiscoveredSection section) { if (section?.Entries == null) { return false; } for (int i = 0; i < section.Entries.Count; i++) { if (ClientLocalBindings.IsBinding(section.Entries[i])) { return true; } } return false; } private static int GetOrder(ConfigEntryBase entry) { object obj; if (entry == null) { obj = null; } else { ConfigDescription description = entry.Description; obj = ((description != null) ? description.Tags : null); } object[] array = (object[])obj; if (array == null) { return 0; } foreach (object obj2 in array) { if (obj2 is ConfigurationManagerAttributes configurationManagerAttributes && configurationManagerAttributes.Order.HasValue) { return configurationManagerAttributes.Order.Value; } PropertyInfo propertyInfo = obj2?.GetType().GetProperty("Order", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (propertyInfo != null && propertyInfo.PropertyType == typeof(int?)) { int? num = (int?)propertyInfo.GetValue(obj2, null); if (num.HasValue) { return num.Value; } } } return 0; } internal static string GetDisplayName(ConfigEntryBase entry) { object obj; if (entry == null) { obj = null; } else { ConfigDescription description = entry.Description; obj = ((description != null) ? description.Tags : null); } object[] array = (object[])obj; if (array != null) { for (int i = 0; i < array.Length; i++) { if (array[i] is ConfigurationManagerAttributes configurationManagerAttributes && !string.IsNullOrEmpty(configurationManagerAttributes.DispName)) { return configurationManagerAttributes.DispName; } PropertyInfo propertyInfo = array[i]?.GetType().GetProperty("DispName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (propertyInfo != null && propertyInfo.PropertyType == typeof(string)) { string text = propertyInfo.GetValue(array[i], null) as string; if (!string.IsNullOrEmpty(text)) { return text; } } } } object obj2; if (entry == null) { obj2 = null; } else { ConfigDefinition definition = entry.Definition; obj2 = ((definition != null) ? definition.Key : null); } if (obj2 == null) { obj2 = string.Empty; } return (string)obj2; } } internal static class PauseMenuButton { [CompilerGenerated] private static class <>O { public static UnityAction <0>__Open; } internal static void Refresh() { try { bool flag = ModdedWolfsConfigsPlugin.ShowMainMenuButton == null || ModdedWolfsConfigsPlugin.ShowMainMenuButton.Value; bool flag2 = ModdedWolfsConfigsPlugin.ShowPauseMenuButton == null || ModdedWolfsConfigsPlugin.ShowPauseMenuButton.Value; if ((Object)(object)FejdStartup.instance != (Object)null) { Transform val = (((Object)(object)FejdStartup.instance.m_menuList != (Object)null) ? FejdStartup.instance.m_menuList.transform : null); SetupFromHierarchy(FindMenuEntries(val), flag); if ((Object)(object)val != (Object)null) { FejdStartup.instance.m_menuButtons = ((Component)val).GetComponentsInChildren<Button>(false); } if (!flag) { HideNamedUnder(((Component)FejdStartup.instance).transform); } } if ((Object)(object)Menu.instance != (Object)null) { SetupPauseMenu(flag2); if (!flag2) { HideNamedUnder(((Component)Menu.instance).transform); } } } catch (Exception ex) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)("Failed to refresh menu button: " + ex.Message)); } } internal static bool IsModConfigsControlActive() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)EventSystem.current == (Object)null) { return false; } if (IsNamedModButton(EventSystem.current.currentSelectedGameObject)) { return true; } if (Input.GetMouseButton(0) || Input.GetMouseButtonUp(0)) { PointerEventData val = new PointerEventData(EventSystem.current) { position = Vector2.op_Implicit(Input.mousePosition) }; List<RaycastResult> list = new List<RaycastResult>(); EventSystem.current.RaycastAll(val, list); for (int i = 0; i < list.Count; i++) { RaycastResult val2 = list[i]; if (IsNamedModButton(((RaycastResult)(ref val2)).gameObject)) { return true; } } } return false; } private static bool IsNamedModButton(GameObject go) { if ((Object)(object)go == (Object)null) { return false; } Transform val = go.transform; while ((Object)(object)val != (Object)null) { if (((Object)val).name == "ModdedWolfsConfigs") { return true; } val = val.parent; } return false; } private static void SetupPauseMenu(bool show) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) Menu instance = Menu.instance; if ((Object)(object)instance == (Object)null) { return; } Button val = instance.m_settingsButton; Transform val2 = null; if ((Object)(object)val != (Object)null) { val2 = ((Component)val).transform.parent; } if ((Object)(object)val2 == (Object)null && (Object)(object)instance.menuEntriesParent != (Object)null) { val2 = (Transform)(object)instance.menuEntriesParent; } if ((Object)(object)val2 == (Object)null) { val2 = FindMenuEntries(instance.m_menuDialog); } if ((Object)(object)val == (Object)null && (Object)(object)val2 != (Object)null) { val = FindSettingsButtonUnder(val2); } if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null)) { Button val3 = EnsureModButton(val2, val); ApplyLabel(((Component)val3).gameObject); RewireClick(val3); ((Component)val3).gameObject.SetActive(show); object obj; if (!((Object)(object)instance.m_logoutButton != (Object)null)) { Navigation navigation = ((Selectable)val).navigation; Selectable selectOnDown = ((Navigation)(ref navigation)).selectOnDown; obj = ((selectOnDown is Button) ? selectOnDown : null); } else { obj = instance.m_logoutButton; } Button nextButton = (Button)obj; WireNavigation(val, val3, nextButton, show); } } private static void SetupFromHierarchy(Transform menuEntries, bool show) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)menuEntries == (Object)null) { return; } Button val = FindSettingsButtonUnder(menuEntries); if (!((Object)(object)val == (Object)null)) { Button val2 = EnsureModButton(menuEntries, val); ApplyLabel(((Component)val2).gameObject); RewireClick(val2); ((Component)val2).gameObject.SetActive(show); Navigation navigation = ((Selectable)val).navigation; Selectable selectOnDown = ((Navigation)(ref navigation)).selectOnDown; Button val3 = (Button)(object)((selectOnDown is Button) ? selectOnDown : null); if ((Object)(object)val3 != (Object)null && ((Object)val3).name == "ModdedWolfsConfigs") { navigation = ((Selectable)val3).navigation; Selectable selectOnDown2 = ((Navigation)(ref navigation)).selectOnDown; val3 = (Button)(object)((selectOnDown2 is Button) ? selectOnDown2 : null); } WireNavigation(val, val2, val3, show); } } private static Button EnsureModButton(Transform parent, Button settingsButton) { Transform val = parent.Find("ModdedWolfsConfigs"); GameObject val2 = (((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null); if ((Object)(object)val2 == (Object)null) { val2 = Object.Instantiate<GameObject>(((Component)settingsButton).gameObject, parent); ((Object)val2).name = "ModdedWolfsConfigs"; val2.transform.SetSiblingIndex(((Component)settingsButton).transform.GetSiblingIndex() + 1); } Button component = val2.GetComponent<Button>(); if ((Object)(object)component == (Object)null) { throw new InvalidOperationException("Cloned Mod Configs control is missing a Button."); } return component; } private static void RewireClick(Button button) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown if ((Object)(object)button == (Object)null) { return; } button.onClick = new ButtonClickedEvent(); ButtonClickedEvent onClick = button.onClick; object obj = <>O.<0>__Open; if (obj == null) { UnityAction val = ConfigPanelOpener.Open; <>O.<0>__Open = val; obj = (object)val; } ((UnityEvent)onClick).AddListener((UnityAction)obj); EventTrigger[] componentsInChildren = ((Component)button).GetComponentsInChildren<EventTrigger>(true); foreach (EventTrigger val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && val2.triggers != null) { val2.triggers.RemoveAll((Entry entry) => entry != null && ((int)entry.eventID == 4 || (int)entry.eventID == 15)); } } } private static void ApplyLabel(GameObject menuButton) { TMP_Text componentInChildren = menuButton.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = "Mod Configs"; } Text componentInChildren2 = menuButton.GetComponentInChildren<Text>(true); if ((Object)(object)componentInChildren2 != (Object)null) { componentInChildren2.text = "Mod Configs"; } } private static Button FindSettingsButtonUnder(Transform menuEntries) { Transform val = menuEntries.Find("Settings"); if ((Object)(object)val == (Object)null) { for (int i = 0; i < menuEntries.childCount; i++) { Transform child = menuEntries.GetChild(i); if ((Object)(object)child != (Object)null && ((Object)child).name.IndexOf("Settings", StringComparison.OrdinalIgnoreCase) >= 0 && ((Object)child).name != "ModdedWolfsConfigs") { val = child; break; } } } if (!((Object)(object)val != (Object)null)) { return null; } return ((Component)val).GetComponent<Button>(); } private static Transform FindMenuEntries(Transform root) { if ((Object)(object)root == (Object)null) { return null; } Transform val = root.Find("MenuEntries"); if ((Object)(object)val != (Object)null) { return val; } Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && ((Object)componentsInChildren[i]).name == "MenuEntries") { return componentsInChildren[i]; } } return null; } private static void HideNamedUnder(Transform root) { if ((Object)(object)root == (Object)null) { return; } Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && ((Object)componentsInChildren[i]).name == "ModdedWolfsConfigs") { ((Component)componentsInChildren[i]).gameObject.SetActive(false); } } } private static void WireNavigation(Button settingsButton, Button modButton, Button nextButton, bool show) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)settingsButton == (Object)null || (Object)(object)modButton == (Object)null) { return; } if ((Object)(object)nextButton != (Object)null && ((Object)nextButton).name == "ModdedWolfsConfigs") { Navigation navigation = ((Selectable)nextButton).navigation; Selectable selectOnDown = ((Navigation)(ref navigation)).selectOnDown; nextButton = (Button)(object)((selectOnDown is Button) ? selectOnDown : null); } Navigation navigation2 = ((Selectable)settingsButton).navigation; Navigation navigation3 = ((Selectable)modButton).navigation; if (show) { ((Navigation)(ref navigation2)).selectOnDown = (Selectable)(object)modButton; ((Navigation)(ref navigation3)).selectOnUp = (Selectable)(object)settingsButton; ((Navigation)(ref navigation3)).selectOnDown = (Selectable)(object)nextButton; ((Navigation)(ref navigation3)).mode = (Mode)4; ((Selectable)modButton).navigation = navigation3; if ((Object)(object)nextButton != (Object)null) { Navigation navigation4 = ((Selectable)nextButton).navigation; ((Navigation)(ref navigation4)).selectOnUp = (Selectable)(object)modButton; ((Selectable)nextButton).navigation = navigation4; } } else if ((Object)(object)nextButton != (Object)null) { ((Navigation)(ref navigation2)).selectOnDown = (Selectable)(object)nextButton; Navigation navigation5 = ((Selectable)nextButton).navigation; ((Navigation)(ref navigation5)).selectOnUp = (Selectable)(object)settingsButton; ((Selectable)nextButton).navigation = navigation5; } ((Selectable)settingsButton).navigation = navigation2; } } [BepInPlugin("ModdedWolf.ModConfigs", "Mod Configs", "1.0.6")] public class ModdedWolfsConfigsPlugin : BaseUnityPlugin { public const string GUID = "ModdedWolf.ModConfigs"; private const string LegacyGuid = "ModdedWolf.ModdedWolfsConfigs"; public const string NAME = "Mod Configs"; public const string VERSION = "1.0.6"; internal const string MenuButtonName = "ModdedWolfsConfigs"; internal const string MenuButtonCaption = "Mod Configs"; internal const string PanelTitle = "Mod Configs"; internal static ConfigEntry<bool> ShowMainMenuButton; internal static ConfigEntry<bool> ShowPauseMenuButton; internal static ConfigEntry<bool> ShowAdvancedSettings; internal static ConfigEntry<bool> HideSelfFromList; internal static ConfigEntry<bool> RememberLastMod; internal const string LastSelectedModGuidKey = "LastSelectedModGuid"; internal static ConfigEntry<string> LastSelectedModGuid; private Harmony _harmony; internal static ModdedWolfsConfigsPlugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; TryMigrateLegacyConfigFile(); ShowMainMenuButton = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowMainMenuButton", false, "Show Mod Configs on the main menu (title screen)."); ShowPauseMenuButton = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowPauseMenuButton", true, "Show Mod Configs on the in-game pause menu."); TryMigrateLegacyShowMenuButton(); ShowAdvancedSettings = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowAdvancedSettings", false, "Show settings marked as advanced (ConfigurationManagerAttributes.IsAdvanced)."); HideSelfFromList = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "HideSelfFromList", false, "Hide this mod's own settings from the in-game config panel."); RememberLastMod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RememberLastMod", true, "When enabled, reopen Mod Configs on the last mod you had selected."); LastSelectedModGuid = ((BaseUnityPlugin)this).Config.Bind<string>("General", "LastSelectedModGuid", "", new ConfigDescription("GUID of the last mod opened in Mod Configs (remembered between sessions).", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Browsable = false } })); ShowMainMenuButton.SettingChanged += delegate { PauseMenuButton.Refresh(); }; ShowPauseMenuButton.SettingChanged += delegate { PauseMenuButton.Refresh(); }; _harmony = new Harmony("ModdedWolf.ModConfigs"); _harmony.PatchAll(); Log.LogInfo((object)"Mod Configs v1.0.6 loaded (client configs)."); } private void TryMigrateLegacyConfigFile() { try { string configPath = Paths.ConfigPath; string text = Path.Combine(configPath, "ModdedWolf.ModConfigs.cfg"); string text2 = Path.Combine(configPath, "ModdedWolf.ModdedWolfsConfigs.cfg"); if (File.Exists(text2) && !File.Exists(text)) { File.Copy(text2, text); Log.LogInfo((object)"Migrated config from ModdedWolf.ModdedWolfsConfigs.cfg to ModdedWolf.ModConfigs.cfg"); } } catch (Exception ex) { Log.LogWarning((object)("Legacy config migration failed: " + ex.Message)); } } private void TryMigrateLegacyShowMenuButton() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown try { ConfigDefinition val = new ConfigDefinition("General", "ShowMenuButton"); if (((BaseUnityPlugin)this).Config.ContainsKey(val)) { if (!((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowMenuButton", true, "Deprecated. Use ShowMainMenuButton / ShowPauseMenuButton.").Value) { ShowMainMenuButton.Value = false; ShowPauseMenuButton.Value = true; } ((BaseUnityPlugin)this).Config.Remove(val); ((BaseUnityPlugin)this).Config.Save(); } } catch { } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } [HarmonyPatch(typeof(Menu), "Start")] internal static class Menu_Start_Patch { private static void Postfix() { PauseMenuButton.Refresh(); } } [HarmonyPatch(typeof(Menu), "UpdateNavigation")] internal static class Menu_UpdateNavigation_Patch { private static void Postfix() { PauseMenuButton.Refresh(); } } [HarmonyPatch(typeof(Menu), "OnSettings")] internal static class Menu_OnSettings_Patch { private static bool Prefix() { if (!PauseMenuButton.IsModConfigsControlActive()) { return true; } ConfigPanelOpener.Open(); return false; } } [HarmonyPatch(typeof(FejdStartup), "Start")] internal static class FejdStartup_Start_Patch { private static void Postfix() { PauseMenuButton.Refresh(); } } [HarmonyPatch(typeof(FejdStartup), "SetupGui")] internal static class FejdStartup_SetupGui_Patch { private static void Postfix() { PauseMenuButton.Refresh(); } } [HarmonyPatch(typeof(Settings), "OnDestroy")] internal static class Settings_OnDestroy_Patch { private static void Postfix(Settings __instance) { ConfigPanelOpener.ForgetInstance(__instance); ModConfigPanel.ForgetInitialized(__instance); PauseMenuButton.Refresh(); } } internal static class SettingsConversionPatches { [HarmonyPatch(typeof(Settings), "Awake")] internal static class SettingsAwakePatch { private static void Prefix(Settings __instance) { if (ConfigPanelOpener.IsOpening) { ConfigPanelOpener.MarkInstance(__instance); } } private static void Postfix(Settings __instance) { if (ShouldConvert(__instance)) { ModConfigPanel.ConvertSettingsInstance(__instance); ModConfigPanel.EnforceConvertedLayout(__instance); } } } [HarmonyPatch(typeof(Settings), "InitializeTabs")] internal static class SettingsInitializeTabsPatch { private static bool Prefix(Settings __instance) { if (!ShouldConvert(__instance)) { return true; } ConfigPanelOpener.MarkInstance(__instance); ModConfigPanel.ConvertSettingsInstance(__instance); ModConfigPanel.EnforceConvertedLayout(__instance); return false; } } [HarmonyPatch(typeof(Settings), "OnBack")] internal static class SettingsOnBackPatch { private static bool Prefix(Settings __instance) { if (ConfigPanelOpener.IsOurInstance(__instance) && KeybindCapture.TryCancelListen()) { return false; } return HandleCloseIfBroken(__instance); } } [HarmonyPatch(typeof(Settings), "OnOk")] internal static class SettingsOnOkPatch { private static bool Prefix(Settings __instance) { return HandleCloseIfBroken(__instance); } } private static bool ShouldConvert(Settings settings) { if (!ConfigPanelOpener.IsOpening) { return ConfigPanelOpener.IsOurInstance(settings); } return true; } private static bool HandleCloseIfBroken(Settings settings) { if (!ConfigPanelOpener.IsOurInstance(settings)) { return true; } List<ISettingsTab> settingsTabs = settings.SettingsTabs; if (settingsTabs != null && settingsTabs.Count > 0) { return true; } ForceClose(settings); return false; } private static void ForceClose(Settings settings) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)settings == (Object)null) { return; } try { if ((Object)(object)Menu.instance != (Object)null && (Object)(object)Menu.instance.m_settingsInstance == (Object)(object)((Component)settings).gameObject) { Menu.instance.m_settingsInstance = null; Menu.instance.m_closeMenuState = (CloseMenuState)2; } Object.Destroy((Object)(object)((Component)settings).gameObject); } catch (Exception ex) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)("Failed to force-close Mod Configs: " + ex.Message)); } } } internal static class ConfigPanelOpener { private static readonly HashSet<int> PendingInstanceIds = new HashSet<int>(); internal static bool IsOpening { get; private set; } internal static void MarkInstance(Settings settings) { if (!((Object)(object)settings == (Object)null)) { PendingInstanceIds.Add(((Object)settings).GetInstanceID()); } } internal static bool IsOurInstance(Settings settings) { if ((Object)(object)settings == (Object)null) { return false; } return PendingInstanceIds.Contains(((Object)settings).GetInstanceID()); } internal static void ForgetInstance(Settings settings) { if (!((Object)(object)settings == (Object)null)) { PendingInstanceIds.Remove(((Object)settings).GetInstanceID()); } } internal static void Open() { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)Settings.instance != (Object)null) { return; } GameObject val = FindSettingsPrefab(); if ((Object)(object)val == (Object)null) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)"Could not find Settings prefab (Menu / FejdStartup). Cannot open config panel."); return; } Transform val2 = null; if ((Object)(object)Menu.instance != (Object)null) { val2 = ((Component)Menu.instance).transform; } else if ((Object)(object)FejdStartup.instance != (Object)null) { val2 = ((Component)FejdStartup.instance).transform; } IsOpening = true; GameObject val3 = Object.Instantiate<GameObject>(val, val2); IsOpening = false; Settings val4 = (((Object)(object)val3 != (Object)null) ? val3.GetComponent<Settings>() : null); if ((Object)(object)val4 != (Object)null) { MarkInstance(val4); ModConfigPanel.ConvertSettingsInstance(val4); ModConfigPanel.EnforceConvertedLayout(val4); } if ((Object)(object)Menu.instance != (Object)null) { Menu.instance.m_settingsInstance = val3; Menu.instance.m_closeMenuState = (CloseMenuState)0; } ModdedWolfsConfigsPlugin.Log.LogInfo((object)"Opened ModdedWolf's Configs panel."); } catch (Exception arg) { IsOpening = false; ModdedWolfsConfigsPlugin.Log.LogWarning((object)$"Failed to open config panel: {arg}"); } } private static GameObject FindSettingsPrefab() { if ((Object)(object)Menu.instance != (Object)null && (Object)(object)Menu.instance.m_settingsPrefab != (Object)null) { return Menu.instance.m_settingsPrefab; } if ((Object)(object)FejdStartup.instance != (Object)null && (Object)(object)FejdStartup.instance.m_settingsPrefab != (Object)null) { return FejdStartup.instance.m_settingsPrefab; } return null; } } internal sealed class KeybindCapture : MonoBehaviour { private ConfigEntryBase _entry; private TMP_Text _valueText; private Button _button; private bool _listening; private int _armFrame = -1; private Coroutine _savedFlash; private static KeybindCapture _active; private static readonly KeyCode[] ModifierKeys; internal static bool IsListening { get { if ((Object)(object)_active != (Object)null) { return _active._listening; } return false; } } internal static bool TryCancelListen() { if ((Object)(object)_active == (Object)null || !_active._listening) { return false; } _active.CancelListen(); return true; } internal void Bind(ConfigEntryBase entry, Button button, TMP_Text valueText) { _entry = entry; _button = button; _valueText = valueText; RefreshLabel(); WireButton(_button); } private void WireButton(Button button) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown if (!((Object)(object)button == (Object)null)) { ((UnityEventBase)button.onClick).RemoveAllListeners(); ((UnityEvent)button.onClick).AddListener(new UnityAction(BeginListen)); } } private void OnDisable() { if (_savedFlash != null) { ((MonoBehaviour)this).StopCoroutine(_savedFlash); _savedFlash = null; } if (_active == this) { _listening = false; _active = null; } } private void BeginListen() { if (_entry != null) { if ((Object)(object)_active != (Object)null && _active != this && _active._listening) { _active.CancelListen(); } if (_savedFlash != null) { ((MonoBehaviour)this).StopCoroutine(_savedFlash); _savedFlash = null; } _listening = true; _armFrame = Time.frameCount; _active = this; if ((Object)(object)_valueText != (Object)null) { _valueText.text = "Press key… (Esc cancel)"; } } } private void CancelListen() { _listening = false; if (_active == this) { _active = null; } RefreshLabel(); } private void Update() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Invalid comparison between Unknown and I4 //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Invalid comparison between Unknown and I4 //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Invalid comparison between Unknown and I4 //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (!CanCapture()) { return; } if (Input.GetKeyDown((KeyCode)27)) { CancelListen(); return; } for (int i = 2; i <= 6; i++) { if (Input.GetMouseButtonDown(i)) { CommitKey((KeyCode)(323 + i)); return; } } foreach (KeyCode value in Enum.GetValues(typeof(KeyCode))) { if ((int)value != 0 && (int)value != 27 && !IsModifier(value) && ((int)value < 323 || (int)value > 329) && (int)value < 330 && Input.GetKeyDown(value)) { CommitKey(value); break; } } } private void OnGUI() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Invalid comparison between Unknown and I4 if (!CanCapture()) { return; } Event current = Event.current; if (current == null) { return; } if ((int)current.type == 4 && (int)current.keyCode != 0) { if ((int)current.keyCode == 27) { CancelListen(); current.Use(); } else if (!IsModifier(current.keyCode) && ((int)current.keyCode < 323 || (int)current.keyCode > 329)) { CommitKey(current.keyCode); current.Use(); } } else if ((int)current.type == 0 && current.button >= 2 && current.button <= 6) { CommitKey((KeyCode)(323 + current.button)); current.Use(); } } private bool CanCapture() { if (_listening && _entry != null) { return Time.frameCount > _armFrame; } return false; } private void CommitKey(KeyCode main) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (_listening) { _listening = false; if (_active == this) { _active = null; } ApplyKey(main); } } private unsafe void ApplyKey(KeyCode main) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) Type settingType = _entry.SettingType; try { if (settingType == typeof(KeyboardShortcut)) { List<KeyCode> list = new List<KeyCode>(); for (int i = 0; i < ModifierKeys.Length; i++) { if (Input.GetKey(ModifierKeys[i])) { list.Add(ModifierKeys[i]); } } _entry.BoxedValue = (object)new KeyboardShortcut(main, list.ToArray()); } else if (settingType == typeof(KeyCode)) { _entry.BoxedValue = main; } else { _entry.SetSerializedValue(((object)(*(KeyCode*)(&main))/*cast due to .constrained prefix*/).ToString()); } ConfigApply.PersistAfterLocalChange(_entry); ShowSavedFlash(FormatCurrentBind()); } catch (Exception ex) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)("Failed to set keybind: " + ex.Message)); RefreshLabel(); } } private void ShowSavedFlash(string bindLabel) { if ((Object)(object)_valueText == (Object)null) { RefreshLabel(); return; } if (_savedFlash != null) { ((MonoBehaviour)this).StopCoroutine(_savedFlash); } _savedFlash = ((MonoBehaviour)this).StartCoroutine(SavedFlashRoutine(bindLabel)); } private IEnumerator SavedFlashRoutine(string bindLabel) { if ((Object)(object)_valueText != (Object)null) { _valueText.text = "Saved: " + bindLabel; } yield return (object)new WaitForSecondsRealtime(1f); _savedFlash = null; RefreshLabel(); } private void RefreshLabel() { if (!((Object)(object)_valueText == (Object)null) && _entry != null) { _valueText.text = FormatCurrentBind(); } } private unsafe string FormatCurrentBind() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (_entry == null) { return "None"; } if (_entry.BoxedValue is KeyboardShortcut shortcut) { return FormatShortcut(shortcut); } if (_entry.BoxedValue is KeyCode val) { if ((int)val != 0) { return ((object)(*(KeyCode*)(&val))/*cast due to .constrained prefix*/).ToString(); } return "None"; } string text = _entry.GetSerializedValue(); if (string.IsNullOrEmpty(text)) { text = _entry.BoxedValue?.ToString() ?? "None"; } return text; } private static string FormatShortcut(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0) { return "None"; } StringBuilder stringBuilder = new StringBuilder(); IEnumerable<KeyCode> modifiers = ((KeyboardShortcut)(ref shortcut)).Modifiers; if (modifiers != null) { foreach (KeyCode item in modifiers) { if (stringBuilder.Length > 0) { stringBuilder.Append('+'); } stringBuilder.Append(item); } } if (stringBuilder.Length > 0) { stringBuilder.Append('+'); } stringBuilder.Append(((KeyboardShortcut)(ref shortcut)).MainKey); return stringBuilder.ToString(); } private static bool IsModifier(KeyCode key) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between I4 and Unknown for (int i = 0; i < ModifierKeys.Length; i++) { if ((int)ModifierKeys[i] == (int)key) { return true; } } return false; } static KeybindCapture() { KeyCode[] array = new KeyCode[8]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); ModifierKeys = (KeyCode[])(object)array; } } internal static class ModConfigPanel { private const string PageName = "ModdedWolfsConfigsPage"; private static readonly HashSet<int> BodyReadyIds = new HashSet<int>(); internal static void ConvertSettingsInstance(Settings settings) { try { if ((Object)(object)settings == (Object)null) { return; } Transform val = FindConvertedPage(settings); if ((Object)(object)val != (Object)null) { RenameTitle(settings); StripSettingsChrome(settings); DisableTabHandler(settings); HideTabStrip(settings); NeutralizeAccessibilityGuiScale(settings); HideVanillaSettingsPages(settings, ((Component)val).gameObject); EnsureSettingsTabs(settings, ((Component)val).GetComponent<ModConfigTab>()); AttachLayoutLock(settings); EnforceConvertedLayout(settings); RestoreGuiScale(); return; } RenameTitle(settings); StripSettingsChrome(settings); DisableTabHandler(settings); HideTabStrip(settings); NeutralizeAccessibilityGuiScale(settings); HideVanillaSettingsPages(settings, null); RectTransform val2 = CreateBodyPage(settings); if ((Object)(object)val2 == (Object)null) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)"Could not find a parent for the Mod Configs body page."); RestoreGuiScale(); return; } ModConfigTab modConfigTab = ((Component)val2).gameObject.AddComponent<ModConfigTab>(); if (!modConfigTab.TryBuild(settings, val2)) { Object.Destroy((Object)(object)((Component)val2).gameObject); ModdedWolfsConfigsPlugin.Log.LogWarning((object)"Failed to build ModdedWolf's Configs body UI."); RestoreGuiScale(); return; } EnsureSettingsTabs(settings, modConfigTab); ActivatePageAndAncestors(((Component)val2).transform, ((Component)settings).transform); WireBodyNavigation(settings, modConfigTab); AttachLayoutLock(settings); EnforceConvertedLayout(settings); RestoreGuiScale(); BodyReadyIds.Add(((Object)settings).GetInstanceID()); ModdedWolfsConfigsPlugin.Log.LogInfo((object)"ModdedWolf's Configs body ready."); } catch (Exception arg) { RestoreGuiScale(); ModdedWolfsConfigsPlugin.Log.LogWarning((object)$"Failed to convert Settings panel: {arg}"); } } private static void NeutralizeAccessibilityGuiScale(Settings settings) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown if ((Object)(object)settings == (Object)null) { return; } AccessibilitySettings[] componentsInChildren = ((Component)settings).GetComponentsInChildren<AccessibilitySettings>(true); foreach (AccessibilitySettings val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { ((Behaviour)val).enabled = false; if ((Object)(object)val.m_guiScaleSlider != (Object)null) { val.m_guiScaleSlider.onValueChanged = new SliderEvent(); } } } } private static void RestoreGuiScale() { try { GuiScaler.SetScale(PlatformPrefs.GetFloat("GuiScale", 1f)); } catch (Exception ex) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)("Failed to restore GUI scale: " + ex.Message)); } } internal static void ForgetInitialized(Settings settings) { if (!((Object)(object)settings == (Object)null)) { BodyReadyIds.Remove(((Object)settings).GetInstanceID()); } } internal static void EnforceConvertedLayout(Settings settings) { if ((Object)(object)settings == (Object)null) { return; } Transform val = FindConvertedPage(settings); if ((Object)(object)val == (Object)null) { return; } try { RenameTitle(settings); StripSettingsChrome(settings); DisableTabHandler(settings); HideTabStrip(settings); HideVanillaSettingsPages(settings, ((Component)val).gameObject); ActivatePageAndAncestors(val, ((Component)settings).transform); } catch (Exception ex) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)("Failed to enforce Mod Configs layout: " + ex.Message)); } } private static void EnsureSettingsTabs(Settings settings, ModConfigTab modTab) { if (!((Object)(object)settings == (Object)null) && !((Object)(object)modTab == (Object)null) && (settings.SettingsTabs == null || settings.SettingsTabs.Count != 1 || (object)settings.SettingsTabs[0] != modTab)) { settings.SettingsTabs = new List<ISettingsTab> { (ISettingsTab)(object)modTab }; } } private static void AttachLayoutLock(Settings settings) { if ((Object)(object)((Component)settings).GetComponent<ModConfigLayoutLock>() == (Object)null) { ((Component)settings).gameObject.AddComponent<ModConfigLayoutLock>(); } } private static void DisableTabHandler(Settings settings) { TabHandler val = (((Object)(object)settings.m_tabHandler != (Object)null) ? settings.m_tabHandler : ((Component)settings).GetComponentInChildren<TabHandler>(true)); if (!((Object)(object)val == (Object)null)) { settings.m_tabHandler = val; ((Behaviour)val).enabled = false; val.m_tabKeyInput = false; val.m_keybaordInput = false; val.m_gamepadInput = false; } } private static void HideTabStrip(Settings settings) { TabHandler val = (((Object)(object)settings.m_tabHandler != (Object)null) ? settings.m_tabHandler : ((Component)settings).GetComponentInChildren<TabHandler>(true)); if ((Object)(object)val == (Object)null) { return; } Transform transform = ((Component)val).transform; if (val.m_tabs == null) { return; } for (int i = 0; i < val.m_tabs.Count; i++) { Tab val2 = val.m_tabs[i]; if (!((Object)(object)val2?.m_button == (Object)null)) { Transform val3 = FindTabRoot(((Component)val2.m_button).transform, transform); if ((Object)(object)val3 == (Object)null) { ((Component)val2.m_button).gameObject.SetActive(false); } else if (!(((Object)val3).name == "ModdedWolfsConfigsPage") && !IsUnderModConfigPage(val3) && (!((Object)(object)settings.m_settingsPanel != (Object)null) || !((Object)(object)((Component)val3).gameObject == (Object)(object)settings.m_settingsPanel)) && (!((Object)(object)settings.m_backButton != (Object)null) || !((Object)(object)((Component)val3).gameObject == (Object)(object)((Component)settings.m_backButton).gameObject)) && (!((Object)(object)settings.m_okButton != (Object)null) || !((Object)(object)((Component)val3).gameObject == (Object)(object)((Component)settings.m_okButton).gameObject))) { ((Component)val3).gameObject.SetActive(false); } } } } private static Transform FindTabRoot(Transform buttonTransform, Transform tabHandlerTransform) { Transform val = buttonTransform; Transform result = buttonTransform; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)tabHandlerTransform) { result = val; if ((Object)(object)val.parent == (Object)(object)tabHandlerTransform) { return val; } val = val.parent; } return result; } private static void HideVanillaSettingsPages(Settings settings, GameObject keepPage) { MonoBehaviour[] componentsInChildren = ((Component)settings).GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !(val is ModConfigTab) && val is ISettingsTab) { ((Behaviour)val).enabled = false; if ((!((Object)(object)keepPage != (Object)null) || !((Object)(object)((Component)val).gameObject == (Object)(object)keepPage)) && (!((Object)(object)settings.m_settingsPanel != (Object)null) || !((Object)(object)((Component)val).gameObject == (Object)(object)settings.m_settingsPanel)) && (!((Object)(object)settings.m_backButton != (Object)null) || !((Object)(object)((Component)val).gameObject == (Object)(object)((Component)settings.m_backButton).gameObject)) && (!((Object)(object)settings.m_okButton != (Object)null) || !((Object)(object)((Component)val).gameObject == (Object)(object)((Component)settings.m_okButton).gameObject)) && (!((Object)(object)keepPage != (Object)null) || !IsAncestorOf(((Component)val).transform, keepPage.transform))) { ((Component)val).gameObject.SetActive(false); } } } } private static bool IsAncestorOf(Transform candidate, Transform descendant) { if ((Object)(object)candidate == (Object)null || (Object)(object)descendant == (Object)null) { return false; } Transform val = descendant; while ((Object)(object)val != (Object)null) { if ((Object)(object)val == (Object)(object)candidate) { return true; } val = val.parent; } return false; } private static RectTransform CreateBodyPage(Settings settings) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) RectTransform val = FindTemplateTabPage(settings); if ((Object)(object)val == (Object)null || (Object)(object)((Transform)val).parent == (Object)null) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)"No vanilla settings tab page template; cannot size Mod Configs body."); return null; } GameObject val2 = new GameObject("ModdedWolfsConfigsPage", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(((Transform)val).parent, false); RectTransform component = val2.GetComponent<RectTransform>(); component.anchorMin = val.anchorMin; component.anchorMax = val.anchorMax; component.pivot = val.pivot; component.anchoredPosition = val.anchoredPosition; component.sizeDelta = val.sizeDelta; component.offsetMin = val.offsetMin; component.offsetMax = val.offsetMax; ((Transform)component).localScale = ((Transform)val).localScale; int num = CopyNativePageChrome(val, component); ModdedWolfsConfigsPlugin.Log.LogInfo((object)$"Mod Configs inner frame: copied {num} chrome piece(s) from '{((Object)val).name}'."); val2.SetActive(true); return component; } private static int CopyNativePageChrome(RectTransform template, RectTransform dest) { if ((Object)(object)template == (Object)null || (Object)(object)dest == (Object)null) { return 0; } int num = 0; Image component = ((Component)template).GetComponent<Image>(); if ((Object)(object)component != (Object)null && (Object)(object)component.sprite != (Object)null) { CopyImageComponent(component, ((Component)dest).gameObject); num++; } num += CopyGraphicEffect<Outline>(((Component)template).gameObject, ((Component)dest).gameObject); num += CopyGraphicEffect<Shadow>(((Component)template).gameObject, ((Component)dest).gameObject); int num2 = 0; for (int i = 0; i < ((Transform)template).childCount; i++) { Transform child = ((Transform)template).GetChild(i); if (LooksLikeChrome(child)) { GameObject obj = Object.Instantiate<GameObject>(((Component)child).gameObject, (Transform)(object)dest, false); ((Object)obj).name = ((Object)child).name; StripInteractiveChrome(obj); obj.SetActive(true); obj.transform.SetAsFirstSibling(); num++; num2++; } } Image component2 = ((Component)dest).GetComponent<Image>(); if ((!((Object)(object)component2 != (Object)null) || !((Object)(object)component2.sprite != (Object)null)) && num2 <= 0) { Image val = FindLargestDecorativeImage((Transform)(object)template); if ((Object)(object)val != (Object)null) { AddStretchedChromeImage(dest, val, "PageChrome"); num++; } } return num; } private static bool LooksLikeChrome(Transform t) { if ((Object)(object)t == (Object)null) { return false; } if ((Object)(object)((Component)t).GetComponentInChildren<Selectable>(true) != (Object)null) { return false; } if ((Object)(object)((Component)t).GetComponentInChildren<TMP_Text>(true) != (Object)null) { return false; } if (NameLooksLikeFrame(((Object)t).name ?? string.Empty)) { return true; } if (!((Object)(object)((Component)t).GetComponent<Image>() != (Object)null) && !((Object)(object)((Component)t).GetComponent<RawImage>() != (Object)null)) { return ((Component)t).GetComponentsInChildren<Image>(true).Length != 0; } return true; } private static bool NameLooksLikeFrame(string n) { if (n.IndexOf("border", StringComparison.OrdinalIgnoreCase) < 0 && n.IndexOf("frame", StringComparison.OrdinalIgnoreCase) < 0 && n.IndexOf("bkg", StringComparison.OrdinalIgnoreCase) < 0 && n.IndexOf("background", StringComparison.OrdinalIgnoreCase) < 0 && n.IndexOf("deco", StringComparison.OrdinalIgnoreCase) < 0 && n.IndexOf("ornament", StringComparison.OrdinalIgnoreCase) < 0 && n.IndexOf("edge", StringComparison.OrdinalIgnoreCase) < 0 && n.IndexOf("well", StringComparison.OrdinalIgnoreCase) < 0 && n.IndexOf("chrome", StringComparison.OrdinalIgnoreCase) < 0) { return n.IndexOf("panel", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static Image FindLargestDecorativeImage(Transform root) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Invalid comparison between Unknown and I4 //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Invalid comparison between Unknown and I4 Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true); Image result = null; float num = 0f; foreach (Image val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)val.sprite == (Object)null || (Object)(object)((Component)val).GetComponent<Selectable>() != (Object)null) { continue; } Selectable componentInParent = ((Component)val).GetComponentInParent<Selectable>(); if ((Object)(object)componentInParent != (Object)null && (Object)(object)((Component)componentInParent).transform != (Object)(object)root) { continue; } Rect rect = ((Graphic)val).rectTransform.rect; float num2 = Mathf.Abs(((Rect)(ref rect)).width * ((Rect)(ref rect)).height); if (!(num2 < 64f)) { float num3 = num2; if ((int)val.type == 1 || (int)val.type == 2) { num3 *= 3f; } if (num3 > num) { num = num3; result = val; } } } return result; } private static void AddStretchedChromeImage(RectTransform dest, Image source, string name) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent((Transform)(object)dest, false); val.transform.SetAsFirstSibling(); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; CopyImageComponent(source, val); } private static void CopyImageComponent(Image source, GameObject dest) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)source == (Object)null) && !((Object)(object)dest == (Object)null)) { Image obj = dest.GetComponent<Image>() ?? dest.AddComponent<Image>(); obj.sprite = source.sprite; obj.overrideSprite = source.overrideSprite; obj.type = source.type; ((Graphic)obj).color = ((Graphic)source).color; obj.fillCenter = source.fillCenter; obj.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier; ((Graphic)obj).material = ((Graphic)source).material; ((Graphic)obj).raycastTarget = false; ((MaskableGraphic)obj).maskable = ((MaskableGraphic)source).maskable; obj.preserveAspect = source.preserveAspect; obj.fillMethod = source.fillMethod; obj.fillAmount = source.fillAmount; } } private static int CopyGraphicEffect<T>(GameObject source, GameObject dest) where T : Shadow { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) T component = source.GetComponent<T>(); if ((Object)(object)component == (Object)null) { return 0; } T obj = dest.GetComponent<T>() ?? dest.AddComponent<T>(); ((Shadow)obj).effectColor = ((Shadow)component).effectColor; ((Shadow)obj).effectDistance = ((Shadow)component).effectDistance; ((Shadow)obj).useGraphicAlpha = ((Shadow)component).useGraphicAlpha; return 1; } private static void StripInteractiveChrome(GameObject go) { if ((Object)(object)go == (Object)null) { return; } Selectable[] componentsInChildren = go.GetComponentsInChildren<Selectable>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { ((Behaviour)componentsInChildren[i]).enabled = false; } } ScrollRect[] componentsInChildren2 = go.GetComponentsInChildren<ScrollRect>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { if ((Object)(object)componentsInChildren2[j] != (Object)null) { ((Behaviour)componentsInChildren2[j]).enabled = false; } } TMP_Text[] componentsInChildren3 = go.GetComponentsInChildren<TMP_Text>(true); for (int k = 0; k < componentsInChildren3.Length; k++) { if ((Object)(object)componentsInChildren3[k] != (Object)null) { ((Component)componentsInChildren3[k]).gameObject.SetActive(false); } } } private static RectTransform FindTemplateTabPage(Settings settings) { TabHandler val = (((Object)(object)settings.m_tabHandler != (Object)null) ? settings.m_tabHandler : ((Component)settings).GetComponentInChildren<TabHandler>(true)); if (val?.m_tabs == null) { return null; } for (int i = 0; i < val.m_tabs.Count; i++) { Tab val2 = val.m_tabs[i]; if ((Object)(object)val2?.m_page != (Object)null) { return val2.m_page; } } return null; } private static void ActivatePageAndAncestors(Transform page, Transform stopAt) { if ((Object)(object)page == (Object)null) { return; } Transform val = page; while ((Object)(object)val != (Object)null) { if (!((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(true); } if (!((Object)(object)stopAt != (Object)null) || !((Object)(object)val == (Object)(object)stopAt)) { val = val.parent; continue; } break; } } private static void WireBodyNavigation(Settings settings, ModConfigTab modTab) { if ((Object)(object)settings == (Object)null || (Object)(object)modTab == (Object)null) { return; } try { modTab.Initialize(); modTab.OnTabOpen(settings.m_backButton, settings.m_okButton); } catch (Exception ex) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)("Failed to wire Mod Configs navigation: " + ex.Message)); } } private static Transform FindConvertedPage(Settings settings) { Transform[] componentsInChildren = ((Component)settings).GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && ((Object)componentsInChildren[i]).name == "ModdedWolfsConfigsPage") { return componentsInChildren[i]; } } return null; } internal static void StripSettingsChrome(Settings settings) { //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Invalid comparison between Unknown and I4 //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Invalid comparison between Unknown and I4 if ((Object)(object)settings == (Object)null) { return; } if (settings.m_tabKeyHints != null) { for (int i = 0; i < settings.m_tabKeyHints.Length; i++) { if ((Object)(object)settings.m_tabKeyHints[i] != (Object)null) { settings.m_tabKeyHints[i].SetActive(false); } } } TabHandler val = (((Object)(object)settings.m_tabHandler != (Object)null) ? settings.m_tabHandler : ((Component)settings).GetComponentInChildren<TabHandler>(true)); if ((Object)(object)val != (Object)null) { val.m_tabKeyInput = false; val.m_keybaordInput = false; val.m_gamepadInput = false; } TMP_Text[] componentsInChildren = ((Component)settings).GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || IsUnderModConfigPage(val2.transform)) { continue; } string text = ((val2.text != null) ? val2.text.Trim() : string.Empty); if (text.Length == 1) { char c = char.ToUpperInvariant(text[0]); if (c == 'Q' || c == 'E') { ((Component)val2).gameObject.SetActive(false); } } } UIGamePad[] componentsInChildren2 = ((Component)settings).GetComponentsInChildren<UIGamePad>(true); foreach (UIGamePad val3 in componentsInChildren2) { if (!((Object)(object)val3 == (Object)null) && (val3.m_zinputKey == "TabLeft" || val3.m_zinputKey == "TabRight" || (int)val3.m_keyCode == 113 || (int)val3.m_keyCode == 101 || ((Object)(object)val3.m_hint != (Object)null && IsLikelyTabHintObject(val3.m_hint)))) { if ((Object)(object)val3.m_hint != (Object)null) { val3.m_hint.SetActive(false); } ((Behaviour)val3).enabled = false; } } } private static bool IsUnderModConfigPage(Transform t) { while ((Object)(object)t != (Object)null) { if (((Object)t).name == "ModdedWolfsConfigsPage") { return true; } t = t.parent; } return false; } private static bool IsLikelyTabHintObject(GameObject go) { if ((Object)(object)go == (Object)null) { return false; } string name = ((Object)go).name; if (name.IndexOf("hint", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("Tab", StringComparison.OrdinalIgnoreCase) < 0) { return name.IndexOf("key", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static void RenameTitle(Settings settings) { Transform[] array = (Transform[])(object)new Transform[5] { ((Component)settings).transform.Find("panel/Title"), ((Component)settings).transform.Find("Panel/Title"), ((Component)settings).transform.Find("Title"), ((Component)settings).transform.Find("panel/Header"), ((Component)settings).transform.Find("Panel/Header") }; for (int i = 0; i < array.Length; i++) { if (!((Object)(object)array[i] == (Object)null)) { TMP_Text componentInChildren = ((Component)array[i]).GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = "Mod Configs"; return; } } } TMP_Text[] componentsInChildren = ((Component)settings).GetComponentsInChildren<TMP_Text>(true); for (int j = 0; j < componentsInChildren.Length; j++) { string text = componentsInChildren[j].text; if (!string.IsNullOrEmpty(text) && (text.Equals("Settings", StringComparison.OrdinalIgnoreCase) || (text.IndexOf("settings", StringComparison.OrdinalIgnoreCase) >= 0 && text.Length < 24)) && (componentsInChildren[j].fontSize >= 24f || (Object)(object)componentsInChildren[j].transform.parent == (Object)(object)((Component)settings).transform || ((Object)(object)componentsInChildren[j].transform.parent != (Object)null && ((Object)componentsInChildren[j].transform.parent).name.IndexOf("title", StringComparison.OrdinalIgnoreCase) >= 0) || ((Object)(object)componentsInChildren[j].transform.parent != (Object)null && ((Object)componentsInChildren[j].transform.parent).name.IndexOf("header", StringComparison.OrdinalIgnoreCase) >= 0))) { componentsInChildren[j].text = "Mod Configs"; return; } } TMP_Text val = null; float num = 0f; for (int k = 0; k < componentsInChildren.Length; k++) { if (componentsInChildren[k].fontSize > num) { num = componentsInChildren[k].fontSize; val = componentsInChildren[k]; } } if ((Object)(object)val != (Object)null && num >= 22f) { val.text = "Mod Configs"; } } } internal sealed class ModConfigLayoutLock : MonoBehaviour { private Settings _settings; private int _framesRemaining = 120; private void Awake() { _settings = ((Component)this).GetComponent<Settings>(); } private void LateUpdate() { if ((Object)(object)_settings == (Object)null) { _settings = ((Component)this).GetComponent<Settings>(); } if ((Object)(object)_settings == (Object)null) { ((Behaviour)this).enabled = false; return; } ModConfigPanel.EnforceConvertedLayout(_settings); if (--_framesRemaining <= 0) { ((Behaviour)this).enabled = false; } } } internal sealed class ModConfigTab : MonoBehaviour, ISettingsTab { private Settings _settings; private Transform _content; private Transform _pinnedHeader; private ModPicker _modPicker; private Button _resetDefaultsButton; private GuiInputField _settingsSearchField; private string _settingsSearchQuery = string.Empty; private TMP_Text _labelTemplate; private Toggle _toggleTemplate; private Slider _sliderTemplate; private GuiDropdown _dropdownTemplate; private GuiInputField _inputFieldTemplate; private Button _buttonTemplate; private List<DiscoveredPlugin> _plugins = new List<DiscoveredPlugin>(); private readonly List<Selectable> _selectables = new List<Selectable>(); private readonly List<GameObject> _dynamicRows = new List<GameObject>(); private int _selectedModIndex; private static ModConfigTab _openInstance; public event Action<string, int> SharedSettingChanged; internal static void RefreshOpenInstance() { if ((Object)(object)_openInstance == (Object)null || !((Behaviour)_openInstance).isActiveAndEnabled) { return; } try { _openInstance.RebuildSelectedModUi(); } catch (Exception ex) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)("Failed to refresh config UI: " + ex.Message)); } } private void OnEnable() { _openInstance = this; } private void OnDisable() { if (_openInstance == this) { _openInstance = null; } } internal bool TryBuild(Settings settings, RectTransform page) { _settings = settings; _dropdownTemplate = NativeWidgetFactory.FindDropdownTemplate(settings); _sliderTemplate = NativeWidgetFactory.FindSliderTemplate(settings); _toggleTemplate = NativeWidgetFactory.FindToggleTemplate(settings); _buttonTemplate = NativeWidgetFactory.FindButtonTemplate(settings); _inputFieldTemplate = NativeWidgetFactory.FindInputFieldTemplate(settings); _labelTemplate = NativeWidgetFactory.FindLabelTemplate(settings, _toggleTemplate, _sliderTemplate); if ((Object)(object)_dropdownTemplate == (Object)null && (Object)(object)_toggleTemplate == (Object)null && (Object)(object)_sliderTemplate == (Object)null && (Object)(object)_buttonTemplate == (Object)null) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)"No native widget templates found."); return false; } ModdedWolfsConfigsPlugin.Log.LogInfo((object)($"Widget templates: dropdown={(Object)(object)_dropdownTemplate != (Object)null}, toggle={(Object)(object)_toggleTemplate != (Object)null}, " + $"slider={(Object)(object)_sliderTemplate != (Object)null}, button={(Object)(object)_buttonTemplate != (Object)null}, " + $"input={(Object)(object)_inputFieldTemplate != (Object)null}")); _pinnedHeader = NativeWidgetFactory.CreatePinnedHeader(page, 115f); NativeWidgetFactory.CreateScrollableContent(page, out _content, 135f); _plugins = DiscoverOrEmpty(); RestoreSelectedModIndex(); BuildModSelector(); RebuildSelectedModUi(); return true; } public void Initialize() { _plugins = DiscoverOrEmpty(); RestoreSelectedModIndex(); RefreshModDropdownOptions(); RebuildSelectedModUi(); } private static List<DiscoveredPlugin> DiscoverOrEmpty() { try { return ConfigDiscovery.Discover() ?? new List<DiscoveredPlugin>(); } catch (Exception ex) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)("Config discovery failed; showing empty mod list: " + ex.Message)); return new List<DiscoveredPlugin>(); } } public void OnTabOpen(Button backButton, Button okButton) { try { ModConfigPanel.StripSettingsChrome(_settings); RebuildSelectedModUi(); Selectable val = (Selectable)((_selectables.Count > 0) ? _selectables[_selectables.Count - 1] : (((Object)(object)_modPicker != (Object)null) ? ((object)_modPicker.Selectable) : ((object)_resetDefaultsButton))); if (!((Object)(object)val == (Object)null)) { if ((Object)(object)backButton != (Object)null) { GuiUtils.SetNavigationDown(val, (Selectable)(object)backButton); GuiUtils.SetNavigationUp((Selectable)(object)backButton, val); } if ((Object)(object)okButton != (Object)null) { GuiUtils.SetNavigationUp((Selectable)(object)okButton, val); } } } catch (Exception ex) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)("OnTabOpen failed: " + ex.Message)); } } public void OnOkAsync(OkActionCompletedHandler okActionCompletedCallback) { if (okActionCompletedCallback != null) { okActionCompletedCallback.Invoke(); } } public void OnBack() { } public void OnSharedSettingChanged(string setting, int value) { } public void Terminate() { } private void BuildModSelector() { //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Expected O, but got Unknown Transform val = (((Object)(object)_pinnedHeader != (Object)null) ? _pinnedHeader : _content); if ((Object)(object)val == (Object)null) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)"Mod picker skipped — missing header parent."); return; } List<string> list = BuildModOptionNames(); _selectedModIndex = Mathf.Clamp(_selectedModIndex, 0, Mathf.Max(0, list.Count - 1)); Transform val2 = NativeWidgetFactory.CreateRow(val, "ModAndReset"); _modPicker = ModPicker.Create(val2, _buttonTemplate, _labelTemplate, null, list, _selectedModIndex, OnModChanged, _inputFieldTemplate, _dropdownTemplate, useParentAsRow: true, enableSearch: true, "Search mods...", "(No mod configs found)"); if ((Object)(object)_modPicker?.Selectable != (Object)null) { _selectables.Add(_modPicker.Selectable); } _resetDefaultsButton = NativeWidgetFactory.CreateInlineButton(val2, _buttonTemplate, "Reset to Defaults", 180f); if ((Object)(object)_resetDefaultsButton == (Object)null) { _resetDefaultsButton = NativeWidgetFactory.CreateStepButton(val2, _buttonTemplate, "Reset to Defaults"); } if ((Object)(object)_resetDefaultsButton != (Object)null) { LayoutElement component = ((Component)_resetDefaultsButton).GetComponent<LayoutElement>(); if ((Object)(object)component != (Object)null) { component.flexibleWidth = 0f; } ((UnityEventBase)_resetDefaultsButton.onClick).RemoveAllListeners(); ((UnityEvent)_resetDefaultsButton.onClick).AddListener(new UnityAction(ResetSelectedModToDefaults)); _selectables.Add((Selectable)(object)_resetDefaultsButton); } Transform row = NativeWidgetFactory.CreateRow(val, "SettingsSearch"); _settingsSearchField = NativeWidgetFactory.CreateSearchField(row, _inputFieldTemplate, "Search settings...", OnSettingsSearchChanged); if ((Object)(object)_settingsSearchField != (Object)null) { _selectables.Add((Selectable)(object)_settingsSearchField); } ModdedWolfsConfigsPlugin.Log.LogInfo((object)$"Mod picker ready with {_plugins.Count} mod(s)."); } private void OnSettingsSearchChanged(string value) { _settingsSearchQuery = value ?? string.Empty; RebuildSelectedModUi(); } private void ClearSettingsSearch() { _settingsSearchQuery = string.Empty; if ((Object)(object)_settingsSearchField != (Object)null) { NativeWidgetFactory.SetInputFieldText(_settingsSearchField, string.Empty); } } private List<string> BuildModOptionNames() { List<string> list = new List<string>(); for (int i = 0; i < _plugins.Count; i++) { list.Add(_plugins[i].Name + " " + _plugins[i].Version); } if (list.Count == 0) { list.Add("(No mod configs found)"); } return list; } private void RefreshModDropdownOptions() { if (!((Object)(object)_modPicker == (Object)null)) { List<string> list = BuildModOptionNames(); _selectedModIndex = Mathf.Clamp(_selectedModIndex, 0, Mathf.Max(0, list.Count - 1)); _modPicker.SetOptions(list, _selectedModIndex); } } private void OnModChanged(int index) { ClearSettingsSearch(); _selectedModIndex = index; PersistSelectedModGuid(); RebuildSelectedModUi(); } private int IndexForSavedModGuid() { string text = ModdedWolfsConfigsPlugin.LastSelectedModGuid?.Value; if (string.IsNullOrEmpty(text)) { return -1; } for (int i = 0; i < _plugins.Count; i++) { if (string.Equals(_plugins[i].Guid, text, StringComparison.OrdinalIgnoreCase)) { return i; } } return -1; } private void RestoreSelectedModIndex() { if (_plugins.Count == 0) { _selectedModIndex = 0; return; } ConfigEntry<bool> rememberLastMod = ModdedWolfsConfigsPlugin.RememberLastMod; if (rememberLastMod != null && rememberLastMod.Value) { int num = IndexForSavedModGuid(); if (num >= 0) { _selectedModIndex = num; return; } } _selectedModIndex = Mathf.Clamp(_selectedModIndex, 0, _plugins.Count - 1); } private void PersistSelectedModGuid() { ConfigEntry<bool> rememberLastMod = ModdedWolfsConfigsPlugin.RememberLastMod; if (rememberLastMod == null || !rememberLastMod.Value || _plugins.Count == 0 || _selectedModIndex < 0 || _selectedModIndex >= _plugins.Count) { return; } ModdedWolfsConfigsPlugin.LastSelectedModGuid.Value = _plugins[_selectedModIndex].Guid; ModdedWolfsConfigsPlugin instance = ModdedWolfsConfigsPlugin.Instance; if (instance != null) { ConfigFile config = ((BaseUnityPlugin)instance).Config; if (config != null) { config.Save(); } } } private void PersistRememberedModGuid(int index) { if (_plugins.Count == 0 || index < 0 || index >= _plugins.Count) { return; } ModdedWolfsConfigsPlugin.LastSelectedModGuid.Value = _plugins[index].Guid; ModdedWolfsConfigsPlugin instance = ModdedWolfsConfigsPlugin.Instance; if (instance != null) { ConfigFile config = ((BaseUnityPlugin)instance).Config; if (config != null) { config.Save(); } } } private void ResetSelectedModToDefaults() { if (_plugins.Count == 0 || _selectedModIndex < 0 || _selectedModIndex >= _plugins.Count) { return; } DiscoveredPlugin discoveredPlugin = _plugins[_selectedModIndex]; int num = 0; for (int i = 0; i < discoveredPlugin.Sections.Count; i++) { DiscoveredSection discoveredSection = discoveredPlugin.Sections[i]; for (int j = 0; j < discoveredSection.Entries.Count; j++) { ConfigEntryBase val = discoveredSection.Entries[j]; if (val == null) { continue; } try { object defaultValue = val.DefaultValue; if (defaultValue != null || val.SettingType.IsClass || Nullable.GetUnderlyingType(val.SettingType) != null) { val.BoxedValue = defaultValue; } else { val.BoxedValue = Activator.CreateInstance(val.SettingType); } Save(val); num++; } catch (Exception ex) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)$"Reset failed for {val.Definition}: {ex.Message}"); } } } ModdedWolfsConfigsPlugin.Log.LogInfo((object)$"Reset {num} setting(s) to defaults for {discoveredPlugin.Name}."); RebuildSelectedModUi(); } private void RebuildSelectedModUi() { ClearDynamicRows(); _selectables.Clear(); if ((Object)(object)_modPicker?.Selectable != (Object)null) { _selectables.Add(_modPicker.Selectable); } if ((Object)(object)_resetDefaultsButton != (Object)null) { _selectables.Add((Selectable)(object)_resetDefaultsButton); } if ((Object)(object)_settingsSearchField != (Object)null) { _selectables.Add((Selectable)(object)_settingsSearchField); } if (_plugins.Count == 0 || _selectedModIndex < 0 || _selectedModIndex >= _plugins.Count) { TMP_Text val = NativeWidgetFactory.CreateSectionHeader(_content, _labelTemplate, "No configurable mods loaded."); if ((Object)(object)val != (Object)null) { _dynamicRows.Add(((Component)val).gameObject); } return; } DiscoveredPlugin discoveredPlugin = _plugins[_selectedModIndex]; string text = (_settingsSearchQuery ?? string.Empty).Trim(); bool flag = text.Length > 0; int num = 0; for (int i = 0; i < discoveredPlugin.Sections.Count; i++) { DiscoveredSection discoveredSection = discoveredPlugin.Sections[i]; List<ConfigEntryBase> list = new List<ConfigEntryBase>(); for (int j = 0; j < discoveredSection.Entries.Count; j++) { ConfigEntryBase val2 = discoveredSection.Entries[j]; if (ConfigDiscovery.ShouldRenderEntry(val2) && (!IsOwnPluginGeneralSection(discoveredPlugin, discoveredSection) || !string.Equals(val2.Definition.Key, "LastSelectedModGuid", StringComparison.OrdinalIgnoreCase)) && (!flag || EntryMatchesSearch(val2, discoveredSection.Name, text))) { list.Add(val2); } } if (flag && list.Count == 0) { continue; } TMP_Text val3 = NativeWidgetFactory.CreateSectionHeader(_content, _labelTemplate, discoveredSection.Name); if ((Object)(object)val3 != (Object)null) { _dynamicRows.Add(((Component)val3).gameObject); } for (int k = 0; k < list.Count; k++) { ConfigEntryBase val4 = list[k]; try { CreateEntryWidget(val4); num++; if (IsOwnPluginGeneralSection(discoveredPlugin, discoveredSection) && string.Equals(val4.Definition.Key, "RememberLastMod", StringComparison.OrdinalIgnoreCase)) { CreateRememberedModPicker(); } } catch (Exception ex) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)$"Failed to create widget for {discoveredPlugin.Guid}/{val4.Definition}: {ex.Message}"); } } } if (flag && num == 0) { TMP_Text val5 = NativeWidgetFactory.CreateSectionHeader(_content, _labelTemplate, "No settings match your search."); if ((Object)(object)val5 != (Object)null) { _dynamicRows.Add(((Component)val5).gameObject); } } WireNavigation(); } private static bool EntryMatchesSearch(ConfigEntryBase entry, string sectionName, string query) { if (string.IsNullOrEmpty(query)) { return true; } if (ContainsIgnoreCase(sectionName, query)) { return true; } if (((entry != null) ? entry.Definition : null) != (ConfigDefinition)null && ContainsIgnoreCase(entry.Definition.Key, query)) { return true; } if (ContainsIgnoreCase(ConfigDiscovery.GetDisplayName(entry), query)) { return true; } return ContainsIgnoreCase(ResolveEntryDescription(entry), query); } private static bool ContainsIgnoreCase(string haystack, string needle) { if (!string.IsNullOrEmpty(haystack)) { return haystack.IndexOf(needle, StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private static bool IsOwnPluginGeneralSection(DiscoveredPlugin plugin, DiscoveredSection section) { if (plugin != null && string.Equals(plugin.Guid, "ModdedWolf.ModConfigs", StringComparison.OrdinalIgnoreCase)) { return string.Equals(section.Name, "General", StringComparison.OrdinalIgnoreCase); } return false; } private void CreateRememberedModPicker() { List<string> list = BuildModOptionNames(); int num = IndexForSavedModGuid(); if (num < 0) { num = Mathf.Clamp(_selectedModIndex, 0, Mathf.Max(0, list.Count - 1)); } Transform val = NativeWidgetFactory.CreateSettingBlock(_content, "LastSelectedMod"); _dynamicRows.Add(((Component)val).gameObject); ModPicker modPicker = ModPicker.Create(val, _buttonTemplate, _labelTemplate, "Last selected mod", list, num, delegate(int index) { PersistRememberedModGuid(index); ConfigEntry<bool> rememberLastMod = ModdedWolfsConfigsPlugin.RememberLastMod; if (rememberLastMod != null && rememberLastMod.Value && index >= 0 && index < _plugins.Count) { _selectedModIndex = index; RefreshModDropdownOptions(); } }, _inputFieldTemplate, _dropdownTemplate, useParentAsRow: false, enableSearch: true, "Search mods...", "(No mod configs found)"); if ((Object)(object)modPicker?.Selectable != (Object)null) { _selectables.Add(modPicker.Selectable); } NativeWidgetFactory.CreateDescription(val, _labelTemplate, "Mod opened by default when you return to Mod Configs."); } private void CreateEntryWidget(ConfigEntryBase entry) { if (!ConfigDiscovery.ShouldRenderEntry(entry)) { return; } if (string.Equals(entry.Definition.Key, "LastSelectedModGuid", StringComparison.OrdinalIgnoreCase)) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)"LastSelectedModGuid reached widget creation; skipping raw GUID field."); return; } string displayName = ConfigDiscovery.GetDisplayName(entry); Type settingType = entry.SettingType; string description = ResolveEntryDescription(entry); Transform val = NativeWidgetFactory.CreateSettingBlock(_content, displayName); _dynamicRows.Add(((Component)val).gameObject); if (ClientLocalBindings.IsBinding(entry)) { CreateKeybindControl(entry, displayName, val); NativeWidgetFactory.CreateDescription(val, _labelTemplate, description); return; } if (TryGetBoolLike(entry, out var value, out var setBool) && (Object)(object)_toggleTemplate != (Object)null) { Toggle val2 = NativeWidgetFactory.CreateToggle(val, _toggleTemplate, _labelTemplate, displayName, delegate(bool obj) { setBool(obj); Save(entry); }); val2.SetIsOnWithoutNotify(value); Track((Selectable)(object)val2); NativeWidgetFactory.CreateDescription(val, _labelTemplate, description); return; } if (IsNumericSettingType(settingType, out var wholeNumbers)) { CreateNumericControl(entry, displayName, wholeNumbers, val); NativeWidgetFactory.CreateDescription(val, _labelTemplate, description); return; } if (settingType.IsEnum) { Array values = Enum.GetValues(settingType); List<string> list = new List<string>(); int currentIndex = 0; object boxedValue = entry.BoxedValue; for (int num = 0; num < values.Length; num++) { list.Add(values.GetValue(num).ToString()); if (object.Equals(values.GetValue(num), boxedValue)) { currentIndex = num; } } CreateOptionPicker(val, displayName, list, currentIndex, delegate(int index) { if (index >= 0 && index < values.Length) { entry.BoxedValue = values.GetValue(index); Save(entry); } }); NativeWidgetFactory.CreateDescription(val, _labelTemplate, description); return; } if (settingType == typeof(string)) { ConfigDescription description2 = entry.Description; if (((description2 != null) ? description2.AcceptableValues : null) is AcceptableValueList<string> val3) { List<string> options = new List<string>(val3.AcceptableValues); int currentIndex2 = Mathf.Max(0, options.IndexOf((entry.BoxedValue as string) ?? string.Empty)); CreateOptionPicker(val, displayName, options, currentIndex2, delegate(int index) { if (index >= 0 && index < options.Count) { entry.BoxedValue = options[index]; Save(entry); } }); NativeWidgetFactory.CreateDescription(val, _labelTemplate, description); return; } } CreateEditableTextEntry(entry, displayName, val); NativeWidgetFactory.CreateDescription(val, _labelTemplate, description); } private static string ResolveEntryDescription(ConfigEntryBase entry) { object obj; if (entry == null) { obj = null; } else { ConfigDescription description = entry.Description; obj = ((description != null) ? description.Description : null); } string text = (string)obj; if (!string.IsNullOrWhiteSpace(text)) { return text; } object obj2; if (entry == null) { obj2 = null; } else { ConfigDescription description2 = entry.Description; obj2 = ((description2 != null) ? description2.Tags : null); } object[] array = (object[])obj2; if (array == null) { return null; } for (int i = 0; i < array.Length; i++) { if (array[i] is ConfigurationManagerAttributes configurationManagerAttributes && !string.IsNullOrWhiteSpace(configurationManagerAttributes.Description)) { return configurationManagerAttributes.Description; } } return null; } private void CreateOptionPicker(Transform block, string label, List<string> options, int currentIndex, Action<int> onPicked) { ModPicker modPicker = ModPicker.Create(block, _buttonTemplate, _labelTemplate, label, options, currentIndex, onPicked, _inputFieldTemplate, _dropdownTemplate, useParentAsRow: false, ModPicker.ShouldEnableOptionSearch(options)); if ((Object)(object)modPicker?.Selectable != (Object)null) { Track(modPicker.Selectable); } } private void CreateEditableTextEntry(ConfigEntryBase entry, string label, Transform parent) { ConfigEntryBase obj = entry; object a; if (obj == null) { a = null; } else { ConfigDefinition definition = obj.Definition; a = ((definition != null) ? definition.Key : null); } if (!string.Equals((string?)a, "LastSelectedModGuid", StringComparison.OrdinalIgnoreCase)) { string initial = entry.GetSerializedValue() ?? entry.BoxedValue?.ToString() ?? string.Empty; Transform row = NativeWidgetFactory.CreateRow(parent, label); NativeWidgetFactory.CreateLabel(row, _labelTemplate, label); GuiInputField val = NativeWidgetFactory.CreateTextField(row, _inputFieldTemplate, initial, delegate(string text) { ApplyTextEntryValue(entry, text); }); if ((Object)(object)val != (Object)null) { _selectables.Add((Selectable)(object)val); } } } private static void ApplyTextEntryValue(ConfigEntryBase entry, string text) { if (entry == null) { return; } if (text == null) { text = string.Empty; } try { if (entry.SettingType == typeof(string)) { entry.BoxedValue = text; } else { entry.SetSerializedValue(text); } Save(entry); } catch (Exception ex) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)$"Failed to apply text value for {entry.Definition}: {ex.Message}"); } } private void CreateKeybindControl(ConfigEntryBase entry, string label, Transform parent) { string initial = entry.GetSerializedValue() ?? entry.BoxedValue?.ToString() ?? "None"; Transform val = NativeWidgetFactory.CreateRow(parent, label); NativeWidgetFactory.CreateLabel(val, _labelTemplate, label); TMP_Text val2 = NativeWidgetFactory.CreateValueText(val, _labelTemplate, initial); if ((Object)(object)val2 != (Object)null) { val2.alignment = (TextAlignmentOptions)4097; LayoutElement component = ((Component)val2).GetComponent<LayoutElement>(); if ((Object)(object)component != (Object)null) { component.minWidth = 140f; component.preferredWidth = 200f; component.flexibleWidth = 1f; } } Button val3 = NativeWidgetFactory.CreateInlineButton(val, _buttonTemplate, "Rebind", 140f); if ((Object)(object)val3 == (Object)null) { val3 = NativeWidgetFactory.CreateStepButton(val, _buttonTemplate, "Rebind"); } ((Component)val).gameObject.AddComponent<KeybindCapture>().Bind(entry, val3, val2); if ((Object)(object)val3 != (Object)null) { _selectables.Add((Selectable)(object)val3); } } private void CreateNumericControl(ConfigEntryBase entry, string label, bool wholeNumbers, Transform parent) { GetNumericRange(entry, wholeNumbers, out var min, out var max, out var value, out var _); Type underlying = Nullable.GetUnderlyingType(entry.SettingType) ?? entry.SettingType; UnityAction<float> val = delegate(float v) { entry.BoxedValue = BoxNumeric(underlying, v); Save(entry); }; if ((Object)(object)_sliderTemplate != (Object)null) { try { TMP_Text valueText; GuiInputField valueInput; Transform row; Slider val2 = NativeWidgetFactory.CreateSlider(parent, _sliderTemplate, _labelTemplate, _inputFieldTemplate, label, min, max, wholeNumbers, val, out valueText, out valueInput, out row); if ((Object)(object)val2 != (Object)null && (Object)(object)row != (Object)null) { val2.SetValueWithoutNotify(value); string text = FormatNumber(value, wholeNumbers); if ((Object)(object)valueInput != (Object)null) { NativeWidgetFactory.SetInputFieldText(valueInput, text); WireSliderValueInput(val2, valueInput, min, max, wholeNumbers, val); _selectables.Add((Selectable)(object)val2); _selectables.Add((Selectable)(object)valueInput); return; } if ((Object)(object)valueText != (Object)null) { valueText.text = text; ((UnityEvent<float>)(object)val2.onValueChanged).AddListener((UnityAction<float>)delegate(float v) { valueText.text = FormatNumber(v, wholeNumbers); }); } _selectables.Add((Selectable)(object)val2); return; } } catch (Exception ex) { ModdedWolfsConfigsPlugin.Log.LogWarning((object)$"Slider failed for {entry.Definition}, using stepper: {ex.Message}"); } } NativeWidgetFactory.CreateNumericStepper(parent, _buttonTemplate, _labelTemplate, label, value, min, max, wholeNumbers, val, out var minusButton, out var plusButton, out var _, out var _); if ((Object)(object)minusButton != (Object)null) { _selectables.Add((Selectable)(object)minusButton); } if ((Object)(object)plusButton != (Object)null) { _selectables.Add((Selectable)(object)plusButton); } } private void WireSliderValueInput(Slider slider, GuiInputField valueInput, float min, float max, bool wholeNumbers, UnityAction<float> apply) { if ((Object)(object)slider == (Object)null || (Object)(object)valueInput == (Object)null) { return; } ((UnityEvent<float>)(object)slider.onValueChanged).AddListener((UnityAction<float>)delegate(float v) { NativeWidgetFactory.SetInputFieldText(valueInput, FormatNumber(v, wholeNumbers)); }); ((UnityEvent<string>)(object)((TMP_InputField)valueInput).onEndEdit).AddListener((UnityAction<string>)delegate(string text) { if (!TryParseSliderInput(text, wholeNumbers, out var value)) { NativeWidgetFactory.SetInputFieldText(valueInput, FormatNumber(slider.value, wholeNumbers)); } else { float num = Mathf.Clamp(value, min, max); if (wholeNumbers) { num = Mathf.Round(num); } slider.SetValueWithoutNotify(num); apply?.Invoke(num); NativeWidgetFactory.SetInputFieldText(valueInput, FormatNumber(num, wholeNumbers)); } }); } private static bool TryParseSliderInput(string text, bool wholeNumbers, out float value) { value = 0f; if (string.IsNullOrWhiteSpace(text)) { return false; } text = text.Trim(); if (wholeNumbers) { if (int.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) || int.TryParse(text, NumberStyles.Integer, CultureInfo.CurrentCulture, out result)) { value = result; return true; } return false; } if (!float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out value)) { return float.TryParse(text, NumberStyles.Float, CultureInfo.CurrentCulture, out value); } return true; } private static bool IsNumericSettingType(Type type, out bool wholeNumbers) { wholeNumbers = false; if (type == null) { return false; } type = Nullable.GetUnderlyingType(type) ?? type; if (type == typeof(int) || type == typeof(long) || type == typeof(short) || type == typeof(byte) || type == typeof(uint) || type == typeof(ushort) || type == typeof(sbyte)) { wholeNumbers = true; return true; } if (type == typeof(float) || type == typeof(double) || type == typeof(decimal)) { wholeNumbers = false; return true; } return false; } private static object BoxNumeric(Type type, float value) { if (type == typeof(int)) { return Mathf.RoundToInt(value); } if (type == typeof(long)) { return (long)Mathf.Round(value); } if (type == typeof(short)) { return (short)Mathf.RoundToInt(value); } if (type == typeof(byte)) { return (byte)Mathf.Clamp(Mathf.RoundToInt(value), 0, 255); } if (type == typeof(uint)) { ret