Decompiled source of Distance Mod Configuration Manager v1.0.0

DistanceModConfigurationManager.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DistanceModConfigurationManager.DistanceGUI.Controls;
using DistanceModConfigurationManager.DistanceGUI.Data;
using DistanceModConfigurationManager.DistanceGUI.Events;
using DistanceModConfigurationManager.DistanceGUI.Menu;
using DistanceModConfigurationManager.Game;
using DistanceModConfigurationManager.Internal;
using Events;
using Events.Menu;
using HarmonyLib;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("DistanceModConfigurationManager")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DistanceModConfigurationManager")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9bc754f3-4bbe-4c84-b06a-79311691dd74")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
public static class System__EnumExtensions
{
	public static bool HasFlag<T>(this T value, T flag) where T : struct
	{
		ulong num = Convert.ToUInt64(value);
		ulong num2 = Convert.ToUInt64(flag);
		return (num & num2) != 0;
	}
}
namespace DistanceModConfigurationManager
{
	internal sealed class ConfigSettingEntry : SettingEntryBase
	{
		public ConfigEntryBase Entry { get; }

		public override Type SettingType => Entry.SettingType;

		public ConfigSettingEntry(ConfigEntryBase entry, BaseUnityPlugin owner)
		{
			Entry = entry;
			DispName = entry.Definition.Key;
			base.Category = entry.Definition.Section;
			ConfigDescription description = entry.Description;
			base.Description = ((description != null) ? description.Description : null);
			TypeConverter converter = TomlTypeConverter.GetConverter(entry.SettingType);
			if (converter != null)
			{
				base.ObjToStr = (object o) => converter.ConvertToString(o, entry.SettingType);
				base.StrToObj = (string s) => converter.ConvertToObject(s, entry.SettingType);
			}
			ConfigDescription description2 = entry.Description;
			AcceptableValueBase val = ((description2 != null) ? description2.AcceptableValues : null);
			if (val != null)
			{
				GetAcceptableValues(val);
			}
			base.DefaultValue = entry.DefaultValue;
			ConfigDescription description3 = entry.Description;
			SetFromAttributes((description3 != null) ? description3.Tags : null, owner);
		}

		private void GetAcceptableValues(AcceptableValueBase values)
		{
			Type type = ((object)values).GetType();
			PropertyInfo property = type.GetProperty("AcceptableValues", BindingFlags.Instance | BindingFlags.Public);
			if ((object)property != null)
			{
				base.AcceptableValues = ((IEnumerable)property.GetValue(values, null)).Cast<object>().ToArray();
				return;
			}
			PropertyInfo property2 = type.GetProperty("MinValue", BindingFlags.Instance | BindingFlags.Public);
			PropertyInfo property3 = type.GetProperty("MaxValue", BindingFlags.Instance | BindingFlags.Public);
			if ((object)property2 != null && (object)property3 != null)
			{
				base.AcceptableValueRange = new KeyValuePair<object, object>(property2.GetValue(values, null), property3.GetValue(values, null));
				base.ShowRangeAsPercent = ((base.AcceptableValueRange.Key.Equals(0) || base.AcceptableValueRange.Key.Equals(1)) && base.AcceptableValueRange.Value.Equals(100)) || (base.AcceptableValueRange.Key.Equals(0f) && base.AcceptableValueRange.Value.Equals(1f));
			}
		}

		public override object Get()
		{
			return Entry.BoxedValue;
		}

		protected override void SetValue(object newVal)
		{
			Entry.BoxedValue = newVal;
		}
	}
	[BepInPlugin("Distance.DistanceModConfigurationManager", "Distance Mod Configuration Manager", "1.0.0")]
	public sealed class Mod : BaseUnityPlugin
	{
		private const string modGUID = "Distance.DistanceModConfigurationManager";

		private const string modName = "Distance Mod Configuration Manager";

		public const string modVersion = "1.0.0";

		public static string ShowVersionKey = "Show Version Info";

		private string _modsWithoutSettings;

		private List<SettingEntryBase> _allSettings;

		private List<PluginSettingsData> _filteredSettings = new List<PluginSettingsData>();

		private static readonly Harmony harmony = new Harmony("Distance.DistanceModConfigurationManager");

		public static ManualLogSource Log = new ManualLogSource("Distance Mod Configuration Manager");

		public static Mod Instance;

		public static ConfigEntry<bool> ShowVersionInfo { get; set; }

		public int modsLoaded { get; set; }

		private void Awake()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			Log = Logger.CreateLogSource("Distance.DistanceModConfigurationManager");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Thanks for using the Distance Mod Configuration Manager!");
			CreateSettingsMenu();
			ShowVersionInfo = ((BaseUnityPlugin)this).Config.Bind<bool>("General", ShowVersionKey, true, new ConfigDescription("Display the Config Manager Version in the main menu", (AcceptableValueBase)null, new object[0]));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading...");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded!");
		}

		private void OnConfigChanged(object sender, EventArgs e)
		{
			SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null);
			if (val != null)
			{
			}
		}

		private void CreateSettingsMenu()
		{
			MenuTree menuTree = new MenuTree("menu.distance.modding.settings", "Mod Settings");
		}

		private static bool IsKeyboardShortcut(SettingEntryBase x)
		{
			return (object)x.SettingType == typeof(KeyboardShortcut) || (object)x.SettingType == typeof(KeyCode);
		}

		public void BuildSettingList()
		{
			SettingSearcher.CollectSettings(out var results, out var modsWithoutSettings);
			_modsWithoutSettings = string.Join(", ", (from x in modsWithoutSettings
				select x.TrimStart(new char[1] { '!' }) into x
				orderby x
				select x).ToArray());
			_allSettings = results.ToList();
			Log.LogInfo((object)("Settings found: " + results.Count()));
			foreach (SettingEntryBase item in results)
			{
				Log.LogInfo((object)item.PluginInfo.Name);
			}
			BuildFilteredSettingList();
		}

		private void BuildFilteredSettingList()
		{
			IEnumerable<SettingEntryBase> allSettings = _allSettings;
			allSettings = allSettings.Where((SettingEntryBase x) => x.IsAdvanced != true);
			foreach (SettingEntryBase item in allSettings)
			{
				Log.LogInfo((object)("Filtered List: " + item.DispName));
			}
			List<PluginSettingsData> list = new List<PluginSettingsData>();
			string text = string.Empty;
			foreach (SettingEntryBase setting in allSettings)
			{
				if (text != setting.PluginInfo.Name)
				{
					text = setting.PluginInfo.Name;
					list.Add(new PluginSettingsData
					{
						Info = setting.PluginInfo,
						Settings = new List<SettingEntryBase> { setting }
					});
				}
				else
				{
					PluginSettingsData pluginSettingsData = list.Find((PluginSettingsData plugin) => plugin.Info == setting.PluginInfo);
					pluginSettingsData.Settings.Add(setting);
				}
			}
			_filteredSettings = list;
			modsLoaded = _filteredSettings.Count;
			AddFilteredSettingsToMenu();
		}

		private void AddFilteredSettingsToMenu()
		{
			foreach (PluginSettingsData filteredSetting in _filteredSettings)
			{
				MenuTree menuTree = new MenuTree("menu.distance.mod." + Regex.Replace(filteredSetting.Info.Name, "\\s+", "").ToLower(), filteredSetting.Info.Name.ToUpper() + " SETTINGS");
				foreach (SettingEntryBase setting in filteredSetting.Settings)
				{
					if ((object)typeof(KeyboardShortcut) != setting.SettingType)
					{
						menuTree.Add(CreateUIForSetting(setting));
					}
				}
				Menus.AddNew(MenuDisplayMode.Both, menuTree, filteredSetting.Info.Name.ToUpper(), "Settings for the " + filteredSetting.Info.Name + " mod");
			}
		}

		private MenuItemBase CreateUIForSetting(SettingEntryBase setting)
		{
			if ((object)typeof(bool) == setting.SettingType)
			{
				return new CheckBox(MenuDisplayMode.Both, "settings:" + Regex.Replace(setting.DispName, "\\s+", "_").ToLower(), setting.DispName.ToUpper()).WithGetter(() => (bool)setting.Get()).WithSetter(delegate(bool x)
				{
					setting.Set(x);
				}).WithDescription(setting.Description ?? "");
			}
			if ((object)typeof(float) == setting.SettingType)
			{
				if (setting.AcceptableValueRange.Key == null)
				{
					return new FloatSlider(MenuDisplayMode.Both, "settings:" + Regex.Replace(setting.DispName, "\\s+", "_").ToLower(), setting.DispName.ToUpper()).WithDefaultValue((float)setting.DefaultValue).LimitedByRange(-180f, 180f).WithGetter(() => (float)setting.Get())
						.WithSetter(delegate(float x)
						{
							setting.Set(x);
						})
						.WithDescription(setting.Description ?? "");
				}
				return new FloatSlider(MenuDisplayMode.Both, "settings:" + Regex.Replace(setting.DispName, "\\s+", "_").ToLower(), setting.DispName.ToUpper()).WithDefaultValue((float)setting.DefaultValue).LimitedByRange((float)setting.AcceptableValueRange.Key, (float)setting.AcceptableValueRange.Value).WithGetter(() => (float)setting.Get())
					.WithSetter(delegate(float x)
					{
						setting.Set(x);
					})
					.WithDescription(setting.Description ?? "");
			}
			if ((object)typeof(int) == setting.SettingType)
			{
				if (setting.AcceptableValueRange.Key == null)
				{
					return new IntegerSlider(MenuDisplayMode.Both, "settings:" + Regex.Replace(setting.DispName, "\\s+", "_").ToLower(), setting.DispName.ToUpper()).WithDefaultValue((int)setting.DefaultValue).LimitedByRange(0, 60).WithGetter(() => (int)setting.Get())
						.WithSetter(delegate(int x)
						{
							setting.Set(x);
						})
						.WithDescription(setting.Description ?? "");
				}
				return new IntegerSlider(MenuDisplayMode.Both, "settings:" + Regex.Replace(setting.DispName, "\\s+", "_").ToLower(), setting.DispName.ToUpper()).WithDefaultValue((int)setting.DefaultValue).LimitedByRange((int)setting.AcceptableValueRange.Key, (int)setting.AcceptableValueRange.Value).WithGetter(() => (int)setting.Get())
					.WithSetter(delegate(int x)
					{
						setting.Set(x);
					})
					.WithDescription(setting.Description ?? "");
			}
			if (setting.SettingType.IsEnum)
			{
				Dictionary<string, int> entries = Enum.GetNames(setting.SettingType).ToDictionary((string name) => name, (string name) => (int)Enum.Parse(setting.SettingType, name));
				return new ListBox<int>(MenuDisplayMode.Both, "settings:" + Regex.Replace(setting.DispName, "\\s+", "_").ToLower(), setting.DispName.ToUpper()).WithEntries(entries).WithGetter(() => (int)setting.Get()).WithSetter(delegate(int x)
				{
					setting.Set(x);
				})
					.WithDescription(setting.Description ?? "");
			}
			return new ActionButton(MenuDisplayMode.Both, "settings:" + Regex.Replace(setting.DispName, "\\s+", "_").ToLower(), setting.DispName.ToUpper()).WithDescription("This setting is not properly displayed! Report this problem to the #modding channel on the Distance discord!");
		}
	}
	public sealed class PluginSettingsData
	{
		public BepInPlugin Info;

		public List<SettingEntryBase> Settings;
	}
	internal class PropertySettingEntry : SettingEntryBase
	{
		private Type _settingType;

		public object Instance { get; internal set; }

		public PropertyInfo Property { get; internal set; }

		public override string DispName
		{
			get
			{
				return string.IsNullOrEmpty(base.DispName) ? Property.Name : base.DispName;
			}
			protected internal set
			{
				base.DispName = value;
			}
		}

		public override Type SettingType => _settingType ?? (_settingType = Property.PropertyType);

		public PropertySettingEntry(object instance, PropertyInfo settingProp, BaseUnityPlugin pluginInstance)
		{
			SetFromAttributes(settingProp.GetCustomAttributes(inherit: false), pluginInstance);
			if (!base.Browsable.HasValue)
			{
				base.Browsable = settingProp.CanRead && settingProp.CanWrite;
			}
			base.ReadOnly = settingProp.CanWrite;
			Property = settingProp;
			Instance = instance;
		}

		public override object Get()
		{
			return Property.GetValue(Instance, null);
		}

		protected override void SetValue(object newVal)
		{
			Property.SetValue(Instance, newVal, null);
		}
	}
	public abstract class SettingEntryBase
	{
		public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput);

		private static readonly PropertyInfo[] _myProperties = typeof(SettingEntryBase).GetProperties(BindingFlags.Instance | BindingFlags.Public);

		public object[] AcceptableValues { get; protected set; }

		public KeyValuePair<object, object> AcceptableValueRange { get; protected set; }

		public bool? ShowRangeAsPercent { get; protected set; }

		public Action<ConfigEntryBase> CustomDrawer { get; private set; }

		public CustomHotkeyDrawerFunc CustomHotkeyDrawer { get; private set; }

		public bool? Browsable { get; protected set; }

		public string Category { get; protected set; }

		public object DefaultValue { get; protected set; }

		public bool HideDefaultButton { get; protected set; }

		public bool HideSettingName { get; protected set; }

		public string Description { get; protected internal set; }

		public virtual string DispName { get; protected internal set; }

		public BepInPlugin PluginInfo { get; protected internal set; }

		public bool? ReadOnly { get; protected set; }

		public abstract Type SettingType { get; }

		public BaseUnityPlugin PluginInstance { get; private set; }

		public bool? IsAdvanced { get; internal set; }

		public int Order { get; protected set; }

		public Func<object, string> ObjToStr { get; internal set; }

		public Func<string, object> StrToObj { get; internal set; }

		public abstract object Get();

		public void Set(object newVal)
		{
			if (ReadOnly != true)
			{
				SetValue(newVal);
			}
		}

		protected abstract void SetValue(object newVal);

		internal void SetFromAttributes(object[] attribs, BaseUnityPlugin pluginInstance)
		{
			PluginInstance = pluginInstance;
			PluginInfo = ((pluginInstance != null) ? pluginInstance.Info.Metadata : null);
			if (attribs == null || attribs.Length == 0)
			{
				return;
			}
			foreach (object obj in attribs)
			{
				object obj2 = obj;
				object obj3 = obj2;
				if (obj3 == null)
				{
					continue;
				}
				if (!(obj3 is DisplayNameAttribute displayNameAttribute))
				{
					if (!(obj3 is CategoryAttribute categoryAttribute))
					{
						if (!(obj3 is DescriptionAttribute descriptionAttribute))
						{
							if (!(obj3 is DefaultValueAttribute defaultValueAttribute))
							{
								if (!(obj3 is ReadOnlyAttribute readOnlyAttribute))
								{
									if (!(obj3 is BrowsableAttribute browsableAttribute))
									{
										Action<SettingEntryBase> action = obj3 as Action<SettingEntryBase>;
										if (action == null)
										{
											if (obj3 is string text)
											{
												switch (text)
												{
												case "ReadOnly":
													ReadOnly = true;
													break;
												case "Browsable":
													Browsable = true;
													break;
												case "Unbrowsable":
												case "Hidden":
													Browsable = false;
													break;
												case "Advanced":
													IsAdvanced = true;
													break;
												}
												continue;
											}
											Type type = obj.GetType();
											if (!(type.Name == "ConfigurationManagerAttributes"))
											{
												break;
											}
											FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
											foreach (var item in from my in _myProperties
												join other in fields on my.Name equals other.Name
												select new { my, other })
											{
												try
												{
													object obj4 = item.other.GetValue(obj);
													if (obj4 != null)
													{
														if ((object)item.my.PropertyType != item.other.FieldType && typeof(Delegate).IsAssignableFrom(item.my.PropertyType))
														{
															obj4 = Delegate.CreateDelegate(item.my.PropertyType, ((Delegate)obj4).Target, ((Delegate)obj4).Method);
														}
														item.my.SetValue(this, obj4, null);
													}
												}
												catch (Exception ex)
												{
													Mod.Log.LogWarning((object)("Failed to copy value " + item.my.Name + " from provided tag object " + type.FullName + " - " + ex.Message));
												}
											}
										}
										else
										{
											CustomDrawer = delegate
											{
												action(this);
											};
										}
									}
									else
									{
										Browsable = browsableAttribute.Browsable;
									}
								}
								else
								{
									ReadOnly = readOnlyAttribute.IsReadOnly;
								}
							}
							else
							{
								DefaultValue = defaultValueAttribute.Value;
							}
						}
						else
						{
							Description = descriptionAttribute.Description;
						}
					}
					else
					{
						Category = categoryAttribute.Category;
					}
				}
				else
				{
					DispName = displayNameAttribute.DisplayName;
				}
			}
		}
	}
	internal static class SettingSearcher
	{
		private static readonly ICollection<string> _updateMethodNames = new string[4] { "Update", "FixedUpdate", "LateUpdate", "OnGUI" };

		public static BaseUnityPlugin[] FindPlugins()
		{
			return (from x in Chainloader.PluginInfos.Values
				select x.Instance into plugin
				where (Object)(object)plugin != (Object)null
				select plugin).Union(Object.FindObjectsOfType(typeof(BaseUnityPlugin)).Cast<BaseUnityPlugin>()).ToArray();
		}

		public static void CollectSettings(out IEnumerable<SettingEntryBase> results, out List<string> modsWithoutSettings)
		{
			modsWithoutSettings = new List<string>();
			try
			{
				results = GetBepInExCoreConfig();
			}
			catch (Exception ex)
			{
				results = Enumerable.Empty<SettingEntryBase>();
				Mod.Log.LogError((object)ex);
			}
			BaseUnityPlugin[] array = FindPlugins();
			foreach (BaseUnityPlugin val in array)
			{
				Type type = ((object)val).GetType();
				BepInPlugin metadata = val.Info.Metadata;
				string text = ((metadata != null) ? metadata.Name : null) ?? ((object)val).GetType().FullName;
				Mod.Log.LogInfo((object)("The name of plugin found: " + text));
				if (type.GetCustomAttributes(typeof(BrowsableAttribute), inherit: false).Cast<BrowsableAttribute>().Any((BrowsableAttribute x) => !x.Browsable))
				{
					modsWithoutSettings.Add(text);
					continue;
				}
				List<SettingEntryBase> list = new List<SettingEntryBase>();
				list.AddRange(GetPluginConfig(val).Cast<SettingEntryBase>());
				list.RemoveAll((SettingEntryBase x) => x.Browsable == false);
				if (list.Count == 0)
				{
					modsWithoutSettings.Add(text);
				}
				if (list.Count <= 0)
				{
					continue;
				}
				results = results.Concat(list);
				foreach (SettingEntryBase item in list)
				{
					Mod.Log.LogInfo((object)item.DispName);
				}
			}
		}

		private static IEnumerable<SettingEntryBase> GetBepInExCoreConfig()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			PropertyInfo property = typeof(ConfigFile).GetProperty("CoreConfig", BindingFlags.Static | BindingFlags.NonPublic);
			if ((object)property == null)
			{
				throw new ArgumentNullException("coreConfigProp");
			}
			ConfigFile source = (ConfigFile)property.GetValue(null, null);
			BepInPlugin bepinMeta = new BepInPlugin("BepInEx", "BepInEx", typeof(Chainloader).Assembly.GetName().Version.ToString());
			return ((IEnumerable<KeyValuePair<ConfigDefinition, ConfigEntryBase>>)source).Select((Func<KeyValuePair<ConfigDefinition, ConfigEntryBase>, SettingEntryBase>)((KeyValuePair<ConfigDefinition, ConfigEntryBase> kvp) => new ConfigSettingEntry(kvp.Value, null)
			{
				IsAdvanced = true,
				PluginInfo = bepinMeta
			}));
		}

		private static IEnumerable<ConfigSettingEntry> GetPluginConfig(BaseUnityPlugin plugin)
		{
			return ((IEnumerable<KeyValuePair<ConfigDefinition, ConfigEntryBase>>)plugin.Config).Select((KeyValuePair<ConfigDefinition, ConfigEntryBase> kvp) => new ConfigSettingEntry(kvp.Value, plugin));
		}
	}
	internal static class Utils
	{
		public static string ToProperClass(this string str)
		{
			if (string.IsNullOrEmpty(str))
			{
				return string.Empty;
			}
			if (str.Length < 2)
			{
				return str;
			}
			string text = str.Substring(0, 1).ToUpper();
			for (int i = 1; i < str.Length; i++)
			{
				if (char.IsUpper(str[i]))
				{
					text += " ";
				}
				text += str[i];
			}
			return text;
		}

		public static string AppendZero(this string s)
		{
			return (!s.Contains(".")) ? (s + ".0") : s;
		}

		public static string AppendZeroIfFloat(this string s, Type type)
		{
			return ((object)type == typeof(float) || (object)type == typeof(double) || (object)type == typeof(decimal)) ? s.AppendZero() : s;
		}
	}
}
namespace DistanceModConfigurationManager.Internal
{
	internal class VersionNumber : MonoBehaviour
	{
		private static class MathUtil
		{
			public static float Map(float s, float a1, float a2, float b1, float b2)
			{
				return b1 + (s - a1) * (b2 - b1) / (a2 - a1);
			}
		}

		internal const float MaximumOpacity = 0.7f;

		internal static bool creatingInstance;

		internal UILabel label;

		internal UIWidget widget;

		internal UIPanel panel;

		private bool _visible = true;

		private Coroutine _transitionCoroutine = null;

		internal static VersionNumber Instance { get; set; }

		internal bool Visible
		{
			get
			{
				return Visible;
			}
			set
			{
				if (value != _visible)
				{
					if (_transitionCoroutine != null)
					{
						((MonoBehaviour)this).StopCoroutine(_transitionCoroutine);
					}
					_transitionCoroutine = ((MonoBehaviour)this).StartCoroutine(Transition(value));
				}
				_visible = value;
			}
		}

		internal bool CanDisplay
		{
			get
			{
				//IL_0004: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Invalid comparison between Unknown and I4
				bool flag = true;
				bool num = flag;
				Scene activeScene = SceneManager.GetActiveScene();
				flag = num & string.Equals(((Scene)(ref activeScene)).name, "mainmenu", StringComparison.InvariantCultureIgnoreCase);
				flag &= G.Sys.MenuPanelManager_.panelStack_.Count == 2;
				flag &= Mod.ShowVersionInfo.Value;
				flag &= G.Sys.GameManager_.IsLevelLoaded_;
				return flag & ((int)G.Sys.GameManager_.BlackFade_.currentState_ == 0);
			}
		}

		internal static void Create(GameObject speedrunTimerLogic = null)
		{
			if (Object.op_Implicit((Object)(object)Instance) || creatingInstance)
			{
				return;
			}
			creatingInstance = true;
			GameObject val = null;
			val = ((!Object.op_Implicit((Object)(object)speedrunTimerLogic)) ? GameObject.Find("Anchor : Speedrun Timer") : GameObjectEx.Parent(speedrunTimerLogic));
			if (Object.op_Implicit((Object)(object)val))
			{
				GameObject val2 = Object.Instantiate<GameObject>(val, val.transform.parent);
				val2.SetActive(true);
				((Object)val2).name = "Anchor : Mod Manager Info";
				GameObjectEx.ForEachChildObjectDepthFirstRecursive(val2, (Action<GameObject>)delegate(GameObject obj)
				{
					obj.SetActive(true);
					GameObjectEx.RemoveComponent<SpeedrunTimerLogic>(obj);
				});
				UILabel componentInChildren = val2.GetComponentInChildren<UILabel>();
				Instance = ((Component)componentInChildren).gameObject.AddComponent<VersionNumber>();
			}
			creatingInstance = false;
		}

		internal void Start()
		{
			GameObject val = GameObjectEx.Parent(((Component)this).gameObject);
			GameObject val2 = GameObjectEx.Parent(val);
			label = ((Component)this).GetComponent<UILabel>();
			widget = val.GetComponent<UIWidget>();
			panel = val2.GetComponent<UIPanel>();
			((UIRect)widget).alpha = 0f;
			AdjustPosition();
		}

		internal void Update()
		{
			label.text = string.Format("DISTANCE MOD CONFIGURATION {0} - {1} MOD(S) LOADED", "1.0.0", Mod.Instance.modsLoaded);
			Visible = CanDisplay;
		}

		internal void AdjustPosition()
		{
			((UIRect)label).SetAnchor(((Component)panel).gameObject, 21, 19, -19, -17);
			((UIWidget)label).pivot = (Pivot)0;
		}

		internal IEnumerator Transition(bool visible, float duration = 0.2f)
		{
			float target = (visible ? 0.7f : 0f);
			float current = ((UIRect)widget).alpha;
			for (float time = 0f; time < duration; time += Timex.deltaTime_)
			{
				if (!G.Sys.OptionsManager_.General_.menuAnimations_)
				{
					break;
				}
				float value = MathUtil.Map(time, 0f, duration, current, target);
				((UIRect)widget).alpha = value;
				yield return null;
			}
			((UIRect)widget).alpha = target;
		}
	}
}
namespace DistanceModConfigurationManager.Patches
{
	[HarmonyPatch(typeof(OptionsMenuLogic), "DisplaySubmenu")]
	internal static class OptionsMenuLogic__DisplaySubmenu
	{
		[HarmonyPrefix]
		internal static bool Prefix(OptionsMenuLogic __instance, string submenuName)
		{
			List<OptionsSubmenu> list = __instance.subMenus_.ToList();
			OptionsSubmenu val = list.Find((OptionsSubmenu x) => x.Name_ == submenuName);
			if (Object.op_Implicit((Object)(object)val) && val is ModdingMenu)
			{
				ModdingMenu moddingMenu = val as ModdingMenu;
				if (!moddingMenu.MenuTree.Any())
				{
					MenuSystem.ShowUnavailableMessage();
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(OptionsMenuLogic), "GetSubmenus")]
	internal static class OptionsMenuLogic__GetSubmenus
	{
		[HarmonyPrefix]
		internal static void Prefix(OptionsMenuLogic __instance)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			OptionsSubmenu[] subMenus_ = __instance.subMenus_;
			foreach (OptionsSubmenu val in subMenus_)
			{
				if (((object)val).GetType().IsSubclassOf(typeof(SuperMenu)))
				{
					MenuSystem.MenuBlueprint = ((SuperMenu)val).menuBlueprint_;
				}
			}
			ModdingMenu moddingMenu = ((Component)__instance).gameObject.AddComponent<ModdingMenu>();
			moddingMenu.MenuTree = MenuSystem.MenuTree;
			List<OptionsSubmenu> list = new List<OptionsSubmenu>(__instance.subMenus_);
			OptionsSubmenu[] subMenus_2 = __instance.subMenus_;
			foreach (OptionsSubmenu val2 in subMenus_2)
			{
				if (val2.Name_ == ((OptionsSubmenu)moddingMenu).Name_)
				{
					list.Remove(val2);
				}
			}
			list.Add((OptionsSubmenu)(object)moddingMenu);
			__instance.subMenus_ = list.ToArray();
		}
	}
	[HarmonyPatch(typeof(SpeedrunTimerLogic), "OnEnable")]
	internal static class SpeedrunTimerLogic__OnEnable
	{
		[HarmonyPostfix]
		internal static void Postfix(SpeedrunTimerLogic __instance)
		{
			try
			{
				VersionNumber.Create(((Component)__instance).gameObject);
			}
			catch (Exception ex)
			{
				Mod.Log.LogError((object)ex);
			}
		}
	}
	[HarmonyPatch(typeof(SplashScreenLogic), "Start")]
	internal static class SplashScreenLogic__Start
	{
		[HarmonyPostfix]
		internal static void CreateSettingList()
		{
			Mod.Instance.BuildSettingList();
		}
	}
}
namespace DistanceModConfigurationManager.Game
{
	public static class Menus
	{
		public static void AddNew(MenuDisplayMode displayMode, MenuTree menuTree, string description = null)
		{
			AddNew(displayMode, menuTree, menuTree.Title, description);
		}

		public static void AddNew(MenuDisplayMode displayMode, MenuTree menuTree, string title, string description = null)
		{
			try
			{
				MenuSystem.MenuTree.Add(new SubMenu(displayMode, menuTree.Id, title).NavigatesTo(menuTree).WithDescription(description));
				Mod.Log.LogInfo((object)("Added new menu tree: '" + menuTree.Id + "', '" + menuTree.Title + "'..."));
			}
			catch (Exception ex)
			{
				Mod.Log.LogError((object)("Failed to add the menu tree: '" + menuTree.Id + "', '" + menuTree.Title + "'."));
				Mod.Log.LogError((object)ex);
			}
		}
	}
	public sealed class MessageBox
	{
		private readonly string Message = "";

		private readonly string Title = "";

		private float Time = 0f;

		private ButtonType Buttons = (ButtonType)0;

		private Action Confirm;

		private Action Cancel;

		private MessageBox(string message, string title)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Message = message;
			Title = title;
			Confirm = EmptyAction;
			Cancel = EmptyAction;
		}

		public static MessageBox Create(string content, string title = "")
		{
			return new MessageBox(content, title);
		}

		public MessageBox SetButtons(ButtonType buttons)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			Buttons = buttons;
			return this;
		}

		public MessageBox SetTimeout(float delay)
		{
			Time = delay;
			return this;
		}

		public MessageBox OnConfirm(Action action)
		{
			Confirm = action;
			return this;
		}

		public MessageBox OnCancel(Action action)
		{
			Cancel = action;
			return this;
		}

		public void Show()
		{
			//IL_001e: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0042: Expected O, but got Unknown
			G.Sys.MenuPanelManager_.ShowMessage(Message, Title, (OnButtonClicked)delegate
			{
				Confirm();
			}, (OnButtonClicked)delegate
			{
				Cancel();
			}, Buttons, false, (Pivot)4, Time);
		}

		private void EmptyAction()
		{
		}
	}
}
namespace DistanceModConfigurationManager.DistanceGUI.Menu
{
	public static class MenuSystem
	{
		internal static GameObject MenuBlueprint { get; set; }

		internal static MenuTree MenuTree { get; set; }

		static MenuSystem()
		{
			MenuTree = new MenuTree("menu.distancemodding.main", "Configure Distance Mods");
		}

		internal static void ShowMenu(MenuTree menuTree, ModdingMenu parentMenu, int pageIndex)
		{
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			if (menuTree.GetItems().Count == 0)
			{
				ShowUnavailableMessage();
				return;
			}
			ModdingMenu[] components = ((OptionsSubmenu)parentMenu).PanelObject_.GetComponents<ModdingMenu>();
			foreach (ModdingMenu moddingMenu in components)
			{
				GameObjectEx.Destroy((Object)(object)moddingMenu);
			}
			ModdingMenu menu = ComponentEx.GetOrAddComponent<ModdingMenu>((Component)(object)Mod.Instance);
			menu.MenuTree = menuTree;
			menu.CurrentPageIndex = pageIndex;
			menu.MenuPanel = MenuPanel.Create(((OptionsSubmenu)menu).PanelObject_, true, true, false, true, true, true);
			menu.MenuPanel.backgroundOpacity_ = 0.75f;
			MenuPanel menuPanel = menu.MenuPanel;
			menuPanel.onIsTopChanged_ = (OnIsTopChanged)Delegate.Combine((Delegate?)(object)menuPanel.onIsTopChanged_, (Delegate?)(OnIsTopChanged)delegate(bool isTop)
			{
				if (isTop)
				{
					menu.ResetAnimations();
				}
				else if (G.Sys.MenuPanelManager_.panelStack_.Contains(menu.MenuPanel))
				{
					menu.SwitchPage(menu.CurrentPageIndex, relative: false);
				}
				else
				{
					menu.SwitchPage(0, relative: false);
				}
			});
			MenuPanel menuPanel2 = menu.MenuPanel;
			menuPanel2.onPanelPop_ = (OnPanelPop)Delegate.Combine((Delegate?)(object)menuPanel2.onPanelPop_, (Delegate?)(OnPanelPop)delegate
			{
				if (!G.Sys.MenuPanelManager_.panelStack_.Contains(menu.MenuPanel))
				{
					menu.SwitchPage(0, relative: false);
					((OptionsSubmenu)parentMenu).PanelObject_.SetActive(true);
					if (menu.MenuTree != MenuTree)
					{
						GameObjectEx.Destroy((Object)(object)((OptionsSubmenu)menu).PanelObject_);
					}
					GameObjectEx.Destroy((Object)(object)menu);
				}
			});
			((OptionsSubmenu)parentMenu).PanelObject_.SetActive(false);
			menu.MenuPanel.Push();
		}

		public static void ShowUnavailableMessage()
		{
			MessageBox.Create("This menu is currently unavailable.\nNo menu entries found.", "MOD SETTINGS MANAGER").SetButtons((ButtonType)0).Show();
		}

		public static MenuDisplayMode GetCurrentDisplayMode()
		{
			//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)
			Scene activeScene = SceneManager.GetActiveScene();
			if (string.Equals(((Scene)(ref activeScene)).name, "mainmenu", StringComparison.OrdinalIgnoreCase))
			{
				return MenuDisplayMode.MainMenu;
			}
			return MenuDisplayMode.PauseMenu;
		}
	}
	public class ModdingMenu : ModdingMenuAbstract
	{
		private const int MaxEntriesPerPage = 9;

		private InputManager InputManager { get; set; }

		private SuperDuperMenu MenuController
		{
			get
			{
				GameObject panelObject_ = ((OptionsSubmenu)this).PanelObject_;
				return (panelObject_ != null) ? panelObject_.GetComponent<SuperDuperMenu>() : null;
			}
		}

		private GameObject[] Blueprints => (GameObject[])(object)new GameObject[4] { MenuController.actionBlueprint_, MenuController.sliderBlueprint_, MenuController.popupBlueprint_, MenuController.toggleBlueprint_ };

		private int PageCount => (int)Math.Max(Math.Ceiling((float)MenuTree.Count / 9f), 1.0);

		private UIExFancyFadeInMenu MenuFade
		{
			get
			{
				GameObject panelObject_ = ((OptionsSubmenu)this).PanelObject_;
				return (panelObject_ != null) ? panelObject_.GetComponent<UIExFancyFadeInMenu>() : null;
			}
		}

		public override string Title => MenuTree.Title;

		public GameObject TitleLabel => ((Component)((OptionsSubmenu)this).PanelObject_.transform.Find("MenuTitleTemplate/UILabel - Title")).gameObject;

		public GameObject DescriptionLabel => ((Component)((OptionsSubmenu)this).PanelObject_.transform.Find("MenuTitleTemplate/UILabel - Description")).gameObject;

		public GameObject OptionsTable => ((Component)((OptionsSubmenu)this).PanelObject_.transform.Find("Options/OptionsTable")).gameObject;

		public MenuPanel MenuPanel { get; internal set; }

		public MenuTree MenuTree { get; internal set; } = new MenuTree("menu.modding.error", "[FF0000]Error[-]");


		public string Description { get; set; }

		public int CurrentPageIndex { get; internal set; } = 0;


		public string Id => MenuTree.Id;

		public override void InitializeVirtual()
		{
			InputManager = G.Sys.InputManager_;
			DisplayMenu();
			StaticEvent<MenuOpened.Data>.Broadcast(new MenuOpened.Data(this));
		}

		private void DisplayMenu()
		{
			MenuTree items = MenuTree.GetItems(MenuSystem.GetCurrentDisplayMode());
			if (items.Any())
			{
				for (int i = CurrentPageIndex * 9; i < CurrentPageIndex * 9 + 9 && i < items.Count; i++)
				{
					items[i]?.Tweak(this);
				}
				return;
			}
			MessageBox.Create("This menu is currently unavailable.\nNo menu entries found.", "MOD SETTINGS MANAGER").SetButtons((ButtonType)0).OnConfirm(delegate
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Expected O, but got Unknown
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Expected O, but got Unknown
				MenuPanel topPanel_ = base.PanelManager.TopPanel_;
				topPanel_.onPanelPop_ = (OnPanelPop)Delegate.Combine((Delegate?)(object)topPanel_.onPanelPop_, (Delegate?)(OnPanelPop)delegate
				{
					MenuPanel.Pop();
				});
			})
				.Show();
		}

		public void OnEnable()
		{
			ResetAnimations();
		}

		public void HideElements()
		{
			GameObject[] children = GameObjectEx.GetChildren(OptionsTable);
			foreach (GameObject val in children)
			{
				if (!Blueprints.Contains(val))
				{
					UIWidget orAddComponent = GameObjectEx.GetOrAddComponent<UIWidget>(val);
					((UIRect)orAddComponent).alpha = 0f;
				}
			}
		}

		public void ResetAnimations()
		{
			//IL_005d: 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)
			//IL_0068: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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)
			List<UIExFancyFadeIn> list = new List<UIExFancyFadeIn>();
			GameObject[] children = GameObjectEx.GetChildren(OptionsTable);
			foreach (GameObject val in children)
			{
				if (!Blueprints.Contains(val))
				{
					UIExFancyFadeIn orAddComponent = GameObjectEx.GetOrAddComponent<UIExFancyFadeIn>(val);
					list.Add(orAddComponent);
				}
			}
			Vector2 val2 = PrimitiveEx.ToVector2(float.MinValue);
			Vector2 val3 = PrimitiveEx.ToVector2(float.MaxValue);
			foreach (UIExFancyFadeIn item in list)
			{
				UIWidget component = ((Component)item).GetComponent<UIWidget>();
				Vector2 val4 = Vector2.op_Implicit(component.worldCenter);
				float num = 1f - Mathf.InverseLerp(val3.y, val2.y, val4.y);
				item.offset_ = new Vector3(MenuFade.offset_, 0f);
				item.duration_ = MenuFade.duration_;
				item.delay_ = num * MenuFade.delay_;
				item.offset_.x *= -1f;
				item.initialAlpha_ = 1f;
				((UIRect)component).alpha = 1f;
				item.Init();
			}
		}

		public void SwitchPage(int value = 0, bool relative = true, bool resetObjects = true)
		{
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			if (relative)
			{
				CurrentPageIndex += value;
			}
			else
			{
				CurrentPageIndex = value;
			}
			CurrentPageIndex = ((CurrentPageIndex < 0) ? (PageCount - 1) : ((CurrentPageIndex <= PageCount - 1) ? CurrentPageIndex : 0));
			if (!resetObjects)
			{
				return;
			}
			foreach (GameObject item in MenuController.items_)
			{
				if (SuperDuperMenu.defaultFloatValues_.ContainsKey(((Object)item).name))
				{
					SuperDuperMenu.defaultFloatValues_.Remove(((Object)item).name);
				}
				UIWidget component = item.GetComponent<UIWidget>();
				if (Object.op_Implicit((Object)(object)component) && MenuFade.widgets_.Contains(component))
				{
					MenuFade.widgets_.Remove(component);
				}
				GameObjectEx.DeactivateAndDestroy(item.gameObject);
			}
			MenuController.items_.Clear();
			foreach (UIButton value2 in MenuController.actions_.Values)
			{
				destroyObject(((Component)value2).gameObject);
			}
			foreach (UIToggle value3 in MenuController.toggles_.Values)
			{
				destroyObject(((Component)value3).gameObject);
			}
			foreach (SliderHelper value4 in MenuController.sliders_.Values)
			{
				destroyObject(((Component)value4).gameObject);
			}
			foreach (PopupHelper value5 in MenuController.popups_.Values)
			{
				destroyObject(((Component)value5).gameObject);
			}
			MenuController.actions_.Clear();
			MenuController.toggles_.Clear();
			MenuController.sliders_.Clear();
			MenuController.popups_.Clear();
			MenuController.buttonsTable_.Reposition();
			MenuController.SetDescription((GameObject)null, "");
			StaticEvent<Data>.Broadcast(new Data(string.Empty, true, string.Empty));
			MenuController.Init((SuperMenu)(object)this);
			MenuController.Initialize();
			static void destroyObject(GameObject obj)
			{
				obj.transform.parent = null;
				GameObjectEx.DeactivateAndDestroy(obj);
				Object.DestroyImmediate((Object)(object)obj);
			}
		}

		public override void Update()
		{
			bool flag = true;
			flag &= (Object)(object)((OptionsSubmenu)this).PanelObject_ != (Object)null;
			bool num = flag;
			GameObject panelObject_ = ((OptionsSubmenu)this).PanelObject_;
			if (num & (((panelObject_ != null) ? new bool?(panelObject_.activeInHierarchy) : null) ?? false))
			{
				UpdateVirtual();
			}
		}

		public override void UpdateVirtual()
		{
			bool flag = MenuTree.Count > 9;
			G.Sys.MenuPanelManager_.SetBottomLeftActionButtonEnabled((InputAction)41, flag);
			G.Sys.MenuPanelManager_.SetBottomLeftActionButtonEnabled((InputAction)40, flag);
			G.Sys.MenuPanelManager_.SetBottomLeftActionButton((InputAction)41, "PREVIOUS");
			G.Sys.MenuPanelManager_.SetBottomLeftActionButton((InputAction)40, "NEXT");
			if (flag)
			{
				if (InputManager.GetKeyUp((InputAction)41, -2))
				{
					SwitchPage(-1);
				}
				if (InputManager.GetKeyUp((InputAction)40, -2))
				{
					SwitchPage(1);
				}
			}
			Description = $"Page {CurrentPageIndex + 1} of {PageCount}";
			GameObject titleLabel = TitleLabel;
			if (titleLabel != null)
			{
				titleLabel.SetActive(true);
			}
			UILabel component = TitleLabel.GetComponent<UILabel>();
			(((SuperMenu)this).menu_.menuTitleLabel_ ?? component).text = Title;
			GameObject descriptionLabel = DescriptionLabel;
			if (descriptionLabel != null)
			{
				descriptionLabel.SetActive(true);
			}
			UILabel component2 = DescriptionLabel.GetComponent<UILabel>();
			MenuDescriptionLabel menuDescriptionLabel_ = ((SuperMenu)this).menu_.menuDescriptionLabel_;
			string text_ = (component2.text = Description);
			menuDescriptionLabel_.text_ = text_;
		}
	}
	public abstract class ModdingMenuAbstract : SuperMenu
	{
		public MenuPanelManager PanelManager => G.Sys.MenuPanelManager_;

		public abstract string Title { get; }

		public override string MenuTitleName_ => Title;

		public override string Name_ => "Mod Settings";

		public override bool DisplayInMenu(bool isPauseMenu)
		{
			return true;
		}

		protected ModdingMenuAbstract()
		{
			base.menuBlueprint_ = MenuSystem.MenuBlueprint;
		}

		public override void InitializeVirtual()
		{
		}

		public virtual void UpdateVirtual()
		{
		}

		public virtual void Update()
		{
		}

		public override void OnPanelPop()
		{
		}
	}
}
namespace DistanceModConfigurationManager.DistanceGUI.Events
{
	public class MenuClosed : StaticEvent<MenuOpened.Data>
	{
		public struct Data
		{
			public ModdingMenu menu;

			public Data(ModdingMenu m)
			{
				menu = m;
			}
		}
	}
	public class MenuOpened : StaticEvent<MenuOpened.Data>
	{
		public struct Data
		{
			public ModdingMenu menu;

			public Data(ModdingMenu m)
			{
				menu = m;
			}
		}
	}
}
namespace DistanceModConfigurationManager.DistanceGUI.Data
{
	[Flags]
	public enum MenuDisplayMode
	{
		None = 0,
		MainMenu = 1,
		PauseMenu = 2,
		Both = 3
	}
	public class MenuItemInfo : MonoBehaviour
	{
		public string Id => Item?.Id;

		public MenuItemBase Item { get; set; }
	}
	public class MenuTree : List<MenuItemBase>
	{
		public string Title { get; set; }

		public string Id { get; set; }

		public MenuTree(string id, string title)
		{
			Id = id;
			Title = title;
		}

		public ActionButton ActionButton(MenuDisplayMode displayMode, string id, string name, Action action, string description = null)
		{
			MenuItemBase menuItemBase = new ActionButton(displayMode, id, name).WhenClicked(action).WithDescription(description);
			Add(menuItemBase);
			return menuItemBase as ActionButton;
		}

		public CheckBox CheckBox(MenuDisplayMode displayMode, string id, string name, Func<bool> getter, Action<bool> setter, string description = null)
		{
			MenuItemBase menuItemBase = new CheckBox(displayMode, id, name).WithGetter(getter).WithSetter(setter).WithDescription(description);
			Add(menuItemBase);
			return menuItemBase as CheckBox;
		}

		public FloatSlider FloatSlider(MenuDisplayMode displayMode, string id, string name, Func<float> getter, Action<float> setter, float minimum = 0f, float maximum = 1f, float defaultValue = 0f, string description = null)
		{
			MenuItemBase menuItemBase = new FloatSlider(displayMode, id, name).WithGetter(getter).WithSetter(setter).LimitedByRange(minimum, maximum)
				.WithDefaultValue(defaultValue)
				.WithDescription(description);
			Add(menuItemBase);
			return menuItemBase as FloatSlider;
		}

		public IntegerSlider IntegerSlider(MenuDisplayMode displayMode, string id, string name, Func<int> getter, Action<int> setter, int minimum = 0, int maximum = 10, int defaultValue = 0, string description = null)
		{
			MenuItemBase menuItemBase = new IntegerSlider(displayMode, id, name).WithGetter(getter).WithSetter(setter).LimitedByRange(minimum, maximum)
				.WithDefaultValue(defaultValue)
				.WithDescription(description);
			Add(menuItemBase);
			return menuItemBase as IntegerSlider;
		}

		public InputPrompt InputPrompt(MenuDisplayMode displayMode, string id, string name, Action<string> submitAction, Action<InputPrompt> closeAction = null, Func<string, string> validator = null, string title = null, string defaultValue = null, string description = null)
		{
			MenuItemBase menuItemBase = new InputPrompt(displayMode, id, name).WithSubmitAction(submitAction).WithCloseAction(closeAction).ValidatedBy(validator)
				.WithTitle(title)
				.WithDefaultValue(defaultValue)
				.WithDescription(description);
			Add(menuItemBase);
			return menuItemBase as InputPrompt;
		}

		public PasswordPrompt PasswordPrompt(MenuDisplayMode displayMode, string id, string name, Action<string> submitAction, Action<InputPrompt> closeAction, Func<string, string> validator, string title = null, string defaultValue = null, string description = null)
		{
			MenuItemBase menuItemBase = new PasswordPrompt(displayMode, id, name).WithSubmitAction(submitAction).WithCloseAction(closeAction).ValidatedBy(validator)
				.WithTitle(title)
				.WithDefaultValue(defaultValue)
				.WithDescription(description);
			Add(menuItemBase);
			return menuItemBase as PasswordPrompt;
		}

		public ListBox<T> ListBox<T>(MenuDisplayMode displayMode, string id, string name, Func<T> getter, Action<T> setter, Dictionary<string, T> entries, string description = null)
		{
			MenuItemBase menuItemBase = new ListBox<T>(displayMode, id, name).WithGetter(getter).WithSetter(setter).WithEntries(entries)
				.WithDescription(description);
			Add(menuItemBase);
			return menuItemBase as ListBox<T>;
		}

		public SubMenu SubmenuButton(MenuDisplayMode displayMode, string id, string name, MenuTree menuTree, string description = null)
		{
			MenuItemBase menuItemBase = new SubMenu(displayMode, id, name).NavigatesTo(menuTree).WithDescription(description);
			Add(menuItemBase);
			return menuItemBase as SubMenu;
		}

		public MenuTree GetItems(MenuDisplayMode mode)
		{
			MenuTree menuTree = new MenuTree(Id, Title);
			ICollectionEx.AddRange<MenuItemBase>((ICollection<MenuItemBase>)menuTree, this.Where((MenuItemBase item) => System__EnumExtensions.HasFlag(item.Mode, mode)));
			return menuTree;
		}

		public MenuTree GetItems()
		{
			return GetItems(MenuSystem.GetCurrentDisplayMode());
		}

		public static implicit operator SubMenu(MenuTree menu)
		{
			return new SubMenu(MenuDisplayMode.Both, menu.Id, menu.Title);
		}
	}
}
namespace DistanceModConfigurationManager.DistanceGUI.Controls
{
	public class ActionButton : MenuItemBase
	{
		public Action OnClick { get; set; }

		public ActionButton(MenuDisplayMode mode, string id, string name)
			: base(mode, id, name)
		{
		}

		public ActionButton WhenClicked(Action onClick)
		{
			OnClick = onClick;
			return this;
		}

		public override void Tweak(ModdingMenu menu)
		{
			if (OnClick == null)
			{
				throw new InvalidOperationException("OnClick action not initialized. Use WhenClicked() to configure the action.");
			}
			((SuperMenu)menu).TweakAction(base.Name, OnClick, base.Description);
			base.Tweak(menu);
		}
	}
	public class CheckBox : MenuItemBase
	{
		public Func<bool> Get { get; set; }

		public Action<bool> Set { get; set; }

		public bool DefaultValue { get; private set; }

		public CheckBox(MenuDisplayMode mode, string id, string name)
			: base(mode, id, name)
		{
			Get = () => DefaultValue;
			Set = delegate
			{
			};
		}

		public CheckBox WithDefaultValue(bool defaultValue)
		{
			DefaultValue = defaultValue;
			return this;
		}

		public CheckBox WithGetter(Func<bool> getter)
		{
			Get = getter ?? throw new ArgumentNullException("Getter cannot be null");
			return this;
		}

		public CheckBox WithSetter(Action<bool> setter)
		{
			Set = setter ?? throw new ArgumentNullException("Setter cannot be null.");
			return this;
		}

		public override void Tweak(ModdingMenu menu)
		{
			if (Get == null || Set == null)
			{
				throw new InvalidOperationException("Cannot call Tweak with Get or Set being null.");
			}
			((SuperMenu)menu).TweakBool(base.Name, Get(), Set, base.Description);
			base.Tweak(menu);
		}
	}
	internal class EmptyElement : MenuItemBase
	{
		public EmptyElement()
			: base(MenuDisplayMode.Both, "empty", string.Empty)
		{
		}
	}
	public class FloatSlider : MenuItemBase
	{
		public float Minimum { get; private set; } = 0f;


		public float Maximum { get; private set; } = 1f;


		public Func<float> Get { get; set; }

		public Action<float> Set { get; set; }

		public float DefaultValue { get; set; }

		public FloatSlider(MenuDisplayMode mode, string id, string name)
			: base(mode, id, name)
		{
			Get = () => DefaultValue;
			Set = delegate
			{
			};
		}

		public FloatSlider WithDefaultValue(float defaultValue)
		{
			if (defaultValue > Maximum || defaultValue < Minimum)
			{
				throw new ArgumentOutOfRangeException("Default value must be between minimum and maximum values.");
			}
			DefaultValue = defaultValue;
			return this;
		}

		public FloatSlider LimitedByRange(float minimum, float maximum)
		{
			if (Minimum > Maximum)
			{
				throw new ArgumentException("Minimum must be lower than maximum.");
			}
			Minimum = minimum;
			Maximum = maximum;
			return this;
		}

		public FloatSlider WithGetter(Func<float> getter)
		{
			Get = getter ?? throw new ArgumentNullException("Getter cannot be null.");
			return this;
		}

		public FloatSlider WithSetter(Action<float> setter)
		{
			Set = setter ?? throw new ArgumentNullException("Setter cannot be null.");
			return this;
		}

		public override void Tweak(ModdingMenu menu)
		{
			if (Get == null || Set == null)
			{
				throw new InvalidOperationException("Cannot call Tweak with Get or Set method being null.");
			}
			((SuperMenu)menu).TweakFloat(base.Name, Get(), Minimum, Maximum, DefaultValue, Set, base.Description);
			base.Tweak(menu);
		}
	}
	public class InputPrompt : MenuItemBase
	{
		public string Title { get; set; }

		public Func<string> DefaultValue { get; set; }

		public Func<string, string> Validator { get; set; }

		public Action<string> SubmitAction { get; set; }

		public Action<InputPrompt> CloseAction { get; set; }

		public InputPrompt(MenuDisplayMode mode, string id, string name)
			: base(mode, id, name)
		{
		}

		public InputPrompt WithTitle(string title)
		{
			Title = title ?? string.Empty;
			return this;
		}

		public InputPrompt WithDefaultValue(string defaultValue)
		{
			DefaultValue = () => defaultValue;
			return this;
		}

		public InputPrompt WithDefaultValue(Func<string> defaultValue)
		{
			DefaultValue = defaultValue ?? ((Func<string>)(() => string.Empty));
			return this;
		}

		public InputPrompt WithSubmitAction(Action<string> submitAction)
		{
			SubmitAction = submitAction ?? throw new ArgumentNullException("Submit action cannot be null.");
			return this;
		}

		public InputPrompt WithCloseAction(Action<InputPrompt> closeAction)
		{
			CloseAction = closeAction;
			return this;
		}

		public InputPrompt ValidatedBy(Func<string, string> validator)
		{
			Validator = validator;
			return this;
		}

		protected virtual bool OnSubmit(out string error, string input)
		{
			error = Validator?.Invoke(input);
			if (error == null)
			{
				SubmitAction?.Invoke(input);
				return true;
			}
			return false;
		}

		protected virtual void OnCancel()
		{
			CloseAction?.Invoke(this);
		}

		protected virtual void OnTweak()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0031: Expected O, but got Unknown
			InputPromptPanel.Create(new OnSubmit(OnSubmit), new OnPop(OnCancel), Title, DefaultValue());
		}

		public override void Tweak(ModdingMenu menu)
		{
			((SuperMenu)menu).TweakAction(base.Name, (Action)delegate
			{
				OnTweak();
				base.Tweak(menu);
			}, base.Description);
		}
	}
	public class IntegerSlider : MenuItemBase
	{
		public int Minimum { get; set; }

		public int Maximum { get; set; }

		public Func<int> Get { get; set; }

		public Action<int> Set { get; set; }

		public int DefaultValue { get; set; }

		public IntegerSlider(MenuDisplayMode mode, string id, string name)
			: base(mode, id, name)
		{
			Get = () => DefaultValue;
			Set = delegate
			{
			};
		}

		public IntegerSlider WithGetter(Func<int> getter)
		{
			Get = getter ?? throw new ArgumentNullException("Getter cannot be null.");
			return this;
		}

		public IntegerSlider WithSetter(Action<int> setter)
		{
			Set = setter ?? throw new ArgumentNullException("Setter cannot be null.");
			return this;
		}

		public IntegerSlider WithDefaultValue(int defaultValue)
		{
			DefaultValue = defaultValue;
			return this;
		}

		public IntegerSlider LimitedByRange(int minimum, int maximum)
		{
			if (Minimum > Maximum)
			{
				throw new ArgumentOutOfRangeException("Minimum must be lower than maximum.");
			}
			Minimum = minimum;
			Maximum = maximum;
			return this;
		}

		public override void Tweak(ModdingMenu menu)
		{
			if (Get == null || Set == null)
			{
				throw new InvalidOperationException("Cannot invoke tweak with Get or Set being null.");
			}
			((SuperMenu)menu).TweakInt(base.Name, Get(), Minimum, Maximum, DefaultValue, Set, base.Description);
			base.Tweak(menu);
		}
	}
	public class ListBox<T> : MenuItemBase
	{
		public Func<T> Get { get; set; }

		public Action<T> Set { get; set; }

		public Dictionary<string, T> Entries { get; set; }

		public ListBox(MenuDisplayMode mode, string id, string name)
			: base(mode, id, name)
		{
		}

		public ListBox<T> WithGetter(Func<T> getter)
		{
			Get = getter ?? throw new ArgumentNullException("Getter cannot be null.");
			return this;
		}

		public ListBox<T> WithSetter(Action<T> setter)
		{
			Set = setter ?? throw new ArgumentNullException("Setter cannot be null.");
			return this;
		}

		public ListBox<T> WithEntries(Dictionary<string, T> entries)
		{
			if (entries == null)
			{
				entries = new Dictionary<string, T>();
			}
			Entries = entries;
			return this;
		}

		public override void Tweak(ModdingMenu menu)
		{
			if (Get == null || Set == null)
			{
				throw new InvalidOperationException("Cannot call TweakEnum with Get or Set being null.");
			}
			((SuperMenu)menu).TweakEnum<T>(base.Name, Get, Set, base.Description, ICollectionEx.ToArray<KeyValuePair<string, T>>((ICollection<KeyValuePair<string, T>>)Entries));
			base.Tweak(menu);
		}
	}
	public abstract class MenuItemBase
	{
		public MenuDisplayMode Mode { get; }

		public string Id { get; }

		public string Name { get; set; }

		public string Description { get; set; }

		protected MenuItemBase(MenuDisplayMode mode, string id, string name)
		{
			Mode = mode;
			Id = id;
			Name = name;
		}

		public MenuItemBase WithDescription(string description)
		{
			Description = description;
			return this;
		}

		public virtual void Tweak(ModdingMenu menu)
		{
			GameObject[] array = (from x in GameObjectEx.GetChildren(menu.OptionsTable)
				where string.Equals(((Object)x).name, Name)
				select x).ToArray();
			GameObject val = null;
			if (array.Length != 0)
			{
				val = array[0];
			}
			if ((Object)(object)val != (Object)null)
			{
				MenuItemInfo menuItemInfo = val.AddComponent<MenuItemInfo>();
				menuItemInfo.Item = this;
			}
		}
	}
	public class PasswordPrompt : InputPrompt
	{
		public PasswordPrompt(MenuDisplayMode mode, string id, string name)
			: base(mode, id, name)
		{
		}

		protected override void OnTweak()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0031: Expected O, but got Unknown
			InputPromptPanel.CreatePassword(new OnSubmit(OnSubmit), new OnPop(OnCancel), base.Title, base.DefaultValue());
		}
	}
	public class SubMenu : MenuItemBase
	{
		public MenuTree MenuTree { get; private set; }

		public SubMenu(MenuDisplayMode mode, string id, string name)
			: base(mode, id, name)
		{
		}

		public SubMenu NavigatesTo(MenuTree menuTree)
		{
			MenuTree = menuTree;
			return this;
		}

		public override void Tweak(ModdingMenu menu)
		{
			((SuperMenu)menu).TweakAction(base.Name, (Action)delegate
			{
				MenuSystem.ShowMenu(MenuTree, menu, 0);
				base.Tweak(menu);
			}, base.Description);
		}
	}
}