Decompiled source of Mod Menu v1.1.3

BepInEx/plugins/ModMenu/ModMenu.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ComputerysModdingUtilities;
using DG.Tweening;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ModMenu.Api;
using ModMenu.Behaviours.ModList;
using ModMenu.Behaviours.OptionList;
using ModMenu.Behaviours.OptionList.Dummies;
using ModMenu.Behaviours.OptionList.ValueControllers;
using ModMenu.Mods;
using ModMenu.Options;
using ModMenu.Patches;
using ModMenu.Utils;
using Newtonsoft.Json;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: StraftatMod(true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace ModMenu
{
	internal static class ModMenuManager
	{
		public static Mod[] mods;

		public static void Init()
		{
			Dictionary<string, PluginInfo>.ValueCollection values = Chainloader.PluginInfos.Values;
			List<Mod> list = new List<Mod>();
			foreach (PluginInfo item in values)
			{
				ModInfo modInfo = default(ModInfo);
				modInfo.guid = item.Metadata.GUID;
				modInfo.name = item.Metadata.Name;
				modInfo.version = item.Metadata.Version.ToString();
				ModInfo info = modInfo;
				list.Add(new Mod(info));
			}
			mods = list.ToArray();
		}
	}
	public static class PluginInfo
	{
		public const string guid = "kestrel.straftat.modmenu";

		public const string name = "ModMenu";

		public const string version = "1.1.3";
	}
	[BepInPlugin("kestrel.straftat.modmenu", "ModMenu", "1.1.3")]
	public class Plugin : BaseUnityPlugin
	{
		private enum TestEnum
		{
			OptionA,
			OptionB,
			OptionC,
			OptionD,
			AndSoOn
		}

		private enum TestEnum2
		{
			AnotherTestEnum,
			IsntThisCool,
			HeyHiiiiHeyLookAtMe,
			ColonThree
		}

		internal static ManualLogSource Logger;

		private static ConfigEntry<string> m_superSecretConfigEntry;

		public static readonly string loadBearingColonThree = ":3";

		public static Plugin Instance { get; private set; }

		private void Awake()
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			if (loadBearingColonThree != ":3")
			{
				Application.Quit();
			}
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			CreateExampleConfigs();
			Assets.Init();
			ModMenuCustomisation.RegisterContentBuilder(CustomContentBuilder);
			ModMenuCustomisation.HideEntry((ConfigEntryBase)(object)m_superSecretConfigEntry);
			ModMenuCustomisation.SetPluginDescription("Configure your mods ingame!");
			ModMenuCustomisation.SetPluginIcon(Assets.ModMenuModIcon);
			new Harmony("kestrel.straftat.modmenu").PatchAll();
			Logger.LogInfo((object)"Hiiiiiiiiiiii :3");
		}

		private void CreateExampleConfigs()
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Expected O, but got Unknown
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Expected O, but got Unknown
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: 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_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Expected O, but got Unknown
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			((BaseUnityPlugin)this).Config.Bind<bool>("Examples.Basic", "Bool", false, "A bool");
			((BaseUnityPlugin)this).Config.Bind<string>("Examples.Basic", "String", "Hiiiii", "A string");
			((BaseUnityPlugin)this).Config.Bind<float>("Examples.Numeric", "Unrestricted Float", 0f, "A float");
			((BaseUnityPlugin)this).Config.Bind<float>("Examples.Numeric", "Acceptable Range Float", 0f, new ConfigDescription("A float with a range restriction", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-100f, 100f), Array.Empty<object>()));
			((BaseUnityPlugin)this).Config.Bind<float>("Examples.Numeric", "Acceptable List Float", 0f, new ConfigDescription("A float with a list of acceptable values", (AcceptableValueBase)(object)new AcceptableValueList<float>(new float[6] { 0f, 0.5f, 1f, 1.5f, 2f, 10f }), Array.Empty<object>()));
			((BaseUnityPlugin)this).Config.Bind<int>("Examples.Numeric", "Unrestricted Int", 0, "An int");
			((BaseUnityPlugin)this).Config.Bind<int>("Examples.Numeric", "Acceptable Range Int", 0, new ConfigDescription("An int with a range restriction", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-10, 10), Array.Empty<object>()));
			((BaseUnityPlugin)this).Config.Bind<int>("Examples.Numeric", "Acceptable List Int", 0, new ConfigDescription("An int with a list of acceptable values", (AcceptableValueBase)(object)new AcceptableValueList<int>(new int[7] { 0, 1, 2, 3, 4, 5, 10 }), Array.Empty<object>()));
			((BaseUnityPlugin)this).Config.Bind<uint>("Examples.Numeric", "UInt", 0u, "An unsigned int");
			((BaseUnityPlugin)this).Config.Bind<sbyte>("Examples.Numeric", "SByte", (sbyte)0, "A signed byte");
			((BaseUnityPlugin)this).Config.Bind<byte>("Examples.Numeric", "Byte", (byte)0, "A byte");
			((BaseUnityPlugin)this).Config.Bind<Vector2>("Examples.UnityTypes", "Unrestricted Vector2", Vector2.zero, "A Vector2");
			((BaseUnityPlugin)this).Config.Bind<Vector2>("Examples.UnityTypes", "Acceptable List Vector2", Vector2.zero, new ConfigDescription("A Vector2 with a list of acceptable values", (AcceptableValueBase)(object)new AcceptableValueList<Vector2>((Vector2[])(object)new Vector2[6]
			{
				Vector2.zero,
				Vector2.one,
				Vector2.up,
				Vector2.down,
				Vector2.left,
				Vector2.right
			}), Array.Empty<object>()));
			((BaseUnityPlugin)this).Config.Bind<Vector3>("Examples.UnityTypes", "Vector3", Vector3.zero, "A Vector3");
			((BaseUnityPlugin)this).Config.Bind<Vector4>("Examples.UnityTypes", "Vector4", Vector4.zero, "A Vector4");
			((BaseUnityPlugin)this).Config.Bind<Quaternion>("Examples.UnityTypes", "Quaternion", Quaternion.identity, "A Quaternion");
			((BaseUnityPlugin)this).Config.Bind<Color>("Examples.UnityTypes", "Color", Color.white, "A Color");
			((BaseUnityPlugin)this).Config.Bind<TestEnum>("Examples.Other", "Enum", TestEnum.OptionA, "An enum");
			((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Examples.Other", "Keyboard Shortcut", new KeyboardShortcut((KeyCode)285, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "A keyboard shortcut");
			((BaseUnityPlugin)this).Config.Bind<KeyCode>("Examples.Other", "KeyCode", (KeyCode)97, "A keycode");
			m_superSecretConfigEntry = ((BaseUnityPlugin)this).Config.Bind<string>("Examples.Secret", "Super Secret Entry", ":3", "shhh");
			m_superSecretConfigEntry.SettingChanged += delegate
			{
				PauseManager.Instance.WriteOfflineLog(">:3");
			};
		}

		private static void CustomContentBuilder(OptionListContext c)
		{
			//IL_00c6: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: 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_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			c.InsertHeader(13, "Custom Section 1");
			((Component)c.InsertTextBox(14, "This section was generated with the Mod Menu API! With it, you can add custom ui elements anywhere in your mod's config page. Go to Assets/Scripts/Plugin.cs in the mod's source code to see example usage of the API.")).GetComponent<LayoutElement>().preferredHeight = 128f;
			c.InsertButton(15, "", "A very interesting button", delegate
			{
				PauseManager.Instance.WriteOfflineLog("Button pressed!");
			});
			c.InsertButton(16, "Plugins Directory", "Show Path", delegate
			{
				string pluginPath = Paths.PluginPath;
				PauseManager.Instance.WriteOfflineLog("Plugins directory: " + pluginPath);
			});
			c.AppendHeader("Custom Section 2");
			c.AppendTextBox("Another custom section!");
			c.AppendTextBox("With some colored text! :3").Color = new Color(0.77f, 0.53f, 1f);
			TestEnum2 dropdownValue = TestEnum2.AnotherTestEnum;
			c.AppendDropdown("Custom Dropdown", () => dropdownValue, delegate(TestEnum2 value)
			{
				dropdownValue = value;
				PauseManager.Instance.WriteOfflineLog($"dropdownValue is {dropdownValue}");
			});
			bool boolValue = false;
			c.AppendCheckbox("Custom Checkbox", () => boolValue, delegate(bool value)
			{
				boolValue = value;
				PauseManager.Instance.WriteOfflineLog($"checkboxValue is {value}");
			});
			Color colorValue = new Color(0.77f, 0.53f, 1f);
			c.AppendColorInput("Custom Color Input", () => colorValue, delegate(Color value)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				colorValue = value;
				PauseManager.Instance.WriteOfflineLog($"colorValue is {value}");
			});
			string stringValue = "hiii";
			c.AppendStringInput("Custom String Input", () => stringValue, delegate(string value)
			{
				stringValue = value;
				PauseManager.Instance.WriteOfflineLog("stringValue is " + value);
			});
			KeyboardShortcut keyboardShortcutValue = KeyboardShortcut.Empty;
			c.AppendKeyboardShortcutInput("Custom Keyboard Shortcut Input", () => keyboardShortcutValue, delegate(KeyboardShortcut value)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				keyboardShortcutValue = value;
				PauseManager.Instance.WriteOfflineLog($"keyboardShortcutValue is {value}");
			});
			KeyCode keyCodeValue = (KeyCode)0;
			c.AppendKeyCodeInput("Custom KeyCode Input", () => keyCodeValue, delegate(KeyCode value)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				keyCodeValue = value;
				PauseManager.Instance.WriteOfflineLog($"keyCodeValue is {value}");
			});
			Quaternion quaternionValue = Quaternion.identity;
			c.AppendQuaternionInput("Custom Quaternion Input", () => quaternionValue, delegate(Quaternion value)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				quaternionValue = value;
				PauseManager.Instance.WriteOfflineLog($"quaternionValue is {value}");
			});
			Vector2 vector2Value = Vector2.zero;
			c.AppendVector2Input("Custom Vector2 Input", () => vector2Value, delegate(Vector2 value)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				vector2Value = value;
				PauseManager.Instance.WriteOfflineLog($"vector2Value is {value}");
			});
			Vector3 vector3Value = Vector3.zero;
			c.AppendVector3Input("Custom Vector3 Input", () => vector3Value, delegate(Vector3 value)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				vector3Value = value;
				PauseManager.Instance.WriteOfflineLog($"vector3Value is {value}");
			});
			Vector4 vector4Value = Vector4.zero;
			c.AppendVector4Input("Custom Vector4 Input", () => vector4Value, delegate(Vector4 value)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				vector4Value = value;
				PauseManager.Instance.WriteOfflineLog($"vector4Value is {value}");
			});
			c.AppendTextBox("Some weirder stuff").Color = new Color(0.77254903f, 0.5254902f, 1f);
			float floatValue = 0f;
			Action<float> setter = delegate(float value)
			{
				floatValue = value;
				PauseManager.Instance.WriteOfflineLog($"floatValue is {floatValue}");
			};
			NumericInputFieldValueController inputField = c.AppendNumericInputField("Custom Float Input", () => floatValue, setter);
			NumericSliderValueController slider = c.AppendNumericSlider("Custom Float Slider", () => floatValue, setter, 0f, 100f);
			NumericInputFieldValueController numericInputFieldValueController = inputField;
			numericInputFieldValueController.setter = (Action<object>)Delegate.Combine(numericInputFieldValueController.setter, (Action<object>)delegate
			{
				slider.UpdateAppearance();
			});
			NumericSliderValueController numericSliderValueController = slider;
			numericSliderValueController.setter = (Action<object>)Delegate.Combine(numericSliderValueController.setter, (Action<object>)delegate
			{
				inputField.UpdateAppearance();
			});
			int sliderMin = -200;
			int sliderMax = 200;
			float floatValue2 = 0f;
			NumericSliderValueController floatSlider2 = c.AppendNumericSlider("Custom Float Slider 2", () => floatValue2, delegate(float value)
			{
				floatValue2 = value;
				PauseManager.Instance.WriteOfflineLog($"floatValue2 is {floatValue2}");
			}, sliderMin, sliderMax);
			NumericSliderValueController minSlider = c.AppendNumericSlider("Slider 2 Min (int slider example)", () => sliderMin, delegate(int value)
			{
				sliderMin = value;
				floatSlider2.slider.minValue = sliderMin;
			}, -1000f, sliderMax - 5);
			NumericSliderValueController maxSlider = c.AppendNumericSlider("Slider 2 Max (int slider example)", () => sliderMax, delegate(int value)
			{
				sliderMax = value;
				floatSlider2.slider.maxValue = sliderMax;
			}, sliderMin + 5, 1000f);
			NumericSliderValueController numericSliderValueController2 = minSlider;
			numericSliderValueController2.setter = (Action<object>)Delegate.Combine(numericSliderValueController2.setter, (Action<object>)delegate
			{
				maxSlider.slider.minValue = sliderMin + 5;
			});
			NumericSliderValueController numericSliderValueController3 = maxSlider;
			numericSliderValueController3.setter = (Action<object>)Delegate.Combine(numericSliderValueController3.setter, (Action<object>)delegate
			{
				minSlider.slider.maxValue = sliderMax - 5;
			});
		}
	}
}
namespace ModMenu.Utils
{
	internal static class AcceptableValueBaseExtensions
	{
		public static string HumanizedString(this AcceptableValueBase avb)
		{
			Type type = ((object)avb).GetType();
			if (avb.IsAcceptableValueRange())
			{
				object value = type.GetProperty("MinValue").GetValue(avb);
				object value2 = type.GetProperty("MaxValue").GetValue(avb);
				return "Accepts " + value?.ToString() + " to " + value2;
			}
			if (avb.IsAcceptableValueList())
			{
				object[] array = ((IEnumerable)type.GetProperty("AcceptableValues").GetValue(avb)).Cast<object>().ToArray();
				return "Accepts " + string.Join(", ", from v in array.SkipLast(1)
					select v.ToString()) + " and " + array[^1];
			}
			throw new NotSupportedException($"Type \"{type}\" is not supported.");
		}

		public static bool IsAcceptableValueList(this AcceptableValueBase avb)
		{
			return ((object)avb).GetType().GetGenericTypeDefinition() == typeof(AcceptableValueList<>);
		}

		public static bool IsAcceptableValueRange(this AcceptableValueBase avb)
		{
			return ((object)avb).GetType().GetGenericTypeDefinition() == typeof(AcceptableValueRange<>);
		}
	}
	internal static class Assets
	{
		private static AssetBundle m_bundle;

		public static Sprite DefaultModIcon { get; private set; }

		public static Sprite ModMenuModIcon { get; private set; }

		public static GameObject CategoryHeader { get; private set; }

		public static GameObject IntegralSliderOption { get; private set; }

		public static GameObject FloatingSliderOption { get; private set; }

		public static GameObject IntegralInputFieldOption { get; private set; }

		public static GameObject FloatingInputFieldOption { get; private set; }

		public static GameObject BoolCheckboxOption { get; private set; }

		public static GameObject StringInputFieldOption { get; private set; }

		public static GameObject EnumDropdownOption { get; private set; }

		public static GameObject KeyCodeOption { get; private set; }

		public static GameObject KeyboardShortcutOption { get; private set; }

		public static GameObject AcceptableListDropdownOption { get; private set; }

		public static GameObject Vector2Option { get; private set; }

		public static GameObject Vector3Option { get; private set; }

		public static GameObject Vector4Option { get; private set; }

		public static GameObject QuaternionOption { get; private set; }

		public static GameObject ColorOption { get; private set; }

		public static GameObject TextDummy { get; private set; }

		public static GameObject ButtonDummy { get; private set; }

		internal static T Load<T>(string name) where T : Object
		{
			return m_bundle.LoadAsset<T>(name);
		}

		public static void Init()
		{
			Plugin.Logger.LogInfo((object)"Loading assets...");
			m_bundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "modmenu"));
			DefaultModIcon = Assets.Load<Sprite>("NoIcon");
			ModMenuModIcon = Assets.Load<Sprite>("ModIcon");
			CategoryHeader = Assets.Load<GameObject>("CategoryHeader");
			IntegralSliderOption = Assets.Load<GameObject>("IntegralSliderOption");
			FloatingSliderOption = Assets.Load<GameObject>("FloatingSliderOption");
			IntegralInputFieldOption = Assets.Load<GameObject>("IntegralInputFieldOption");
			FloatingInputFieldOption = Assets.Load<GameObject>("FloatingInputFieldOption");
			BoolCheckboxOption = Assets.Load<GameObject>("BoolCheckboxOption");
			StringInputFieldOption = Assets.Load<GameObject>("StringInputFieldOption");
			EnumDropdownOption = Assets.Load<GameObject>("EnumDropdownOption");
			KeyCodeOption = Assets.Load<GameObject>("KeyCodeOption");
			KeyboardShortcutOption = Assets.Load<GameObject>("KeyboardShortcutOption");
			AcceptableListDropdownOption = Assets.Load<GameObject>("AcceptableListDropdownOption");
			Vector2Option = Assets.Load<GameObject>("Vector2Option");
			Vector3Option = Assets.Load<GameObject>("Vector3Option");
			Vector4Option = Assets.Load<GameObject>("Vector4Option");
			QuaternionOption = Assets.Load<GameObject>("QuaternionOption");
			ColorOption = Assets.Load<GameObject>("ColorOption");
			TextDummy = Assets.Load<GameObject>("TextDummy");
			ButtonDummy = Assets.Load<GameObject>("ButtonDummy");
			Plugin.Logger.LogInfo((object)"Assets loaded!");
		}
	}
	internal static class BepInExUtils
	{
		internal static Dictionary<Assembly, PluginInfo> PluginInfoCache { get; } = new Dictionary<Assembly, PluginInfo>();


		internal static Dictionary<PluginInfo, string> PluginTypeNameCache { get; } = new Dictionary<PluginInfo, string>();


		internal static string GetPluginInfoTypeName(PluginInfo pluginInfo)
		{
			if (PluginTypeNameCache.TryGetValue(pluginInfo, out var value))
			{
				return value;
			}
			value = AccessTools.Property(typeof(PluginInfo), "TypeName").GetValue(pluginInfo) as string;
			PluginTypeNameCache.Add(pluginInfo, value);
			return value;
		}

		internal static PluginInfo GetPluginInfoFromAssembly(Assembly assembly)
		{
			if (PluginInfoCache.TryGetValue(assembly, out var value))
			{
				return value;
			}
			using (IEnumerator<PluginInfo> enumerator = Chainloader.PluginInfos.Values.Where((PluginInfo info) => assembly.GetType(GetPluginInfoTypeName(info)) != null).GetEnumerator())
			{
				if (enumerator.MoveNext())
				{
					PluginInfo current = enumerator.Current;
					PluginInfoCache.Add(assembly, current);
					return current;
				}
			}
			PluginInfoCache.Add(assembly, null);
			return null;
		}
	}
	internal static class TypeExtensions
	{
		public static bool IsIntegral(this Type type)
		{
			if (!(type == typeof(sbyte)) && !(type == typeof(byte)) && !(type == typeof(short)) && !(type == typeof(ushort)) && !(type == typeof(int)) && !(type == typeof(uint)) && !(type == typeof(long)))
			{
				return type == typeof(ulong);
			}
			return true;
		}

		public static bool IsFloating(this Type type)
		{
			if (!(type == typeof(float)) && !(type == typeof(double)))
			{
				return type == typeof(decimal);
			}
			return true;
		}
	}
}
namespace ModMenu.Patches
{
	[HarmonyPatch(typeof(PauseManager))]
	internal static class PauseManagerPatch
	{
		public static readonly HashSet<BoxedValueController> currentlyRebindingKeybindContollers = new HashSet<BoxedValueController>();

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void InitModsTab(GameObject ___optionsMenu)
		{
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Expected O, but got Unknown
			//IL_010c: 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_0150: 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)
			//IL_0158: Expected O, but got Unknown
			//IL_015d: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)___optionsMenu))
			{
				return;
			}
			((Component)___optionsMenu.transform.Find("OPTIONS HUD").GetChild(0).GetChild(3)).gameObject.SetActive(false);
			GameObject pcTab = ((Component)___optionsMenu.transform.Find("PcTab")).gameObject;
			GameObject audioTab = ((Component)___optionsMenu.transform.Find("AudioTab")).gameObject;
			GameObject graphTab = ((Component)___optionsMenu.transform.Find("GraphTab")).gameObject;
			GameObject modsTab = Object.Instantiate<GameObject>(Assets.Load<GameObject>("ModMenu"), ___optionsMenu.transform);
			((Object)modsTab).name = "ModsTab";
			modsTab.SetActive(false);
			Transform val = ___optionsMenu.transform.Find("Tabsbutton");
			Button component = Object.Instantiate<GameObject>(Assets.Load<GameObject>("ModsTabButton"), ((Component)val).transform).GetComponent<Button>();
			UnityAction val2 = default(UnityAction);
			for (int i = 0; i < val.childCount; i++)
			{
				RectTransform component2 = ((Component)val.GetChild(i)).GetComponent<RectTransform>();
				if (component2 == null)
				{
					continue;
				}
				component2.sizeDelta = new Vector2(110f, 63.21f);
				component2.anchoredPosition = new Vector2((float)(-710 + i * 110), 343.8f);
				ButtonClickedEvent onClick = ((Component)component2).GetComponent<Button>().onClick;
				UnityAction obj = val2;
				if (obj == null)
				{
					UnityAction val3 = delegate
					{
						modsTab.SetActive(false);
					};
					UnityAction val4 = val3;
					val2 = val3;
					obj = val4;
				}
				((UnityEvent)onClick).AddListener(obj);
			}
			((UnityEvent)component.onClick).AddListener((UnityAction)delegate
			{
				modsTab.SetActive(true);
				pcTab.SetActive(false);
				audioTab.SetActive(false);
				graphTab.SetActive(false);
			});
		}

		[HarmonyPatch("Menu")]
		[HarmonyPrefix]
		public static bool DoNotOpenIfRebinding()
		{
			return currentlyRebindingKeybindContollers.Count == 0;
		}
	}
}
namespace ModMenu.Options
{
	internal class AcceptableListDropdownOption : Option
	{
		public AcceptableListDropdownOption(ConfigEntryBase entry)
			: base(entry)
		{
		}

		public override GameObject GetListItemPrefab()
		{
			return Assets.AcceptableListDropdownOption;
		}
	}
	internal class BoolOption : ValueOption<bool>
	{
		public BoolOption(ConfigEntryBase entry)
			: base(entry)
		{
		}

		public override GameObject GetListItemPrefab()
		{
			return Assets.BoolCheckboxOption;
		}
	}
	internal class ColorOption : ValueOption<Color>
	{
		public ColorOption(ConfigEntryBase entry)
			: base(entry)
		{
		}

		public override GameObject GetListItemPrefab()
		{
			return Assets.ColorOption;
		}
	}
	internal class EnumDropdownOption : Option
	{
		public EnumDropdownOption(ConfigEntryBase entry)
			: base(entry)
		{
		}

		public override GameObject GetListItemPrefab()
		{
			return Assets.EnumDropdownOption;
		}
	}
	internal class FloatingInputFieldOption : Option
	{
		public FloatingInputFieldOption(ConfigEntryBase entry)
			: base(entry)
		{
		}

		public override GameObject GetListItemPrefab()
		{
			return Assets.FloatingInputFieldOption;
		}
	}
	internal class FloatingSliderOption : Option
	{
		public FloatingSliderOption(ConfigEntryBase entry)
			: base(entry)
		{
		}

		public override GameObject GetListItemPrefab()
		{
			return Assets.FloatingSliderOption;
		}
	}
	internal class IntegralInputFieldOption : Option
	{
		public IntegralInputFieldOption(ConfigEntryBase entry)
			: base(entry)
		{
		}

		public override GameObject GetListItemPrefab()
		{
			return Assets.IntegralInputFieldOption;
		}
	}
	internal class IntegralSliderOption : Option
	{
		public IntegralSliderOption(ConfigEntryBase entry)
			: base(entry)
		{
		}

		public override GameObject GetListItemPrefab()
		{
			return Assets.IntegralSliderOption;
		}
	}
	internal class KeyboardShortcutOption : ValueOption<KeyboardShortcut>
	{
		public KeyboardShortcutOption(ConfigEntryBase entry)
			: base(entry)
		{
		}

		public override GameObject GetListItemPrefab()
		{
			return Assets.KeyboardShortcutOption;
		}
	}
	internal class KeyCodeOption : ValueOption<KeyCode>
	{
		public KeyCodeOption(ConfigEntryBase entry)
			: base(entry)
		{
		}

		public override GameObject GetListItemPrefab()
		{
			return Assets.KeyCodeOption;
		}
	}
	internal abstract class Option
	{
		public string Name => BaseEntry.Definition.Key;

		public string Section => BaseEntry.Definition.Section;

		public string Description => BaseEntry.Description.Description;

		public AcceptableValueBase AcceptableValues => BaseEntry.Description.AcceptableValues;

		public ConfigEntryBase BaseEntry { get; }

		public object BoxedValue
		{
			get
			{
				return BaseEntry.BoxedValue;
			}
			set
			{
				BaseEntry.BoxedValue = value;
			}
		}

		protected Option(ConfigEntryBase entry)
		{
			BaseEntry = entry;
		}

		public abstract GameObject GetListItemPrefab();

		public void ResetToDefault()
		{
			BoxedValue = BaseEntry.DefaultValue;
		}

		public static Option CreateForEntry(ConfigEntryBase entry)
		{
			Type settingType = entry.SettingType;
			AcceptableValueBase acceptableValues = entry.Description.AcceptableValues;
			if (acceptableValues != null && acceptableValues.IsAcceptableValueList())
			{
				return new AcceptableListDropdownOption(entry);
			}
			if (settingType == typeof(bool))
			{
				return new BoolOption(entry);
			}
			if (settingType == typeof(string))
			{
				return new StringInputFieldOption(entry);
			}
			if (settingType.IsIntegral())
			{
				if (acceptableValues != null && acceptableValues.IsAcceptableValueRange())
				{
					return new IntegralSliderOption(entry);
				}
				return new IntegralInputFieldOption(entry);
			}
			if (settingType.IsFloating())
			{
				if (acceptableValues != null && acceptableValues.IsAcceptableValueRange())
				{
					return new FloatingSliderOption(entry);
				}
				return new FloatingInputFieldOption(entry);
			}
			if (settingType == typeof(KeyCode))
			{
				return new KeyCodeOption(entry);
			}
			if (settingType == typeof(KeyboardShortcut))
			{
				return new KeyboardShortcutOption(entry);
			}
			if (settingType == typeof(Vector2))
			{
				return new Vector2Option(entry);
			}
			if (settingType == typeof(Vector3))
			{
				return new Vector3Option(entry);
			}
			if (settingType == typeof(Vector4))
			{
				return new Vector4Option(entry);
			}
			if (settingType == typeof(Quaternion))
			{
				return new QuaternionOption(entry);
			}
			if (settingType == typeof(Color))
			{
				return new ColorOption(entry);
			}
			if (settingType.IsEnum && !settingType.IsDefined(typeof(FlagsAttribute), inherit: false))
			{
				return new EnumDropdownOption(entry);
			}
			throw new NotSupportedException($"Options of type \"{settingType}\" are not supported.");
		}
	}
	internal abstract class ValueOption<T> : Option
	{
		public T Value
		{
			get
			{
				return (T)base.BaseEntry.BoxedValue;
			}
			set
			{
				base.BaseEntry.BoxedValue = value;
			}
		}

		protected ValueOption(ConfigEntryBase entry)
			: base(entry)
		{
		}
	}
	internal class QuaternionOption : ValueOption<Quaternion>
	{
		public QuaternionOption(ConfigEntryBase entry)
			: base(entry)
		{
		}

		public override GameObject GetListItemPrefab()
		{
			return Assets.QuaternionOption;
		}
	}
	internal class StringInputFieldOption : ValueOption<string>
	{
		public StringInputFieldOption(ConfigEntryBase entry)
			: base(entry)
		{
		}

		public override GameObject GetListItemPrefab()
		{
			return Assets.StringInputFieldOption;
		}
	}
	internal class Vector2Option : ValueOption<Vector2>
	{
		public Vector2Option(ConfigEntryBase entry)
			: base(entry)
		{
		}

		public override GameObject GetListItemPrefab()
		{
			return Assets.Vector2Option;
		}
	}
	internal class Vector3Option : ValueOption<Vector3>
	{
		public Vector3Option(ConfigEntryBase entry)
			: base(entry)
		{
		}

		public override GameObject GetListItemPrefab()
		{
			return Assets.Vector3Option;
		}
	}
	internal class Vector4Option : ValueOption<Vector4>
	{
		public Vector4Option(ConfigEntryBase entry)
			: base(entry)
		{
		}

		public override GameObject GetListItemPrefab()
		{
			return Assets.Vector4Option;
		}
	}
}
namespace ModMenu.Mods
{
	internal class Mod
	{
		public readonly List<Option> config = new List<Option>();

		public ModInfo info;

		public readonly PluginInfo pluginInfo;

		public readonly Action<OptionListContext>? customContentBuilder;

		public bool HasAnyConfigs => config.Count > 0;

		public bool HasAdvancedMetadata { get; private set; }

		public Mod(ModInfo info)
		{
			this.info = info;
			if (Chainloader.PluginInfos.TryGetValue(info.guid, out pluginInfo))
			{
				ModMenuCustomisation.Builders.TryGetValue(info.guid, out customContentBuilder);
				LoadMetadata();
				LoadConfigEntries();
			}
		}

		private void LoadMetadata()
		{
			info.icon = Assets.DefaultModIcon;
			info.description = "No description found.";
			if (pluginInfo == null)
			{
				return;
			}
			string text = Path.GetFullPath(pluginInfo.Location);
			DirectoryInfo parent = Directory.GetParent(text);
			while (parent != null && !string.Equals(parent.Name, "plugins", StringComparison.OrdinalIgnoreCase))
			{
				text = parent.FullName;
				parent = Directory.GetParent(text);
			}
			if (text.EndsWith(".dll"))
			{
				return;
			}
			if (ModMenuCustomisation.Icons.TryGetValue(info.guid, out var value))
			{
				info.icon = value;
				HasAdvancedMetadata = true;
			}
			else
			{
				string text2 = Directory.EnumerateFiles(text, "icon.png", SearchOption.AllDirectories).FirstOrDefault();
				if (!string.IsNullOrEmpty(text2))
				{
					TryLoadIcon(text2);
				}
			}
			string text3 = Directory.EnumerateFiles(text, "manifest.json", SearchOption.AllDirectories).FirstOrDefault();
			if (!string.IsNullOrEmpty(text3))
			{
				TryLoadManifest(text3);
			}
			if (ModMenuCustomisation.Descriptions.TryGetValue(info.guid, out var value2))
			{
				info.description = value2;
				HasAdvancedMetadata = true;
			}
		}

		private void LoadConfigEntries()
		{
			foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in pluginInfo.Instance.Config)
			{
				try
				{
					if (!ModMenuCustomisation.HiddenConfigEntries.Contains(item.Value))
					{
						config.Add(Option.CreateForEntry(item.Value));
					}
				}
				catch (NotSupportedException ex)
				{
					Plugin.Logger.LogWarning((object)$"Error generating config entry \"{item.Key}\" for \"{info.name}\": {ex.Message}");
				}
			}
		}

		private bool TryLoadIcon(string path)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(256, 256);
			if (!ImageConversion.LoadImage(val, File.ReadAllBytes(path)))
			{
				return false;
			}
			info.icon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
			HasAdvancedMetadata = true;
			return true;
		}

		private bool TryLoadManifest(string path)
		{
			//IL_004d: Expected O, but got Unknown
			try
			{
				ThunderstoreManifest thunderstoreManifest = JsonConvert.DeserializeObject<ThunderstoreManifest>(File.ReadAllText(path));
				info.description = thunderstoreManifest?.Description;
				info.name = thunderstoreManifest?.Name.Replace('_', ' ');
				HasAdvancedMetadata = true;
			}
			catch (JsonException val)
			{
				JsonException val2 = val;
				Plugin.Logger.LogWarning((object)("Error trying to load manifest for \"" + info.name + "\": " + ((Exception)(object)val2).Message));
				return false;
			}
			return true;
		}
	}
	internal struct ModInfo
	{
		public string name;

		public string guid;

		public string description;

		public string version;

		public Sprite icon;
	}
	internal class ThunderstoreManifest
	{
		[JsonProperty("name")]
		public string Name { get; set; }

		[JsonProperty("version_number")]
		public string Version { get; set; }

		[JsonProperty("website_url")]
		public string WebsiteUrl { get; set; }

		[JsonProperty("description")]
		public string Description { get; set; }

		[JsonProperty("dependencies")]
		public string[] Dependencies { get; set; }
	}
}
namespace ModMenu.Behaviours
{
	internal class ModMenu : MonoBehaviour
	{
		public ModListPanel modListPanel;

		private void Awake()
		{
			ModMenuManager.Init();
		}
	}
	internal class ShowTooltip : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		public string textToShow;

		public void OnPointerEnter(PointerEventData eventData)
		{
			FloatingName.Instance.nameToShow = textToShow;
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			FloatingName.Instance.nameToShow = "";
		}
	}
}
namespace ModMenu.Behaviours.OptionList
{
	internal class OptionInfoPanel : MonoBehaviour
	{
		public TextMeshProUGUI nameText;

		public TextMeshProUGUI categoryText;

		public TextMeshProUGUI descriptionText;

		public Button resetButton;

		private void Awake()
		{
			ClearInfo();
		}

		public void PlayClickSound()
		{
			PauseManager.Instance.PlayMenuClip(PauseManager.Instance.releaseMenuClip);
		}

		public void ShowInfoFor(Option option)
		{
			ClearInfo();
			((TMP_Text)nameText).text = option.Name;
			((TMP_Text)descriptionText).text = option.Description;
			string section = option.Section;
			string name = option.BaseEntry.SettingType.Name;
			((TMP_Text)categoryText).text = section + " | " + name + " | Defaults to " + option.BaseEntry.DefaultValue;
			if (option.AcceptableValues != null)
			{
				TextMeshProUGUI obj = categoryText;
				((TMP_Text)obj).text = ((TMP_Text)obj).text + " | " + option.AcceptableValues.HumanizedString();
			}
		}

		public void ShowResetButtonFor(BoxedValueController controller)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			((Component)resetButton).gameObject.SetActive(true);
			((UnityEvent)resetButton.onClick).AddListener((UnityAction)delegate
			{
				controller.ResetValue();
				controller.UpdateAppearance();
			});
		}

		public void ClearInfo()
		{
			((UnityEventBase)resetButton.onClick).RemoveAllListeners();
			((Component)resetButton).gameObject.SetActive(false);
			((TMP_Text)nameText).text = "";
			((TMP_Text)categoryText).text = "";
			((TMP_Text)descriptionText).text = "";
		}
	}
	public class OptionListItem : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		public delegate void ItemHoverHandler();

		public TextMeshProUGUI nameText;

		public string NameText
		{
			get
			{
				return ((TMP_Text)nameText).text;
			}
			set
			{
				((TMP_Text)nameText).text = value;
			}
		}

		public event ItemHoverHandler OnItemHovered;

		public event ItemHoverHandler OnItemUnhovered;

		public void OnPointerEnter(PointerEventData eventData)
		{
			this.OnItemHovered?.Invoke();
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			this.OnItemUnhovered?.Invoke();
		}
	}
	internal class OptionListPanel : MonoBehaviour
	{
		public GameObject container;

		public OptionInfoPanel infoPanel;

		private Dictionary<string, GameObject[]> m_optionCache = new Dictionary<string, GameObject[]>();

		private string m_currentEnabledGuid = "";

		private GameObject m_noOptionsText;

		private GameObject m_noOptionsSadFace;

		private void Awake()
		{
			OptionListContext optionListContext = new OptionListContext(container.transform);
			m_noOptionsText = ((Component)optionListContext.AppendHeader("No options found")).gameObject;
			m_noOptionsSadFace = ((Component)optionListContext.AppendHeader(":c")).gameObject;
			((Object)m_noOptionsText).name = "No options found header";
			((Object)m_noOptionsSadFace).name = "No options found sad face";
			((TMP_Text)m_noOptionsSadFace.GetComponent<TextMeshProUGUI>()).fontSize = 24f;
			m_noOptionsText.SetActive(false);
			m_noOptionsSadFace.SetActive(false);
		}

		public void ShowListFor(Mod mod)
		{
			ClearList();
			m_currentEnabledGuid = mod.info.guid;
			if (m_optionCache.TryGetValue(m_currentEnabledGuid, out var value))
			{
				GameObject[] array = value;
				foreach (GameObject obj in array)
				{
					obj.SetActive(true);
					obj.GetComponent<BoxedValueController>()?.UpdateAppearance();
				}
				return;
			}
			List<GameObject> list = new List<GameObject>();
			if (!mod.HasAnyConfigs)
			{
				list.Add(m_noOptionsText);
				list.Add(m_noOptionsSadFace);
				m_noOptionsText.SetActive(true);
				m_noOptionsSadFace.SetActive(true);
			}
			else
			{
				OptionListContext optionListContext = new OptionListContext(container.transform);
				string text = "";
				foreach (Option item in mod.config)
				{
					if (item.Section != text)
					{
						TextDummy textDummy = optionListContext.AppendHeader(item.Section);
						((Object)textDummy).name = mod.info.name + "/" + item.Section;
						list.Add(((Component)textDummy).gameObject);
					}
					text = item.Section;
					GameObject val = optionListContext.AppendControllerForOption(item, infoPanel);
					((Object)val).name = mod.info.name + "/" + item.Section + "/" + item.Name;
					list.Add(val);
				}
				optionListContext = new OptionListContext(container.transform);
				try
				{
					mod.customContentBuilder?.Invoke(optionListContext);
				}
				catch (Exception arg)
				{
					Plugin.Logger.LogError((object)$"Error invoking custom content builder for {mod.info.guid}: {arg}");
				}
				list.AddRange(optionListContext.GetNewChildren());
			}
			m_optionCache[m_currentEnabledGuid] = list.ToArray();
		}

		private void ClearList()
		{
			if (m_optionCache.TryGetValue(m_currentEnabledGuid, out var value))
			{
				GameObject[] array = value;
				for (int i = 0; i < array.Length; i++)
				{
					array[i].SetActive(false);
				}
			}
		}
	}
}
namespace ModMenu.Behaviours.OptionList.ValueControllers
{
	public class BoolValueController : ValueController<bool>
	{
		public Toggle toggle;

		public void OnCheckboxValueChanged(bool value)
		{
			SetValue(value);
			UpdateAppearance();
		}

		public override void UpdateAppearance()
		{
			toggle.SetIsOnWithoutNotify(GetValue());
		}
	}
	public class ColorValueController : ValueController<Color>
	{
		public TMP_InputField inputField;

		public Image preview;

		public void OnInputFieldEndEdit(string value)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Color value2 = default(Color);
			if (ColorUtility.TryParseHtmlString(value, ref value2))
			{
				SetValue(value2);
			}
			UpdateAppearance();
		}

		public override void UpdateAppearance()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			inputField.SetTextWithoutNotify("#" + ColorUtility.ToHtmlStringRGBA(GetValue()).ToLower());
			((Graphic)preview).color = GetValue();
		}
	}
	public class DropdownValueController : BoxedValueController
	{
		public TMP_Dropdown dropdown;

		private string[] m_dropdownNames;

		private object[] m_dropdownValues;

		protected override void Setup()
		{
			dropdown.ClearOptions();
			dropdown.AddOptions(m_dropdownNames.ToList());
		}

		public void OnDropdownValueChanged(int index)
		{
			setter(m_dropdownValues[index]);
			UpdateAppearance();
		}

		public override void UpdateAppearance()
		{
			dropdown.SetValueWithoutNotify(Array.IndexOf(m_dropdownValues, getter()));
		}

		internal override void SetupFromOption(Option option)
		{
			Type settingType = option.BaseEntry.SettingType;
			if (settingType.IsEnum)
			{
				SetValuesFromEnum(settingType);
			}
			else
			{
				if (!option.AcceptableValues.IsAcceptableValueList())
				{
					throw new InvalidOperationException("Cannot setup a dropdown value controller from a non-enum option type with no acceptable value list.");
				}
				SetValuesFromOption(option);
			}
			base.SetupFromOption(option);
		}

		internal override void SetupFromValues<T>(Func<T> getter, Action<T> setter)
		{
			if (!typeof(T).IsEnum)
			{
				throw new InvalidOperationException("Cannot setup a dropdown value controller by values from a non-enum type");
			}
			SetValuesFromEnum(typeof(T));
			base.SetupFromValues(getter, setter);
		}

		private void SetValuesFromEnum(Type enumType)
		{
			m_dropdownNames = Enum.GetNames(enumType);
			m_dropdownValues = Enum.GetValues(enumType).Cast<object>().ToArray();
		}

		private void SetValuesFromOption(Option option)
		{
			AcceptableValueBase acceptableValues = option.AcceptableValues;
			m_dropdownValues = ((IEnumerable)((object)acceptableValues).GetType().GetProperty("AcceptableValues").GetValue(acceptableValues)).Cast<object>().ToArray();
			m_dropdownNames = m_dropdownValues.Select((object v) => v.ToString()).ToArray();
		}
	}
	public abstract class KeybindValueController<T> : ValueController<T>
	{
		public TextMeshProUGUI buttonText;

		protected bool rebinding;

		protected KeyCode[] keysToCheck;

		protected override void Setup()
		{
			keysToCheck = UnityInput.Current.SupportedKeyCodes.Except((IEnumerable<KeyCode>)(object)new KeyCode[3]
			{
				(KeyCode)323,
				default(KeyCode),
				(KeyCode)27
			}).ToArray();
		}

		public void OnRebindButtonPressed()
		{
			if (!rebinding)
			{
				StartRebinding();
			}
			else
			{
				StopRebinding();
			}
			UpdateAppearance();
		}

		public override void ResetValue()
		{
			base.ResetValue();
			StopRebinding();
		}

		public override void UpdateAppearance()
		{
			((TMP_Text)buttonText).text = (rebinding ? "Cancel" : GetValue().ToString());
		}

		protected abstract void UpdateRebinding();

		protected void StartRebinding()
		{
			rebinding = true;
			PauseManagerPatch.currentlyRebindingKeybindContollers.Add(this);
			UpdateAppearance();
		}

		protected void StopRebinding()
		{
			rebinding = false;
			PauseManagerPatch.currentlyRebindingKeybindContollers.Remove(this);
			UpdateAppearance();
		}

		private void OnDisable()
		{
			StopRebinding();
		}

		private void Update()
		{
			if (rebinding)
			{
				UpdateRebinding();
			}
		}
	}
	public class KeyboardShortcutValueController : KeybindValueController<KeyboardShortcut>
	{
		protected override void UpdateRebinding()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown((KeyCode)27))
			{
				SetValue(KeyboardShortcut.Empty);
				StopRebinding();
				return;
			}
			KeyCode[] array = keysToCheck;
			foreach (KeyCode val in array)
			{
				if (Input.GetKeyUp(val))
				{
					SetValue(new KeyboardShortcut(val, ((IEnumerable<KeyCode>)keysToCheck).Where((Func<KeyCode, bool>)Input.GetKey).ToArray()));
					StopRebinding();
					break;
				}
			}
		}
	}
	public class KeyCodeValueController : KeybindValueController<KeyCode>
	{
		protected override void UpdateRebinding()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown((KeyCode)27))
			{
				SetValue((KeyCode)0);
				StopRebinding();
				return;
			}
			KeyCode[] array = keysToCheck;
			foreach (KeyCode val in array)
			{
				if (Input.GetKeyUp(val))
				{
					SetValue(val);
					StopRebinding();
					break;
				}
			}
		}
	}
	public class NumericInputFieldValueController : BoxedValueController
	{
		public TMP_InputField inputField;

		private bool m_isIntegralType;

		protected override void Setup()
		{
			m_isIntegralType = base.ValueType.IsIntegral();
		}

		public void OnInputFieldEndEdit(string value)
		{
			try
			{
				object obj = Convert.ChangeType(value, base.ValueType);
				if (obj != null)
				{
					setter(obj);
				}
			}
			catch (Exception ex) when (ex is OverflowException || ex is FormatException || ex is InvalidCastException)
			{
			}
			UpdateAppearance();
		}

		public override void UpdateAppearance()
		{
			inputField.SetTextWithoutNotify(m_isIntegralType ? getter().ToString() : $"{getter():F}");
		}
	}
	public class NumericSliderValueController : BoxedValueController
	{
		public Slider slider;

		public TMP_InputField inputField;

		private bool m_isIntegralType;

		protected override void Setup()
		{
			m_isIntegralType = base.ValueType.IsIntegral();
		}

		internal override void SetupFromOption(Option option)
		{
			AcceptableValueBase acceptableValues = option.AcceptableValues;
			Type type = ((object)acceptableValues).GetType();
			slider.minValue = Convert.ToSingle(type.GetProperty("MinValue").GetValue(acceptableValues));
			slider.maxValue = Convert.ToSingle(type.GetProperty("MaxValue").GetValue(acceptableValues));
			base.SetupFromOption(option);
		}

		public void OnSliderValueChanged(float value)
		{
			object obj = Convert.ChangeType(value, base.ValueType);
			if (obj != null)
			{
				setter(obj);
			}
			UpdateAppearance();
		}

		public void OnInputFieldEndEdit(string value)
		{
			try
			{
				object obj = Convert.ChangeType(value, base.ValueType);
				if (obj != null)
				{
					setter(obj);
				}
			}
			catch (Exception ex) when (ex is OverflowException || ex is FormatException || ex is InvalidCastException)
			{
			}
			UpdateAppearance();
		}

		public override void UpdateAppearance()
		{
			object obj = getter();
			slider.SetValueWithoutNotify(Convert.ToSingle(obj));
			inputField.SetTextWithoutNotify(m_isIntegralType ? obj.ToString() : $"{obj:F}");
		}
	}
	public class QuaternionValueController : ValueController<Quaternion>
	{
		public TMP_InputField xInputField;

		public TMP_InputField yInputField;

		public TMP_InputField zInputField;

		public TMP_InputField wInputField;

		public void OnInputFieldEndEdit()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			Quaternion value = GetValue();
			float num = value.x;
			float num2 = value.y;
			float num3 = value.z;
			float num4 = value.w;
			if (float.TryParse(xInputField.text, out var result))
			{
				num = result;
			}
			if (float.TryParse(yInputField.text, out var result2))
			{
				num2 = result2;
			}
			if (float.TryParse(zInputField.text, out var result3))
			{
				num3 = result3;
			}
			if (float.TryParse(wInputField.text, out var result4))
			{
				num4 = result4;
			}
			SetValue(new Quaternion(num, num2, num3, num4));
			UpdateAppearance();
		}

		public override void UpdateAppearance()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Quaternion value = GetValue();
			xInputField.SetTextWithoutNotify(value.x.ToString("F"));
			yInputField.SetTextWithoutNotify(value.y.ToString("F"));
			zInputField.SetTextWithoutNotify(value.z.ToString("F"));
			wInputField.SetTextWithoutNotify(value.w.ToString("F"));
		}
	}
	public class StringValueController : ValueController<string>
	{
		public TMP_InputField inputField;

		public void OnInputFieldEndEdit(string value)
		{
			SetValue(value);
			UpdateAppearance();
		}

		public override void UpdateAppearance()
		{
			inputField.SetTextWithoutNotify(GetValue());
		}
	}
	public abstract class BoxedValueController : OptionListItem
	{
		public Func<object> getter;

		public Action<object> setter;

		private object m_defaultValue;

		private Tweener m_errorShake;

		public Type ValueType { get; private set; }

		private void Start()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			m_errorShake = (Tweener)(object)TweenExtensions.Pause<TweenerCore<Vector3, Vector3[], Vector3ArrayOptions>>(TweenSettingsExtensions.SetAutoKill<TweenerCore<Vector3, Vector3[], Vector3ArrayOptions>>(DOTween.Shake((DOGetter<Vector3>)(() => ((Component)this).transform.localPosition), (DOSetter<Vector3>)delegate(Vector3 p)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				((Component)this).transform.localPosition = p;
			}, 0.2f, 15f * Vector3.right, 20, 90f, true, (ShakeRandomnessMode)0), false));
		}

		public virtual void ResetValue()
		{
			setter(m_defaultValue);
		}

		public abstract void UpdateAppearance();

		protected virtual void Setup()
		{
		}

		internal virtual void SetupFromOption(Option option)
		{
			m_defaultValue = option.BaseEntry.DefaultValue;
			ValueType = option.BaseEntry.SettingType;
			getter = () => option.BoxedValue;
			setter = delegate(object value)
			{
				try
				{
					option.BoxedValue = value;
				}
				catch (Exception ex)
				{
					Tweener errorShake = m_errorShake;
					if (errorShake != null)
					{
						TweenExtensions.Restart((Tween)(object)errorShake, true, -1f);
					}
					UpdateAppearance();
					if (!(ex is InvalidOperationException))
					{
						throw;
					}
				}
			};
			Setup();
			UpdateAppearance();
		}

		internal virtual void SetupFromValues<T>(Func<T> getter, Action<T> setter)
		{
			m_defaultValue = default(T);
			ValueType = typeof(T);
			this.getter = () => getter();
			this.setter = delegate(object value)
			{
				setter((T)value);
			};
			Setup();
			UpdateAppearance();
		}
	}
	public abstract class ValueController<T> : BoxedValueController
	{
		public T GetValue()
		{
			return (T)getter();
		}

		public void SetValue(T value)
		{
			setter(value);
		}
	}
	public class Vector2ValueController : ValueController<Vector2>
	{
		public TMP_InputField xInputField;

		public TMP_InputField yInputField;

		public void OnInputFieldEndEdit()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			Vector2 value = GetValue();
			float num = value.x;
			float num2 = value.y;
			if (float.TryParse(xInputField.text, out var result))
			{
				num = result;
			}
			if (float.TryParse(yInputField.text, out var result2))
			{
				num2 = result2;
			}
			SetValue(new Vector2(num, num2));
			UpdateAppearance();
		}

		public override void UpdateAppearance()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Vector2 value = GetValue();
			xInputField.SetTextWithoutNotify(value.x.ToString("F"));
			yInputField.SetTextWithoutNotify(value.y.ToString("F"));
		}
	}
	public class Vector3ValueController : ValueController<Vector3>
	{
		public TMP_InputField xInputField;

		public TMP_InputField yInputField;

		public TMP_InputField zInputField;

		public void OnInputFieldEndEdit()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			Vector3 value = GetValue();
			float num = value.x;
			float num2 = value.y;
			float num3 = value.z;
			if (float.TryParse(xInputField.text, out var result))
			{
				num = result;
			}
			if (float.TryParse(yInputField.text, out var result2))
			{
				num2 = result2;
			}
			if (float.TryParse(zInputField.text, out var result3))
			{
				num3 = result3;
			}
			SetValue(new Vector3(num, num2, num3));
			UpdateAppearance();
		}

		public override void UpdateAppearance()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Vector3 value = GetValue();
			xInputField.SetTextWithoutNotify(value.x.ToString("F"));
			yInputField.SetTextWithoutNotify(value.y.ToString("F"));
			zInputField.SetTextWithoutNotify(value.z.ToString("F"));
		}
	}
	public class Vector4ValueController : ValueController<Vector4>
	{
		public TMP_InputField xInputField;

		public TMP_InputField yInputField;

		public TMP_InputField zInputField;

		public TMP_InputField wInputField;

		public void OnInputFieldEndEdit()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			Vector4 value = GetValue();
			float num = value.x;
			float num2 = value.y;
			float num3 = value.z;
			float num4 = value.w;
			if (float.TryParse(xInputField.text, out var result))
			{
				num = result;
			}
			if (float.TryParse(yInputField.text, out var result2))
			{
				num2 = result2;
			}
			if (float.TryParse(zInputField.text, out var result3))
			{
				num3 = result3;
			}
			if (float.TryParse(wInputField.text, out var result4))
			{
				num4 = result4;
			}
			SetValue(new Vector4(num, num2, num3, num4));
			UpdateAppearance();
		}

		public override void UpdateAppearance()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Vector4 value = GetValue();
			xInputField.SetTextWithoutNotify(value.x.ToString("F"));
			yInputField.SetTextWithoutNotify(value.y.ToString("F"));
			zInputField.SetTextWithoutNotify(value.z.ToString("F"));
			wInputField.SetTextWithoutNotify(value.w.ToString("F"));
		}
	}
}
namespace ModMenu.Behaviours.OptionList.Dummies
{
	public class ButtonDummy : OptionListItem
	{
		public TextMeshProUGUI buttonTextMeshProText;

		public Button button;

		public string ButtonText
		{
			get
			{
				return ((TMP_Text)buttonTextMeshProText).text;
			}
			set
			{
				((TMP_Text)buttonTextMeshProText).text = value;
			}
		}

		private void Start()
		{
			if (string.IsNullOrWhiteSpace(base.NameText))
			{
				((Component)button).GetComponent<LayoutElement>().flexibleWidth = 1f;
				((Component)nameText).gameObject.SetActive(false);
			}
		}
	}
	public class TextDummy : OptionListItem
	{
		public string Text
		{
			get
			{
				return ((TMP_Text)nameText).text;
			}
			set
			{
				((TMP_Text)nameText).text = value;
			}
		}

		public Color Color
		{
			get
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				return ((Graphic)nameText).color;
			}
			set
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				((Graphic)nameText).color = value;
			}
		}

		public TMP_Style Style
		{
			get
			{
				return ((TMP_Text)nameText).textStyle;
			}
			set
			{
				((TMP_Text)nameText).textStyle = value;
			}
		}

		public float FontSize
		{
			get
			{
				return ((TMP_Text)nameText).fontSize;
			}
			set
			{
				((TMP_Text)nameText).fontSize = value;
			}
		}
	}
}
namespace ModMenu.Behaviours.ModList
{
	internal class ModInfoPanel : MonoBehaviour
	{
		public TextMeshProUGUI descriptionText;

		public TextMeshProUGUI nameText;

		public TextMeshProUGUI extraInfoText;

		public Image icon;

		public ShowTooltip nameTooltip;

		private void Awake()
		{
			ClearInfo();
		}

		public void ShowInfoFor(Mod mod)
		{
			((Behaviour)icon).enabled = true;
			((TMP_Text)nameText).text = mod.info.name;
			((TMP_Text)nameText).ForceMeshUpdate(false, false);
			nameTooltip.textToShow = (((TMP_Text)nameText).isTextTruncated ? mod.info.name : "");
			((TMP_Text)descriptionText).text = mod.info.description;
			icon.sprite = mod.info.icon;
			((TMP_Text)extraInfoText).text = mod.info.guid + "\nv" + mod.info.version;
		}

		public void ClearInfo()
		{
			((Behaviour)icon).enabled = false;
			((TMP_Text)descriptionText).text = "";
			((TMP_Text)nameText).text = "";
			nameTooltip.textToShow = "";
			((TMP_Text)extraInfoText).text = "";
		}
	}
	internal class ModListItem : MonoBehaviour
	{
		public delegate void ModSelectHandler(Mod mod);

		public Image icon;

		public TextMeshProUGUI nameText;

		public TextMeshProUGUI versionText;

		private Mod m_mod;

		public Mod Mod
		{
			get
			{
				return m_mod;
			}
			set
			{
				m_mod = value;
				((TMP_Text)nameText).text = m_mod.info.name;
				((TMP_Text)versionText).text = "v" + m_mod.info.version;
				icon.sprite = m_mod.info.icon;
			}
		}

		public event ModSelectHandler OnModSelected;

		public void OnClick()
		{
			this.OnModSelected?.Invoke(Mod);
		}
	}
	internal class ModListPanel : MonoBehaviour
	{
		public GameObject container;

		public GameObject itemPrefab;

		public OptionListPanel optionListPanel;

		public ModInfoPanel modInfoPanel;

		public OptionInfoPanel optionInfoPanel;

		private void Awake()
		{
			foreach (Mod item in from m in ModMenuManager.mods
				orderby !m.HasAdvancedMetadata, m.info.name, m.info.guid
				select m)
			{
				ModListItem component = Object.Instantiate<GameObject>(itemPrefab, container.transform).GetComponent<ModListItem>();
				((Object)component).name = item.info.name;
				component.Mod = item;
				component.OnModSelected += SelectMod;
			}
		}

		private void SelectMod(Mod mod)
		{
			optionListPanel.ShowListFor(mod);
			optionInfoPanel.ClearInfo();
			modInfoPanel.ShowInfoFor(mod);
		}
	}
}
namespace ModMenu.Api
{
	public static class ModMenuCustomisation
	{
		internal static Dictionary<string, Action<OptionListContext>> Builders { get; private set; } = new Dictionary<string, Action<OptionListContext>>();


		internal static Dictionary<string, Sprite> Icons { get; private set; } = new Dictionary<string, Sprite>();


		internal static Dictionary<string, string> Descriptions { get; private set; } = new Dictionary<string, string>();


		internal static HashSet<ConfigEntryBase> HiddenConfigEntries { get; private set; } = new HashSet<ConfigEntryBase>();


		public static void RegisterContentBuilder(Action<OptionListContext> builder)
		{
			try
			{
				PluginInfo pluginInfoFromAssembly = BepInExUtils.GetPluginInfoFromAssembly(Assembly.GetCallingAssembly());
				if (pluginInfoFromAssembly != null)
				{
					Builders.Add(pluginInfoFromAssembly.Metadata.GUID, builder);
					return;
				}
				throw new InvalidOperationException("RegisterContentBuilder must be called from an assembly containing a BepInEx plugin.");
			}
			catch (ArgumentException)
			{
				throw new InvalidOperationException("RegisterContentBuilder can only be called once per assembly.");
			}
		}

		public static void HideEntry(ConfigEntryBase entry)
		{
			HiddenConfigEntries.Add(entry);
		}

		public static void HideEntries(IEnumerable<ConfigEntryBase> entries)
		{
			foreach (ConfigEntryBase entry in entries)
			{
				HiddenConfigEntries.Add(entry);
			}
		}

		public static void SetPluginIcon(Sprite icon)
		{
			try
			{
				PluginInfo pluginInfoFromAssembly = BepInExUtils.GetPluginInfoFromAssembly(Assembly.GetCallingAssembly());
				if (pluginInfoFromAssembly != null)
				{
					Icons.Add(pluginInfoFromAssembly.Metadata.GUID, icon);
					return;
				}
				throw new InvalidOperationException("SetPluginIcon must be called from an assembly containing a BepInEx plugin.");
			}
			catch (ArgumentException)
			{
				throw new InvalidOperationException("SetPluginIcon can only be called once per assembly.");
			}
		}

		public static void SetPluginDescription(string description)
		{
			try
			{
				PluginInfo pluginInfoFromAssembly = BepInExUtils.GetPluginInfoFromAssembly(Assembly.GetCallingAssembly());
				if (pluginInfoFromAssembly != null)
				{
					Descriptions.Add(pluginInfoFromAssembly.Metadata.GUID, description);
					return;
				}
				throw new InvalidOperationException("SetPluginDescription must be called from an assembly containing a BepInEx plugin.");
			}
			catch (ArgumentException)
			{
				throw new InvalidOperationException("SetPluginDescription can only be called once per assembly.");
			}
		}
	}
	public class OptionListContext
	{
		private HashSet<GameObject> m_originalChildren = new HashSet<GameObject>();

		public Transform Root { get; }

		internal OptionListContext(Transform root)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			Root = root;
			foreach (Transform item in root)
			{
				Transform val = item;
				m_originalChildren.Add(((Component)val).gameObject);
			}
		}

		internal GameObject AppendControllerForOption(Option option, OptionInfoPanel infoPanel)
		{
			GameObject val = Object.Instantiate<GameObject>(option.GetListItemPrefab(), Root);
			BoxedValueController controller = val.GetComponent<BoxedValueController>();
			controller.SetupFromOption(option);
			controller.NameText = option.Name;
			controller.OnItemHovered += delegate
			{
				infoPanel.ShowInfoFor(option);
				infoPanel.ShowResetButtonFor(controller);
			};
			return ((Component)controller).gameObject;
		}

		internal GameObject[] GetNewChildren()
		{
			if (Root.childCount == m_originalChildren.Count)
			{
				return Array.Empty<GameObject>();
			}
			List<GameObject> list = new List<GameObject>();
			for (int i = 0; i < Root.childCount; i++)
			{
				GameObject gameObject = ((Component)Root.GetChild(i)).gameObject;
				if (!m_originalChildren.Contains(gameObject))
				{
					list.Add(gameObject);
				}
			}
			return list.ToArray();
		}

		private int FindActualIndex(int index)
		{
			Transform[] array = (from Transform child in (IEnumerable)Root
				where ((Component)child).gameObject.activeSelf
				select child).ToArray();
			index = Math.Clamp(index, 0, array.Length - 1);
			return ((Component)array[index]).transform.GetSiblingIndex();
		}

		private T PrependItem<T>(T item) where T : OptionListItem
		{
			((Component)item).transform.SetAsFirstSibling();
			return item;
		}

		private T InsertItem<T>(int position, T item) where T : OptionListItem
		{
			((Component)item).transform.SetSiblingIndex(FindActualIndex(position));
			return item;
		}

		public TextDummy AppendHeader(string text)
		{
			TextDummy component = Object.Instantiate<GameObject>(Assets.CategoryHeader, Root).GetComponent<TextDummy>();
			component.Text = text;
			return component;
		}

		public TextDummy PrependHeader(string text)
		{
			return PrependItem(AppendHeader(text));
		}

		public TextDummy InsertHeader(int position, string text)
		{
			return InsertItem(position, AppendHeader(text));
		}

		public TextDummy AppendTextBox(string text)
		{
			TextDummy component = Object.Instantiate<GameObject>(Assets.TextDummy, Root).GetComponent<TextDummy>();
			component.Text = text;
			return component;
		}

		public TextDummy PrependTextBox(string text)
		{
			return PrependItem(AppendTextBox(text));
		}

		public TextDummy InsertTextBox(int position, string text)
		{
			return InsertItem(position, AppendTextBox(text));
		}

		public ButtonDummy AppendButton(string nameText, string buttonText, Action onClick)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			ButtonDummy component = Object.Instantiate<GameObject>(Assets.ButtonDummy, Root).GetComponent<ButtonDummy>();
			((UnityEvent)component.button.onClick).AddListener(new UnityAction(onClick.Invoke));
			component.ButtonText = buttonText;
			component.NameText = nameText;
			return component;
		}

		public ButtonDummy PrependButton(string nameText, string buttonText, Action onClick)
		{
			return PrependItem(PrependButton(nameText, buttonText, onClick));
		}

		public ButtonDummy InsertButton(int position, string nameText, string buttonText, Action onClick)
		{
			return InsertItem(position, AppendButton(nameText, buttonText, onClick));
		}

		private TController AppendValueController<TController, TValue>(GameObject prefab, string nameText, Func<TValue> getter, Action<TValue> setter) where TController : ValueController<TValue>
		{
			TController component = Object.Instantiate<GameObject>(prefab, Root).GetComponent<TController>();
			component.SetupFromValues(getter, setter);
			component.NameText = nameText;
			return component;
		}

		public BoolValueController AppendCheckbox(string nameText, Func<bool> getter, Action<bool> setter)
		{
			return AppendValueController<BoolValueController, bool>(Assets.BoolCheckboxOption, nameText, getter, setter);
		}

		public BoolValueController PrependCheckbox(string nameText, Func<bool> getter, Action<bool> setter)
		{
			return PrependItem(AppendCheckbox(nameText, getter, setter));
		}

		public BoolValueController InsertCheckbox(int position, string nameText, Func<bool> getter, Action<bool> setter)
		{
			return InsertItem(position, AppendCheckbox(nameText, getter, setter));
		}

		public StringValueController AppendStringInput(string nameText, Func<string> getter, Action<string> setter)
		{
			return AppendValueController<StringValueController, string>(Assets.StringInputFieldOption, nameText, getter, setter);
		}

		public StringValueController PrependStringInput(string nameText, Func<string> getter, Action<string> setter)
		{
			return PrependItem(AppendStringInput(nameText, getter, setter));
		}

		public StringValueController InsertStringInput(int position, string nameText, Func<string> getter, Action<string> setter)
		{
			return InsertItem(position, AppendStringInput(nameText, getter, setter));
		}

		public ColorValueController AppendColorInput(string nameText, Func<Color> getter, Action<Color> setter)
		{
			return AppendValueController<ColorValueController, Color>(Assets.ColorOption, nameText, getter, setter);
		}

		public ColorValueController PrependColorInput(string nameText, Func<Color> getter, Action<Color> setter)
		{
			return PrependItem(AppendColorInput(nameText, getter, setter));
		}

		public ColorValueController InsertColorInput(int position, string nameText, Func<Color> getter, Action<Color> setter)
		{
			return InsertItem(position, AppendColorInput(nameText, getter, setter));
		}

		public KeyboardShortcutValueController AppendKeyboardShortcutInput(string nameText, Func<KeyboardShortcut> getter, Action<KeyboardShortcut> setter)
		{
			return AppendValueController<KeyboardShortcutValueController, KeyboardShortcut>(Assets.KeyboardShortcutOption, nameText, getter, setter);
		}

		public KeyboardShortcutValueController PrependKeyboardShortcutInput(string nameText, Func<KeyboardShortcut> getter, Action<KeyboardShortcut> setter)
		{
			return PrependItem(AppendKeyboardShortcutInput(nameText, getter, setter));
		}

		public KeyboardShortcutValueController InsertKeyboardShortcutInput(int position, string nameText, Func<KeyboardShortcut> getter, Action<KeyboardShortcut> setter)
		{
			return InsertItem(position, AppendKeyboardShortcutInput(nameText, getter, setter));
		}

		public KeyCodeValueController AppendKeyCodeInput(string nameText, Func<KeyCode> getter, Action<KeyCode> setter)
		{
			return AppendValueController<KeyCodeValueController, KeyCode>(Assets.KeyCodeOption, nameText, getter, setter);
		}

		public KeyCodeValueController PrependKeyCodeInput(string nameText, Func<KeyCode> getter, Action<KeyCode> setter)
		{
			return PrependItem(AppendKeyCodeInput(nameText, getter, setter));
		}

		public KeyCodeValueController InsertKeyCodeInput(int position, string nameText, Func<KeyCode> getter, Action<KeyCode> setter)
		{
			return InsertItem(position, AppendKeyCodeInput(nameText, getter, setter));
		}

		public QuaternionValueController AppendQuaternionInput(string nameText, Func<Quaternion> getter, Action<Quaternion> setter)
		{
			return AppendValueController<QuaternionValueController, Quaternion>(Assets.QuaternionOption, nameText, getter, setter);
		}

		public QuaternionValueController PrependQuaternionInput(string nameText, Func<Quaternion> getter, Action<Quaternion> setter)
		{
			return PrependItem(AppendQuaternionInput(nameText, getter, setter));
		}

		public QuaternionValueController InsertQuaternionInput(int position, string nameText, Func<Quaternion> getter, Action<Quaternion> setter)
		{
			return InsertItem(position, AppendQuaternionInput(nameText, getter, setter));
		}

		public Vector2ValueController AppendVector2Input(string nameText, Func<Vector2> getter, Action<Vector2> setter)
		{
			return AppendValueController<Vector2ValueController, Vector2>(Assets.Vector2Option, nameText, getter, setter);
		}

		public Vector2ValueController PrependVector2Input(string nameText, Func<Vector2> getter, Action<Vector2> setter)
		{
			return PrependItem(AppendVector2Input(nameText, getter, setter));
		}

		public Vector2ValueController InsertVector2Input(int position, string nameText, Func<Vector2> getter, Action<Vector2> setter)
		{
			return InsertItem(position, AppendVector2Input(nameText, getter, setter));
		}

		public Vector3ValueController AppendVector3Input(string nameText, Func<Vector3> getter, Action<Vector3> setter)
		{
			return AppendValueController<Vector3ValueController, Vector3>(Assets.Vector3Option, nameText, getter, setter);
		}

		public Vector3ValueController PrependVector3Input(string nameText, Func<Vector3> getter, Action<Vector3> setter)
		{
			return PrependItem(AppendVector3Input(nameText, getter, setter));
		}

		public Vector3ValueController InsertVector3Input(int position, string nameText, Func<Vector3> getter, Action<Vector3> setter)
		{
			return InsertItem(position, AppendVector3Input(nameText, getter, setter));
		}

		public Vector4ValueController AppendVector4Input(string nameText, Func<Vector4> getter, Action<Vector4> setter)
		{
			return AppendValueController<Vector4ValueController, Vector4>(Assets.Vector4Option, nameText, getter, setter);
		}

		public Vector4ValueController PrependVector4Input(string nameText, Func<Vector4> getter, Action<Vector4> setter)
		{
			return PrependItem(AppendVector4Input(nameText, getter, setter));
		}

		public Vector4ValueController InsertVector4Input(int position, string nameText, Func<Vector4> getter, Action<Vector4> setter)
		{
			return InsertItem(position, AppendVector4Input(nameText, getter, setter));
		}

		public DropdownValueController AppendDropdown<T>(string nameText, Func<T> getter, Action<T> setter) where T : Enum
		{
			DropdownValueController component = Object.Instantiate<GameObject>(Assets.EnumDropdownOption, Root).GetComponent<DropdownValueController>();
			component.SetupFromValues(getter, setter);
			component.NameText = nameText;
			return component;
		}

		public DropdownValueController PrependDropdown<T>(string nameText, Func<T> getter, Action<T> setter) where T : Enum
		{
			return PrependItem(AppendDropdown(nameText, getter, setter));
		}

		public DropdownValueController InsertDropdown<T>(int position, string nameText, Func<T> getter, Action<T> setter) where T : Enum
		{
			return InsertItem(position, AppendDropdown(nameText, getter, setter));
		}

		public NumericInputFieldValueController AppendNumericInputField<T>(string nameText, Func<T> getter, Action<T> setter) where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
		{
			NumericInputFieldValueController component = Object.Instantiate<GameObject>(typeof(T).IsFloating() ? Assets.FloatingInputFieldOption : Assets.IntegralInputFieldOption, Root).GetComponent<NumericInputFieldValueController>();
			component.SetupFromValues(getter, setter);
			component.NameText = nameText;
			return component;
		}

		public NumericInputFieldValueController PrependNumericInputField<T>(string nameText, Func<T> getter, Action<T> setter) where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
		{
			return PrependItem(AppendNumericInputField(nameText, getter, setter));
		}

		public NumericInputFieldValueController InsertNumericInputField<T>(int position, string nameText, Func<T> getter, Action<T> setter) where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
		{
			return InsertItem(position, AppendNumericInputField(nameText, getter, setter));
		}

		public NumericSliderValueController AppendNumericSlider<T>(string nameText, Func<T> getter, Action<T> setter, float minValue, float maxValue) where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
		{
			if (minValue >= maxValue)
			{
				throw new ArgumentException("minValue must be < maxValue");
			}
			NumericSliderValueController component = Object.Instantiate<GameObject>(typeof(T).IsFloating() ? Assets.FloatingSliderOption : Assets.IntegralSliderOption, Root).GetComponent<NumericSliderValueController>();
			component.SetupFromValues(getter, setter);
			component.slider.minValue = minValue;
			component.slider.maxValue = maxValue;
			component.NameText = nameText;
			return component;
		}

		public NumericSliderValueController PrependNumericSlider<T>(string nameText, Func<T> getter, Action<T> setter, float minValue, float maxValue) where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
		{
			return PrependItem(AppendNumericSlider(nameText, getter, setter, minValue, maxValue));
		}

		public NumericSliderValueController InsertNumericSlider<T>(int position, string nameText, Func<T> getter, Action<T> setter, float minValue, float maxValue) where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
		{
			return InsertItem(position, AppendNumericSlider(nameText, getter, setter, minValue, maxValue));
		}
	}
}