Decompiled source of ModSettingsMenu v1.0.0

BepInEx/plugins/ModSettingsMenu/ModSettingsMenu.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using ModSettingsMenu.Api;
using ModSettingsMenu.Configuration;
using ModSettingsMenu.Localization;
using ModSettingsMenu.Runtime;
using ShiftAtMidnightLocalizationAPI.Api;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ModSettingsMenu")]
[assembly: AssemblyDescription("Mod Settings Menu mod for Shift At Midnight by Ice Box Studio")]
[assembly: AssemblyCompany("Ice Box Studio")]
[assembly: AssemblyProduct("ModSettingsMenu")]
[assembly: AssemblyCopyright("Copyright © 2026 Ice Box Studio All rights reserved.")]
[assembly: ComVisible(false)]
[assembly: Guid("6d512f55-e9ee-445c-9fb4-93ed6c1ef50a")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ModSettingsMenu
{
	[BepInPlugin("IceBoxStudio.ShiftAtMidnight.ModSettingsMenu", "ModSettingsMenu", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ModSettingsMenu : BasePlugin
	{
		public static ModSettingsMenu _Instance;

		private Harmony _harmony;

		public static ModSettingsMenu Instance => _Instance;

		internal static ManualLogSource Logger { get; private set; }

		public override void Load()
		{
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			_Instance = this;
			Logger = ((BasePlugin)this).Log;
			LocalizationApi.LanguageChanged += OnLanguageChanged;
			ModSettingsRegistry.RefreshRequested += ModSettingsMenuController.RefreshLocalizedText;
			bool flag = default(bool);
			try
			{
				Logger.LogInfo((object)"=============================================");
				ManualLogSource logger = Logger;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(1, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("ModSettingsMenu");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(I18n.Text("plugin.initializing"));
				}
				logger.LogInfo(val);
				ManualLogSource logger2 = Logger;
				val = new BepInExInfoLogInterpolatedStringHandler(54, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(I18n.Text("plugin.author_prefix"));
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Ice Box Studio(https://steamcommunity.com/id/ibox666/)");
				}
				logger2.LogInfo(val);
				_harmony = new Harmony("IceBoxStudio.ShiftAtMidnight.ModSettingsMenu");
				_harmony.PatchAll(Assembly.GetExecutingAssembly());
				ManualLogSource logger3 = Logger;
				val = new BepInExInfoLogInterpolatedStringHandler(1, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("ModSettingsMenu");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(I18n.Text("plugin.initialized"));
				}
				logger3.LogInfo(val);
				Logger.LogInfo((object)"=============================================");
			}
			catch (Exception ex)
			{
				ManualLogSource logger4 = Logger;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(40, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to initialize Mod Settings Menu: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				logger4.LogError(val2);
			}
		}

		private static void OnLanguageChanged(string _)
		{
			ModSettingsMenuController.RefreshLocalizedText();
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "IceBoxStudio.ShiftAtMidnight.ModSettingsMenu";

		public const string PLUGIN_NAME = "ModSettingsMenu";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace ModSettingsMenu.Runtime
{
	internal sealed class ConfigRows
	{
		private readonly Transform _content;

		private readonly GameObject _slider;

		private readonly GameObject _toggle;

		private readonly GameObject _dropdown;

		private readonly GameObject _input;

		private readonly GameObject _keybind;

		private readonly KeybindCapture _keybindCapture;

		private readonly DescriptionLayout _description;

		private readonly ModInfoRow _modInfo;

		private readonly List<GameObject> _createdRows = new List<GameObject>();

		public ConfigRows(Transform content, GameObject slider, GameObject toggle, GameObject dropdown, GameObject input, GameObject keybind, KeybindCapture keybindCapture, DescriptionLayout description, ModInfoRow modInfo)
		{
			_content = content;
			_slider = slider;
			_toggle = toggle;
			_dropdown = dropdown;
			_input = input;
			_keybind = keybind;
			_keybindCapture = keybindCapture;
			_description = description;
			_modInfo = modInfo;
		}

		public void Build(ModConfig mod)
		{
			ClearRows();
			if (mod == null)
			{
				CreateHeading(I18n.Text("menu.no_configurable_mods"));
			}
			else
			{
				AddModInfo(mod);
				foreach (ConfigEntryBase item in mod.ConfigFile.Values.OrderBy<ConfigEntryBase, string>((ConfigEntryBase entry) => entry.Definition.Section, StringComparer.OrdinalIgnoreCase).ThenBy<ConfigEntryBase, string>((ConfigEntryBase entry) => entry.Definition.Key, StringComparer.OrdinalIgnoreCase).ToList())
				{
					CreateEntryRow(item);
				}
			}
			LayoutRebuild();
		}

		private void ClearRows()
		{
			foreach (GameObject createdRow in _createdRows)
			{
				if ((Object)(object)createdRow != (Object)null)
				{
					createdRow.SetActive(false);
					Object.Destroy((Object)(object)createdRow);
				}
			}
			_createdRows.Clear();
		}

		private void CreateHeading(string text)
		{
			GameObject val = NewRow(_slider, "Mod Settings Heading");
			string[] array = new string[2] { "Slider", "Value" };
			foreach (string text2 in array)
			{
				Transform val2 = val.transform.Find(text2);
				if ((Object)(object)val2 != (Object)null)
				{
					((Component)val2).gameObject.SetActive(false);
				}
			}
			NativeUi.SetRowTitle(val, text);
			CompleteRow(val);
		}

		private void CreateEntryRow(ConfigEntryBase entry)
		{
			Type settingType = entry.SettingType;
			ConfigDescription description = entry.Description;
			AcceptableValueBase acceptable = ((description != null) ? description.AcceptableValues : null);
			IReadOnlyList<object> values;
			float min;
			float max;
			if (settingType == typeof(bool))
			{
				CreateBoolRow(entry);
			}
			else if (settingType == typeof(KeyCode))
			{
				CreateKeybindRow(entry);
			}
			else if (settingType.IsEnum)
			{
				CreateDropdownRow(entry, Enum.GetValues(settingType).Cast<object>().ToList());
			}
			else if (ConfigValues.TryGetAcceptableValues(acceptable, out values))
			{
				CreateDropdownRow(entry, values);
			}
			else if (ConfigValues.TryGetNumericRange(acceptable, out min, out max) && ConfigValues.IsSliderType(settingType))
			{
				CreateSliderRow(entry, min, max);
			}
			else
			{
				CreateInputRow(entry);
			}
		}

		private void CreateBoolRow(ConfigEntryBase entry)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			GameObject val = NewRow(_toggle, GetRowName(entry));
			Toggle toggle = val.GetComponentInChildren<Toggle>(true);
			if ((Object)(object)toggle == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				CreateInputRow(entry);
				return;
			}
			toggle.onValueChanged = new ToggleEvent();
			toggle.SetIsOnWithoutNotify((bool)entry.BoxedValue);
			((UnityEvent<bool>)(object)toggle.onValueChanged).AddListener(DelegateSupport.ConvertDelegate<UnityAction<bool>>((Delegate)(Action<bool>)delegate(bool value)
			{
				if (!ConfigValues.TrySetValue(entry, value))
				{
					toggle.SetIsOnWithoutNotify((bool)entry.BoxedValue);
				}
			}));
			NativeUi.SetRowTitle(val, entry.Definition.Key);
			_description.Apply(val, entry, 6f);
			NativeUi.CenterControl(((Component)toggle).GetComponent<RectTransform>());
			CompleteRow(val);
		}

		private void CreateKeybindRow(ConfigEntryBase entry)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			GameObject val = NewRow(_keybind, GetRowName(entry));
			Button button = val.GetComponentInChildren<Button>(true);
			Button obj = button;
			TMP_Text buttonText = ((obj != null) ? ((Component)obj).GetComponentInChildren<TMP_Text>(true) : null);
			if ((Object)(object)button == (Object)null || (Object)(object)buttonText == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				CreateInputRow(entry);
				return;
			}
			button.onClick = new ButtonClickedEvent();
			((UnityEvent)button.onClick).AddListener(DelegateSupport.ConvertDelegate<UnityAction>((Delegate)(Action)delegate
			{
				_keybindCapture.Begin(entry, button, buttonText);
			}));
			NativeUi.CopyFont(NativeUi.SetRowTitle(val, entry.Definition.Key), buttonText);
			NativeUi.SetLocalizedText(buttonText, KeybindCapture.FormatKeyCode(entry.BoxedValue));
			_description.Apply(val, entry, 6f);
			NativeUi.CenterControl(((Component)button).GetComponent<RectTransform>());
			CompleteRow(val);
		}

		private void CreateSliderRow(ConfigEntryBase entry, float min, float max)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			GameObject val = NewRow(_slider, GetRowName(entry));
			Slider slider = val.GetComponentInChildren<Slider>(true);
			if ((Object)(object)slider == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				CreateInputRow(entry);
				return;
			}
			slider.onValueChanged = new SliderEvent();
			slider.minValue = min;
			slider.maxValue = max;
			slider.wholeNumbers = ConfigValues.IsIntegralType(entry.SettingType);
			slider.SetValueWithoutNotify(Convert.ToSingle(entry.BoxedValue, CultureInfo.InvariantCulture));
			Transform obj = val.transform.Find("Value");
			TMP_Text valueText = ((obj != null) ? ((Component)obj).GetComponent<TMP_Text>() : null);
			((UnityEvent<float>)(object)slider.onValueChanged).AddListener(DelegateSupport.ConvertDelegate<UnityAction<float>>((Delegate)(Action<float>)delegate(float value)
			{
				object value2 = ConfigValues.ConvertSliderValue(value, entry.SettingType);
				if (!ConfigValues.TrySetValue(entry, value2))
				{
					slider.SetValueWithoutNotify(Convert.ToSingle(entry.BoxedValue, CultureInfo.InvariantCulture));
				}
				if ((Object)(object)valueText != (Object)null)
				{
					valueText.text = ConfigValues.FormatValue(entry.BoxedValue);
				}
			}));
			NativeUi.CopyFont(NativeUi.SetRowTitle(val, entry.Definition.Key), valueText);
			if ((Object)(object)valueText != (Object)null)
			{
				valueText.text = ConfigValues.FormatValue(entry.BoxedValue);
			}
			_description.Apply(val, entry);
			CompleteRow(val);
		}

		private void CreateDropdownRow(ConfigEntryBase entry, IReadOnlyList<object> values)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			GameObject val = NewRow(_dropdown, GetRowName(entry));
			TMP_Dropdown dropdown = val.GetComponentInChildren<TMP_Dropdown>(true);
			if ((Object)(object)dropdown == (Object)null || values.Count == 0)
			{
				Object.Destroy((Object)(object)val);
				CreateInputRow(entry);
				return;
			}
			dropdown.ClearOptions();
			foreach (object value in values)
			{
				dropdown.options.Add(new OptionData(ConfigValues.FormatValue(value)));
			}
			var anon = values.Select((object value, int index) => new { value, index }).FirstOrDefault(item => object.Equals(item.value, entry.BoxedValue));
			dropdown.onValueChanged = new DropdownEvent();
			dropdown.SetValueWithoutNotify(anon?.index ?? 0);
			dropdown.RefreshShownValue();
			((UnityEvent<int>)(object)dropdown.onValueChanged).AddListener(DelegateSupport.ConvertDelegate<UnityAction<int>>((Delegate)(Action<int>)delegate(int index)
			{
				if (index >= 0 && index < values.Count && !ConfigValues.TrySetValue(entry, values[index]))
				{
					int valueWithoutNotify = values.Select((object value, int valueIndex) => new { value, valueIndex }).FirstOrDefault(item => object.Equals(item.value, entry.BoxedValue))?.valueIndex ?? 0;
					dropdown.SetValueWithoutNotify(valueWithoutNotify);
					dropdown.RefreshShownValue();
				}
			}));
			TMP_Text source = NativeUi.SetRowTitle(val, entry.Definition.Key);
			NativeUi.CopyFont(source, dropdown.captionText);
			NativeUi.CopyFont(source, dropdown.itemText);
			_description.Apply(val, entry);
			CompleteRow(val);
		}

		private void CreateInputRow(ConfigEntryBase entry)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			GameObject val = NewRow(_input, GetRowName(entry));
			TMP_InputField input = val.GetComponentInChildren<TMP_InputField>(true);
			if ((Object)(object)input == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return;
			}
			input.onEndEdit = new SubmitEvent();
			input.SetTextWithoutNotify(entry.GetSerializedValue());
			((UnityEvent<string>)(object)input.onEndEdit).AddListener(DelegateSupport.ConvertDelegate<UnityAction<string>>((Delegate)(Action<string>)delegate(string value)
			{
				if (!ConfigValues.TrySetSerializedValue(entry, value))
				{
					input.SetTextWithoutNotify(entry.GetSerializedValue());
				}
			}));
			TMP_Text source = NativeUi.SetRowTitle(val, entry.Definition.Key);
			NativeUi.CopyFont(source, input.textComponent);
			Graphic placeholder = input.placeholder;
			NativeUi.CopyFont(source, (placeholder != null) ? ((Il2CppObjectBase)placeholder).TryCast<TMP_Text>() : null);
			_description.Apply(val, entry);
			CompleteRow(val);
		}

		private void AddModInfo(ModConfig mod)
		{
			GameObject val = _modInfo.Create(mod);
			if ((Object)(object)val != (Object)null)
			{
				CompleteRow(val);
			}
		}

		private void CompleteRow(GameObject row)
		{
			row.SetActive(true);
			_createdRows.Add(row);
		}

		private GameObject NewRow(GameObject source, string name)
		{
			GameObject val = Object.Instantiate<GameObject>(source, _content);
			((Object)val).name = name;
			val.SetActive(false);
			MatchRow(val);
			NativeUi.DisableRowComponents(val);
			return val;
		}

		private void MatchRow(GameObject row)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = _slider.GetComponent<RectTransform>();
			RectTransform component2 = row.GetComponent<RectTransform>();
			if (!((Object)(object)component == (Object)null) && !((Object)(object)component2 == (Object)null))
			{
				component2.anchorMin = component.anchorMin;
				component2.anchorMax = component.anchorMax;
				component2.pivot = component.pivot;
				component2.sizeDelta = component.sizeDelta;
				component2.anchoredPosition = component.anchoredPosition;
				((Transform)component2).localScale = ((Transform)component).localScale;
				((Transform)component2).localRotation = ((Transform)component).localRotation;
			}
		}

		private void LayoutRebuild()
		{
			LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)_content).GetComponent<RectTransform>());
			Transform parent = _content.parent;
			object obj;
			if (parent == null)
			{
				obj = null;
			}
			else
			{
				Transform parent2 = parent.parent;
				obj = ((parent2 != null) ? ((Component)parent2).GetComponent<ScrollRect>() : null);
			}
			ScrollRect val = (ScrollRect)obj;
			if ((Object)(object)val != (Object)null)
			{
				val.verticalNormalizedPosition = 1f;
			}
		}

		private static string GetRowName(ConfigEntryBase entry)
		{
			return "Mod Setting - " + entry.Definition.Key;
		}
	}
	internal sealed class DescriptionLayout
	{
		private readonly GameObject _slider;

		private readonly GameObject _dropdown;

		private readonly GameObject _description;

		private readonly TMP_Text _descriptionFont;

		public DescriptionLayout(GameObject slider, GameObject dropdown, GameObject description, TMP_Text descriptionFont)
		{
			_slider = slider;
			_dropdown = dropdown;
			_description = description;
			_descriptionFont = descriptionFont;
		}

		public void Apply(GameObject row, ConfigEntryBase entry, float additionalControlGap = 0f)
		{
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			string configDescription = LocalizationApi.GetConfigDescription(entry);
			if (string.IsNullOrWhiteSpace(configDescription))
			{
				return;
			}
			RectTransform component = row.GetComponent<RectTransform>();
			RectTransform component2 = _slider.GetComponent<RectTransform>();
			RectTransform component3 = _description.GetComponent<RectTransform>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)component3 == (Object)null)
			{
				return;
			}
			Transform titleTransform;
			List<RectTransform> activeControls = GetActiveControls(row, out titleTransform);
			if ((Object)(object)titleTransform != (Object)null)
			{
				((Component)titleTransform).gameObject.SetActive(false);
			}
			GameObject val = Object.Instantiate<GameObject>(_description, row.transform);
			((Object)val).name = "Description";
			val.SetActive(false);
			RectTransform component4 = val.GetComponent<RectTransform>();
			TMP_Text component5 = val.GetComponent<TMP_Text>();
			if ((Object)(object)component4 == (Object)null || (Object)(object)component5 == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return;
			}
			component5.enableAutoSizing = false;
			component5.fontSize = _descriptionFont.fontSize;
			NativeUi.SetLocalizedText(component5, configDescription.Trim());
			float x = component3.sizeDelta.x;
			float y = component5.GetPreferredValues(component5.text, x, 0f).y;
			float num = Mathf.Max(_descriptionFont.fontSize, y);
			Transform obj = _dropdown.transform.Find("Title");
			RectTransform val2 = ((obj != null) ? ((Component)obj).GetComponent<RectTransform>() : null);
			Transform obj2 = _dropdown.transform.Find("Dropdown");
			RectTransform val3 = ((obj2 != null) ? ((Component)obj2).GetComponent<RectTransform>() : null);
			if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || activeControls.Count == 0)
			{
				Object.Destroy((Object)(object)val);
				return;
			}
			float num2 = Mathf.Abs(GetRectTop(val3) - GetRectBottom(val2));
			float num3 = GetRectTop(val2) - GetRectBottom(val3);
			float num4 = Mathf.Max(0f, component2.sizeDelta.y - num3);
			float num5 = ((IEnumerable<RectTransform>)activeControls).Max((Func<RectTransform, float>)GetRectTop);
			float num6 = ((IEnumerable<RectTransform>)activeControls).Min((Func<RectTransform, float>)GetRectBottom);
			float num7 = num5 + num2 + additionalControlGap;
			float num8 = num7 + num;
			float num9 = (num8 + num6) * 0.5f;
			float num10 = num8 - num6;
			foreach (RectTransform item in activeControls)
			{
				item.anchoredPosition = new Vector2(item.anchoredPosition.x, item.anchoredPosition.y - num9);
			}
			component.sizeDelta = new Vector2(component.sizeDelta.x, Mathf.Max(component2.sizeDelta.y, num10 + num4));
			component4.anchorMin = component3.anchorMin;
			component4.anchorMax = component3.anchorMax;
			component4.pivot = component3.pivot;
			component4.sizeDelta = new Vector2(x, num);
			component4.anchoredPosition = new Vector2(0f, num7 + num * 0.5f - num9);
			((Transform)component4).localScale = ((Transform)component3).localScale;
			((Transform)component4).localRotation = ((Transform)component3).localRotation;
			val.SetActive(true);
		}

		private static List<RectTransform> GetActiveControls(GameObject row, out Transform titleTransform)
		{
			List<RectTransform> list = new List<RectTransform>();
			titleTransform = row.transform.Find("Title") ?? row.transform.Find("Title (1)");
			for (int i = 0; i < row.transform.childCount; i++)
			{
				Transform child = row.transform.GetChild(i);
				if (!((Object)(object)child == (Object)(object)titleTransform) && !string.Equals(((Object)child).name, "EditingBar", StringComparison.Ordinal) && ((Component)child).gameObject.activeSelf)
				{
					RectTransform component = ((Component)child).GetComponent<RectTransform>();
					if ((Object)(object)component != (Object)null)
					{
						list.Add(component);
					}
				}
			}
			return list;
		}

		private static float GetRectTop(RectTransform rectTransform)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			float y = rectTransform.anchoredPosition.y;
			Rect rect = rectTransform.rect;
			return y + ((Rect)(ref rect)).height * Mathf.Abs(((Transform)rectTransform).localScale.y) * 0.5f;
		}

		private static float GetRectBottom(RectTransform rectTransform)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			float y = rectTransform.anchoredPosition.y;
			Rect rect = rectTransform.rect;
			return y - ((Rect)(ref rect)).height * Mathf.Abs(((Transform)rectTransform).localScale.y) * 0.5f;
		}
	}
	internal sealed class KeybindCapture
	{
		private ConfigEntryBase _entry;

		private TMP_Text _buttonText;

		public bool IsActive => _entry != null;

		public void Begin(ConfigEntryBase entry, Button button, TMP_Text buttonText)
		{
			_entry = entry;
			_buttonText = buttonText;
			NativeUi.SetLocalizedText(buttonText, string.Empty);
			NativeUi.SelectObject(((Component)button).gameObject);
		}

		public void CaptureInput()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				return;
			}
			if (((ButtonControl)current.escapeKey).wasPressedThisFrame)
			{
				Finish(save: false, (KeyCode)0);
				return;
			}
			foreach (Key value in Enum.GetValues(typeof(Key)))
			{
				if ((int)value != 0)
				{
					KeyControl val2;
					try
					{
						val2 = current[value];
					}
					catch
					{
						continue;
					}
					if (val2 != null && ((ButtonControl)val2).wasPressedThisFrame && TryConvertKeyCode(value, out var keyCode))
					{
						Finish(save: true, keyCode);
						break;
					}
				}
			}
		}

		public void Clear()
		{
			_entry = null;
			_buttonText = null;
		}

		public unsafe static string FormatKeyCode(object value)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (!(value is KeyCode val))
			{
				return ConfigValues.FormatValue(value);
			}
			return ((object)(*(KeyCode*)(&val))/*cast due to .constrained prefix*/).ToString();
		}

		private void Finish(bool save, KeyCode keyCode)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (save && _entry != null && !ConfigValues.TrySetValue(_entry, keyCode))
			{
				keyCode = (KeyCode)_entry.BoxedValue;
			}
			else if (_entry != null)
			{
				keyCode = (KeyCode)_entry.BoxedValue;
			}
			NativeUi.SetLocalizedText(_buttonText, FormatKeyCode(keyCode));
			Clear();
		}

		private unsafe static bool TryConvertKeyCode(Key key, out KeyCode keyCode)
		{
			string text = ((object)(*(Key*)(&key))/*cast due to .constrained prefix*/).ToString();
			if (text.StartsWith("Digit", StringComparison.Ordinal))
			{
				text = "Alpha" + text.Substring("Digit".Length);
			}
			else if (text.StartsWith("Numpad", StringComparison.Ordinal))
			{
				text = "Keypad" + text.Substring("Numpad".Length);
			}
			else if (string.Equals(text, "Enter", StringComparison.Ordinal))
			{
				text = "Return";
			}
			else if (string.Equals(text, "Backquote", StringComparison.Ordinal))
			{
				text = "BackQuote";
			}
			return Enum.TryParse<KeyCode>(text, ignoreCase: true, out keyCode);
		}
	}
	internal sealed class ModInfoRow
	{
		private readonly Transform _content;

		private readonly GameObject _slider;

		private readonly GameObject _divider;

		private readonly GameObject _nexusButton;

		private readonly GameObject _description;

		private readonly TMP_Text _descriptionFont;

		public ModInfoRow(Transform content, GameObject slider, GameObject divider, GameObject nexusButton, GameObject description, TMP_Text descriptionFont)
		{
			_content = content;
			_slider = slider;
			_divider = divider;
			_nexusButton = nexusButton;
			_description = description;
			_descriptionFont = descriptionFont;
		}

		public GameObject Create(ModConfig mod)
		{
			ModSettingsRegistration registration = mod.Registration;
			if (registration == null)
			{
				return null;
			}
			string nexusLinkPrefix;
			string nexusLinkText;
			string text = BuildPluginInfoText(registration, out nexusLinkPrefix, out nexusLinkText);
			if (string.IsNullOrWhiteSpace(text) && !registration.NexusModsId.HasValue)
			{
				return null;
			}
			return CreateInfoTextRow(text, registration.NexusModsId, nexusLinkPrefix, nexusLinkText);
		}

		private GameObject CreateInfoTextRow(string text, int? nexusModsId, string nexusLinkPrefix, string nexusLinkText)
		{
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = NewRow("Mod Settings Information");
			string[] array = new string[4] { "Title", "Title (1)", "Slider", "Value" };
			foreach (string text2 in array)
			{
				Transform val2 = val.transform.Find(text2);
				if ((Object)(object)val2 != (Object)null)
				{
					((Component)val2).gameObject.SetActive(false);
				}
			}
			RectTransform component = val.GetComponent<RectTransform>();
			RectTransform component2 = _slider.GetComponent<RectTransform>();
			RectTransform component3 = _description.GetComponent<RectTransform>();
			GameObject val3 = Object.Instantiate<GameObject>(_divider, val.transform);
			((Object)val3).name = "Information Divider";
			val3.SetActive(false);
			RectTransform component4 = val3.GetComponent<RectTransform>();
			RectTransform component5 = _divider.GetComponent<RectTransform>();
			Transform parent = _divider.transform.parent;
			RectTransform val4 = ((parent != null) ? ((Component)parent).GetComponent<RectTransform>() : null);
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)component3 == (Object)null || (Object)(object)component4 == (Object)null || (Object)(object)component5 == (Object)null || (Object)(object)val4 == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			float x = component3.sizeDelta.x;
			RectTransform infoRect;
			TMP_Text infoText;
			float infoHeight;
			GameObject val5 = CreateInfoText(val, text, x, out infoRect, out infoText, out infoHeight);
			if (!string.IsNullOrWhiteSpace(text) && (Object)(object)val5 == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			RectTransform buttonRect;
			GameObject val6 = CreateNexusButton(val, nexusModsId, out buttonRect);
			if (nexusModsId.HasValue && (Object)(object)val6 == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			float num = val4.sizeDelta.y * (component5.anchorMax.y - component5.anchorMin.y);
			float num2 = infoHeight + num + 12f + 6f;
			component.sizeDelta = new Vector2(component2.sizeDelta.x, num2);
			float contentTop = num2 * 0.5f - 6f;
			if ((Object)(object)infoRect != (Object)null)
			{
				SetInfoRect(infoRect, component3, x, infoHeight, contentTop);
			}
			if ((Object)(object)buttonRect != (Object)null && (Object)(object)infoText != (Object)null)
			{
				SetNexusButtonRect(buttonRect, component3, infoText, nexusLinkPrefix, nexusLinkText, x, contentTop);
				ConfigureNexusHover(val6, infoText, nexusLinkPrefix, nexusLinkText);
			}
			component4.anchorMin = component3.anchorMin;
			component4.anchorMax = component3.anchorMax;
			component4.pivot = component3.pivot;
			component4.sizeDelta = new Vector2(val4.sizeDelta.x, num);
			component4.anchoredPosition = new Vector2(0f, 0f - num2 * 0.5f + 6f + num * 0.5f);
			((Transform)component4).localScale = ((Transform)component5).localScale;
			((Transform)component4).localRotation = ((Transform)component5).localRotation;
			if (val5 != null)
			{
				val5.SetActive(true);
			}
			if (val6 != null)
			{
				val6.SetActive(true);
			}
			val3.SetActive(true);
			return val;
		}

		private GameObject CreateInfoText(GameObject row, string text, float infoWidth, out RectTransform infoRect, out TMP_Text infoText, out float infoHeight)
		{
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			infoRect = null;
			infoText = null;
			infoHeight = 0f;
			if (string.IsNullOrWhiteSpace(text))
			{
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(_description, row.transform);
			((Object)val).name = "Information Text";
			val.SetActive(false);
			infoRect = val.GetComponent<RectTransform>();
			infoText = val.GetComponent<TMP_Text>();
			if ((Object)(object)infoRect == (Object)null || (Object)(object)infoText == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			infoText.enableAutoSizing = false;
			infoText.enableWordWrapping = true;
			infoText.richText = true;
			infoText.alignment = (TextAlignmentOptions)257;
			infoText.fontSize = _descriptionFont.fontSize;
			NativeUi.SetLocalizedText(infoText, text.Trim());
			infoHeight = Mathf.Max(_descriptionFont.fontSize, infoText.GetPreferredValues(infoText.text, infoWidth, 0f).y);
			return val;
		}

		private GameObject CreateNexusButton(GameObject row, int? nexusModsId, out RectTransform buttonRect)
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00d7: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			buttonRect = null;
			if (!nexusModsId.HasValue)
			{
				return null;
			}
			string nexusModsUrl = ModSettingsRegistry.GetNexusModsUrl(nexusModsId.Value);
			GameObject val = Object.Instantiate<GameObject>(_nexusButton, row.transform);
			((Object)val).name = "Nexus Mods Link";
			val.SetActive(false);
			NativeUi.DisableRowComponents(val);
			buttonRect = val.GetComponent<RectTransform>();
			Button component = val.GetComponent<Button>();
			TMP_Text componentInChildren = val.GetComponentInChildren<TMP_Text>(true);
			Image component2 = val.GetComponent<Image>();
			if ((Object)(object)buttonRect == (Object)null || (Object)(object)component == (Object)null || (Object)(object)componentInChildren == (Object)null || (Object)(object)component2 == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			component.onClick = new ButtonClickedEvent();
			((UnityEvent)component.onClick).AddListener(DelegateSupport.ConvertDelegate<UnityAction>((Delegate)(Action)delegate
			{
				Application.OpenURL(nexusModsUrl);
			}));
			((Selectable)component).transition = (Transition)0;
			((Selectable)component).targetGraphic = (Graphic)(object)component2;
			((Graphic)component2).color = new Color(((Graphic)component2).color.r, ((Graphic)component2).color.g, ((Graphic)component2).color.b, 0f);
			((Graphic)component2).raycastTarget = true;
			NativeUi.SetLocalizedText(componentInChildren, string.Empty);
			((Graphic)componentInChildren).raycastTarget = false;
			return val;
		}

		private static void SetInfoRect(RectTransform infoRect, RectTransform sourceRect, float width, float height, float contentTop)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			infoRect.anchorMin = sourceRect.anchorMin;
			infoRect.anchorMax = sourceRect.anchorMax;
			infoRect.pivot = sourceRect.pivot;
			infoRect.sizeDelta = new Vector2(width, height);
			infoRect.anchoredPosition = new Vector2(0f, contentTop - height * 0.5f);
			((Transform)infoRect).localScale = ((Transform)sourceRect).localScale;
			((Transform)infoRect).localRotation = ((Transform)sourceRect).localRotation;
		}

		private void SetNexusButtonRect(RectTransform buttonRect, RectTransform sourceDescriptionRect, TMP_Text infoText, string linkPrefix, string linkText, float infoWidth, float contentTop)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = _nexusButton.GetComponent<RectTransform>();
			Vector2 preferredValues = infoText.GetPreferredValues(linkPrefix);
			Vector2 preferredValues2 = infoText.GetPreferredValues(linkText);
			Vector2 preferredValues3 = infoText.GetPreferredValues(linkPrefix + linkText, infoWidth, 0f);
			bool num = preferredValues.x + preferredValues2.x <= infoWidth;
			float num2 = (num ? preferredValues2.x : infoWidth);
			float num3 = (num ? Mathf.Max(infoText.fontSize, preferredValues2.y) : Mathf.Max(infoText.fontSize, preferredValues3.y));
			float num4 = (num ? (0f - infoWidth * 0.5f + preferredValues.x + num2 * 0.5f) : 0f);
			buttonRect.anchorMin = sourceDescriptionRect.anchorMin;
			buttonRect.anchorMax = sourceDescriptionRect.anchorMax;
			buttonRect.pivot = sourceDescriptionRect.pivot;
			buttonRect.sizeDelta = new Vector2(num2, num3);
			buttonRect.anchoredPosition = new Vector2(num4, contentTop - num3 * 0.5f);
			((Transform)buttonRect).localScale = ((Transform)component).localScale;
			((Transform)buttonRect).localRotation = ((Transform)component).localRotation;
		}

		private static void ConfigureNexusHover(GameObject buttonObject, TMP_Text infoText, string linkPrefix, string linkText)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			string text = linkPrefix + linkText;
			if (!((Object)(object)buttonObject == (Object)null) && !((Object)(object)infoText == (Object)null) && !string.IsNullOrEmpty(linkText) && infoText.text.StartsWith(text, StringComparison.Ordinal))
			{
				string normalText = infoText.text;
				string hoverText = linkPrefix + "<u>" + linkText + "</u>" + normalText.Substring(text.Length);
				EventTrigger obj = buttonObject.GetComponent<EventTrigger>() ?? buttonObject.AddComponent<EventTrigger>();
				obj.triggers.Clear();
				Entry val = new Entry
				{
					eventID = (EventTriggerType)0
				};
				((UnityEvent<BaseEventData>)(object)val.callback).AddListener(DelegateSupport.ConvertDelegate<UnityAction<BaseEventData>>((Delegate)(Action<BaseEventData>)delegate
				{
					infoText.text = hoverText;
				}));
				obj.triggers.Add(val);
				Entry val2 = new Entry
				{
					eventID = (EventTriggerType)1
				};
				((UnityEvent<BaseEventData>)(object)val2.callback).AddListener(DelegateSupport.ConvertDelegate<UnityAction<BaseEventData>>((Delegate)(Action<BaseEventData>)delegate
				{
					infoText.text = normalText;
				}));
				obj.triggers.Add(val2);
			}
		}

		private static string BuildPluginInfoText(ModSettingsRegistration registration, out string nexusLinkPrefix, out string nexusLinkText)
		{
			List<string> list = new List<string>();
			if (!string.IsNullOrWhiteSpace(registration.Version))
			{
				list.Add("V" + registration.Version.Trim());
			}
			if (!string.IsNullOrWhiteSpace(registration.Author))
			{
				list.Add(registration.Author.Trim());
			}
			nexusLinkPrefix = string.Empty;
			nexusLinkText = string.Empty;
			if (registration.NexusModsId.HasValue)
			{
				nexusLinkText = I18n.Text("menu.open_nexus_page");
				if (list.Count > 0)
				{
					nexusLinkPrefix = string.Join(" · ", list) + " · ";
				}
			}
			List<string> list2 = new List<string>();
			if (!string.IsNullOrWhiteSpace(nexusLinkText))
			{
				list2.Add(nexusLinkPrefix + nexusLinkText);
			}
			else if (list.Count > 0)
			{
				list2.Add(string.Join(" · ", list));
			}
			if (!string.IsNullOrWhiteSpace(registration.Description))
			{
				if (list2.Count > 0)
				{
					list2.Add(string.Empty);
				}
				list2.Add(registration.Description.Trim());
			}
			return string.Join("\n", list2);
		}

		private GameObject NewRow(string name)
		{
			GameObject val = Object.Instantiate<GameObject>(_slider, _content);
			((Object)val).name = name;
			val.SetActive(false);
			MatchRow(val);
			NativeUi.DisableRowComponents(val);
			return val;
		}

		private void MatchRow(GameObject row)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = _slider.GetComponent<RectTransform>();
			RectTransform component2 = row.GetComponent<RectTransform>();
			if (!((Object)(object)component == (Object)null) && !((Object)(object)component2 == (Object)null))
			{
				component2.anchorMin = component.anchorMin;
				component2.anchorMax = component.anchorMax;
				component2.pivot = component.pivot;
				component2.sizeDelta = component.sizeDelta;
				component2.anchoredPosition = component.anchoredPosition;
				((Transform)component2).localScale = ((Transform)component).localScale;
				((Transform)component2).localRotation = ((Transform)component).localRotation;
			}
		}
	}
	public static class ModSettingsMenuController
	{
		private const string MainMenuButtonPath = "Main Menu/Settings Button";

		private const string QuitButtonPath = "Main Menu/Quit BTN";

		private const string SettingsPanelName = "Settings";

		private static Transform _mainMenuRoot;

		private static GameObject _mainMenuObject;

		private static GameObject _modSettingsButton;

		private static ModSettingsPanel _settingsPanel;

		public static void TryCreate(MainMenu mainMenu)
		{
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			try
			{
				if ((Object)(object)mainMenu == (Object)null || (Object)(object)mainMenu.mainMenu == (Object)null)
				{
					return;
				}
				GameObject mainMenu2 = mainMenu.mainMenu;
				if (!((Object)(object)_modSettingsButton != (Object)null) || !((Object)(object)_mainMenuObject == (Object)(object)mainMenu2))
				{
					ResetReferences();
					Transform transform = mainMenu2.transform;
					Transform source = NativeUi.RequireTransform(transform, "Main Menu/Settings Button");
					Transform quitButton = NativeUi.RequireTransform(transform, "Main Menu/Quit BTN");
					Transform parent = transform.parent;
					if ((Object)(object)parent == (Object)null)
					{
						throw new InvalidOperationException("Canvas parent is missing.");
					}
					Transform source2 = NativeUi.RequireTransform(parent, "Settings");
					_mainMenuRoot = transform;
					_mainMenuObject = mainMenu2;
					_settingsPanel = ModSettingsPanel.Create(source2, parent, CloseSettings);
					_modSettingsButton = CreateMainMenuButton(source, quitButton);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger = ModSettingsMenu.Logger;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(40, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to create the mod settings menu: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				logger.LogError(val);
				ResetReferences();
			}
		}

		public static void CheckBackInput()
		{
			if (_settingsPanel == null || !_settingsPanel.IsOpen)
			{
				return;
			}
			if (_settingsPanel.IsCapturingKeybind)
			{
				_settingsPanel.CaptureKeybindInput();
				return;
			}
			_settingsPanel.ScrollModList();
			Keyboard current = Keyboard.current;
			Gamepad current2 = Gamepad.current;
			if ((current != null && ((ButtonControl)current.escapeKey).wasPressedThisFrame) || (current2 != null && current2.buttonEast.wasPressedThisFrame))
			{
				CloseSettings();
			}
		}

		public static void RefreshLocalizedText()
		{
			if ((Object)(object)_modSettingsButton != (Object)null)
			{
				NativeUi.SetText(_modSettingsButton, I18n.Text("menu.mod_settings"));
			}
			_settingsPanel?.RefreshLocalizedText();
		}

		private static GameObject CreateMainMenuButton(Transform source, Transform quitButton)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, source.parent);
			((Object)val).name = "Mod Settings Button";
			Transform val2 = NativeUi.RequireTransform(source.parent, "PlayButtonHolder");
			Transform obj = NativeUi.RequireTransform(source.parent, "Credits Button");
			RectTransform component = ((Component)val2).GetComponent<RectTransform>();
			RectTransform component2 = ((Component)obj).GetComponent<RectTransform>();
			RectTransform component3 = ((Component)source).GetComponent<RectTransform>();
			RectTransform component4 = ((Component)quitButton).GetComponent<RectTransform>();
			RectTransform component5 = val.GetComponent<RectTransform>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)component3 == (Object)null || (Object)(object)component4 == (Object)null || (Object)(object)component5 == (Object)null)
			{
				throw new InvalidOperationException("Main menu buttons or PlayButtonHolder are missing RectTransform.");
			}
			float num = component3.anchoredPosition.y - component4.anchoredPosition.y;
			float num2 = (component.anchoredPosition.y - component4.anchoredPosition.y) / 4f;
			if (num <= 0f || num2 <= 0f)
			{
				Object.Destroy((Object)(object)val);
				throw new InvalidOperationException("Main menu button spacing is invalid.");
			}
			float num3 = num2 / num;
			Vector3 val3 = ((Transform)component3).localScale * num3;
			float y = component.anchoredPosition.y;
			((Transform)component).localScale = val3;
			SetButtonLayout(component2, val3, y - num2);
			SetButtonLayout(component3, val3, y - num2 * 2f);
			SetButtonLayout(component5, val3, y - num2 * 3f);
			SetButtonLayout(component4, val3, y - num2 * 4f);
			val.transform.SetSiblingIndex(quitButton.GetSiblingIndex());
			Button component6 = val.GetComponent<Button>();
			if ((Object)(object)component6 == (Object)null)
			{
				throw new InvalidOperationException("Cloned main menu button is missing Button.");
			}
			component6.onClick = new ButtonClickedEvent();
			((UnityEvent)component6.onClick).AddListener(DelegateSupport.ConvertDelegate<UnityAction>((Delegate)new Action(OpenSettings)));
			NativeUi.SetText(val, I18n.Text("menu.mod_settings"));
			Button component7 = ((Component)source).GetComponent<Button>();
			if ((Object)(object)component7 != (Object)null)
			{
				Navigation navigation = ((Selectable)component7).navigation;
				navigation.selectOnDown = (Selectable)(object)component6;
				((Selectable)component7).navigation = navigation;
			}
			Navigation navigation2 = ((Selectable)component6).navigation;
			navigation2.selectOnUp = (Selectable)(object)component7;
			navigation2.selectOnDown = (Selectable)(object)((Component)quitButton).GetComponent<Button>();
			((Selectable)component6).navigation = navigation2;
			Button component8 = ((Component)quitButton).GetComponent<Button>();
			if ((Object)(object)component8 != (Object)null)
			{
				Navigation navigation3 = ((Selectable)component8).navigation;
				navigation3.selectOnUp = (Selectable)(object)component6;
				((Selectable)component8).navigation = navigation3;
			}
			return val;
		}

		private static void OpenSettings()
		{
			if (_settingsPanel != null && !((Object)(object)_mainMenuRoot == (Object)null))
			{
				_settingsPanel.Prepare();
				((Component)_mainMenuRoot).gameObject.SetActive(false);
				_settingsPanel.Show();
			}
		}

		private static void CloseSettings()
		{
			if (_settingsPanel != null && !((Object)(object)_mainMenuRoot == (Object)null))
			{
				_settingsPanel.Hide();
				((Component)_mainMenuRoot).gameObject.SetActive(true);
				NativeUi.SelectObject(_modSettingsButton);
			}
		}

		private static void SetButtonLayout(RectTransform rectTransform, Vector3 scale, float anchoredY)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			rectTransform.anchoredPosition = new Vector2(rectTransform.anchoredPosition.x, anchoredY);
			((Transform)rectTransform).localScale = scale;
		}

		private static void ResetReferences()
		{
			_mainMenuRoot = null;
			_mainMenuObject = null;
			_modSettingsButton = null;
			_settingsPanel = null;
		}
	}
	internal sealed class ModSettingsPanel
	{
		private const string InputRowPath = "CreateLobbySettings/Lobby Name";

		private const string DescriptionTextPath = "NetworkErrorPopup/DescriptionText (TMP)";

		private static readonly string[] PluginButtonSlotPaths = new string[4] { "Audio Button", "KeyboardControls Button", "GamepadControlsButton", "Video Button" };

		private readonly GameObject _panel;

		private readonly TMP_Text _title;

		private readonly GameObject _backButtonObject;

		private readonly GameObject _buttonTemplate;

		private readonly Transform _buttonParent;

		private readonly ScrollRect _modScroll;

		private readonly float _modButtonStep;

		private readonly ConfigRows _rows;

		private readonly KeybindCapture _keybindCapture;

		private readonly List<GameObject> _modButtons = new List<GameObject>();

		private IReadOnlyList<ModConfig> _mods = Array.Empty<ModConfig>();

		private string _selectedGuid;

		public bool IsOpen
		{
			get
			{
				if ((Object)(object)_panel != (Object)null)
				{
					return _panel.activeSelf;
				}
				return false;
			}
		}

		public bool IsCapturingKeybind => _keybindCapture.IsActive;

		private ModSettingsPanel(GameObject panel, TMP_Text title, GameObject backButtonObject, GameObject buttonTemplate, Transform buttonParent, ScrollRect modScroll, float modButtonStep, ConfigRows rows, KeybindCapture keybindCapture)
		{
			_panel = panel;
			_title = title;
			_backButtonObject = backButtonObject;
			_buttonTemplate = buttonTemplate;
			_buttonParent = buttonParent;
			_modScroll = modScroll;
			_modButtonStep = modButtonStep;
			_rows = rows;
			_keybindCapture = keybindCapture;
		}

		public static ModSettingsPanel Create(Transform source, Transform canvas, Action closeSettings)
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, canvas);
			((Object)val).name = "Mod Settings";
			val.SetActive(false);
			NativeUi.DisableComponent<ControlsMenuSwitcher>(val);
			NativeUi.DisableComponent<SettingsBackButtonNavigation>(val);
			NativeUi.DisableComponent<PauseMenu>(val);
			NativeUi.DisableComponent<SelectObjectOnDisable>(val);
			for (int i = 0; i < val.transform.childCount; i++)
			{
				((Component)val.transform.GetChild(i)).gameObject.SetActive(false);
			}
			Transform val2 = NativeUi.RequireTransform(val.transform, "BG");
			GameObject gameObject = ((Component)NativeUi.RequireTransform(val.transform, "Back to menu Button")).gameObject;
			Transform val3 = NativeUi.RequireTransform(val.transform, "Audio Menu");
			((Component)val2).gameObject.SetActive(true);
			gameObject.SetActive(true);
			((Component)val3).gameObject.SetActive(true);
			Button component = gameObject.GetComponent<Button>();
			if ((Object)(object)component == (Object)null)
			{
				throw new InvalidOperationException("Mod settings back button is missing Button.");
			}
			component.onClick = new ButtonClickedEvent();
			((UnityEvent)component.onClick).AddListener(DelegateSupport.ConvertDelegate<UnityAction>((Delegate)closeSettings));
			List<RectTransform> list = new List<RectTransform>();
			string[] pluginButtonSlotPaths = PluginButtonSlotPaths;
			foreach (string text in pluginButtonSlotPaths)
			{
				Transform obj = NativeUi.RequireTransform(val.transform, text);
				RectTransform component2 = ((Component)obj).GetComponent<RectTransform>();
				if ((Object)(object)component2 == (Object)null)
				{
					throw new InvalidOperationException("Mod button slot " + text + " is missing RectTransform.");
				}
				list.Add(component2);
				((Component)obj).gameObject.SetActive(false);
			}
			GameObject gameObject2 = ((Component)NativeUi.RequireTransform(val.transform, PluginButtonSlotPaths[0])).gameObject;
			Transform obj2 = val3.Find("TITLE (1)");
			TMP_Text val4 = ((obj2 != null) ? ((Component)obj2).GetComponent<TMP_Text>() : null);
			NativeUi.SetLocalizedText(val4, I18n.Text("menu.mod_settings"));
			NativeUi.DisableComponent<SelectObjectOnDisable>(((Component)val3).gameObject);
			NativeUi.DisableComponent<ScrollRectControllerFocus>(((Component)val3).gameObject);
			Transform val5 = NativeUi.RequireTransform(val3, "Scroll View (1)");
			NativeUi.DisableComponent<ScrollRectControllerSupport>(((Component)val5).gameObject);
			NativeUi.DisableComponent<ConsoleUINavigation>(((Component)val5).gameObject);
			NativeUi.DisableComponent<ScrollRectFollowSelection>(((Component)val5).gameObject);
			Transform val6 = NativeUi.RequireTransform(val5, "Viewport/Content");
			NativeUi.DisableComponent<PerPlayerVolumeUI>(((Component)val6).gameObject);
			Transform content;
			float buttonStep;
			ScrollRect modScroll = CreateModList(val.transform, val5, list, out content, out buttonStep);
			GameObject gameObject3 = ((Component)NativeUi.RequireTransform(val6, "Music Bar")).gameObject;
			GameObject gameObject4 = ((Component)NativeUi.RequireTransform(gameObject3.transform, "Slider/Background")).gameObject;
			GameObject gameObject5 = ((Component)NativeUi.RequireTransform(val.transform, "Video Menu/Scroll View/Viewport/Content/Display Mode (1)")).gameObject;
			TMP_Text component3 = ((Component)NativeUi.RequireTransform(gameObject5.transform, "Dropdown/Label")).GetComponent<TMP_Text>();
			if ((Object)(object)component3 == (Object)null)
			{
				throw new InvalidOperationException("Config description font template is missing TextMeshProUGUI.");
			}
			GameObject gameObject6 = ((Component)NativeUi.RequireTransform(val.transform, "Video Menu/Scroll View/Viewport/Content/Arachnophobia Mode")).gameObject;
			GameObject gameObject7 = ((Component)NativeUi.RequireTransform(canvas, "CreateLobbySettings/Lobby Name")).gameObject;
			GameObject gameObject8 = ((Component)NativeUi.RequireTransform(val.transform, "Controls Menu/Scroll View/Viewport/Content/MoveForward")).gameObject;
			GameObject gameObject9 = ((Component)NativeUi.RequireTransform(gameObject8.transform, "Button")).gameObject;
			GameObject gameObject10 = ((Component)NativeUi.RequireTransform(canvas, "NetworkErrorPopup/DescriptionText (TMP)")).gameObject;
			for (int k = 0; k < val6.childCount; k++)
			{
				((Component)val6.GetChild(k)).gameObject.SetActive(false);
			}
			KeybindCapture keybindCapture = new KeybindCapture();
			DescriptionLayout description = new DescriptionLayout(gameObject3, gameObject5, gameObject10, component3);
			ModInfoRow modInfo = new ModInfoRow(val6, gameObject3, gameObject4, gameObject9, gameObject10, component3);
			ConfigRows rows = new ConfigRows(val6, gameObject3, gameObject6, gameObject5, gameObject7, gameObject8, keybindCapture, description, modInfo);
			return new ModSettingsPanel(val, val4, gameObject, gameObject2, content, modScroll, buttonStep, rows, keybindCapture);
		}

		public void Prepare()
		{
			_keybindCapture.Clear();
			BuildModButtons();
			BuildRows();
		}

		public void Show()
		{
			_panel.SetActive(true);
			NativeUi.SelectObject(_modButtons.FirstOrDefault() ?? _backButtonObject);
		}

		public void Hide()
		{
			_keybindCapture.Clear();
			_panel.SetActive(false);
		}

		public void CaptureKeybindInput()
		{
			_keybindCapture.CaptureInput();
		}

		public void ScrollModList()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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)
			Mouse current = Mouse.current;
			RectTransform viewport = _modScroll.viewport;
			RectTransform content = _modScroll.content;
			if (current == null || (Object)(object)viewport == (Object)null || (Object)(object)content == (Object)null)
			{
				return;
			}
			Vector2 val = ((InputControl<Vector2>)(object)current.scroll).ReadValue();
			if (!Mathf.Approximately(val.y, 0f) && RectTransformUtility.RectangleContainsScreenPoint(viewport, ((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue(), (Camera)null))
			{
				Rect rect = content.rect;
				float height = ((Rect)(ref rect)).height;
				rect = viewport.rect;
				float num = height - ((Rect)(ref rect)).height;
				if (!(num <= 0f))
				{
					_modScroll.StopMovement();
					_modScroll.verticalNormalizedPosition = Mathf.Clamp01(_modScroll.verticalNormalizedPosition + Mathf.Sign(val.y) * (_modButtonStep / num));
				}
			}
		}

		public void RefreshLocalizedText()
		{
			NativeUi.SetLocalizedText(_title, I18n.Text("menu.mod_settings"));
			if (IsOpen)
			{
				Prepare();
			}
		}

		private void BuildModButtons()
		{
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			foreach (GameObject modButton in _modButtons)
			{
				if ((Object)(object)modButton != (Object)null)
				{
					modButton.SetActive(false);
					Object.Destroy((Object)(object)modButton);
				}
			}
			_modButtons.Clear();
			_mods = ModConfigs.Load();
			if (!_mods.Any((ModConfig mod) => string.Equals(mod.Info.Metadata.GUID, _selectedGuid, StringComparison.OrdinalIgnoreCase)))
			{
				ModConfig? modConfig = _mods.FirstOrDefault();
				_selectedGuid = ((modConfig != null) ? modConfig.Info.Metadata.GUID : null);
			}
			for (int num = 0; num < _mods.Count; num++)
			{
				ModConfig modConfig2 = _mods[num];
				GameObject val = Object.Instantiate<GameObject>(_buttonTemplate, _buttonParent);
				((Object)val).name = "Mod Settings - " + modConfig2.Info.Metadata.GUID;
				val.SetActive(false);
				RectTransform component = val.GetComponent<RectTransform>();
				Button component2 = val.GetComponent<Button>();
				if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null)
				{
					Object.Destroy((Object)(object)val);
					throw new InvalidOperationException("Cloned mod selection button is missing RectTransform or Button.");
				}
				NativeUi.DisableComponent<RemoveOnConsole>(val);
				string guid = modConfig2.Info.Metadata.GUID;
				component2.onClick = new ButtonClickedEvent();
				((UnityEvent)component2.onClick).AddListener(DelegateSupport.ConvertDelegate<UnityAction>((Delegate)(Action)delegate
				{
					SelectMod(guid);
				}));
				NativeUi.SetText(val, GetModName(modConfig2));
				val.SetActive(true);
				_modButtons.Add(val);
			}
			for (int num2 = 0; num2 < _modButtons.Count; num2++)
			{
				Button component3 = _modButtons[num2].GetComponent<Button>();
				Navigation navigation = ((Selectable)component3).navigation;
				navigation.mode = (Mode)4;
				navigation.selectOnUp = (Selectable)(object)((num2 > 0) ? _modButtons[num2 - 1].GetComponent<Button>() : null);
				navigation.selectOnDown = (Selectable)(object)((num2 + 1 < _modButtons.Count) ? _modButtons[num2 + 1].GetComponent<Button>() : null);
				((Selectable)component3).navigation = navigation;
			}
			LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)_buttonParent).GetComponent<RectTransform>());
			_modScroll.StopMovement();
			if (_mods.Count <= PluginButtonSlotPaths.Length)
			{
				_modScroll.verticalNormalizedPosition = 1f;
			}
		}

		private void BuildRows()
		{
			ModConfig mod = _mods.FirstOrDefault((ModConfig item) => string.Equals(item.Info.Metadata.GUID, _selectedGuid, StringComparison.OrdinalIgnoreCase));
			_rows.Build(mod);
		}

		private void SelectMod(string guid)
		{
			_selectedGuid = guid;
			BuildRows();
		}

		private static string GetModName(ModConfig mod)
		{
			string text = mod.Registration?.Name;
			if (string.IsNullOrWhiteSpace(text))
			{
				text = mod.Info.Metadata.Name;
			}
			return SplitName(text);
		}

		private static string SplitName(string name)
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				return string.Empty;
			}
			return Regex.Replace(name.Replace('_', ' ').Replace('-', ' '), "(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])", " ");
		}

		private static ScrollRect CreateModList(Transform panel, Transform source, IReadOnlyList<RectTransform> slots, out Transform content, out float buttonStep)
		{
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, panel);
			((Object)val).name = "Mod List";
			val.SetActive(false);
			NativeUi.DisableComponent<ScrollRectControllerSupport>(val);
			NativeUi.DisableComponent<ConsoleUINavigation>(val);
			RectTransform component = val.GetComponent<RectTransform>();
			Transform val2 = NativeUi.RequireTransform(val.transform, "Viewport");
			RectTransform component2 = ((Component)val2).GetComponent<RectTransform>();
			content = NativeUi.RequireTransform(val2, "Content");
			RectTransform component3 = ((Component)content).GetComponent<RectTransform>();
			VerticalLayoutGroup component4 = ((Component)content).GetComponent<VerticalLayoutGroup>();
			ContentSizeFitter component5 = ((Component)content).GetComponent<ContentSizeFitter>();
			ScrollRect component6 = val.GetComponent<ScrollRect>();
			RectTransform component7 = ((Component)source).GetComponent<RectTransform>();
			object obj;
			if (component6 == null)
			{
				obj = null;
			}
			else
			{
				Scrollbar verticalScrollbar = component6.verticalScrollbar;
				obj = ((verticalScrollbar != null) ? ((Component)verticalScrollbar).GetComponent<RectTransform>() : null);
			}
			RectTransform val3 = (RectTransform)obj;
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)component3 == (Object)null || (Object)(object)component4 == (Object)null || (Object)(object)component5 == (Object)null || (Object)(object)component6 == (Object)null || (Object)(object)component7 == (Object)null || (Object)(object)val3 == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				throw new InvalidOperationException("Native mod list scroll template is missing required components.");
			}
			RectTransform val4 = slots[0];
			RectTransform val5 = slots[slots.Count - 1];
			float y = val4.anchoredPosition.y;
			Rect rect = val4.rect;
			float num = y + ((Rect)(ref rect)).height * 0.5f;
			float y2 = val5.anchoredPosition.y;
			rect = val5.rect;
			float num2 = y2 - ((Rect)(ref rect)).height * 0.5f;
			float num3 = Mathf.Abs(component2.sizeDelta.x);
			rect = val4.rect;
			float x = panel.InverseTransformPoint(((Transform)val4).TransformPoint(new Vector3(((Rect)(ref rect)).xMin, 0f, 0f))).x;
			rect = component7.rect;
			float num4 = panel.InverseTransformPoint(source.TransformPoint(new Vector3(((Rect)(ref rect)).xMin, 0f, 0f))).x - x;
			rect = val3.rect;
			float num5 = num4 - ((Rect)(ref rect)).width;
			rect = val4.rect;
			float width = ((Rect)(ref rect)).width;
			rect = val4.rect;
			float num6 = width + ((Rect)(ref rect)).height + num3;
			float num7 = Mathf.Min(num5, num6);
			float num8 = num7 - num3;
			rect = val4.rect;
			if (num8 <= ((Rect)(ref rect)).width)
			{
				Object.Destroy((Object)(object)val);
				throw new InvalidOperationException("Native settings panel does not have enough space for a wider mod list.");
			}
			component.anchorMin = val4.anchorMin;
			component.anchorMax = val4.anchorMax;
			component.pivot = val4.pivot;
			float x2 = val4.anchoredPosition.x;
			rect = val4.rect;
			component.anchoredPosition = new Vector2(x2 + (num7 - ((Rect)(ref rect)).width) * 0.5f, (num + num2) * 0.5f);
			component.sizeDelta = new Vector2(num7, num - num2);
			((Transform)component).localScale = ((Transform)val4).localScale;
			((Transform)component).localRotation = ((Transform)val4).localRotation;
			val4.sizeDelta = new Vector2(num8, val4.sizeDelta.y);
			component3.anchorMin = new Vector2(0f, 1f);
			component3.anchorMax = new Vector2(1f, 1f);
			component3.pivot = new Vector2(0.5f, 1f);
			component3.anchoredPosition = Vector2.zero;
			component3.sizeDelta = Vector2.zero;
			float num9 = num - num2;
			rect = val4.rect;
			float num10 = (num9 - ((Rect)(ref rect)).height * (float)slots.Count) / (float)(slots.Count - 1);
			rect = val4.rect;
			buttonStep = ((Rect)(ref rect)).height + num10;
			((LayoutGroup)component4).padding = new RectOffset(0, 0, 0, 0);
			((LayoutGroup)component4).childAlignment = (TextAnchor)1;
			((HorizontalOrVerticalLayoutGroup)component4).spacing = num10;
			((HorizontalOrVerticalLayoutGroup)component4).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)component4).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)component4).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)component4).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)component4).childScaleWidth = false;
			((HorizontalOrVerticalLayoutGroup)component4).childScaleHeight = false;
			component5.horizontalFit = (FitMode)0;
			component5.verticalFit = (FitMode)2;
			component6.content = component3;
			component6.viewport = component2;
			component6.horizontal = false;
			component6.vertical = true;
			component6.verticalScrollbarVisibility = (ScrollbarVisibility)2;
			component6.verticalNormalizedPosition = 1f;
			ScrollRectFollowSelection component8 = val.GetComponent<ScrollRectFollowSelection>();
			if ((Object)(object)component8 != (Object)null)
			{
				component8.scrollRect = component6;
				((Behaviour)component8).enabled = true;
			}
			NativeUi.DisableComponent<PerPlayerVolumeUI>(((Component)content).gameObject);
			for (int i = 0; i < content.childCount; i++)
			{
				((Component)content.GetChild(i)).gameObject.SetActive(false);
			}
			val.SetActive(true);
			return component6;
		}
	}
	internal static class NativeUi
	{
		public static void DisableRowComponents(GameObject row)
		{
			UseLanguageFontsOnly(row);
			NativeUi.DisableComponent<RemoveOnConsole>(row);
			NativeUi.DisableComponent<RemoveIfNotController>(row);
			NativeUi.DisableComponent<ControllerButtonPrompt>(row);
			NativeUi.DisableComponent<ChangeTextToKeybind>(row);
			for (int i = 0; i < row.transform.childCount; i++)
			{
				GameObject gameObject = ((Component)row.transform.GetChild(i)).gameObject;
				if (((Object)gameObject).name.StartsWith("CONTROLLER BUTTON PROMPT", StringComparison.Ordinal))
				{
					gameObject.SetActive(false);
				}
			}
		}

		public static void UseLanguageFontsOnly(GameObject root)
		{
			Il2CppArrayBase<LanguageText> componentsInChildren = root.GetComponentsInChildren<LanguageText>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				LanguageText obj = componentsInChildren[i];
				((Behaviour)obj).enabled = false;
				obj.fontOnly = true;
				obj.OnEnable();
				obj.SetText();
			}
		}

		public static void SetLocalizedText(TMP_Text label, string text)
		{
			if (!((Object)(object)label == (Object)null))
			{
				UseLanguageFontsOnly(((Component)label).gameObject);
				label.text = text;
			}
		}

		public static void SetText(GameObject root, string text)
		{
			UseLanguageFontsOnly(root);
			TMP_Text componentInChildren = root.GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.text = text;
			}
		}

		public static TMP_Text SetRowTitle(GameObject row, string text)
		{
			Transform val = row.transform.Find("Title") ?? row.transform.Find("Title (1)");
			if ((Object)(object)val == (Object)null)
			{
				SetText(row, text);
				return row.GetComponentInChildren<TMP_Text>(true);
			}
			TMP_Text component = ((Component)val).GetComponent<TMP_Text>();
			SetLocalizedText(component, text);
			return component;
		}

		public static void CopyFont(TMP_Text source, TMP_Text target)
		{
			if ((Object)(object)source != (Object)null && (Object)(object)source.font != (Object)null && (Object)(object)target != (Object)null)
			{
				target.font = source.font;
			}
		}

		public static void CenterControl(RectTransform controlRect)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)controlRect != (Object)null)
			{
				controlRect.anchoredPosition = new Vector2(0f, controlRect.anchoredPosition.y);
			}
		}

		public static void SelectObject(GameObject target)
		{
			if ((Object)(object)target != (Object)null && (Object)(object)EventSystem.current != (Object)null)
			{
				EventSystem.current.SetSelectedGameObject(target);
			}
		}

		public static Transform RequireTransform(Transform root, string path)
		{
			Transform obj = root.Find(path);
			if ((Object)(object)obj == (Object)null)
			{
				throw new InvalidOperationException("Resource path not found: " + GetTransformPath(root) + "/" + path);
			}
			return obj;
		}

		public static void DisableComponent<T>(GameObject root) where T : Behaviour
		{
			T component = root.GetComponent<T>();
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = false;
			}
		}

		private static string GetTransformPath(Transform transform)
		{
			List<string> list = new List<string>();
			Transform val = transform;
			while ((Object)(object)val != (Object)null)
			{
				list.Add(((Object)val).name);
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}
	}
}
namespace ModSettingsMenu.Patches
{
	[HarmonyPatch(typeof(MainMenu), "Start")]
	public static class MainMenuStartPatch
	{
		[HarmonyPostfix]
		public static void Postfix(MainMenu __instance)
		{
			ModSettingsMenuController.TryCreate(__instance);
		}
	}
	[HarmonyPatch(typeof(MainMenu), "Update")]
	public static class MainMenuUpdatePatch
	{
		[HarmonyPostfix]
		public static void Postfix()
		{
			ModSettingsMenuController.CheckBackInput();
		}
	}
}
namespace ModSettingsMenu.Localization
{
	public static class I18n
	{
		private const string FileName = "ModSettingsMenu.Localization.json";

		private static ModLocalizer _localizer;

		public static ModLocalizer L => _localizer ?? (_localizer = CreateLocalizer());

		public static string Text(string key, params object[] args)
		{
			return L.GetLocalizedText(key, args);
		}

		private static ModLocalizer CreateLocalizer()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			ModLocalizer obj = LocalizationApi.For("IceBoxStudio.ShiftAtMidnight.ModSettingsMenu");
			obj.RegisterJson(Path.Combine(directoryName, "ModSettingsMenu.Localization.json"));
			return obj;
		}
	}
}
namespace ModSettingsMenu.Configuration
{
	internal static class ConfigValues
	{
		public static bool TrySetValue(ConfigEntryBase entry, object value)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			try
			{
				entry.BoxedValue = value;
				entry.ConfigFile.Save();
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource logger = ModSettingsMenu.Logger;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(25, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to save setting ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ConfigDefinition>(entry.Definition);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				logger.LogError(val);
				return false;
			}
		}

		public static bool TrySetSerializedValue(ConfigEntryBase entry, string value)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			try
			{
				entry.SetSerializedValue(value);
				entry.ConfigFile.Save();
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource logger = ModSettingsMenu.Logger;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(25, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to save setting ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ConfigDefinition>(entry.Definition);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				logger.LogError(val);
				return false;
			}
		}

		public static string FormatValue(object value)
		{
			if (value == null)
			{
				return string.Empty;
			}
			if (value is IFormattable formattable)
			{
				return formattable.ToString(null, CultureInfo.InvariantCulture) ?? string.Empty;
			}
			return value.ToString() ?? string.Empty;
		}

		public static object ConvertSliderValue(float value, Type targetType)
		{
			if (targetType == typeof(float))
			{
				return value;
			}
			if (targetType == typeof(double))
			{
				return (double)value;
			}
			if (targetType == typeof(decimal))
			{
				return (decimal)value;
			}
			if (targetType == typeof(byte))
			{
				return (byte)Math.Round(value);
			}
			if (targetType == typeof(sbyte))
			{
				return (sbyte)Math.Round(value);
			}
			if (targetType == typeof(short))
			{
				return (short)Math.Round(value);
			}
			if (targetType == typeof(ushort))
			{
				return (ushort)Math.Round(value);
			}
			if (targetType == typeof(int))
			{
				return (int)Math.Round(value);
			}
			if (targetType == typeof(uint))
			{
				return (uint)Math.Round(value);
			}
			if (targetType == typeof(long))
			{
				return (long)Math.Round(value);
			}
			if (targetType == typeof(ulong))
			{
				return (ulong)Math.Round(value);
			}
			return value;
		}

		public static bool IsSliderType(Type type)
		{
			if (!(type == typeof(byte)) && !(type == typeof(sbyte)) && !(type == typeof(short)) && !(type == typeof(ushort)) && !(type == typeof(int)) && !(type == typeof(uint)) && !(type == typeof(long)) && !(type == typeof(ulong)) && !(type == typeof(float)) && !(type == typeof(double)))
			{
				return type == typeof(decimal);
			}
			return true;
		}

		public static bool IsIntegralType(Type type)
		{
			if (!(type == typeof(byte)) && !(type == typeof(sbyte)) && !(type == typeof(short)) && !(type == typeof(ushort)) && !(type == typeof(int)) && !(type == typeof(uint)) && !(type == typeof(long)))
			{
				return type == typeof(ulong);
			}
			return true;
		}

		public static bool TryGetAcceptableValues(AcceptableValueBase acceptable, out IReadOnlyList<object> values)
		{
			values = Array.Empty<object>();
			if (acceptable == null)
			{
				return false;
			}
			if (!(((object)acceptable).GetType().GetProperty("AcceptableValues")?.GetValue(acceptable) is IEnumerable source))
			{
				return false;
			}
			values = source.Cast<object>().ToList();
			return values.Count > 0;
		}

		public static bool TryGetNumericRange(AcceptableValueBase acceptable, out float min, out float max)
		{
			min = 0f;
			max = 1f;
			if (acceptable == null)
			{
				return false;
			}
			Type type = ((object)acceptable).GetType();
			PropertyInfo property = type.GetProperty("MinValue");
			PropertyInfo property2 = type.GetProperty("MaxValue");
			if (property == null || property2 == null)
			{
				return false;
			}
			try
			{
				min = Convert.ToSingle(property.GetValue(acceptable), CultureInfo.InvariantCulture);
				max = Convert.ToSingle(property2.GetValue(acceptable), CultureInfo.InvariantCulture);
				return float.IsFinite(min) && float.IsFinite(max) && min < max;
			}
			catch
			{
				return false;
			}
		}
	}
	public sealed class ModConfig
	{
		public PluginInfo Info;

		public ConfigFile ConfigFile;

		public ModSettingsRegistration Registration;
	}
	public static class ModConfigs
	{
		public static IReadOnlyList<ModConfig> Load()
		{
			List<ModConfig> list = new List<ModConfig>();
			if (((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance)?.Plugins == null)
			{
				return list;
			}
			foreach (PluginInfo item in ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.Values.Where((PluginInfo info) => ((info != null) ? info.Metadata : null) != null).OrderBy<PluginInfo, string>((PluginInfo info) => info.Metadata.Name, StringComparer.OrdinalIgnoreCase).ToList())
			{
				if (!string.Equals(item.Metadata.GUID, "IceBoxStudio.ShiftAtMidnight.ModSettingsMenu", StringComparison.OrdinalIgnoreCase))
				{
					object instance = item.Instance;
					BasePlugin val = (BasePlugin)((instance is BasePlugin) ? instance : null);
					if (val != null && val.Config != null && val.Config.Values.Count != 0)
					{
						list.Add(new ModConfig
						{
							Info = item,
							ConfigFile = val.Config,
							Registration = (ModSettingsRegistry.TryGet(item.Metadata.GUID, out var registration) ? registration : null)
						});
					}
				}
			}
			return list;
		}
	}
}
namespace ModSettingsMenu.Api
{
	public sealed class ModSettingsModOptions
	{
		public string Name { get; set; }

		public string Description { get; set; }

		public string Author { get; set; }

		public string Version { get; set; }

		public int? NexusModsId { get; set; }
	}
	public sealed class ModSettingsRegistration
	{
		public string PluginGuid { get; }

		public string Name { get; private set; }

		public string Description { get; private set; }

		public string Author { get; private set; }

		public string Version { get; private set; }

		public int? NexusModsId { get; private set; }

		internal ModSettingsRegistration(string pluginGuid, ModSettingsModOptions options)
		{
			PluginGuid = pluginGuid ?? throw new ArgumentNullException("pluginGuid");
			if (options != null && options.NexusModsId.HasValue)
			{
				ModSettingsRegistry.GetNexusModsUrl(options.NexusModsId.Value);
			}
			Name = options?.Name;
			Description = options?.Description;
			Author = options?.Author;
			Version = options?.Version;
			NexusModsId = options?.NexusModsId;
		}
	}
	public static class ModSettingsRegistry
	{
		public const string NexusModsGameUrl = "https://www.nexusmods.com/games/shiftatmidnight";

		private const string NexusModsModUrlPrefix = "https://www.nexusmods.com/shiftatmidnight/mods/";

		private static readonly object Sync = new object();

		private static readonly Dictionary<string, ModSettingsRegistration> Registrations = new Dictionary<string, ModSettingsRegistration>(StringComparer.OrdinalIgnoreCase);

		internal static event Action RefreshRequested;

		public static ModSettingsRegistration Register(string pluginGuid, ModSettingsModOptions options = null)
		{
			if (string.IsNullOrWhiteSpace(pluginGuid))
			{
				throw new ArgumentException("Plugin GUID cannot be empty.", "pluginGuid");
			}
			ModSettingsRegistration modSettingsRegistration = new ModSettingsRegistration(pluginGuid, options);
			lock (Sync)
			{
				Registrations[pluginGuid] = modSettingsRegistration;
			}
			RequestRefresh();
			return modSettingsRegistration;
		}

		public static bool Unregister(string pluginGuid)
		{
			bool flag;
			lock (Sync)
			{
				flag = !string.IsNullOrWhiteSpace(pluginGuid) && Registrations.Remove(pluginGuid);
			}
			if (flag)
			{
				RequestRefresh();
			}
			return flag;
		}

		public static string GetNexusModsUrl(int nexusModsId)
		{
			if (nexusModsId <= 0)
			{
				throw new ArgumentOutOfRangeException("nexusModsId", nexusModsId, "Nexus Mods ID must be a positive integer.");
			}
			return "https://www.nexusmods.com/shiftatmidnight/mods/" + nexusModsId.ToString(CultureInfo.InvariantCulture);
		}

		internal static bool TryGet(string pluginGuid, out ModSettingsRegistration registration)
		{
			registration = null;
			lock (Sync)
			{
				return !string.IsNullOrWhiteSpace(pluginGuid) && Registrations.TryGetValue(pluginGuid, out registration);
			}
		}

		private static void RequestRefresh()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			Action refreshRequested = ModSettingsRegistry.RefreshRequested;
			if (refreshRequested == null)
			{
				return;
			}
			Delegate[] invocationList = refreshRequested.GetInvocationList();
			bool flag = default(bool);
			foreach (Delegate obj in invocationList)
			{
				try
				{
					((Action)obj)();
				}
				catch (Exception ex)
				{
					ManualLogSource logger = ModSettingsMenu.Logger;
					if (logger != null)
					{
						BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(38, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Mod settings refresh callback failed: ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
						}
						logger.LogError(val);
					}
				}
			}
		}
	}
}