Decompiled source of ModConfigs v1.0.0

ModConfigs.dll

Decompiled 2 days ago
using System;
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.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.0.202607190821")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ModConfigs")]
[assembly: AssemblyTitle("ModConfigs")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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 == 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>();
			foreach (KeyValuePair<string, PluginInfo> item in Chainloader.PluginInfos.OrderBy<KeyValuePair<string, PluginInfo>, string>((KeyValuePair<string, PluginInfo> p) => p.Value.Metadata.Name, StringComparer.OrdinalIgnoreCase))
			{
				PluginInfo value = item.Value;
				BaseUnityPlugin instance = value.Instance;
				if ((Object)(object)instance == (Object)null || (ModdedWolfsConfigsPlugin.HideSelfFromList.Value && value.Metadata.GUID == "ModdedWolf.ModConfigs"))
				{
					continue;
				}
				Dictionary<string, DiscoveredSection> dictionary = new Dictionary<string, DiscoveredSection>(StringComparer.OrdinalIgnoreCase);
				foreach (ConfigDefinition key in instance.Config.Keys)
				{
					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 = instance.Config[key];
					if (IsBrowsable(val))
					{
						if (!dictionary.TryGetValue(key.Section, out var value2))
						{
							value2 = new DiscoveredSection
							{
								Name = key.Section
							};
							dictionary[key.Section] = value2;
						}
						value2.Entries.Add(val);
					}
				}
				if (dictionary.Count == 0)
				{
					continue;
				}
				DiscoveredPlugin discoveredPlugin = new DiscoveredPlugin
				{
					Guid = value.Metadata.GUID,
					Name = value.Metadata.Name,
					Version = (value.Metadata.Version?.ToString() ?? ""),
					Plugin = instance
				};
				foreach (DiscoveredSection item2 in dictionary.Values.OrderBy<DiscoveredSection, string>((DiscoveredSection s) => s.Name, StringComparer.OrdinalIgnoreCase))
				{
					item2.Entries = item2.Entries.OrderByDescending(GetOrder).ThenBy<ConfigEntryBase, string>((ConfigEntryBase e) => e.Definition.Key, StringComparer.OrdinalIgnoreCase).ToList();
					discoveredPlugin.Sections.Add(item2);
				}
				list.Add(discoveredPlugin);
			}
			return list;
		}

		private static bool IsBrowsable(ConfigEntryBase entry)
		{
			if (entry == 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 int GetOrder(ConfigEntryBase entry)
		{
			ConfigDescription description = entry.Description;
			object[] array = ((description != null) ? description.Tags : null);
			if (array == null)
			{
				return 0;
			}
			foreach (object obj in array)
			{
				if (obj is ConfigurationManagerAttributes configurationManagerAttributes && configurationManagerAttributes.Order.HasValue)
				{
					return configurationManagerAttributes.Order.Value;
				}
				PropertyInfo propertyInfo = obj?.GetType().GetProperty("Order", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (propertyInfo != null && propertyInfo.PropertyType == typeof(int?))
				{
					int? num = (int?)propertyInfo.GetValue(obj, null);
					if (num.HasValue)
					{
						return num.Value;
					}
				}
			}
			return 0;
		}

		internal static string GetDisplayName(ConfigEntryBase entry)
		{
			ConfigDescription description = entry.Description;
			object[] array = ((description != null) ? description.Tags : null);
			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;
						}
					}
				}
			}
			return entry.Definition.Key;
		}
	}
	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);
					Setup(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)
				{
					Setup(FindMenuEntries(Menu.instance.m_menuDialog), flag2);
					if (!flag2)
					{
						HideNamedUnder(((Component)Menu.instance).transform);
					}
				}
			}
			catch (Exception ex)
			{
				ModdedWolfsConfigsPlugin.Log.LogWarning((object)("Failed to refresh menu button: " + ex.Message));
			}
		}

		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 Setup(Transform menuEntries, bool show)
		{
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			if ((Object)(object)menuEntries == (Object)null)
			{
				return;
			}
			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)
					{
						val = child;
						break;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Transform obj = menuEntries.Find("ModdedWolfsConfigs");
			GameObject val2 = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, menuEntries);
				((Object)val2).name = "ModdedWolfsConfigs";
				val2.transform.SetSiblingIndex(val.GetSiblingIndex() + 1);
				Button component = val2.GetComponent<Button>();
				for (int j = 0; j < ((UnityEventBase)component.onClick).GetPersistentEventCount(); j++)
				{
					((UnityEventBase)component.onClick).SetPersistentListenerState(j, (UnityEventCallState)0);
				}
				((UnityEventBase)component.onClick).RemoveAllListeners();
				ButtonClickedEvent onClick = component.onClick;
				object obj2 = <>O.<0>__Open;
				if (obj2 == null)
				{
					UnityAction val3 = ConfigPanelOpener.Open;
					<>O.<0>__Open = val3;
					obj2 = (object)val3;
				}
				((UnityEvent)onClick).AddListener((UnityAction)obj2);
				Navigation navigation = ((Selectable)component).navigation;
				((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)((Component)val).GetComponent<Button>();
				((Selectable)component).navigation = navigation;
			}
			TMP_Text componentInChildren = val2.GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.text = "Mod Configs";
			}
			Text componentInChildren2 = val2.GetComponentInChildren<Text>(true);
			if ((Object)(object)componentInChildren2 != (Object)null)
			{
				componentInChildren2.text = "Mod Configs";
			}
			val2.SetActive(show);
			WireNavigation(((Component)val).GetComponent<Button>(), val2.GetComponent<Button>(), show);
		}

		private static void WireNavigation(Button settingsButton, Button modButton, bool show)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)settingsButton == (Object)null || (Object)(object)modButton == (Object)null)
			{
				return;
			}
			Navigation navigation = ((Selectable)settingsButton).navigation;
			Navigation navigation2 = ((Selectable)modButton).navigation;
			Selectable selectOnDown = ((Navigation)(ref navigation2)).selectOnDown;
			Button val = (Button)(object)((selectOnDown is Button) ? selectOnDown : null);
			if (show)
			{
				((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)modButton;
				if ((Object)(object)val != (Object)null)
				{
					Navigation navigation3 = ((Selectable)val).navigation;
					((Navigation)(ref navigation3)).selectOnUp = (Selectable)(object)modButton;
					((Selectable)val).navigation = navigation3;
				}
				((Navigation)(ref navigation2)).selectOnUp = (Selectable)(object)settingsButton;
				((Selectable)modButton).navigation = navigation2;
			}
			else if ((Object)(object)val != (Object)null)
			{
				((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)val;
				Navigation navigation4 = ((Selectable)val).navigation;
				((Navigation)(ref navigation4)).selectOnUp = (Selectable)(object)settingsButton;
				((Selectable)val).navigation = navigation4;
			}
			else
			{
				Transform parent = ((Component)settingsButton).transform.parent;
				if ((Object)(object)parent != (Object)null)
				{
					for (int i = ((Component)settingsButton).transform.GetSiblingIndex() + 1; i < parent.childCount; i++)
					{
						Button component = ((Component)parent.GetChild(i)).GetComponent<Button>();
						if ((Object)(object)component != (Object)null && ((Component)component).gameObject.activeInHierarchy && (Object)(object)component != (Object)(object)modButton)
						{
							((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)component;
							Navigation navigation5 = ((Selectable)component).navigation;
							((Navigation)(ref navigation5)).selectOnUp = (Selectable)(object)settingsButton;
							((Selectable)component).navigation = navigation5;
							break;
						}
					}
				}
			}
			((Selectable)settingsButton).navigation = navigation;
		}
	}
	[BepInPlugin("ModdedWolf.ModConfigs", "Mod Configs", "1.0.0")]
	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.0";

		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.0 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(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()
		{
			PauseMenuButton.Refresh();
		}
	}
	[HarmonyPatch(typeof(Settings), "InitializeTabs")]
	internal static class SettingsInitializeTabsPatch
	{
		private static void Prefix(Settings __instance)
		{
			if (ConfigPanelOpener.IsOpening)
			{
				ModConfigPanel.ConvertSettingsInstance(__instance);
			}
		}
	}
	internal static class ConfigPanelOpener
	{
		internal static bool IsOpening { get; private set; }

		internal static void Open()
		{
			//IL_009b: 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 settingsInstance = Object.Instantiate<GameObject>(val, val2);
				IsOpening = false;
				if ((Object)(object)Menu.instance != (Object)null)
				{
					Menu.instance.m_settingsInstance = settingsInstance;
					Menu.instance.m_closeMenuState = (CloseMenuState)0;
				}
				else
				{
					_ = (Object)(object)FejdStartup.instance != (Object)null;
				}
				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 static readonly KeyCode[] ModifierKeys;

		internal void Bind(ConfigEntryBase entry, Button button, TMP_Text valueText)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			_entry = entry;
			_button = button;
			_valueText = valueText;
			RefreshLabel();
			if ((Object)(object)_button != (Object)null)
			{
				((UnityEventBase)_button.onClick).RemoveAllListeners();
				((UnityEvent)_button.onClick).AddListener(new UnityAction(BeginListen));
			}
		}

		private void BeginListen()
		{
			if (_entry != null)
			{
				_listening = true;
				_armFrame = Time.frameCount;
				if ((Object)(object)_valueText != (Object)null)
				{
					_valueText.text = "Press key… (Esc cancel)";
				}
			}
		}

		private void Update()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Invalid comparison between Unknown and I4
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Invalid comparison between Unknown and I4
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			if (!_listening || _entry == null || Time.frameCount <= _armFrame)
			{
				return;
			}
			if (Input.GetKeyDown((KeyCode)27))
			{
				_listening = false;
				RefreshLabel();
				return;
			}
			foreach (KeyCode value in Enum.GetValues(typeof(KeyCode)))
			{
				if ((int)value != 0 && !IsModifier(value) && (int)value != 323 && (int)value != 324 && Input.GetKeyDown(value))
				{
					ApplyKey(value);
					_listening = false;
					break;
				}
			}
		}

		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());
				}
				ConfigFile configFile = _entry.ConfigFile;
				if (configFile != null)
				{
					configFile.Save();
				}
			}
			catch (Exception ex)
			{
				ModdedWolfsConfigsPlugin.Log.LogWarning((object)("Failed to set keybind: " + ex.Message));
			}
			RefreshLabel();
		}

		private void RefreshLabel()
		{
			if (!((Object)(object)_valueText == (Object)null) && _entry != null)
			{
				string text = _entry.GetSerializedValue();
				if (string.IsNullOrEmpty(text))
				{
					text = _entry.BoxedValue?.ToString() ?? "None";
				}
				_valueText.text = text;
			}
		}

		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 const string TabLabel = "Mods";

		internal static void ConvertSettingsInstance(Settings settings)
		{
			try
			{
				if (!((Object)(object)settings == (Object)null))
				{
					RenameTitle(settings);
					StripSettingsChrome(settings);
					ReplaceTabs(settings);
					StripSettingsChrome(settings);
				}
			}
			catch (Exception arg)
			{
				ModdedWolfsConfigsPlugin.Log.LogWarning((object)$"Failed to convert Settings panel: {arg}");
			}
		}

		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";
			}
		}

		private static void ReplaceTabs(Settings settings)
		{
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Expected O, but got Unknown
			//IL_01da: Expected O, but got Unknown
			TabHandler componentInChildren = ((Component)settings).GetComponentInChildren<TabHandler>(true);
			if ((Object)(object)componentInChildren == (Object)null || componentInChildren.m_tabs == null)
			{
				ModdedWolfsConfigsPlugin.Log.LogWarning((object)"TabHandler missing; cannot build mod config tabs.");
				return;
			}
			Tab val = null;
			for (int i = 0; i < componentInChildren.m_tabs.Count; i++)
			{
				Tab val2 = componentInChildren.m_tabs[i];
				if ((Object)(object)val2?.m_button != (Object)null && (Object)(object)val2.m_page != (Object)null)
				{
					val = val2;
					break;
				}
			}
			if (val == null)
			{
				ModdedWolfsConfigsPlugin.Log.LogWarning((object)"No settings tab template found.");
				return;
			}
			for (int j = 0; j < componentInChildren.m_tabs.Count; j++)
			{
				Tab val3 = componentInChildren.m_tabs[j];
				if ((Object)(object)val3?.m_button != (Object)null)
				{
					((Component)val3.m_button).gameObject.SetActive(false);
				}
				if (!((Object)(object)val3?.m_page != (Object)null))
				{
					continue;
				}
				((Component)val3.m_page).gameObject.SetActive(false);
				MonoBehaviour[] components = ((Component)val3.m_page).GetComponents<MonoBehaviour>();
				for (int k = 0; k < components.Length; k++)
				{
					if (components[k] is ISettingsTab)
					{
						((Behaviour)components[k]).enabled = false;
					}
				}
			}
			Button val4 = CloneTabButton(val.m_button, "Mods");
			RectTransform val5 = CreatePage(val.m_page);
			if (!((Component)val5).gameObject.AddComponent<ModConfigTab>().TryBuild(settings, val5))
			{
				Object.Destroy((Object)(object)((Component)val4).gameObject);
				Object.Destroy((Object)(object)((Component)val5).gameObject);
				ModdedWolfsConfigsPlugin.Log.LogWarning((object)"Failed to build ModdedWolf's Configs tab UI.");
				return;
			}
			componentInChildren.m_tabs.Clear();
			componentInChildren.m_tabs.Add(new Tab
			{
				m_button = val4,
				m_page = val5,
				m_default = true,
				m_onClick = new UnityEvent()
			});
			ModdedWolfsConfigsPlugin.Log.LogInfo((object)"ModdedWolf's Configs tab ready.");
		}

		private static Button CloneTabButton(Button template, string label)
		{
			GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, ((Component)template).transform.parent);
			((Object)val).name = "Tab_ModdedWolfsConfigs";
			val.SetActive(true);
			Button component = val.GetComponent<Button>();
			((UnityEventBase)component.onClick).RemoveAllListeners();
			((Selectable)component).interactable = true;
			Transform val2 = val.transform.Find("Selected");
			if ((Object)(object)val2 != (Object)null)
			{
				((Component)val2).gameObject.SetActive(false);
			}
			SetButtonLabel(component, label);
			val.transform.SetAsLastSibling();
			return component;
		}

		private static void SetButtonLabel(Button button, string label)
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)button).transform.Find("Selected");
			TMP_Text val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInChildren<TMP_Text>(true) : null);
			TMP_Text val3 = null;
			TMP_Text[] componentsInChildren = ((Component)button).GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val4 in componentsInChildren)
			{
				if ((!((Object)(object)val != (Object)null) || !val4.transform.IsChildOf(val)) && ((Object)(object)val3 == (Object)null || (Object)(object)val4.transform.parent == (Object)(object)((Component)button).transform))
				{
					val3 = val4;
					if ((Object)(object)val4.transform.parent == (Object)(object)((Component)button).transform)
					{
						break;
					}
				}
			}
			if ((Object)(object)val2 != (Object)null)
			{
				val2.text = label;
				((Component)val2).gameObject.SetActive(true);
			}
			if ((Object)(object)val3 != (Object)null)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					Color color = ((Graphic)val3).color;
					val3.font = val2.font;
					val3.fontSharedMaterial = val2.fontSharedMaterial;
					val3.fontSize = val2.fontSize;
					val3.fontStyle = val2.fontStyle;
					((Graphic)val3).color = color;
				}
				val3.text = label;
				((Component)val3).gameObject.SetActive(true);
			}
		}

		private static RectTransform CreatePage(RectTransform templatePage)
		{
			//IL_0018: 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_0024: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ModdedWolfsConfigsPage", new Type[1] { typeof(RectTransform) });
			val.SetActive(false);
			val.transform.SetParent(((Transform)templatePage).parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = templatePage.anchorMin;
			component.anchorMax = templatePage.anchorMax;
			component.pivot = templatePage.pivot;
			component.anchoredPosition = templatePage.anchoredPosition;
			component.sizeDelta = templatePage.sizeDelta;
			component.offsetMin = templatePage.offsetMin;
			component.offsetMax = templatePage.offsetMax;
			((Transform)component).localScale = ((Transform)templatePage).localScale;
			return component;
		}
	}
	internal sealed class ModConfigTab : MonoBehaviour, ISettingsTab
	{
		private Settings _settings;

		private Transform _content;

		private Transform _pinnedHeader;

		private ModPicker _modPicker;

		private Button _resetDefaultsButton;

		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, 100f);
			NativeWidgetFactory.CreateScrollableContent(page, out _content, 120f);
			_plugins = ConfigDiscovery.Discover();
			RestoreSelectedModIndex();
			BuildModSelector();
			RebuildSelectedModUi();
			return true;
		}

		public void Initialize()
		{
			_plugins = ConfigDiscovery.Discover();
			RestoreSelectedModIndex();
			RefreshModDropdownOptions();
			RebuildSelectedModUi();
		}

		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_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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));
			_modPicker = ModPicker.Create(val, _buttonTemplate, _labelTemplate, "Mod", list, _selectedModIndex, OnModChanged);
			if ((Object)(object)_modPicker?.Selectable != (Object)null)
			{
				_selectables.Add(_modPicker.Selectable);
			}
			Transform row = NativeWidgetFactory.CreateRow(val, "ResetDefaults");
			NativeWidgetFactory.CreateLabel(row, _labelTemplate, "This mod");
			_resetDefaultsButton = NativeWidgetFactory.CreateInlineButton(row, _buttonTemplate, "Reset to Defaults", 180f);
			if ((Object)(object)_resetDefaultsButton == (Object)null)
			{
				_resetDefaultsButton = NativeWidgetFactory.CreateStepButton(row, _buttonTemplate, "Reset to Defaults");
			}
			if ((Object)(object)_resetDefaultsButton != (Object)null)
			{
				((UnityEventBase)_resetDefaultsButton.onClick).RemoveAllListeners();
				((UnityEvent)_resetDefaultsButton.onClick).AddListener(new UnityAction(ResetSelectedModToDefaults));
				_selectables.Add((Selectable)(object)_resetDefaultsButton);
			}
			ModdedWolfsConfigsPlugin.Log.LogInfo((object)$"Mod picker ready with {_plugins.Count} mod(s).");
		}

		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)
		{
			_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 (_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];
			for (int i = 0; i < discoveredPlugin.Sections.Count; i++)
			{
				DiscoveredSection discoveredSection = discoveredPlugin.Sections[i];
				TMP_Text val2 = NativeWidgetFactory.CreateSectionHeader(_content, _labelTemplate, discoveredSection.Name);
				if ((Object)(object)val2 != (Object)null)
				{
					_dynamicRows.Add(((Component)val2).gameObject);
				}
				for (int j = 0; j < discoveredSection.Entries.Count; j++)
				{
					ConfigEntryBase val3 = discoveredSection.Entries[j];
					if (!ConfigDiscovery.ShouldRenderEntry(val3))
					{
						continue;
					}
					try
					{
						if (!IsOwnPluginGeneralSection(discoveredPlugin, discoveredSection) || !string.Equals(val3.Definition.Key, "LastSelectedModGuid", StringComparison.OrdinalIgnoreCase))
						{
							CreateEntryWidget(val3);
							if (IsOwnPluginGeneralSection(discoveredPlugin, discoveredSection) && string.Equals(val3.Definition.Key, "RememberLastMod", StringComparison.OrdinalIgnoreCase))
							{
								CreateRememberedModPicker();
							}
						}
					}
					catch (Exception ex)
					{
						ModdedWolfsConfigsPlugin.Log.LogWarning((object)$"Failed to create widget for {discoveredPlugin.Guid}/{val3.Definition}: {ex.Message}");
					}
				}
			}
			WireNavigation();
		}

		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();
				}
			});
			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 (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 (ClientLocalBindings.IsBinding(entry))
			{
				CreateKeybindControl(entry, displayName, val);
				NativeWidgetFactory.CreateDescription(val, _labelTemplate, description);
				return;
			}
			if (settingType.IsEnum && (Object)(object)_dropdownTemplate != (Object)null)
			{
				Array values = Enum.GetValues(settingType);
				List<string> list = new List<string>();
				int valueWithoutNotify = 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))
					{
						valueWithoutNotify = num;
					}
				}
				GuiDropdown val3 = NativeWidgetFactory.CreateDropdown(val, _dropdownTemplate, _labelTemplate, displayName, list, delegate(int index)
				{
					if (index >= 0 && index < values.Length)
					{
						entry.BoxedValue = values.GetValue(index);
						Save(entry);
					}
				});
				((TMP_Dropdown)val3).SetValueWithoutNotify(valueWithoutNotify);
				Track((Selectable)(object)val3);
				NativeWidgetFactory.CreateDescription(val, _labelTemplate, description);
				return;
			}
			if (settingType == typeof(string))
			{
				ConfigDescription description2 = entry.Description;
				if (((description2 != null) ? description2.AcceptableValues : null) is AcceptableValueList<string> val4 && (Object)(object)_dropdownTemplate != (Object)null)
				{
					List<string> options = new List<string>(val4.AcceptableValues);
					int valueWithoutNotify2 = Mathf.Max(0, options.IndexOf((entry.BoxedValue as string) ?? string.Empty));
					GuiDropdown val5 = NativeWidgetFactory.CreateDropdown(val, _dropdownTemplate, _labelTemplate, displayName, options, delegate(int index)
					{
						if (index >= 0 && index < options.Count)
						{
							entry.BoxedValue = options[index];
							Save(entry);
						}
					});
					((TMP_Dropdown)val5).SetValueWithoutNotify(valueWithoutNotify2);
					Track((Selectable)(object)val5);
					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 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 text = entry.GetSerializedValue() ?? entry.BoxedValue?.ToString() ?? "None";
			Transform row = NativeWidgetFactory.CreateRow(parent, label);
			NativeWidgetFactory.CreateLabel(row, _labelTemplate, label);
			TMP_Text val = NativeWidgetFactory.CreateValueText(row, _labelTemplate, text);
			if ((Object)(object)val != (Object)null)
			{
				val.alignment = (TextAlignmentOptions)4097;
				LayoutElement component = ((Component)val).GetComponent<LayoutElement>();
				if ((Object)(object)component != (Object)null)
				{
					component.minWidth = 120f;
					component.preferredWidth = 160f;
				}
			}
			Button val2 = NativeWidgetFactory.CreateInlineButton(row, _buttonTemplate, "Rebind");
			if ((Object)(object)val2 != (Object)null)
			{
				((Component)val2).gameObject.AddComponent<KeybindCapture>().Bind(entry, val2, val);
				_selectables.Add((Selectable)(object)val2);
			}
			else if ((Object)(object)val != (Object)null)
			{
				val.text = text + " (edit in config file)";
			}
		}

		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> onChanged = delegate(float v)
			{
				entry.BoxedValue = BoxNumeric(underlying, v);
				Save(entry);
			};
			if ((Object)(object)_sliderTemplate != (Object)null)
			{
				try
				{
					TMP_Text valueText;
					Transform row;
					Slider val = NativeWidgetFactory.CreateSlider(parent, _sliderTemplate, _labelTemplate, label, min, max, wholeNumbers, onChanged, out valueText, out row);
					if ((Object)(object)val != (Object)null && (Object)(object)row != (Object)null)
					{
						val.SetValueWithoutNotify(value);
						if ((Object)(object)valueText != (Object)null)
						{
							valueText.text = FormatNumber(value, wholeNumbers);
							((UnityEvent<float>)(object)val.onValueChanged).AddListener((UnityAction<float>)delegate(float v)
							{
								valueText.text = FormatNumber(v, wholeNumbers);
							});
						}
						_selectables.Add((Selectable)(object)val);
						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, onChanged, 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 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))
			{
				return (uint)Mathf.Max(0, Mathf.RoundToInt(value));
			}
			if (type == typeof(ushort))
			{
				return (ushort)Mathf.Clamp(Mathf.RoundToInt(value), 0, 65535);
			}
			if (type == typeof(sbyte))
			{
				return (sbyte)Mathf.Clamp(Mathf.RoundToInt(value), -128, 127);
			}
			if (type == typeof(double))
			{
				return (double)value;
			}
			if (type == typeof(decimal))
			{
				return (decimal)value;
			}
			return value;
		}

		private static void GetNumericRange(ConfigEntryBase entry, bool wholeNumbers, out float min, out float max, out float value, out bool hadRange)
		{
			hadRange = false;
			value = 0f;
			if (entry.BoxedValue != null)
			{
				value = Convert.ToSingle(entry.BoxedValue, CultureInfo.InvariantCulture);
			}
			min = (wholeNumbers ? 0f : 0f);
			max = (wholeNumbers ? 100f : 1f);
			ConfigDescription description = entry.Description;
			if (((description != null) ? description.AcceptableValues : null) is AcceptableValueRange<float> val)
			{
				min = val.MinValue;
				max = val.MaxValue;
				hadRange = true;
			}
			else
			{
				ConfigDescription description2 = entry.Description;
				if (((description2 != null) ? description2.AcceptableValues : null) is AcceptableValueRange<int> val2)
				{
					min = val2.MinValue;
					max = val2.MaxValue;
					hadRange = true;
				}
				else
				{
					ConfigDescription description3 = entry.Description;
					if (((description3 != null) ? description3.AcceptableValues : null) is AcceptableValueRange<double> val3)
					{
						min = (float)val3.MinValue;
						max = (float)val3.MaxValue;
						hadRange = true;
					}
					else if (wholeNumbers)
					{
						min = Mathf.Min(0f, value - 50f);
						max = Mathf.Max(new float[3]
						{
							value + 50f,
							value + 10f,
							10f
						});
					}
					else
					{
						float num = Mathf.Max(1f, Mathf.Abs(value) * 2f);
						min = ((value >= 0f) ? 0f : (value - num));
						max = value + num;
						if (Mathf.Approximately(min, max))
						{
							max = min + 1f;
						}
					}
				}
			}
			if (value < min)
			{
				min = value;
			}
			if (value > max)
			{
				max = value;
			}
		}

		private static bool TryGetBoolLike(ConfigEntryBase entry, out bool value, out Action<bool> setter)
		{
			value = false;
			setter = null;
			Type settingType = entry.SettingType;
			if (settingType == typeof(bool))
			{
				ConfigEntry<bool> typed = (ConfigEntry<bool>)(object)entry;
				value = typed.Value;
				setter = delegate(bool v)
				{
					typed.Value = v;
				};
				return true;
			}
			if (!settingType.IsEnum)
			{
				return false;
			}
			string[] names = Enum.GetNames(settingType);
			if (names.Length != 2)
			{
				return false;
			}
			int onIndex = IndexOfBoolName(names, on: true);
			int offIndex = IndexOfBoolName(names, on: false);
			if (onIndex < 0 || offIndex < 0)
			{
				return false;
			}
			Array values = Enum.GetValues(settingType);
			object boxedValue = entry.BoxedValue;
			value = object.Equals(boxedValue, values.GetValue(onIndex));
			setter = delegate(bool v)
			{
				entry.BoxedValue = values.GetValue(v ? onIndex : offIndex);
			};
			return true;
		}

		private static int IndexOfBoolName(string[] names, bool on)
		{
			for (int i = 0; i < names.Length; i++)
			{
				string text = names[i];
				if (on)
				{
					if (text.Equals("On", StringComparison.OrdinalIgnoreCase) || text.Equals("True", StringComparison.OrdinalIgnoreCase) || text.Equals("Enabled", StringComparison.OrdinalIgnoreCase) || text.Equals("Yes", StringComparison.OrdinalIgnoreCase))
					{
						return i;
					}
				}
				else if (text.Equals("Off", StringComparison.OrdinalIgnoreCase) || text.Equals("False", StringComparison.OrdinalIgnoreCase) || text.Equals("Disabled", StringComparison.OrdinalIgnoreCase) || text.Equals("No", StringComparison.OrdinalIgnoreCase))
				{
					return i;
				}
			}
			return -1;
		}

		private static string FormatNumber(float value, bool wholeNumbers)
		{
			if (!wholeNumbers)
			{
				return value.ToString("0.##", CultureInfo.InvariantCulture);
			}
			return Mathf.RoundToInt(value).ToString(CultureInfo.InvariantCulture);
		}

		private void Track(Selectable selectable)
		{
			if (!((Object)(object)selectable == (Object)null))
			{
				_selectables.Add(selectable);
			}
		}

		private void ClearDynamicRows()
		{
			for (int i = 0; i < _dynamicRows.Count; i++)
			{
				if ((Object)(object)_dynamicRows[i] != (Object)null)
				{
					Object.Destroy((Object)(object)_dynamicRows[i]);
				}
			}
			_dynamicRows.Clear();
		}

		private void WireNavigation()
		{
			for (int i = 0; i < _selectables.Count - 1; i++)
			{
				if (!((Object)(object)_selectables[i] == (Object)null) && !((Object)(object)_selectables[i + 1] == (Object)null))
				{
					GuiUtils.SetNavigationDown(_selectables[i], _selectables[i + 1]);
					GuiUtils.SetNavigationUp(_selectables[i + 1], _selectables[i]);
				}
			}
		}

		private static void Save(ConfigEntryBase entry)
		{
			ConfigApply.PersistAfterLocalChange(entry);
		}
	}
	internal sealed class ModPicker : MonoBehaviour
	{
		private static readonly Color PanelColor = new Color(0.1f, 0.07f, 0.04f, 0.98f);

		private static readonly Color RowColor = new Color(0.2f, 0.14f, 0.08f, 0.98f);

		private static readonly Color RowSelected = new Color(0.55f, 0.32f, 0.1f, 1f);

		private static readonly Color CaptionBg = new Color(0.18f, 0.12f, 0.07f, 0.95f);

		private Button _captionButton;

		private TMP_Text _captionText;

		private GameObject _listRoot;

		private GameObject _blocker;

		private ScrollRect _scroll;

		private Transform _listContent;

		private TMP_Text _labelTemplate;

		private Action<int> _onPicked;

		private List<string> _options = new List<string>();

		private int _selected;

		internal Selectable Selectable => (Selectable)(object)_captionButton;

		internal static ModPicker Create(Transform parent, Button buttonTemplate, TMP_Text labelTemplate, string label, List<string> options, int selectedIndex, Action<int> onPicked)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Expected O, but got Unknown
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			Transform val = NativeWidgetFactory.CreateRow(parent, label);
			NativeWidgetFactory.CreateLabel(val, labelTemplate, label);
			GameObject val2 = new GameObject("ModPicker", new Type[2]
			{
				typeof(RectTransform),
				typeof(LayoutElement)
			});
			val2.transform.SetParent(val, false);
			LayoutElement component = val2.GetComponent<LayoutElement>();
			component.minWidth = 320f;
			component.preferredWidth = 440f;
			component.flexibleWidth = 1f;
			component.minHeight = 40f;
			component.preferredHeight = 44f;
			ModPicker modPicker = val2.AddComponent<ModPicker>();
			modPicker._labelTemplate = labelTemplate;
			modPicker._onPicked = onPicked;
			modPicker._options = options ?? new List<string>();
			modPicker._selected = Mathf.Clamp(selectedIndex, 0, Mathf.Max(0, modPicker._options.Count - 1));
			GameObject val3 = new GameObject("Caption", new Type[4]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(Button),
				typeof(LayoutElement)
			});
			val3.transform.SetParent(val2.transform, false);
			RectTransform component2 = val3.GetComponent<RectTransform>();
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.offsetMin = Vector2.zero;
			component2.offsetMax = Vector2.zero;
			Image component3 = val3.GetComponent<Image>();
			((Graphic)component3).color = CaptionBg;
			((Graphic)component3).raycastTarget = true;
			LayoutElement component4 = val3.GetComponent<LayoutElement>();
			component4.flexibleWidth = 1f;
			component4.minHeight = 40f;
			component4.preferredHeight = 44f;
			modPicker._captionButton = val3.GetComponent<Button>();
			((Selectable)modPicker._captionButton).targetGraphic = (Graphic)(object)component3;
			((Selectable)modPicker._captionButton).transition = (Transition)1;
			ColorBlock colors = ((Selectable)modPicker._captionButton).colors;
			((ColorBlock)(ref colors)).highlightedColor = new Color(0.3f, 0.2f, 0.1f, 1f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.4f, 0.26f, 0.12f, 1f);
			((Selectable)modPicker._captionButton).colors = colors;
			if ((Object)(object)labelTemplate != (Object)null)
			{
				GameObject val4 = Object.Instantiate<GameObject>(((Component)labelTemplate).gameObject, val3.transform);
				((Object)val4).name = "CaptionText";
				modPicker._captionText = val4.GetComponent<TMP_Text>();
				RectTransform component5 = val4.GetComponent<RectTransform>();
				component5.anchorMin = Vector2.zero;
				component5.anchorMax = Vector2.one;
				component5.offsetMin = new Vector2(12f, 4f);
				component5.offsetMax = new Vector2(-12f, -4f);
				LayoutElement component6 = val4.GetComponent<LayoutElement>();
				if ((Object)(object)component6 != (Object)null)
				{
					Object.Destroy((Object)(object)component6);
				}
			}
			if ((Object)(object)modPicker._captionText != (Object)null)
			{
				((Graphic)modPicker._captionText).color = UiTheme.ValueWhite;
				modPicker._captionText.alignment = (TextAlignmentOptions)4097;
				((Graphic)modPicker._captionText).raycastTarget = false;
			}
			((UnityEventBase)modPicker._captionButton.onClick).RemoveAllListeners();
			((UnityEvent)modPicker._captionButton.onClick).AddListener(new UnityAction(modPicker.ToggleList));
			modPicker.RefreshCaption();
			return modPicker;
		}

		internal void SetOptions(List<string> options, int selectedIndex)
		{
			_options = options ?? new List<string>();
			_selected = Mathf.Clamp(selectedIndex, 0, Mathf.Max(0, _options.Count - 1));
			RefreshCaption();
			if ((Object)(object)_listRoot != (Object)null && _listRoot.activeSelf)
			{
				RebuildListRows();
			}
		}

		internal void CloseList()
		{
			if ((Object)(object)_listRoot != (Object)null)
			{
				_listRoot.SetActive(false);
			}
			if ((Object)(object)_blocker != (Object)null)
			{
				_blocker.SetActive(false);
			}
			if ((Object)(object)Settings.instance != (Object)null)
			{
				Settings.instance.BlockNavigation(false);
			}
		}

		private void RefreshCaption()
		{
			if (!((Object)(object)_captionText == (Object)null))
			{
				_captionText.text = ((_options.Count == 0) ? "(No mod configs found)" : _options[Mathf.Clamp(_selected, 0, _options.Count - 1)]);
			}
		}

		private void ToggleList()
		{
			if ((Object)(object)_listRoot != (Object)null && _listRoot.activeSelf)
			{
				CloseList();
				return;
			}
			EnsureListRoot();
			RebuildListRows();
			BringToFront();
			_blocker.SetActive(true);
			_listRoot.SetActive(true);
			if ((Object)(object)_scroll != (Object)null)
			{
				_scroll.verticalNormalizedPosition = 1f;
			}
		}

		private void EnsureListRoot()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Expected O, but got Unknown
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Expected O, but got Unknown
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Expected O, but got Unknown
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			//IL_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_0497: Expected O, but got Unknown
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_050d: Unknown result type (might be due to invalid IL or missing references)
			//IL_052f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0539: Expected O, but got Unknown
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_listRoot != (Object)null))
			{
				Transform val = FindRootUiCanvasTransform();
				_blocker = new GameObject("ModPickerBlocker", new Type[5]
				{
					typeof(RectTransform),
					typeof(Image),
					typeof(Button),
					typeof(Canvas),
					typeof(GraphicRaycaster)
				});
				_blocker.transform.SetParent(val, false);
				Canvas component = _blocker.GetComponent<Canvas>();
				component.overrideSorting = true;
				component.sortingOrder = 9000;
				RectTransform component2 = _blocker.GetComponent<RectTransform>();
				component2.anchorMin = Vector2.zero;
				component2.anchorMax = Vector2.one;
				component2.offsetMin = Vector2.zero;
				component2.offsetMax = Vector2.zero;
				Image component3 = _blocker.GetComponent<Image>();
				((Graphic)component3).color = new Color(0f, 0f, 0f, 0.35f);
				((Graphic)component3).raycastTarget = true;
				Button component4 = _blocker.GetComponent<Button>();
				((Selectable)component4).transition = (Transition)0;
				((UnityEvent)component4.onClick).AddListener(new UnityAction(CloseList));
				_blocker.SetActive(false);
				_listRoot = new GameObject("ModPickerList", new Type[4]
				{
					typeof(RectTransform),
					typeof(Image),
					typeof(Canvas),
					typeof(GraphicRaycaster)
				});
				_listRoot.transform.SetParent(val, false);
				Canvas component5 = _listRoot.GetComponent<Canvas>();
				component5.overrideSorting = true;
				component5.sortingOrder = 9001;
				Canvas component6 = ((Component)val).GetComponent<Canvas>();
				if ((Object)(object)component6 != (Object)null)
				{
					component5.renderMode = component6.renderMode;
					component5.worldCamera = component6.worldCamera;
				}
				Image component7 = _listRoot.GetComponent<Image>();
				((Graphic)component7).color = PanelColor;
				((Graphic)component7).raycastTarget = true;
				GameObject val2 = new GameObject("Scroll", new Type[4]
				{
					typeof(RectTransform),
					typeof(ScrollRect),
					typeof(Image),
					typeof(RectMask2D)
				});
				val2.transform.SetParent(_listRoot.transform, false);
				RectTransform component8 = val2.GetComponent<RectTransform>();
				component8.anchorMin = Vector2.zero;
				component8.anchorMax = Vector2.one;
				component8.offsetMin = new Vector2(6f, 6f);
				component8.offsetMax = new Vector2(-6f, -6f);
				Image component9 = val2.GetComponent<Image>();
				((Graphic)component9).color = new Color(0f, 0f, 0f, 0.01f);
				((Graphic)component9).raycastTarget = true;
				GameObject val3 = new GameObject("Scrollbar", new Type[3]
				{
					typeof(RectTransform),
					typeof(Image),
					typeof(Scrollbar)
				});
				val3.transform.SetParent(_listRoot.transform, false);
				RectTransform component10 = val3.GetComponent<RectTransform>();
				component10.anchorMin = new Vector2(1f, 0f);
				component10.anchorMax = new Vector2(1f, 1f);
				component10.pivot = new Vector2(1f, 1f);
				component10.sizeDelta = new Vector2(18f, -12f);
				component10.anchoredPosition = new Vector2(-4f, 0f);
				((Graphic)val3.GetComponent<Image>()).color = new Color(0.05f, 0.04f, 0.03f, 0.9f);
				GameObject val4 = new GameObject("Handle", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				val4.transform.SetParent(val3.transform, false);
				RectTransform component11 = val4.GetComponent<RectTransform>();
				component11.anchorMin = Vector2.zero;
				component11.anchorMax = Vector2.one;
				component11.offsetMin = Vector2.zero;
				component11.offsetMax = Vector2.zero;
				Image component12 = val4.GetComponent<Image>();
				((Graphic)component12).color = UiTheme.AccentOrange;
				Scrollbar component13 = val3.GetComponent<Scrollbar>();
				component13.direction = (Direction)2;
				component13.handleRect = component11;
				((Selectable)component13).targetGraphic = (Graphic)(object)component12;
				((Selectable)component13).transition = (Transition)0;
				GameObject val5 = new GameObject("Content", new Type[3]
				{
					typeof(RectTransform),
					typeof(VerticalLayoutGroup),
					typeof(ContentSizeFitter)
				});
				val5.transform.SetParent(val2.transform, false);
				RectTransform component14 = val5.GetComponent<RectTransform>();
				component14.anchorMin = new Vector2(0f, 1f);
				component14.anchorMax = new Vector2(1f, 1f);
				component14.pivot = new Vector2(0.5f, 1f);
				component14.anchoredPosition = Vector2.zero;
				component14.sizeDelta = new Vector2(0f, 0f);
				VerticalLayoutGroup component15 = val5.GetComponent<VerticalLayoutGroup>();
				((HorizontalOrVerticalLayoutGroup)component15).spacing = 3f;
				((LayoutGroup)component15).padding = new RectOffset(4, 22, 4, 4);
				((LayoutGroup)component15).childAlignment = (TextAnchor)0;
				((HorizontalOrVerticalLayoutGroup)component15).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)component15).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)component15).childForceExpandHeight = false;
				((HorizontalOrVerticalLayoutGroup)component15).childForceExpandWidth = true;
				ContentSizeFitter component16 = val5.GetComponent<ContentSizeFitter>();
				component16.verticalFit = (FitMode)2;
				component16.horizontalFit = (FitMode)0;
				_scroll = val2.GetComponent<ScrollRect>();
				_scroll.content = component14;
				_scroll.viewport = component8;
				_scroll.horizontal = false;
				_scroll.vertical = true;
				_scroll.movementType = (MovementType)2;
				_scroll.scrollSensitivity = 80f;
				_scroll.inertia = true;
				_scroll.verticalScrollbar = component13;
				_scroll.verticalScrollbarVisibility = (ScrollbarVisibility)0;
				val2.AddComponent<ModPickerScrollRelay>().Init(_scroll);
				_listContent = val5.transform;
				_listRoot.SetActive(false);
			}
		}

		private void BringToFront()
		{
			Transform val = FindRootUiCanvasTransform();
			if ((Object)(object)_blocker != (Object)null)
			{
				_blocker.transform.SetParent(val, false);
				_blocker.transform.SetAsLastSibling();
				Canvas component = _blocker.GetComponent<Canvas>();
				if ((Object)(object)component != (Object)null)
				{
					component.overrideSorting = true;
					component.sortingOrder = 9000;
				}
			}
			if ((Object)(object)_listRoot != (Object)null)
			{
				_listRoot.transform.SetParent(val, false);
				_listRoot.transform.SetAsLastSibling();
				Canvas component2 = _listRoot.GetComponent<Canvas>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.overrideSorting = true;
					component2.sortingOrder = 9001;
				}
				PositionListUnderCaption(_listRoot.GetComponent<RectTransform>());
			}
		}

		private Transform FindRootUiCanvasTransform()
		{
			Canvas componentInParent = ((Component)this).GetComponentInParent<Canvas>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return ((Component)(((Object)(object)componentInParent.rootCanvas != (Object)null) ? componentInParent.rootCanvas : componentInParent)).transform;
			}
			if ((Object)(object)Settings.instance != (Object)null)
			{
				Canvas componentInParent2 = ((Component)Settings.instance).GetComponentInParent<Canvas>();
				if ((Object)(object)componentInParent2 != (Object)null)
				{
					return ((Component)(((Object)(object)componentInParent2.rootCanvas != (Object)null) ? componentInParent2.rootCanvas : componentInParent2)).transform;
				}
			}
			return ((Component)this).transform.root;
		}

		private void PositionListUnderCaption(RectTransform listRt)
		{
			//IL_003c: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = ((Component)_captionButton).GetComponent<RectTransform>();
			Transform parent = ((Transform)listRt).parent;
			RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
			if (!((Object)(object)component == (Object)null) && !((Object)(object)val == (Object)null))
			{
				Canvas component2 = ((Component)listRt).GetComponent<Canvas>();
				Camera val2 = (((Object)(object)component2 != (Object)null && (int)component2.renderMode != 0) ? component2.worldCamera : null);
				Vector3[] array = (Vector3[])(object)new Vector3[4];
				component.GetWorldCorners(array);
				Vector2 val3 = RectTransformUtility.WorldToScreenPoint(val2, array[0]);
				Vector2 val4 = RectTransformUtility.WorldToScreenPoint(val2, array[2]);
				Vector2 val5 = default(Vector2);
				RectTransformUtility.ScreenPointToLocalPointInRectangle(val, val3, val2, ref val5);
				Vector2 val6 = default(Vector2);
				RectTransformUtility.ScreenPointToLocalPointInRectangle(val, val4, val2, ref val6);
				float num = Mathf.Max(360f, Mathf.Abs(val6.x - val5.x) + 40f);
				float num2 = Mathf.Clamp(56f + (float)_options.Count * 38f, 200f, 480f);
				listRt.anchorMin = new Vector2(0.5f, 0.5f);
				listRt.anchorMax = new Vector2(0.5f, 0.5f);
				listRt.pivot = new Vector2(0.5f, 1f);
				listRt.sizeDelta = new Vector2(num, num2);
				listRt.anchoredPosition = new Vector2((val5.x + val6.x) * 0.5f, val5.y - 8f);
			}
		}

		private void RebuildListRows()
		{
			if ((Object)(object)_listContent == (Object)null)
			{
				return;
			}
			for (int num = _listContent.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)_listContent.GetChild(num)).gameObject);
			}
			if (_options.Count == 0)
			{
				CreateRowButton("(No mod configs found)", -1);
				return;
			}
			for (int i = 0; i < _options.Count; i++)
			{
				CreateRowButton(_options[i], i);
			}
		}

		private void CreateRowButton(string text, int index)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Expected O, but got Unknown
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Mod_" + index, new Type[4]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(Button),
				typeof(LayoutElement)
			});
			val.transform.SetParent(_listContent, false);
			LayoutElement component = val.GetComponent<LayoutElement>();
			component.minHeight = 36f;
			component.preferredHeight = 38f;
			component.flexibleWidth = 1f;
			Image component2 = val.GetComponent<Image>();
			((Graphic)component2).color = ((index == _selected) ? RowSelected : RowColor);
			((Graphic)component2).raycastTarget = true;
			Button component3 = val.GetComponent<Button>();
			((Selectable)component3).targetGraphic = (Graphic)(object)component2;
			((Selectable)component3).transition = (Transition)1;
			ColorBlock colors = ((Selectable)component3).colors;
			((ColorBlock)(ref colors)).highlightedColor = RowSelected;
			((ColorBlock)(ref colors)).pressedColor = new Color(0.65f, 0.4f, 0.12f, 1f);
			((Selectable)component3).colors = colors;
			int captured = index;
			((UnityEventBase)component3.onClick).RemoveAllListeners();
			((UnityEvent)component3.onClick).AddListener((UnityAction)delegate
			{
				if (captured < 0)
				{
					CloseList();
				}
				else
				{
					_selected = captured;
					RefreshCaption();
					CloseList();
					_onPicked?.Invoke(_selected);
				}
			});
			GameObject val2;
			TMP_Text component4;
			if ((Object)(object)_labelTemplate != (Object)null)
			{
				val2 = Object.Instantiate<GameObject>(((Component)_labelTemplate).gameObject, val.transform);
				component4 = val2.GetComponent<TMP_Text>();
			}
			else
			{
				val2 = new GameObject("Text", new Type[2]
				{
					typeof(RectTransform),
					typeof(TextMeshProUGUI)
				});
				val2.transform.SetParent(val.transform, false);
				component4 = val2.GetComponent<TMP_Text>();
			}
			((Object)val2).name = "Text";
			RectTransform component5 = val2.GetComponent<RectTransform>();
			component5.anchorMin = Vector2.zero;
			component5.anchorMax = Vector2.one;
			component5.offsetMin = new Vector2(12f, 2f);
			component5.offsetMax = new Vector2(-12f, -2f);
			LayoutElement component6 = val2.GetComponent<LayoutElement>();
			if ((Object)(object)component6 != (Object)null)
			{
				Object.Destroy((Object)(object)component6);
			}
			if ((Object)(object)component4 != (Object)null)
			{
				component4.text = text ?? string.Empty;
				((Graphic)component4).color = UiTheme.ValueWhite;
				component4.alignment = (TextAlignmentOptions)4097;
				((Graphic)component4).raycastTarget = false;
				component4.overflowMode = (TextOverflowModes)1;
			}
		}

		private void OnDisable()
		{
			CloseList();
		}

		private void OnDestroy()
		{
			if ((Object)(object)_listRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_listRoot);
			}
			if ((Object)(object)_blocker != (Object)null)
			{
				Object.Destroy((Object)(object)_blocker);
			}
		}
	}
	internal sealed class ModPickerScrollRelay : MonoBehaviour, IScrollHandler, IEventSystemHandler
	{
		private ScrollRect _scroll;

		internal void Init(ScrollRect scroll)
		{
			_scroll = scroll;
		}

		public void OnScroll(PointerEventData eventData)
		{
			if (!((Object)(object)_scroll == (Object)null))
			{
				_scroll.OnScroll(eventData);
			}
		}
	}
	internal static class NativeWidgetFactory
	{
		private sealed class ToggleStateLabelBinder : MonoBehaviour
		{
			private Toggle _toggle;

			private Action<bool> _sync;

			internal void Bind(Toggle toggle, Action<bool> sync)
			{
				_toggle = toggle;
				_sync = sync;
			}

			private void LateUpdate()
			{
				if ((Object)(object)_toggle != (Object)null && _sync != null)
				{
					_sync(_toggle.isOn);
					((Behaviour)this).enabled = false;
				}
			}
		}

		internal static GuiInputField FindInputFieldTemplate(Settings settings)
		{
			FejdStartup instance = FejdStartup.instance;
			if ((Object)(object)instance?.m_csNewCharacterName != (Object)null)
			{
				ModdedWolfsConfigsPlugin.Log.LogInfo((object)"Input field template: FejdStartup.m_csNewCharacterName");
				return instance.m_csNewCharacterName;
			}
			Feedback val = FindFirstSceneObject<Feedback>();
			if ((Object)(object)val?.m_subject != (Object)null)
			{
				ModdedWolfsConfigsPlugin.Log.LogInfo((object)"Input field template: Feedback.m_subject");
				return val.m_subject;
			}
			if ((Object)(object)TextInput.instance?.m_inputField != (Object)null)
			{
				ModdedWolfsConfigsPlugin.Log.LogInfo((object)"Input field template: TextInput.m_inputField");
				return TextInput.instance.m_inputField;
			}
			if ((Object)(object)Minimap.instance?.m_nameInput != (Object)null)
			{
				ModdedWolfsConfigsPlugin.Log.LogInfo((object)"Input field template: Minimap.m_nameInput");
				return Minimap.instance.m_nameInput;
			}
			if ((Object)(object)instance?.m_newWorldName != (Object)null)
			{
				ModdedWolfsConfigsPlugin.Log.LogInfo((object)"Input field template: FejdStartup.m_newWorldName");
				return instance.m_newWorldName;
			}
			if ((Object)(object)instance?.m_serverPassword != (Object)null)
			{
				ModdedWolfsConfigsPlugin.Log.LogInfo((object)"Input field template: FejdStartup.m_serverPassword");
				return instance.m_serverPassword;
			}
			if ((Object)(object)val?.m_text != (Object)null)
			{
				ModdedWolfsConfigsPlugin.Log.LogInfo((object)"Input field template: Feedback.m_text");
				return val.m_text;
			}
			if ((Object)(object)settings != (Object)null)
			{
				GuiInputField componentInChildren = ((Component)settings).GetComponentInChildren<GuiInputField>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					ModdedWolfsConfigsPlugin.Log.LogInfo((object)("Input field template: Settings/" + ((Object)((Component)componentInChildren).gameObject).name));
					return componentInChildren;
				}
			}
			GuiInputField val2 = FindFirstSceneObject<GuiInputField>();
			if ((Object)(object)val2 != (Object)null && !IsConsoleOrChatInput(val2))
			{
				ModdedWolfsConfigsPlugin.Log.LogInfo((object)("Input field template: scene fallback/" + ((Object)((Component)val2).gameObject).name));
				return val2;
			}
			ModdedWolfsConfigsPlugin.Log.LogError((object)"No native GuiInputField template found (Settings, Feedback, TextInput, Minimap, FejdStartup). String/hex config fields cannot be rendered. Console/Chat templates are excluded (ghost text).");
			return null;
		}

		private static bool IsConsoleOrChatInput(GuiInputField input)
		{
			if ((Object)(object)input == (Object)null)
			{
				return false;
			}
			if ((Object)(object)Console.instance != (Object)null && input == ((Terminal)Console.instance).m_input)
			{
				return true;
			}
			if ((Object)(object)Chat.instance != (Object)null)
			{
				return input == ((Terminal)Chat.instance).m_input;
			}
			return false;
		}

		internal static GuiDropdown FindDropdownTemplate(Settings settings)
		{
			GraphicsSettings val = (((Object)(object)settings != (Object)null) ? ((Component)settings).GetComponentInChildren<GraphicsSettings>(true) : null);
			if ((Object)(object)val != (Object)null)
			{
				if ((Object)(object)val.m_upscalingAlgorithmDropdown != (Object)null)
				{
					return val.m_upscalingAlgorithmDropdown;
				}
				if ((Object)(object)val.m_renderScaleDropdown != (Object)null)
				{
					return val.m_renderScaleDropdown;
				}
				if ((Object)(object)val.m_resolutionDropdown != (Object)null)
				{
					return val.m_resolutionDropdown;
				}
			}
			if ((Object)(object)settings != (Object)null)
			{
				GuiDropdown componentInChildren = ((Component)settings).GetComponentInChildren<GuiDropdown>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					return componentInChildren;
				}
			}
			return FindFirstSceneObject<GuiDropdown>();
		}

		internal static Slider FindSliderTemplate(Settings settings)
		{
			AccessibilitySettings val = (((Object)(object)settings != (Object)null) ? ((Component)settings).GetComponentInChildren<AccessibilitySettings>(true) : null);
			if ((Object)(object)val?.m_guiScaleSlider != (Object)null)
			{
				return val.m_guiScaleSlider;
			}
			AudioSettings val2 = (((Object)(object)settings != (Object)null) ? ((Component)settings).GetComponentInChildren<AudioSettings>(true) : null);
			if ((Object)(object)val2?.m_volumeSlider != (Object)null)
			{
				return val2.m_volumeSlider;
			}
			GraphicsSettings val3 = (((Object)(object)settings != (Object)null) ?