Decompiled source of ModMenu v1.0.2

plugins\ModMenu\ModMenu.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using Assets.Scripts.UI;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using DRS.UI;
using FundayFactory.UI;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ModMenu")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyProduct("ModMenu")]
[assembly: AssemblyTitle("ModMenu")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ModMenu
{
	internal enum ControlKind
	{
		Toggle,
		Slider,
		Choice,
		ReadOnly
	}
	internal class ModConfig
	{
		public string Name;

		public ConfigFile File;

		public List<ConfigEntryBase> Entries = new List<ConfigEntryBase>();
	}
	internal class EntryView
	{
		public ConfigEntryBase Entry;

		public ControlKind Kind;

		public float Min;

		public float Max;

		public bool Whole;

		public object[] Choices;
	}
	internal static class Configs
	{
		public static List<ModConfig> All()
		{
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			List<ModConfig> list = new List<ModConfig>();
			try
			{
				foreach (KeyValuePair<string, PluginInfo> plugin in ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins)
				{
					PluginInfo value = plugin.Value;
					object obj = ((value != null) ? value.Instance : null);
					BasePlugin val = (BasePlugin)((obj is BasePlugin) ? obj : null);
					if (val == null || val.Config == null)
					{
						continue;
					}
					List<ConfigEntryBase> list2 = new List<ConfigEntryBase>();
					foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in val.Config)
					{
						list2.Add(item.Value);
					}
					if (list2.Count != 0)
					{
						list.Add(new ModConfig
						{
							Name = value.Metadata.Name,
							File = val.Config,
							Entries = list2
						});
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(20, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Couldn't list mods: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				logger.LogError(val2);
			}
			return list.OrderBy<ModConfig, string>((ModConfig m) => m.Name, StringComparer.OrdinalIgnoreCase).ToList();
		}

		public static EntryView Describe(ConfigEntryBase e)
		{
			EntryView entryView = new EntryView
			{
				Entry = e
			};
			Type settingType = e.SettingType;
			ConfigDescription description = e.Description;
			AcceptableValueBase val = ((description != null) ? description.AcceptableValues : null);
			if (settingType == typeof(bool))
			{
				entryView.Kind = ControlKind.Toggle;
				return entryView;
			}
			if (settingType.IsEnum)
			{
				entryView.Kind = ControlKind.Choice;
				entryView.Choices = Enum.GetValues(settingType).Cast<object>().ToArray();
				return entryView;
			}
			if (val != null && ((object)val).GetType().IsGenericType && ((object)val).GetType().GetGenericTypeDefinition() == typeof(AcceptableValueList<>))
			{
				Array source = (Array)((object)val).GetType().GetProperty("AcceptableValues").GetValue(val);
				entryView.Kind = ControlKind.Choice;
				entryView.Choices = source.Cast<object>().ToArray();
				return entryView;
			}
			bool flag = settingType == typeof(int) || settingType == typeof(long) || settingType == typeof(short) || settingType == typeof(byte);
			bool flag2 = settingType == typeof(float) || settingType == typeof(double) || settingType == typeof(decimal);
			if (flag || flag2)
			{
				entryView.Kind = ControlKind.Slider;
				entryView.Whole = flag;
				if (val != null && ((object)val).GetType().IsGenericType && ((object)val).GetType().GetGenericTypeDefinition() == typeof(AcceptableValueRange<>))
				{
					entryView.Min = Convert.ToSingle(((object)val).GetType().GetProperty("MinValue").GetValue(val));
					entryView.Max = Convert.ToSingle(((object)val).GetType().GetProperty("MaxValue").GetValue(val));
				}
				else
				{
					float num = Convert.ToSingle(e.DefaultValue);
					float num2 = Convert.ToSingle(e.BoxedValue);
					float num3 = Math.Max(Math.Max(Math.Abs(num), Math.Abs(num2)), 1f);
					entryView.Min = ((num < 0f || num2 < 0f) ? ((0f - num3) * 2f) : 0f);
					entryView.Max = (flag ? Math.Max(10f, (float)Math.Ceiling(num3 * 4f)) : Math.Max(1f, num3 * 4f));
				}
				return entryView;
			}
			entryView.Kind = ControlKind.ReadOnly;
			return entryView;
		}

		public static float ToFloat(object o)
		{
			try
			{
				return Convert.ToSingle(o);
			}
			catch
			{
				return 0f;
			}
		}

		public static object FromFloat(float f, Type t)
		{
			if (t == typeof(float))
			{
				return (float)Math.Round(f, 3);
			}
			if (t == typeof(double))
			{
				return Math.Round(f, 3);
			}
			if (t == typeof(decimal))
			{
				return (decimal)Math.Round(f, 3);
			}
			return Convert.ChangeType(Math.Round(f), t);
		}

		public static string Pretty(string key)
		{
			return Regex.Replace(Regex.Replace(key ?? "", "([a-z0-9])([A-Z])", "$1 $2"), "([A-Z]+)([A-Z][a-z])", "$1 $2").Replace('_', ' ').Trim();
		}

		public static string Format(object o)
		{
			if (!(o is float num))
			{
				if (!(o is double num2))
				{
					if (!(o is Enum obj))
					{
						if (o == null)
						{
							return "";
						}
						return o.ToString();
					}
					return Pretty(obj.ToString());
				}
				return num2.ToString("0.##");
			}
			return num.ToString("0.##");
		}
	}
	internal static class MenuBuilder
	{
		private static IntPtr builtFor;

		internal static GameObject ToggleTpl;

		internal static GameObject SliderTpl;

		internal static GameObject SelectorTpl;

		internal static Transform Content;

		public static void Build(UISettingsForm form)
		{
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Expected O, but got Unknown
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)form == (Object)null || ((Il2CppObjectBase)form).Pointer == builtFor)
			{
				return;
			}
			Transform transform = ((Component)form).transform;
			Transform val = transform.Find("Window/Content/PageContent");
			Transform val2 = transform.Find("Window/Content/MenuTabs");
			Transform val3 = ((val != null) ? val.Find("AboutPage") : null);
			Transform val4 = ((val != null) ? val.Find("GameplayPage") : null);
			Transform val5 = ((val2 != null) ? val2.Find("MenuTabButton_Legal") : null);
			if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null)
			{
				Plugin.Logger.LogError((object)"Settings menu layout not as expected (game update?). Mods tab not added.");
				builtFor = ((Il2CppObjectBase)form).Pointer;
				return;
			}
			Transform obj = val4.Find("UIToggle_Rumble");
			ToggleTpl = ((obj != null) ? ((Component)obj).gameObject : null);
			Transform obj2 = val4.Find("SettingsSliderCamShake");
			SliderTpl = ((obj2 != null) ? ((Component)obj2).gameObject : null);
			Transform obj3 = val4.Find("Locale_StepSelector");
			SelectorTpl = ((obj3 != null) ? ((Component)obj3).gameObject : null);
			if ((Object)(object)ToggleTpl == (Object)null || (Object)(object)SliderTpl == (Object)null || (Object)(object)SelectorTpl == (Object)null)
			{
				Plugin.Logger.LogError((object)"Couldn't find the toggle/slider/selector templates. Mods tab not added.");
				builtFor = ((Il2CppObjectBase)form).Pointer;
				return;
			}
			GameObject val6 = Object.Instantiate<GameObject>(((Component)val3).gameObject, val, false);
			((Object)val6).name = "ModsPage";
			val6.SetActive(false);
			UIPage component = val6.GetComponent<UIPage>();
			Transform val7 = val6.transform.Find("Scroll View/Viewport/Content");
			for (int i = 0; i < val7.childCount; i++)
			{
				((Component)val7.GetChild(i)).gameObject.SetActive(false);
			}
			RectTransform component2 = ((Component)val7).GetComponent<RectTransform>();
			component2.sizeDelta = new Vector2(1300f, component2.sizeDelta.y);
			VerticalLayoutGroup obj4 = ((Component)val7).gameObject.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj4).spacing = 26f;
			((LayoutGroup)obj4).padding.top = 30;
			((LayoutGroup)obj4).padding.bottom = 60;
			((LayoutGroup)obj4).childAlignment = (TextAnchor)1;
			((HorizontalOrVerticalLayoutGroup)obj4).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj4).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandHeight = false;
			((Component)val7).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			Content = val7;
			((UIPageAlbum)form).pages.Add(component);
			GameObject val8 = Object.Instantiate<GameObject>(((Component)val5).gameObject, val2, false);
			((Object)val8).name = "MenuTabButton_Mods";
			val8.transform.SetSiblingIndex(val5.GetSiblingIndex() + 1);
			StripLocalisation(val8);
			string[] array = new string[2] { "HoverGlow", "ActiveBackground" };
			foreach (string text in array)
			{
				Transform obj5 = val8.transform.Find(text);
				if (obj5 != null)
				{
					((Component)obj5).gameObject.SetActive(false);
				}
			}
			TMP_Text componentInChildren = val8.GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.text = "Mods";
				Transform obj6 = val2.Find("MenuTabButton_GamePlay");
				TMP_Text val9 = ((obj6 != null) ? ((Component)obj6).GetComponentInChildren<TMP_Text>(true) : null);
				((Graphic)componentInChildren).color = new Color(0.855f, 0.863f, 0.898f, 1f);
				if ((Object)(object)val9 != (Object)null && (Object)(object)val9.fontSharedMaterial != (Object)null)
				{
					componentInChildren.fontSharedMaterial = val9.fontSharedMaterial;
				}
			}
			UIPageTab component3 = val8.GetComponent<UIPageTab>();
			component3.page = component;
			component3.uiPageAlbum = (UIFormTabbedPageAlbum)(object)form;
			FitTabs(val2);
			val6.AddComponent<ModsPageDriver>();
			builtFor = ((Il2CppObjectBase)form).Pointer;
			ManualLogSource logger = Plugin.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val10 = new BepInExInfoLogInterpolatedStringHandler(37, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val10).AppendLiteral("Mods tab added (");
				((BepInExLogInterpolatedStringHandler)val10).AppendFormatted<int>(Configs.All().Count);
				((BepInExLogInterpolatedStringHandler)val10).AppendLiteral(" mods with settings).");
			}
			logger.LogInfo(val10);
		}

		private static void FitTabs(Transform tabs)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			List<RectTransform> list = new List<RectTransform>();
			for (int i = 0; i < tabs.childCount; i++)
			{
				Transform child = tabs.GetChild(i);
				if (((Object)child).name.StartsWith("MenuTabButton"))
				{
					list.Add(((Component)child).GetComponent<RectTransform>());
				}
			}
			if (list.Count == 0)
			{
				return;
			}
			Rect rect = ((Component)tabs).GetComponent<RectTransform>().rect;
			float num = Mathf.Clamp((((Rect)(ref rect)).width - 96f - (float)(list.Count + 1) * 4f) / (float)list.Count, 120f, 204f);
			foreach (RectTransform item in list)
			{
				item.sizeDelta = new Vector2(num, item.sizeDelta.y);
				Transform obj = ((Transform)item).Find("ActiveBackground");
				RectTransform val = ((obj != null) ? ((Component)obj).GetComponent<RectTransform>() : null);
				if ((Object)(object)val != (Object)null)
				{
					val.sizeDelta = new Vector2(num - 14f, val.sizeDelta.y);
				}
			}
		}

		internal static void StripLocalisation(GameObject go)
		{
			foreach (Component componentsInChild in go.GetComponentsInChildren<Component>(true))
			{
				if (!((Object)(object)componentsInChild == (Object)null) && ((Object)componentsInChild).GetIl2CppType().FullName.Contains("LocalizeStringEvent"))
				{
					Object.DestroyImmediate((Object)(object)componentsInChild);
				}
			}
		}

		internal static GameObject CloneRow(GameObject tpl, string name)
		{
			GameObject val = Object.Instantiate<GameObject>(tpl, Content, false);
			((Object)val).name = name;
			StripLocalisation(val);
			foreach (Toggle componentsInChild in val.GetComponentsInChildren<Toggle>(true))
			{
				GameObject gameObject = ((Component)componentsInChild).gameObject;
				Graphic graphic = componentsInChild.graphic;
				Graphic targetGraphic = ((Selectable)componentsInChild).targetGraphic;
				Object.DestroyImmediate((Object)(object)componentsInChild);
				Toggle val2 = gameObject.AddComponent<Toggle>();
				val2.graphic = graphic;
				((Selectable)val2).targetGraphic = targetGraphic;
				Repoint(gameObject, (Selectable)(object)val2);
			}
			foreach (Slider componentsInChild2 in val.GetComponentsInChildren<Slider>(true))
			{
				GameObject gameObject2 = ((Component)componentsInChild2).gameObject;
				RectTransform fillRect = componentsInChild2.fillRect;
				RectTransform handleRect = componentsInChild2.handleRect;
				Graphic targetGraphic2 = ((Selectable)componentsInChild2).targetGraphic;
				Object.DestroyImmediate((Object)(object)componentsInChild2);
				Slider val3 = gameObject2.AddComponent<Slider>();
				val3.fillRect = fillRect;
				val3.handleRect = handleRect;
				((Selectable)val3).targetGraphic = targetGraphic2;
				val3.direction = (Direction)0;
				Repoint(gameObject2, (Selectable)(object)val3);
			}
			val.SetActive(true);
			return val;
		}

		private static void Repoint(GameObject go, Selectable fresh)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			bool flag = default(bool);
			foreach (UISelectable component in go.GetComponents<UISelectable>())
			{
				try
				{
					component.selectable = fresh;
				}
				catch (Exception ex)
				{
					ManualLogSource logger = Plugin.Logger;
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(47, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Couldn't re-link highlight on ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)go).name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("); removing it.");
					}
					logger.LogWarning(val);
					Object.DestroyImmediate((Object)(object)component);
				}
			}
		}
	}
	public class ModsPageDriver : MonoBehaviour
	{
		public ModsPageDriver(IntPtr ptr)
			: base(ptr)
		{
		}

		private void OnEnable()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			try
			{
				ModsPage.OnShown();
			}
			catch (Exception ex)
			{
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(11, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Mods page: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				logger.LogError(val);
			}
		}

		private void Update()
		{
			try
			{
				ModsPage.Poll();
			}
			catch (Exception e)
			{
				ModsPage.LogOnce(e);
			}
		}

		private void LateUpdate()
		{
			try
			{
				ModsPage.RefreshTexts();
			}
			catch (Exception e)
			{
				ModsPage.LogOnce(e);
			}
		}
	}
	internal static class ModsPage
	{
		private class Row
		{
			public GameObject Go;

			public EntryView View;

			public Toggle Toggle;

			public Slider Slider;

			public StepSelectorBase Selector;

			public TMP_Text ValueText;

			public bool IsModPicker;

			public float LastControl;

			public float LastEntry;
		}

		private static readonly List<Row> Rows = new List<Row>();

		private static List<ModConfig> mods = new List<ModConfig>();

		private static int modIndex;

		private static bool rebuildPending;

		private static readonly HashSet<ConfigFile> Dirty = new HashSet<ConfigFile>();

		private static float saveAt;

		private static bool loggedError;

		public static void LogOnce(Exception e)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!loggedError)
			{
				loggedError = true;
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(11, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Mods page: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(e);
				}
				logger.LogError(val);
			}
		}

		public static void OnShown()
		{
			List<ModConfig> list = Configs.All();
			string current = ((modIndex < mods.Count) ? mods[modIndex].Name : null);
			mods = list;
			modIndex = Math.Max(0, mods.FindIndex((ModConfig m) => m.Name == current));
			Rebuild();
		}

		private static void Rebuild()
		{
			foreach (Row row in Rows)
			{
				if ((Object)(object)row.Go != (Object)null && !((Il2CppObjectBase)row.Go).WasCollected)
				{
					Object.Destroy((Object)(object)row.Go);
				}
			}
			Rows.Clear();
			if ((Object)(object)MenuBuilder.Content == (Object)null)
			{
				return;
			}
			if (mods.Count == 0)
			{
				Header("No mods with settings found");
				return;
			}
			MakeChoice("Mod", ((IEnumerable<ModConfig>)mods).Select((Func<ModConfig, object>)((ModConfig m) => m.Name)).ToArray(), modIndex).IsModPicker = true;
			foreach (IGrouping<string, ConfigEntryBase> item in from val2 in mods[modIndex].Entries
				group val2 by val2.Definition.Section)
			{
				Header(item.Key);
				foreach (ConfigEntryBase e in item)
				{
					EntryView entryView = Configs.Describe(e);
					switch (entryView.Kind)
					{
					case ControlKind.Toggle:
						MakeToggle(entryView);
						break;
					case ControlKind.Slider:
						MakeSlider(entryView);
						break;
					case ControlKind.Choice:
					{
						int val = Array.FindIndex(entryView.Choices, (object c) => object.Equals(c, e.BoxedValue));
						MakeChoice(Configs.Pretty(e.Definition.Key), entryView.Choices, Math.Max(0, val)).View = entryView;
						break;
					}
					default:
						ReadOnly(entryView);
						break;
					}
				}
			}
			try
			{
				ScrollRect componentInParent = ((Component)MenuBuilder.Content).GetComponentInParent<ScrollRect>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					componentInParent.verticalNormalizedPosition = 1f;
				}
			}
			catch
			{
			}
		}

		private static TMP_Text Text(GameObject go, string path)
		{
			Transform obj = go.transform.Find(path);
			if (obj == null)
			{
				return null;
			}
			return ((Component)obj).GetComponent<TMP_Text>();
		}

		private static void Header(string title)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = MenuBuilder.CloneRow(MenuBuilder.ToggleTpl, "Header");
			Toggle component = val.GetComponent<Toggle>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			Transform obj = val.transform.Find("Background");
			if (obj != null)
			{
				((Component)obj).gameObject.SetActive(false);
			}
			TMP_Text val2 = Text(val, "Label");
			if ((Object)(object)val2 != (Object)null)
			{
				val2.text = title.ToUpperInvariant();
				((Graphic)val2).color = new Color(1f, 0.612f, 0f, 1f);
				val2.alignment = (TextAlignmentOptions)514;
				RectTransform rectTransform = val2.rectTransform;
				rectTransform.anchorMin = new Vector2(0f, 0.5f);
				rectTransform.anchorMax = new Vector2(1f, 0.5f);
				rectTransform.anchoredPosition = Vector2.zero;
				rectTransform.sizeDelta = new Vector2(0f, rectTransform.sizeDelta.y);
			}
			Rows.Add(new Row
			{
				Go = val
			});
		}

		private static void MakeToggle(EntryView v)
		{
			GameObject val = MenuBuilder.CloneRow(MenuBuilder.ToggleTpl, "Toggle_" + v.Entry.Definition.Key);
			TMP_Text val2 = Text(val, "Label");
			if ((Object)(object)val2 != (Object)null)
			{
				val2.text = Configs.Pretty(v.Entry.Definition.Key);
			}
			Toggle component = val.GetComponent<Toggle>();
			bool flag = (bool)v.Entry.BoxedValue;
			component.isOn = flag;
			Rows.Add(new Row
			{
				Go = val,
				View = v,
				Toggle = component,
				LastControl = (flag ? 1 : 0),
				LastEntry = (flag ? 1 : 0)
			});
		}

		private static void MakeSlider(EntryView v)
		{
			GameObject val = MenuBuilder.CloneRow(MenuBuilder.SliderTpl, "Slider_" + v.Entry.Definition.Key);
			TMP_Text val2 = Text(val, "MasterSlider/NameText");
			if ((Object)(object)val2 != (Object)null)
			{
				val2.text = Configs.Pretty(v.Entry.Definition.Key);
			}
			Slider component = val.GetComponent<Slider>();
			component.minValue = v.Min;
			component.maxValue = v.Max;
			component.wholeNumbers = v.Whole;
			float lastEntry = (component.value = Configs.ToFloat(v.Entry.BoxedValue));
			Rows.Add(new Row
			{
				Go = val,
				View = v,
				Slider = component,
				ValueText = Text(val, "MasterSlider/ValueText"),
				LastControl = component.value,
				LastEntry = lastEntry
			});
		}

		private static Row MakeChoice(string title, object[] options, int index)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = MenuBuilder.CloneRow(MenuBuilder.SelectorTpl, "Choice_" + title);
			TMP_Text val2 = Text(val, "Title");
			if ((Object)(object)val2 != (Object)null)
			{
				val2.text = title;
				val2.rectTransform.sizeDelta = new Vector2(360f, val2.rectTransform.sizeDelta.y);
				val2.enableAutoSizing = true;
				val2.fontSizeMin = 14f;
				val2.fontSizeMax = 24f;
			}
			StepSelectorBase component = val.GetComponent<StepSelectorBase>();
			component.ListMaxSize = options.Length;
			component.SetIndex(index, false);
			Row row = new Row
			{
				Go = val,
				Selector = component,
				ValueText = Text(val, "Current_Selected_Text"),
				LastControl = index,
				LastEntry = index,
				View = new EntryView
				{
					Kind = ControlKind.Choice,
					Choices = options
				}
			};
			Rows.Add(row);
			return row;
		}

		private static void ReadOnly(EntryView v)
		{
			GameObject val = MenuBuilder.CloneRow(MenuBuilder.ToggleTpl, "ReadOnly_" + v.Entry.Definition.Key);
			Toggle component = val.GetComponent<Toggle>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			Transform obj = val.transform.Find("Background");
			if (obj != null)
			{
				((Component)obj).gameObject.SetActive(false);
			}
			TMP_Text val2 = Text(val, "Label");
			if ((Object)(object)val2 != (Object)null)
			{
				val2.text = $"{Configs.Pretty(v.Entry.Definition.Key)}: {v.Entry.BoxedValue}";
			}
			Rows.Add(new Row
			{
				Go = val,
				View = v
			});
		}

		public static void Poll()
		{
			//IL_041f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Expected O, but got Unknown
			if (rebuildPending)
			{
				rebuildPending = false;
				Rebuild();
				return;
			}
			foreach (Row r in Rows)
			{
				if ((Object)(object)r.Go == (Object)null || ((Il2CppObjectBase)r.Go).WasCollected)
				{
					continue;
				}
				if ((Object)(object)r.Toggle != (Object)null)
				{
					float num = (r.Toggle.isOn ? 1 : 0);
					float num2 = (((bool)r.View.Entry.BoxedValue) ? 1 : 0);
					if (num != r.LastControl)
					{
						Set(r.View.Entry, num > 0.5f);
						r.LastControl = num;
						r.LastEntry = num;
					}
					else if (num2 != r.LastEntry)
					{
						r.Toggle.isOn = num2 > 0.5f;
						r.LastControl = (r.LastEntry = num2);
					}
				}
				else if ((Object)(object)r.Slider != (Object)null)
				{
					float value = r.Slider.value;
					float num3 = Configs.ToFloat(r.View.Entry.BoxedValue);
					if (Math.Abs(value - r.LastControl) > 0.0001f)
					{
						Set(r.View.Entry, Configs.FromFloat(value, r.View.Entry.SettingType));
						r.LastControl = value;
						r.LastEntry = Configs.ToFloat(r.View.Entry.BoxedValue);
					}
					else if (Math.Abs(num3 - r.LastEntry) > 0.0001f)
					{
						r.Slider.value = num3;
						r.LastControl = r.Slider.value;
						r.LastEntry = num3;
					}
				}
				else
				{
					if (!((Object)(object)r.Selector != (Object)null))
					{
						continue;
					}
					int num4 = r.View.Choices.Length;
					int num5 = r.Selector.CurrentIndex;
					if (num5 < 0 || num5 >= num4)
					{
						num5 = (num5 % num4 + num4) % num4;
						r.Selector.SetIndex(num5, false);
					}
					if (num5 != (int)r.LastControl)
					{
						r.LastControl = num5;
						if (r.IsModPicker)
						{
							modIndex = num5;
							rebuildPending = true;
							return;
						}
						Set(r.View.Entry, r.View.Choices[num5]);
						r.LastEntry = num5;
					}
					else if (r.View.Entry != null)
					{
						int num6 = Array.FindIndex(r.View.Choices, (object c) => object.Equals(c, r.View.Entry.BoxedValue));
						if (num6 >= 0 && num6 != (int)r.LastEntry)
						{
							r.Selector.SetIndex(num6, false);
							r.LastControl = (r.LastEntry = num6);
						}
					}
				}
			}
			if (Dirty.Count <= 0 || !(Time.unscaledTime >= saveAt))
			{
				return;
			}
			bool flag = default(bool);
			foreach (ConfigFile item in Dirty)
			{
				try
				{
					item.Save();
				}
				catch (Exception ex)
				{
					ManualLogSource logger = Plugin.Logger;
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(13, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Save failed: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					}
					logger.LogWarning(val);
				}
			}
			Dirty.Clear();
		}

		public static void RefreshTexts()
		{
			foreach (Row row in Rows)
			{
				if (!((Object)(object)row.Go == (Object)null) && !((Il2CppObjectBase)row.Go).WasCollected && !((Object)(object)row.ValueText == (Object)null))
				{
					if ((Object)(object)row.Slider != (Object)null)
					{
						row.ValueText.text = (row.View.Whole ? ((long)Math.Round(row.Slider.value)).ToString() : row.Slider.value.ToString("0.##"));
					}
					else if ((Object)(object)row.Selector != (Object)null)
					{
						int num = Mathf.Clamp(row.Selector.CurrentIndex, 0, row.View.Choices.Length - 1);
						row.ValueText.text = Configs.Format(row.View.Choices[num]);
					}
				}
			}
		}

		private static void Set(ConfigEntryBase entry, object value)
		{
			ConfigFile configFile = entry.ConfigFile;
			bool saveOnConfigSet = configFile.SaveOnConfigSet;
			try
			{
				configFile.SaveOnConfigSet = false;
				entry.BoxedValue = value;
			}
			finally
			{
				configFile.SaveOnConfigSet = saveOnConfigSet;
			}
			Dirty.Add(configFile);
			saveAt = Time.unscaledTime + 0.5f;
		}
	}
	[BepInPlugin("tobipolar.drgs.modmenu", "Mod Menu", "1.0.2")]
	public class Plugin : BasePlugin
	{
		public const string Guid = "tobipolar.drgs.modmenu";

		public const string Name = "Mod Menu";

		public const string Version = "1.0.2";

		internal static ManualLogSource Logger;

		private void MigrateOldConfig(params string[] oldNames)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				string configFilePath = ((BasePlugin)this).Config.ConfigFilePath;
				if (File.Exists(configFilePath) && new FileInfo(configFilePath).Length != 0)
				{
					return;
				}
				foreach (string text in oldNames)
				{
					string text2 = Path.Combine(Paths.ConfigPath, text);
					if (File.Exists(text2))
					{
						File.Copy(text2, configFilePath, overwrite: true);
						((BasePlugin)this).Config.Reload();
						ManualLogSource log = ((BasePlugin)this).Log;
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(56, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Settings copied from the old ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". You can delete that file.");
						}
						log.LogInfo(val);
						break;
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = ((BasePlugin)this).Log;
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Couldn't copy old settings: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log2.LogWarning(val2);
			}
		}

		public override void Load()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			Logger = ((BasePlugin)this).Log;
			MigrateOldConfig("toby.drgs.modmenu.cfg");
			bool flag = default(bool);
			try
			{
				ClassInjector.RegisterTypeInIl2Cpp<ModsPageDriver>();
			}
			catch (Exception ex)
			{
				ManualLogSource logger = Logger;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(31, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Couldn't register page driver: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				logger.LogError(val);
			}
			Harmony.CreateAndPatchAll(typeof(Patches), "tobipolar.drgs.modmenu");
			ManualLogSource logger2 = Logger;
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(9, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("Mod Menu");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("1.0.2");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" loaded.");
			}
			logger2.LogInfo(val2);
		}
	}
	internal static class Patches
	{
		[HarmonyPatch(typeof(UISettingsForm), "Show")]
		[HarmonyPrefix]
		private static void BeforeShow(UISettingsForm __instance)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			try
			{
				MenuBuilder.Build(__instance);
			}
			catch (Exception ex)
			{
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(30, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Building the Mods tab failed: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				logger.LogError(val);
			}
		}
	}
}