Decompiled source of REPOConfig v1.0.1

REPOConfig.dll

Decompiled 6 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("REPOConfig")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("REPOConfig")]
[assembly: AssemblyTitle("REPOConfig")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 REPOConfig
{
	[BepInPlugin("nickklmao.repoconfig", "REPO Config", "1.0.0")]
	internal sealed class Entry : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action<Action<MenuManager>, MenuManager> <0>__MenuManager_StartHook;

			public static Action<Action<MenuSlider>, MenuSlider> <1>__MenuSlider_StartHook;

			public static Action<Action<MenuPage>, MenuPage> <2>__MenuPage_StartHook;

			public static Manipulator <3>__MenuButton_OnSelectILHook;
		}

		private const string MOD_NAME = "REPO Config";

		internal static readonly ManualLogSource logger = Logger.CreateLogSource("REPO Config");

		private static void MenuManager_StartHook(Action<MenuManager> orig, MenuManager self)
		{
			orig(self);
			ModMenu.Initialize();
		}

		private static void MenuSlider_StartHook(Action<MenuSlider> orig, MenuSlider self)
		{
			orig(self);
			if (ModMenu.lateSliderSetup.TryGetValue(self, out var value))
			{
				((MonoBehaviour)self).StartCoroutine(SetupSlidersLate(self, value));
			}
			static IEnumerator SetupSlidersLate(MenuSlider slider, Action setupAction)
			{
				yield return null;
				setupAction?.Invoke();
				ModMenu.lateSliderSetup.Remove(slider);
			}
		}

		private static void MenuPage_StartHook(Action<MenuPage> orig, MenuPage self)
		{
			orig(self);
			if (ModMenu.latePageSetup.TryGetValue(self, out var value))
			{
				((MonoBehaviour)self).StartCoroutine(SetupPageLate(self, value));
			}
			static IEnumerator SetupPageLate(MenuPage menuPage, Action setupAction)
			{
				yield return null;
				setupAction?.Invoke();
				ModMenu.latePageSetup.Remove(menuPage);
			}
		}

		private static void MenuButton_OnSelectILHook(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			val.GotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction instruction) => ILPatternMatchingExt.MatchLdfld<MenuButton>(instruction, "button")
			});
			int index = val.Index;
			val.Index = index - 1;
			val.RemoveRange(4);
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Action<MenuButton>>((Action<MenuButton>)delegate(MenuButton menuButton)
			{
				if (ModMenu.customMenuButtonActions.TryGetValue(((Object)menuButton).name, out var value))
				{
					value?.Invoke();
				}
				else
				{
					object? value2 = AccessTools.Field(typeof(MenuButton), "button").GetValue(menuButton);
					object? obj = ((value2 is Button) ? value2 : null);
					if (obj != null)
					{
						ButtonClickedEvent onClick = ((Button)obj).onClick;
						if (onClick != null)
						{
							((UnityEvent)onClick).Invoke();
						}
					}
				}
			});
		}

		private void Awake()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			logger.LogDebug((object)"Hooking `MenuManager.Start`");
			new Hook((MethodBase)AccessTools.Method(typeof(MenuManager), "Start", (Type[])null, (Type[])null), (Delegate)new Action<Action<MenuManager>, MenuManager>(MenuManager_StartHook));
			logger.LogDebug((object)"Hooking `MenuSlider.Start`");
			new Hook((MethodBase)AccessTools.Method(typeof(MenuSlider), "Start", (Type[])null, (Type[])null), (Delegate)new Action<Action<MenuSlider>, MenuSlider>(MenuSlider_StartHook));
			logger.LogDebug((object)"Hooking `MenuPage.Start`");
			new Hook((MethodBase)AccessTools.Method(typeof(MenuPage), "Start", (Type[])null, (Type[])null), (Delegate)new Action<Action<MenuPage>, MenuPage>(MenuPage_StartHook));
			logger.LogDebug((object)"Hooking `MenuButton.OnSelect`");
			MethodInfo methodInfo = AccessTools.Method(typeof(MenuButton), "OnSelect", (Type[])null, (Type[])null);
			object obj = <>O.<3>__MenuButton_OnSelectILHook;
			if (obj == null)
			{
				Manipulator val = MenuButton_OnSelectILHook;
				<>O.<3>__MenuButton_OnSelectILHook = val;
				obj = (object)val;
			}
			new ILHook((MethodBase)methodInfo, (Manipulator)obj);
		}
	}
	internal static class ModMenu
	{
		private struct ModConfigEntry
		{
			internal REPOConfigEntryAttribute repoConfigEntry;

			internal ConfigEntryBase configEntryBase;
		}

		internal static readonly Dictionary<string, Action> customMenuButtonActions = new Dictionary<string, Action>();

		internal static readonly Dictionary<MenuSlider, Action> lateSliderSetup = new Dictionary<MenuSlider, Action>();

		internal static readonly Dictionary<MenuPage, Action> latePageSetup = new Dictionary<MenuPage, Action>();

		private static readonly Dictionary<string, ModConfigEntry[]> modConfigEntries = new Dictionary<string, ModConfigEntry[]>();

		private static readonly Dictionary<MenuPageIndex, Transform> modButtons = new Dictionary<MenuPageIndex, Transform>();

		internal static void Initialize()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if (modConfigEntries.Count == 0)
			{
				GetModConfigEntries();
			}
			customMenuButtonActions.Clear();
			lateSliderSetup.Clear();
			latePageSetup.Clear();
			MenuPageIndex[] array = (MenuPageIndex[])(object)new MenuPageIndex[2]
			{
				default(MenuPageIndex),
				(MenuPageIndex)1
			};
			foreach (MenuPageIndex val in array)
			{
				if (!modButtons.TryGetValue(val, out var value) || !Object.op_Implicit((Object)(object)value))
				{
					CreateModsButton(val);
				}
			}
		}

		private static void GetModConfigEntries()
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				string name = assembly.GetName().Name;
				if (name.StartsWith("System.") || name.StartsWith("Unity.") || name.StartsWith("UnityEngine.") || name.StartsWith("Assembly-") || name.StartsWith("Photon") || assembly.GetTypes().All((Type type) => !type.IsSubclassOf(typeof(BaseUnityPlugin))))
				{
					continue;
				}
				List<ModConfigEntry> list = new List<ModConfigEntry>();
				Type[] types = assembly.GetTypes();
				foreach (Type type2 in types)
				{
					FieldInfo[] fields = type2.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (FieldInfo fieldInfo in fields)
					{
						if (!(fieldInfo.FieldType.BaseType == typeof(ConfigEntryBase)))
						{
							continue;
						}
						if (!fieldInfo.IsStatic || !fieldInfo.IsPublic)
						{
							Entry.logger.LogDebug((object)("Field \"" + fieldInfo.Name + "\" must be both public and static for it to be visible in the settings menu!"));
							continue;
						}
						object? value = fieldInfo.GetValue(null);
						ConfigEntryBase val = (ConfigEntryBase)((value is ConfigEntryBase) ? value : null);
						if (val == null)
						{
							Entry.logger.LogDebug((object)("Field \"" + fieldInfo.Name + "\" cannot be null, it will not be visible in the settings menu!"));
							continue;
						}
						list.Add(new ModConfigEntry
						{
							repoConfigEntry = fieldInfo.GetCustomAttribute<REPOConfigEntryAttribute>(),
							configEntryBase = val
						});
					}
					PropertyInfo[] properties = type2.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (PropertyInfo propertyInfo in properties)
					{
						if (!(propertyInfo.PropertyType.BaseType == typeof(ConfigEntryBase)))
						{
							continue;
						}
						MethodInfo getMethod = propertyInfo.GetGetMethod(nonPublic: true);
						if (!getMethod.IsStatic || !getMethod.IsPublic)
						{
							Entry.logger.LogDebug((object)("Property \"" + propertyInfo.Name + "\" must be both public and static for it to be visible in the settings menu!"));
							continue;
						}
						object? obj = getMethod.Invoke(null, null);
						ConfigEntryBase val2 = (ConfigEntryBase)((obj is ConfigEntryBase) ? obj : null);
						if (val2 == null)
						{
							Entry.logger.LogDebug((object)("Property \"" + propertyInfo.Name + "\" cannot be null, it will not be visible in the settings menu!"));
							continue;
						}
						list.Add(new ModConfigEntry
						{
							repoConfigEntry = propertyInfo.GetCustomAttribute<REPOConfigEntryAttribute>(),
							configEntryBase = val2
						});
					}
				}
				if (list.Count > 0)
				{
					modConfigEntries.TryAdd(name, list.ToArray());
				}
			}
		}

		private static MenuPage CreateModsPage()
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Expected O, but got Unknown
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0424: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Expected O, but got Unknown
			//IL_0435: Unknown result type (might be due to invalid IL or missing references)
			//IL_0446: Unknown result type (might be due to invalid IL or missing references)
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Expected O, but got Unknown
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Expected O, but got Unknown
			GameObject val = ((IEnumerable<MenuPages>)MenuManager.instance.menuPages).FirstOrDefault((Func<MenuPages, bool>)((MenuPages page) => (int)page.menuPageIndex == 2))?.menuPage;
			MenuPages? obj = ((IEnumerable<MenuPages>)MenuManager.instance.menuPages).FirstOrDefault((Func<MenuPages, bool>)((MenuPages page) => (int)page.menuPageIndex == 4));
			Transform val2 = ((obj != null) ? obj.menuPage.transform.Find("Menu Scroll Box") : null);
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2))
			{
				return null;
			}
			GameObject val3 = Object.Instantiate<GameObject>(val, ((Component)MenuHolder.instance).transform);
			((Object)val3).name = "Menu Page Mods";
			MenuPage component = val3.GetComponent<MenuPage>();
			component.menuPageIndex = (MenuPageIndex)(-1);
			string key = (((TMP_Text)component.menuHeader).text = (component.menuHeaderName = "Mods"));
			Transform val4 = null;
			Transform backButtonTransform = null;
			foreach (Transform item in ((Component)component).transform)
			{
				Transform val5 = item;
				if (!((Object)val5).name.Contains("Menu Button"))
				{
					continue;
				}
				key = ((Object)val5).name;
				if (!(key == "Menu Button - Back"))
				{
					if (key == "Menu Button - Gameplay")
					{
						val4 = val5;
					}
					else
					{
						Object.Destroy((Object)(object)((Component)val5).gameObject);
					}
				}
				else
				{
					backButtonTransform = val5;
				}
			}
			if (!Object.op_Implicit((Object)(object)val4))
			{
				throw new NullReferenceException("Gameplay button couldn't be found...");
			}
			MenuScrollBox menuScrollBox = ((Component)Object.Instantiate<Transform>(val2, val3.transform)).GetComponent<MenuScrollBox>();
			Transform obj2 = ((Component)menuScrollBox).transform.Find("Mask");
			RectTransform val6 = (RectTransform)obj2;
			((Transform)val6).localPosition = new Vector3(132f, 20f);
			val6.sizeDelta = new Vector2(180f, 283f);
			RectTransform val7 = (RectTransform)((Component)menuScrollBox).transform.Find("ScrollBoxHoverArea");
			((Transform)val7).localPosition = new Vector3(70f, 20f);
			val7.sizeDelta = new Vector2(250f, 340f);
			Transform val8 = obj2.Find("Scroller");
			val8.localPosition = new Vector3(33f, 300f);
			foreach (Transform item2 in ((Component)val8).transform)
			{
				Transform val9 = item2;
				key = ((Object)val9).name;
				if ((!(key == "[ALWAYS TOP CHILD]") && !(key == "[ALWAYS SECOND CHILD]")) || 1 == 0)
				{
					Object.Destroy((Object)(object)((Component)val9).gameObject);
				}
			}
			int num = -60;
			foreach (KeyValuePair<string, ModConfigEntry[]> modConfigEntry in modConfigEntries)
			{
				modConfigEntry.Deconstruct(out key, out var value);
				string modName = key;
				ModConfigEntry[] entries = value;
				Transform obj3 = Object.Instantiate<Transform>(val4, val8);
				((Object)obj3).name = "Menu Button - " + modName;
				((Component)obj3).transform.localPosition = new Vector3(-33f, (float)num);
				MenuButton component2 = ((Component)obj3).GetComponent<MenuButton>();
				TextMeshProUGUI componentInChildren = ((Component)component2).GetComponentInChildren<TextMeshProUGUI>();
				((TMP_Text)componentInChildren).text = ((modName.Length >= 19) ? (modName.Substring(0, 16) + "...") : modName);
				((RectTransform)((Component)component2).transform).sizeDelta = ((TMP_Text)componentInChildren).GetPreferredValues();
				Button component3 = ((Component)obj3).GetComponent<Button>();
				component3.onClick = new ButtonClickedEvent();
				((UnityEvent)component3.onClick).AddListener((UnityAction)delegate
				{
					MenuManager.instance.PageCloseAllAddedOnTop();
					OpenPageOnTop(CreateConfigPage(modName, entries));
				});
				num -= 42;
			}
			Transform parent = ((Transform)menuScrollBox.scrollBarBackground).parent;
			parent.localPosition = new Vector3(100f, 60f);
			RectTransform val10 = (RectTransform)parent.Find("Scroll Bar Bg (1)");
			RectTransform val11 = (RectTransform)parent.Find("Scroll Bar Bg (2)");
			val10.sizeDelta = new Vector2(24f, 244f);
			val11.sizeDelta = new Vector2(20f, 240f);
			menuScrollBox.scrollBarBackground.sizeDelta = new Vector2(40f, 240f);
			latePageSetup.Add(component, delegate
			{
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				AccessTools.Method(typeof(MenuScrollBox), "Start", (Type[])null, (Type[])null).Invoke(menuScrollBox, null);
				Rect rect = menuScrollBox.scrollBarBackground.rect;
				float num2 = ((Rect)(ref rect)).height / 1.1f;
				AccessTools.Field(typeof(MenuScrollBox), "scrollHandleTargetPosition").SetValue(menuScrollBox, num2);
				Vector3 localPosition = ((Transform)menuScrollBox.scrollHandle).localPosition;
				localPosition.y = num2;
				((Transform)menuScrollBox.scrollHandle).localPosition = localPosition;
				if (menuScrollBox.scrollBar.activeSelf)
				{
					backButtonTransform.localPosition = new Vector3(62f, 15f);
					menuScrollBox.heightPadding = 200f;
					AccessTools.Method(typeof(MenuScrollBox), "Start", (Type[])null, (Type[])null).Invoke(menuScrollBox, null);
				}
			});
			Object.Destroy((Object)(object)((Component)val4).gameObject);
			return component;
		}

		private static MenuPage CreateConfigPage(string modName, ModConfigEntry[] configEntries)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Expected O, but got Unknown
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Expected O, but got Unknown
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Expected O, but got Unknown
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Expected O, but got Unknown
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Expected O, but got Unknown
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Expected O, but got Unknown
			//IL_0a45: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a4a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a5d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0614: Unknown result type (might be due to invalid IL or missing references)
			//IL_061e: Expected O, but got Unknown
			//IL_0985: Unknown result type (might be due to invalid IL or missing references)
			//IL_098f: Expected O, but got Unknown
			GameObject val = ((IEnumerable<MenuPages>)MenuManager.instance.menuPages).FirstOrDefault((Func<MenuPages, bool>)((MenuPages page) => (int)page.menuPageIndex == 4))?.menuPage;
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, ((Component)MenuHolder.instance).transform);
			((Object)val2).name = "Menu Config Page - " + modName;
			MenuPage menuPage = val2.GetComponent<MenuPage>();
			menuPage.menuPageIndex = (MenuPageIndex)(-1);
			((TMP_Text)menuPage.menuHeader).text = (menuPage.menuHeaderName = ((modName.Length >= 19) ? (modName.Substring(0, 16) + "...") : modName));
			Transform obj = ((Component)menuPage).transform.Find("Menu Scroll Box/Mask/Scroller");
			MenuButtonPopUp componentInChildren = ((Component)obj).GetComponentInChildren<MenuButtonPopUp>();
			componentInChildren.headerText = "RESET " + modName + "?";
			componentInChildren.bodyText = "Reset all " + modName + (modName.EndsWith('s') ? "'" : "'s") + " settings to default?";
			componentInChildren.option1Event = new UnityEvent();
			componentInChildren.option1Event.AddListener((UnityAction)delegate
			{
				ModConfigEntry[] array5 = configEntries;
				for (int j = 0; j < array5.Length; j++)
				{
					ModConfigEntry modConfigEntry2 = array5[j];
					modConfigEntry2.configEntryBase.BoxedValue = modConfigEntry2.configEntryBase.DefaultValue;
				}
				MenuManager.instance.PageCloseAllAddedOnTop();
				OpenPageOnTop(CreateConfigPage(modName, configEntries));
			});
			MenuSettingElement[] componentsInChildren = ((Component)obj).GetComponentsInChildren<MenuSettingElement>();
			MenuSettingElement val3 = componentsInChildren.First((MenuSettingElement element) => ((Object)element).name.Contains("Bool"));
			MenuSettingElement val4 = componentsInChildren.First((MenuSettingElement element) => ((Object)element).name.Contains("Slider"));
			int num = -66;
			ModConfigEntry[] array = configEntries;
			for (int i = 0; i < array.Length; i++)
			{
				ModConfigEntry modConfigEntry = array[i];
				Transform val5 = null;
				ConfigEntryBase configEntryBase = modConfigEntry.configEntryBase;
				ConfigEntry<bool> val6 = configEntryBase as ConfigEntry<bool>;
				if (val6 == null)
				{
					ConfigEntry<int> val7 = configEntryBase as ConfigEntry<int>;
					if (val7 == null)
					{
						ConfigEntry<float> val8 = configEntryBase as ConfigEntry<float>;
						if (val8 != null)
						{
							val5 = ((Component)Object.Instantiate<MenuSettingElement>(val4, ((Component)val4).transform.parent)).transform;
							MenuSlider menuSlider2 = ((Component)val5).GetComponent<MenuSlider>();
							string entryName2 = modConfigEntry.repoConfigEntry?.displayName ?? modConfigEntry.configEntryBase.Definition.Key;
							((Object)menuSlider2).name = "Slider Setting - " + entryName2;
							Object.Destroy((Object)(object)((Component)menuSlider2).GetComponent<MenuSetting>());
							menuSlider2.customOptions.Clear();
							menuSlider2.hasCustomValues = false;
							menuSlider2.hasBar = true;
							menuSlider2.stringAtStartOfValue = modConfigEntry.repoConfigEntry?.prefix ?? string.Empty;
							menuSlider2.stringAtEndOfValue = modConfigEntry.repoConfigEntry?.postfix ?? string.Empty;
							string[] array2 = modConfigEntry.repoConfigEntry?.customOptions;
							if (array2 != null && array2.Length > 0)
							{
								menuSlider2.startValue = 0;
								menuSlider2.endValue = array2.Length - 1;
								menuSlider2.customOptions.AddRange(((IEnumerable<string>)array2).Select((Func<string, CustomOption>)((string option) => new CustomOption
								{
									customOptionText = option
								})));
								menuSlider2.hasCustomOptions = true;
								AccessTools.Field(typeof(MenuSlider), "settingSegments").SetValue(menuSlider2, array2.Length);
							}
							else
							{
								int? num2 = modConfigEntry.repoConfigEntry?.min;
								int? num3 = modConfigEntry.repoConfigEntry?.max;
								if (num2.HasValue && num3.HasValue)
								{
									menuSlider2.startValue = num2.Value;
									menuSlider2.endValue = num3.Value;
								}
								else
								{
									menuSlider2.hasBar = false;
									menuSlider2.startValue = -500;
									menuSlider2.endValue = 500;
								}
								menuSlider2.hasCustomOptions = false;
								AccessTools.Field(typeof(MenuSlider), "settingSegments").SetValue(menuSlider2, menuSlider2.endValue - menuSlider2.startValue);
							}
							menuSlider2.onChange = new UnityEvent();
							val8.Value = Mathf.Clamp(val8.Value, (float)menuSlider2.startValue, (float)menuSlider2.endValue);
							float startingValue2 = (val8.Value - (float)menuSlider2.startValue) * (1f / (float)(menuSlider2.endValue - menuSlider2.startValue));
							UnityAction val9 = default(UnityAction);
							lateSliderSetup.Add(menuSlider2, delegate
							{
								//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_006f: Expected O, but got Unknown
								//IL_0074: Expected O, but got Unknown
								((TMP_Text)menuSlider2.elementNameText).text = entryName2;
								AccessTools.Field(typeof(MenuSlider), "settingsValue").SetValue(menuSlider2, startingValue2);
								menuSlider2.UpdateSegmentTextAndValue();
								UnityEvent onChange2 = menuSlider2.onChange;
								UnityAction obj3 = val9;
								if (obj3 == null)
								{
									UnityAction val13 = delegate
									{
										val8.Value = (int)AccessTools.Field(typeof(MenuSlider), "currentValue").GetValue(menuSlider2);
									};
									UnityAction val14 = val13;
									val9 = val13;
									obj3 = val14;
								}
								onChange2.AddListener(obj3);
							});
						}
					}
					else
					{
						val5 = ((Component)Object.Instantiate<MenuSettingElement>(val4, ((Component)val4).transform.parent)).transform;
						MenuSlider menuSlider = ((Component)val5).GetComponent<MenuSlider>();
						string entryName = modConfigEntry.repoConfigEntry?.displayName ?? modConfigEntry.configEntryBase.Definition.Key;
						((Object)menuSlider).name = "Slider Setting - " + entryName;
						Object.Destroy((Object)(object)((Component)menuSlider).GetComponent<MenuSetting>());
						menuSlider.customOptions.Clear();
						menuSlider.hasCustomValues = false;
						menuSlider.hasBar = true;
						menuSlider.stringAtStartOfValue = modConfigEntry.repoConfigEntry?.prefix ?? string.Empty;
						menuSlider.stringAtEndOfValue = modConfigEntry.repoConfigEntry?.postfix ?? string.Empty;
						string[] array3 = modConfigEntry.repoConfigEntry?.customOptions;
						if (array3 != null && array3.Length > 0)
						{
							menuSlider.startValue = 0;
							menuSlider.endValue = array3.Length - 1;
							menuSlider.customOptions.AddRange(((IEnumerable<string>)array3).Select((Func<string, CustomOption>)((string option) => new CustomOption
							{
								customOptionText = option
							})));
							menuSlider.hasCustomOptions = true;
							AccessTools.Field(typeof(MenuSlider), "settingSegments").SetValue(menuSlider, array3.Length);
						}
						else
						{
							int? num4 = modConfigEntry.repoConfigEntry?.min;
							int? num5 = modConfigEntry.repoConfigEntry?.max;
							if (num4.HasValue && num5.HasValue)
							{
								menuSlider.startValue = num4.Value;
								menuSlider.endValue = num5.Value;
							}
							else
							{
								menuSlider.hasBar = false;
								menuSlider.startValue = -500;
								menuSlider.endValue = 500;
							}
							menuSlider.hasCustomOptions = false;
							AccessTools.Field(typeof(MenuSlider), "settingSegments").SetValue(menuSlider, menuSlider.endValue - menuSlider.startValue);
						}
						menuSlider.onChange = new UnityEvent();
						val7.Value = Mathf.Clamp(val7.Value, menuSlider.startValue, menuSlider.endValue);
						float startingValue = (float)(val7.Value - menuSlider.startValue) * (1f / (float)(menuSlider.endValue - menuSlider.startValue));
						UnityAction val10 = default(UnityAction);
						lateSliderSetup.Add(menuSlider, delegate
						{
							//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_006f: Expected O, but got Unknown
							//IL_0074: Expected O, but got Unknown
							((TMP_Text)menuSlider.elementNameText).text = entryName;
							AccessTools.Field(typeof(MenuSlider), "settingsValue").SetValue(menuSlider, startingValue);
							menuSlider.UpdateSegmentTextAndValue();
							UnityEvent onChange = menuSlider.onChange;
							UnityAction obj2 = val10;
							if (obj2 == null)
							{
								UnityAction val11 = delegate
								{
									val7.Value = (int)AccessTools.Field(typeof(MenuSlider), "currentValue").GetValue(menuSlider);
								};
								UnityAction val12 = val11;
								val10 = val11;
								obj2 = val12;
							}
							onChange.AddListener(obj2);
						});
					}
				}
				else
				{
					val5 = ((Component)Object.Instantiate<MenuSettingElement>(val3, ((Component)val3).transform.parent)).transform;
					MenuTwoOptions component = ((Component)val5).GetComponent<MenuTwoOptions>();
					string text = modConfigEntry.repoConfigEntry?.displayName ?? modConfigEntry.configEntryBase.Definition.Key;
					((Object)component).name = "Bool Setting - " + text;
					((TMP_Text)((Component)component).GetComponentInChildren<TextMeshProUGUI>()).text = (component.settingName = text);
					component.setting = (Setting)(-1);
					component.settingSet = false;
					component.fetchSetting = new UnityEvent();
					component.customFetch = (component.customEvents = true);
					component.startSettingFetch = val6.Value;
					component.onOption1 = new UnityEvent();
					component.onOption1.AddListener((UnityAction)delegate
					{
						val6.Value = true;
					});
					component.onOption2 = new UnityEvent();
					component.onOption2.AddListener((UnityAction)delegate
					{
						val6.Value = false;
					});
				}
				if (Object.op_Implicit((Object)(object)val5))
				{
					Vector3 localPosition = ((Component)val5).transform.localPosition;
					localPosition.y = num;
					((Component)val5).transform.localPosition = localPosition;
					num -= 32;
				}
			}
			MenuSettingElement[] array4 = componentsInChildren;
			for (int i = 0; i < array4.Length; i++)
			{
				Object.Destroy((Object)(object)((Component)array4[i]).gameObject);
			}
			FieldInfo fieldInfo = AccessTools.Field(typeof(MenuPage), "scrollBoxes");
			fieldInfo.SetValue(menuPage, (int)fieldInfo.GetValue(menuPage) + 1);
			latePageSetup.Add(menuPage, delegate
			{
				AccessTools.Method(typeof(MenuScrollBox), "Start", (Type[])null, (Type[])null).Invoke(((Component)menuPage).GetComponentInChildren<MenuScrollBox>(), null);
			});
			return menuPage;
		}

		private static void CreateModsButton(MenuPageIndex menuPageIndex)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Invalid comparison between Unknown and I4
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = ((IEnumerable<MenuPages>)MenuManager.instance.menuPages).FirstOrDefault((Func<MenuPages, bool>)((MenuPages page) => page.menuPageIndex == menuPageIndex))?.menuPage;
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			List<Transform> list = (from Transform child in (IEnumerable)val.transform
				where ((Object)child).name.StartsWith("Menu Button")
				select child).ToList();
			Transform val2 = null;
			foreach (Transform item in list)
			{
				if (((Object)item).name.Contains("Quit"))
				{
					item.position -= Vector3.up * 11f;
					val2 = item;
				}
				else if ((int)menuPageIndex != 1)
				{
					item.position += Vector3.up * 30f;
				}
			}
			if (Object.op_Implicit((Object)(object)val2))
			{
				Transform val3 = Object.Instantiate<Transform>(val2);
				Object.Destroy((Object)(object)((Component)val3).GetComponent<MenuButtonPopUp>());
				val3.SetParent(val.transform);
				((Object)val3).name = $"Menu Button - Mods ({menuPageIndex})";
				val3.position = val2.position + Vector3.up * 41f;
				((Component)val3).GetComponent<MenuButton>().buttonTextString = "Mods";
				customMenuButtonActions.TryAdd(((Object)val3).name, delegate
				{
					OpenPageFromOriginal(CreateModsPage());
				});
				modButtons.TryAdd(menuPageIndex, val3);
			}
		}

		private static void OpenPageFromOriginal(MenuPage customPage)
		{
			object? value = AccessTools.Field(typeof(MenuManager), "currentMenuPage").GetValue(MenuManager.instance);
			MenuPage val = (MenuPage)((value is MenuPage) ? value : null);
			AccessTools.Method(typeof(MenuManager), "PageInactiveAdd", (Type[])null, (Type[])null).Invoke(MenuManager.instance, new object[1] { val });
			if (val != null)
			{
				val.PageStateSet((PageState)3);
			}
			OpenPage(customPage, addedPageOnTop: false);
			AccessTools.Field(typeof(MenuPage), "pageIsOnTopOfOtherPage").SetValue(customPage, true);
			AccessTools.Field(typeof(MenuPage), "pageUnderThisPage").SetValue(customPage, val);
		}

		private static void OpenPage(MenuPage customPage, bool addedPageOnTop)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			((Component)customPage).transform.localPosition = Vector3.zero;
			MenuManager.instance.PageAdd(customPage);
			((MonoBehaviour)customPage).StartCoroutine(AccessTools.Method(typeof(MenuPage), "LateStart", (Type[])null, (Type[])null).Invoke(customPage, null) as IEnumerator);
			AccessTools.Field(typeof(MenuPage), "addedPageOnTop").SetValue(customPage, false);
			if (!addedPageOnTop)
			{
				MenuManager.instance.PageSetCurrent((MenuPageIndex)(-1), customPage);
				return;
			}
			object? value = AccessTools.Field(typeof(MenuManager), "currentMenuPage").GetValue(MenuManager.instance);
			MenuPage value2 = (MenuPage)((value is MenuPage) ? value : null);
			AccessTools.Field(typeof(MenuPage), "parentPage").SetValue(customPage, value2);
		}

		private static void OpenPageOnTop(MenuPage customPage)
		{
			object? value = AccessTools.Field(typeof(MenuManager), "currentMenuPage").GetValue(MenuManager.instance);
			MenuPage item = (MenuPage)((value is MenuPage) ? value : null);
			if (AccessTools.Field(typeof(MenuManager), "addedPagesOnTop").GetValue(MenuManager.instance) is List<MenuPage> list && !list.Contains(item))
			{
				OpenPage(customPage, addedPageOnTop: true);
				if (!list.Contains(item))
				{
					list.Add(customPage);
				}
			}
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
	public class REPOConfigEntryAttribute : Attribute
	{
		internal readonly string displayName;

		internal readonly int? min;

		internal readonly int? max;

		internal readonly string prefix;

		internal readonly string postfix;

		internal readonly string[] customOptions;

		public REPOConfigEntryAttribute(string displayName)
		{
			this.displayName = displayName;
		}

		public REPOConfigEntryAttribute(string displayName, int min, int max, string prefix = "", string postfix = "")
		{
			this.displayName = displayName;
			this.min = min;
			this.max = max;
			this.prefix = prefix;
			this.postfix = postfix;
		}

		public REPOConfigEntryAttribute(string displayName, string prefix = "", string postfix = "")
		{
			this.displayName = displayName;
			this.prefix = prefix;
			this.postfix = postfix;
		}

		public REPOConfigEntryAttribute(string displayName, params string[] customOptions)
		{
			this.displayName = displayName;
			this.customOptions = customOptions;
		}
	}
}