Decompiled source of HowToFishModMenu v0.3.2

BepInEx/plugins/HowToFish.ModMenu/HowToFish.ModAPI.dll

Decompiled 5 hours ago
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx.Configuration;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace HowToFish.ModAPI;

public interface IModSettingsProvider
{
	string SettingsTitle { get; }

	string Description { get; }

	string Warning { get; }

	IEnumerable<ConfigEntryBase> GetSettings();
}

BepInEx/plugins/HowToFish.ModMenu/HowToFish.ModMenu.dll

Decompiled 5 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HowToFish.ModAPI;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace HowToFish.ModMenu;

internal sealed class ModRecord
{
	internal string Guid;

	internal string Name;

	internal string Version;

	internal string Author;

	internal string Description;

	internal string Warning;

	internal BaseUnityPlugin Instance;

	internal List<ConfigEntryBase> Settings = new List<ConfigEntryBase>();
}
internal static class ModCatalog
{
	internal static List<ModRecord> Discover()
	{
		Dictionary<string, ModRecord> dictionary = new Dictionary<string, ModRecord>(StringComparer.OrdinalIgnoreCase);
		foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
		{
			PluginInfo value = pluginInfo.Value;
			ModRecord modRecord = new ModRecord();
			modRecord.Guid = value.Metadata.GUID;
			modRecord.Name = value.Metadata.Name;
			modRecord.Version = value.Metadata.Version.ToString();
			modRecord.Instance = value.Instance;
			ModRecord modRecord2 = modRecord;
			ReadAssemblyMetadata(modRecord2);
			if ((Object)(object)modRecord2.Instance != (Object)null)
			{
				BaseUnityPlugin instance = modRecord2.Instance;
				IModSettingsProvider val = (IModSettingsProvider)(object)((instance is IModSettingsProvider) ? instance : null);
				if (val != null)
				{
					modRecord2.Description = val.Description;
					modRecord2.Warning = val.Warning;
					IEnumerable<ConfigEntryBase> settings = val.GetSettings();
					if (settings != null)
					{
						modRecord2.Settings.AddRange(settings);
					}
				}
				else
				{
					foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in modRecord2.Instance.Config)
					{
						modRecord2.Settings.Add(item.Value);
					}
				}
			}
			if (modRecord2.Guid.IndexOf("debugtools", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				modRecord2.Warning = "DEVELOPMENT TOOL\nContains gameplay-changing debugging features.\nDo not use for leaderboard speedruns.";
			}
			dictionary[modRecord2.Guid] = modRecord2;
		}
		return dictionary.Values.OrderBy<ModRecord, string>((ModRecord m) => m.Name, StringComparer.OrdinalIgnoreCase).ToList();
	}

	private static void ReadAssemblyMetadata(ModRecord record)
	{
		try
		{
			Assembly assembly = (((Object)(object)record.Instance == (Object)null) ? null : ((object)record.Instance).GetType().Assembly);
			if (!(assembly == null))
			{
				object[] customAttributes = assembly.GetCustomAttributes(typeof(AssemblyCompanyAttribute), inherit: false);
				object[] customAttributes2 = assembly.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), inherit: false);
				if (customAttributes.Length > 0)
				{
					record.Author = ((AssemblyCompanyAttribute)customAttributes[0]).Company;
				}
				if (customAttributes2.Length > 0)
				{
					record.Description = ((AssemblyDescriptionAttribute)customAttributes2[0]).Description;
				}
			}
		}
		catch
		{
		}
	}
}
internal sealed class NativeModMenu
{
	private readonly ManualLogSource _log;

	private GameObject _entryButton;

	private GameObject _page;

	private GameObject _buttonTemplate;

	private GameObject _nativeSliderTemplate;

	private GameObject _nativeToggleTemplate;

	private GameObject _nativeInputTemplate;

	private Image _nativePanelStyle;

	private Image _nativeBackdropStyle;

	private Transform _mainCanvasRoot;

	private RectTransform _left;

	private RectTransform _right;

	private TextMeshProUGUI _title;

	private TextMeshProUGUI _details;

	private TextMeshProUGUI _notice;

	private GameObject _mainMenuPage;

	private GameObject _mainMenuTitle;

	private GameObject _discordButton;

	private bool _mainMenuPageWasActive;

	private bool _mainMenuTitleWasActive;

	private bool _discordButtonWasActive;

	private bool _mainMenuHidden;

	private List<ModRecord> _mods = new List<ModRecord>();

	private ModRecord _selected;

	private float _nextProbe;

	private bool _open;

	private ConfigEntryBase _capture;

	private string _captureBuffer;

	private Button _resetButton;

	private float _resetConfirmUntil;

	internal NativeModMenu(ManualLogSource log)
	{
		_log = log;
	}

	internal void Tick()
	{
		if (_capture != null)
		{
			CaptureInput();
		}
		if (_open && UnityInput.Current.GetKeyDown((KeyCode)27))
		{
			Close();
		}
		else if (!(Time.unscaledTime < _nextProbe))
		{
			_nextProbe = Time.unscaledTime + 1f;
			if ((Object)(object)_entryButton == (Object)null && MainMenuManager.IsInMenu)
			{
				TryInject();
			}
			if ((Object)(object)_entryButton != (Object)null)
			{
				_entryButton.SetActive(MainMenuManager.IsInMenu && !_open);
			}
			if (_open && !MainMenuManager.IsInMenu)
			{
				Close();
			}
		}
	}

	internal void Dispose()
	{
		RestoreMainMenu();
		if ((Object)(object)_page != (Object)null)
		{
			Object.Destroy((Object)(object)_page);
		}
		if ((Object)(object)_entryButton != (Object)null)
		{
			Object.Destroy((Object)(object)_entryButton);
		}
	}

	private void TryInject()
	{
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Expected O, but got Unknown
		try
		{
			CanvasManager val = Object.FindObjectOfType<CanvasManager>(true);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			FieldInfo field = typeof(CanvasManager).GetField("_mainMenuCanvas", BindingFlags.Instance | BindingFlags.NonPublic);
			CanvasGroup val2 = (CanvasGroup)((field == null) ? null : /*isinst with value type is only supported in some contexts*/);
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			_mainCanvasRoot = ((Component)val2).transform;
			CaptureMainMenuObjects(val);
			TextMeshProUGUI val3 = FindMenuText(((Component)val2).transform, "Options");
			if (!((Object)(object)val3 == (Object)null))
			{
				Button componentInParent = ((Component)val3).GetComponentInParent<Button>(true);
				if (!((Object)(object)componentInParent == (Object)null))
				{
					_buttonTemplate = ((Component)componentInParent).gameObject;
					DiscoverNativeOptionsStyle(((Component)val2).transform);
					_entryButton = CreateStyledButton(_buttonTemplate, ((Component)componentInParent).transform.parent, "Mod Settings", new UnityAction(Open));
					InsertAfter(((Component)componentInParent).GetComponent<RectTransform>(), _entryButton.GetComponent<RectTransform>());
					_log.LogInfo((object)"Independent Mod Settings button created with the native Options visual style.");
				}
			}
		}
		catch (Exception ex)
		{
			_nextProbe = float.MaxValue;
			_log.LogWarning((object)("Could not locate Main Menu button template. Mod Settings UI disabled for this game version: " + ex.Message));
		}
	}

	private void Open()
	{
		_mods = ModCatalog.Discover();
		_open = true;
		_entryButton.SetActive(false);
		HideMainMenu();
		BuildPage();
	}

	private void Close()
	{
		_open = false;
		_capture = null;
		if ((Object)(object)_page != (Object)null)
		{
			Object.Destroy((Object)(object)_page);
		}
		_page = null;
		RestoreMainMenu();
		if ((Object)(object)_entryButton != (Object)null && MainMenuManager.IsInMenu)
		{
			_entryButton.SetActive(true);
		}
	}

	private void BuildPage()
	{
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Expected O, but got Unknown
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: 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_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0221: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		//IL_0235: Unknown result type (might be due to invalid IL or missing references)
		//IL_023a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0255: Unknown result type (might be due to invalid IL or missing references)
		//IL_0264: 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_0280: Expected O, but got Unknown
		if ((Object)(object)_page != (Object)null)
		{
			Object.Destroy((Object)(object)_page);
		}
		Transform val = (((Object)(object)_mainCanvasRoot == (Object)null) ? _entryButton.transform.parent : _mainCanvasRoot);
		_page = new GameObject("HowToFish.ModMenu.Page", new Type[3]
		{
			typeof(RectTransform),
			typeof(CanvasGroup),
			typeof(Image)
		});
		RectTransform component = _page.GetComponent<RectTransform>();
		((Transform)component).SetParent(val, false);
		Stretch(component);
		((Transform)component).SetAsLastSibling();
		Image component2 = _page.GetComponent<Image>();
		if ((Object)(object)_nativeBackdropStyle != (Object)null && ((Graphic)_nativeBackdropStyle).color.a > 0.05f)
		{
			CopyImageStyle(_nativeBackdropStyle, component2);
		}
		else
		{
			((Graphic)component2).color = new Color(0.015f, 0.035f, 0.075f, 0.62f);
		}
		((Graphic)component2).raycastTarget = true;
		_title = CreateText("Title", (Transform)(object)component, "Mod Settings", 58f, (TextAlignmentOptions)514);
		SetRect(((TMP_Text)_title).rectTransform, new Vector2(0.1f, 0.875f), new Vector2(0.9f, 0.975f), Vector2.zero, Vector2.zero);
		RectTransform parent = CreatePanel("OptionsPanel", component, new Vector2(0.1f, 0.13f), new Vector2(0.9f, 0.86f));
		_left = CreateScrollArea("InstalledMods", parent, new Vector2(0.035f, 0.07f), new Vector2(0.335f, 0.94f));
		_right = CreateScrollArea("Settings", parent, new Vector2(0.37f, 0.07f), new Vector2(0.965f, 0.94f));
		_notice = CreateText("RestartNotice", (Transform)(object)component, "Use the left and right arrows to change values", 18f, (TextAlignmentOptions)1026);
		SetRect(((TMP_Text)_notice).rectTransform, new Vector2(0.32f, 0.015f), new Vector2(0.68f, 0.075f), Vector2.zero, Vector2.zero);
		CreateAnchoredButton(component, "Back", new Vector2(0.1f, 0.055f), new Vector2(0.25f, 0.115f), new UnityAction(Close), OptionButtonTemplate());
		_selected = null;
		RenderModList();
		if (_mods.Count > 0)
		{
			Select(_mods[0]);
		}
	}

	private void RenderModList()
	{
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Expected O, but got Unknown
		Clear((Transform)(object)_left);
		float num = 0f;
		TextMeshProUGUI val = CreateText("Heading", (Transform)(object)_left, "Installed Mods", 29f, (TextAlignmentOptions)514);
		PositionAt(((TMP_Text)val).rectTransform, num, 48f);
		num += 56f;
		using (List<ModRecord>.Enumerator enumerator = _mods.GetEnumerator())
		{
			while (enumerator.MoveNext())
			{
				UnityAction val2 = null;
				ModRecord mod = enumerator.Current;
				string text = mod.Name + "  v" + mod.Version;
				RectTransform left = _left;
				float y = num;
				if (val2 == null)
				{
					val2 = (UnityAction)delegate
					{
						Select(mod);
					};
				}
				CreateRowButton((Transform)(object)left, text, y, val2);
				num += 54f;
			}
		}
		SetScrollContentHeight(_left, num);
	}

	private void Select(ModRecord mod)
	{
		_selected = mod;
		_capture = null;
		_resetConfirmUntil = 0f;
		RenderSettings();
	}

	private void RenderSettings()
	{
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Expected O, but got Unknown
		Clear((Transform)(object)_right);
		float num = 0f;
		TextMeshProUGUI val = CreateText("ModTitle", (Transform)(object)_right, _selected.Name, 31f, (TextAlignmentOptions)514);
		PositionAt(((TMP_Text)val).rectTransform, num, 48f);
		num += 56f;
		string text = "Version " + _selected.Version + (string.IsNullOrEmpty(_selected.Author) ? string.Empty : ("  ·  " + _selected.Author));
		_details = CreateText("Metadata", (Transform)(object)_right, text + "\n" + (_selected.Description ?? string.Empty), 18f, (TextAlignmentOptions)514);
		PositionAt(((TMP_Text)_details).rectTransform, num, 62f);
		num += 70f;
		if (!string.IsNullOrEmpty(_selected.Warning))
		{
			TextMeshProUGUI val2 = CreateText("Warning", (Transform)(object)_right, _selected.Warning, 19f, (TextAlignmentOptions)514);
			((Graphic)val2).color = new Color(1f, 0.58f, 0.25f, 1f);
			PositionAt(((TMP_Text)val2).rectTransform, num, 74f);
			num += 82f;
		}
		foreach (ConfigEntryBase setting in _selected.Settings)
		{
			ConfigEntryBase val3 = setting;
			string value = ((val3 == _capture) ? ("[ " + _captureBuffer + "_ ]") : val3.GetSerializedValue());
			CreateConfigSettingRow((Transform)(object)_right, val3, value, num);
			num += 54f;
		}
		_resetButton = CreateRowButton((Transform)(object)_right, "Reset to Defaults", num, new UnityAction(ConfirmReset)).GetComponent<Button>();
		num += 54f;
		SetScrollContentHeight(_right, num);
	}

	private void ChangeSetting(ConfigEntryBase entry, int direction)
	{
		try
		{
			Type settingType = entry.SettingType;
			Array acceptableValues = GetAcceptableValues(entry);
			if (acceptableValues != null && acceptableValues.Length > 0)
			{
				int num = Array.IndexOf(acceptableValues, entry.BoxedValue);
				if (num < 0)
				{
					num = 0;
				}
				entry.BoxedValue = acceptableValues.GetValue((num + direction + acceptableValues.Length) % acceptableValues.Length);
			}
			else if (settingType == typeof(bool))
			{
				entry.BoxedValue = !(bool)entry.BoxedValue;
			}
			else if (settingType.IsEnum)
			{
				Array values = Enum.GetValues(settingType);
				int num2 = Array.IndexOf(values, entry.BoxedValue);
				entry.BoxedValue = values.GetValue((num2 + direction + values.Length) % values.Length);
			}
			else if (settingType == typeof(string) || settingType.FullName == "BepInEx.Configuration.KeyboardShortcut")
			{
				_capture = entry;
				_captureBuffer = ((settingType == typeof(string)) ? Convert.ToString(entry.BoxedValue) : string.Empty);
			}
			else if (IsNumber(settingType))
			{
				double num3 = Convert.ToDouble(entry.BoxedValue, CultureInfo.InvariantCulture);
				double numericStep = GetNumericStep(entry, settingType, num3);
				object obj = Convert.ChangeType(Math.Round(num3 + numericStep * (double)direction, 4), settingType, CultureInfo.InvariantCulture);
				AcceptableValueBase acceptableValues2 = entry.Description.AcceptableValues;
				entry.BoxedValue = ((acceptableValues2 == null) ? obj : acceptableValues2.Clamp(obj));
			}
			entry.ConfigFile.Save();
		}
		catch (Exception ex)
		{
			((TMP_Text)_notice).text = "Could not apply setting: " + ex.Message;
		}
		RenderSettings();
	}

	private void CaptureInput()
	{
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: 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_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		if (_capture.SettingType == typeof(string))
		{
			bool flag = false;
			string inputString = Input.inputString;
			foreach (char c in inputString)
			{
				if (c == '\b' && _captureBuffer.Length > 0)
				{
					_captureBuffer = _captureBuffer.Substring(0, _captureBuffer.Length - 1);
					flag = true;
					continue;
				}
				if (c == '\n' || c == '\r')
				{
					_capture.BoxedValue = _captureBuffer;
					FinishCapture();
					return;
				}
				if (!char.IsControl(c))
				{
					_captureBuffer += c;
					flag = true;
				}
			}
			if (flag)
			{
				RenderSettings();
			}
		}
		else
		{
			if (!UnityInput.Current.anyKeyDown)
			{
				return;
			}
			foreach (KeyCode value in Enum.GetValues(typeof(KeyCode)))
			{
				if ((int)value != 0 && UnityInput.Current.GetKeyDown(value))
				{
					_capture.BoxedValue = (object)new KeyboardShortcut(value, (KeyCode[])(object)new KeyCode[0]);
					FinishCapture();
					break;
				}
			}
		}
	}

	private void FinishCapture()
	{
		_capture.ConfigFile.Save();
		_capture = null;
		_captureBuffer = string.Empty;
		RenderSettings();
	}

	private void ConfirmReset()
	{
		if (Time.unscaledTime > _resetConfirmUntil)
		{
			_resetConfirmUntil = Time.unscaledTime + 4f;
			SetButtonText(((Component)_resetButton).gameObject, "Confirm reset to defaults?");
			return;
		}
		foreach (ConfigEntryBase setting in _selected.Settings)
		{
			setting.BoxedValue = setting.DefaultValue;
		}
		if ((Object)(object)_selected.Instance != (Object)null)
		{
			_selected.Instance.Config.Save();
		}
		((TMP_Text)_notice).text = _selected.Name + " settings reset.";
		RenderSettings();
	}

	private static Array GetAcceptableValues(ConfigEntryBase entry)
	{
		AcceptableValueBase acceptableValues = entry.Description.AcceptableValues;
		if (acceptableValues == null)
		{
			return null;
		}
		PropertyInfo property = ((object)acceptableValues).GetType().GetProperty("AcceptableValues", BindingFlags.Instance | BindingFlags.Public);
		if (!(property == null))
		{
			return property.GetValue(acceptableValues, null) as Array;
		}
		return null;
	}

	private static double GetNumericStep(ConfigEntryBase entry, Type type, double current)
	{
		if (type == typeof(int) || type == typeof(long) || type == typeof(short) || type == typeof(byte))
		{
			return 1.0;
		}
		AcceptableValueBase acceptableValues = entry.Description.AcceptableValues;
		if (acceptableValues != null)
		{
			PropertyInfo property = ((object)acceptableValues).GetType().GetProperty("MinValue", BindingFlags.Instance | BindingFlags.Public);
			PropertyInfo property2 = ((object)acceptableValues).GetType().GetProperty("MaxValue", BindingFlags.Instance | BindingFlags.Public);
			if (property != null && property2 != null)
			{
				double num = Convert.ToDouble(property.GetValue(acceptableValues, null), CultureInfo.InvariantCulture);
				double num2 = Convert.ToDouble(property2.GetValue(acceptableValues, null), CultureInfo.InvariantCulture);
				double num3 = Math.Abs(num2 - num) / 10.0;
				if (num3 > 0.0)
				{
					double num4 = Math.Pow(10.0, Math.Floor(Math.Log10(num3)));
					double num5 = num3 / num4;
					double num6 = ((num5 < 1.5) ? 1.0 : ((num5 < 3.5) ? 2.0 : ((num5 < 7.5) ? 5.0 : 10.0)));
					return num6 * num4;
				}
			}
		}
		return Math.Max(Math.Abs(current) * 0.1, 0.05);
	}

	private static bool TryGetNumericRange(ConfigEntryBase entry, out double min, out double max)
	{
		min = 0.0;
		max = 0.0;
		AcceptableValueBase acceptableValues = entry.Description.AcceptableValues;
		if (acceptableValues == null)
		{
			return false;
		}
		PropertyInfo property = ((object)acceptableValues).GetType().GetProperty("MinValue", BindingFlags.Instance | BindingFlags.Public);
		PropertyInfo property2 = ((object)acceptableValues).GetType().GetProperty("MaxValue", BindingFlags.Instance | BindingFlags.Public);
		if (property == null || property2 == null)
		{
			return false;
		}
		min = Convert.ToDouble(property.GetValue(acceptableValues, null), CultureInfo.InvariantCulture);
		max = Convert.ToDouble(property2.GetValue(acceptableValues, null), CultureInfo.InvariantCulture);
		return max > min;
	}

	private GameObject CreateRowButton(Transform parent, string text, float y, UnityAction action)
	{
		GameObject val = CreateStyledButton(OptionButtonTemplate(), parent, text, action);
		PositionAt(val.GetComponent<RectTransform>(), y, 46f);
		return val;
	}

	private void CreateSettingRow(Transform parent, string label, string value, float y, UnityAction previous, UnityAction next)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		//IL_0063: 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_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: 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_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: 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)
		GameObject val = new GameObject("SettingRow_" + label, new Type[1] { typeof(RectTransform) });
		RectTransform component = val.GetComponent<RectTransform>();
		((Transform)component).SetParent(parent, false);
		PositionAt(component, y, 46f);
		TextMeshProUGUI val2 = CreateText("Label", (Transform)(object)component, label, 25f, (TextAlignmentOptions)4097);
		SetRect(((TMP_Text)val2).rectTransform, Vector2.zero, new Vector2(0.5f, 1f), Vector2.zero, Vector2.zero);
		GameObject val3 = CreateStyledButton(OptionButtonTemplate(), (Transform)(object)component, "<", previous);
		SetRect(val3.GetComponent<RectTransform>(), new Vector2(0.52f, 0f), new Vector2(0.6f, 1f), Vector2.zero, Vector2.zero);
		GameObject val4 = CreateStyledButton(OptionButtonTemplate(), (Transform)(object)component, value, next);
		RectTransform component2 = val4.GetComponent<RectTransform>();
		SetRect(component2, new Vector2(0.61f, 0f), new Vector2(0.9f, 1f), Vector2.zero, Vector2.zero);
		GameObject val5 = CreateStyledButton(OptionButtonTemplate(), (Transform)(object)component, ">", next);
		SetRect(val5.GetComponent<RectTransform>(), new Vector2(0.91f, 0f), Vector2.one, Vector2.zero, Vector2.zero);
	}

	private void CreateConfigSettingRow(Transform parent, ConfigEntryBase entry, string value, float y)
	{
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Expected O, but got Unknown
		//IL_00bd: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: 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_01a4: Expected O, but got Unknown
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Expected O, but got Unknown
		//IL_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Expected O, but got Unknown
		//IL_021e: 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_022d: Unknown result type (might be due to invalid IL or missing references)
		UnityAction val = null;
		UnityAction val2 = null;
		GameObject val3 = new GameObject("SettingRow_" + entry.Definition.Key, new Type[1] { typeof(RectTransform) });
		RectTransform component = val3.GetComponent<RectTransform>();
		((Transform)component).SetParent(parent, false);
		PositionAt(component, y, 46f);
		string value2 = entry.Definition.Section + " / " + entry.Definition.Key;
		TextMeshProUGUI val4 = CreateText("Label", (Transform)(object)component, value2, 25f, (TextAlignmentOptions)4097);
		SetRect(((TMP_Text)val4).rectTransform, Vector2.zero, new Vector2(0.5f, 1f), Vector2.zero, Vector2.zero);
		Type settingType = entry.SettingType;
		if (IsNumber(settingType) && (Object)(object)_nativeSliderTemplate != (Object)null && TryGetNumericRange(entry, out var min, out var max))
		{
			CreateNumericSlider(component, entry, value, min, max);
		}
		else if (settingType == typeof(bool) && (Object)(object)_nativeToggleTemplate != (Object)null)
		{
			CreateBooleanToggle(component, entry);
		}
		else if (GetAcceptableValues(entry) != null || settingType.IsEnum || settingType == typeof(bool) || IsNumber(settingType))
		{
			if (val == null)
			{
				val = (UnityAction)delegate
				{
					ChangeSetting(entry, -1);
				};
			}
			UnityAction previous = val;
			if (val2 == null)
			{
				val2 = (UnityAction)delegate
				{
					ChangeSetting(entry, 1);
				};
			}
			CreateArrowControls(component, value, previous, val2);
		}
		else if (settingType == typeof(string) && (Object)(object)_nativeInputTemplate != (Object)null)
		{
			CreateTextInput(component, entry);
		}
		else
		{
			GameObject val5 = CreateStyledButton(OptionButtonTemplate(), (Transform)(object)component, value, (UnityAction)delegate
			{
				ChangeSetting(entry, 1);
			});
			SetRect(val5.GetComponent<RectTransform>(), new Vector2(0.52f, 0f), Vector2.one, Vector2.zero, Vector2.zero);
		}
	}

	private void CreateTextInput(RectTransform rowRect, ConfigEntryBase entry)
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Expected O, but got Unknown
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Expected O, but got Unknown
		//IL_00ab: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Expected O, but got Unknown
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Object.Instantiate<GameObject>(_nativeInputTemplate, (Transform)(object)rowRect, false);
		((Object)val).name = "ModMenuInput_" + entry.Definition.Key;
		val.SetActive(false);
		DisableClonedLocalization(val);
		TMP_InputField input = val.GetComponent<TMP_InputField>();
		input.onValueChanged = new OnChangeEvent();
		input.onEndEdit = new SubmitEvent();
		input.text = Convert.ToString(entry.BoxedValue, CultureInfo.InvariantCulture);
		SetRect(val.GetComponent<RectTransform>(), new Vector2(0.52f, 0f), new Vector2(0.9f, 1f), Vector2.zero, Vector2.zero);
		UnityAction action = (UnityAction)delegate
		{
			try
			{
				entry.BoxedValue = input.text;
				entry.ConfigFile.Save();
				((TMP_Text)_notice).text = entry.Definition.Key + " saved.";
			}
			catch (Exception ex)
			{
				((TMP_Text)_notice).text = "Could not apply setting: " + ex.Message;
			}
		};
		GameObject val2 = CreateStyledButton(OptionButtonTemplate(), (Transform)(object)rowRect, string.Empty, action);
		((Object)val2).name = "ModMenuConfirm_" + entry.Definition.Key;
		SetRect(val2.GetComponent<RectTransform>(), new Vector2(0.91f, 0f), Vector2.one, Vector2.zero, Vector2.zero);
		AddConfirmIcon(val2);
		val.SetActive(true);
	}

	private void AddConfirmIcon(GameObject button)
	{
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Expected O, but got Unknown
		//IL_00a4: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		Image val = null;
		if ((Object)(object)_nativeToggleTemplate != (Object)null)
		{
			Toggle component = _nativeToggleTemplate.GetComponent<Toggle>();
			if ((Object)(object)component != (Object)null)
			{
				Graphic graphic = component.graphic;
				val = (Image)(object)((graphic is Image) ? graphic : null);
			}
		}
		if ((Object)(object)val == (Object)null)
		{
			SetButtonText(button, "✓");
			return;
		}
		GameObject val2 = new GameObject("ConfirmCheckmark", new Type[3]
		{
			typeof(RectTransform),
			typeof(CanvasRenderer),
			typeof(Image)
		});
		RectTransform component2 = val2.GetComponent<RectTransform>();
		((Transform)component2).SetParent(button.transform, false);
		SetRect(component2, new Vector2(0.24f, 0.2f), new Vector2(0.76f, 0.8f), Vector2.zero, Vector2.zero);
		Image component3 = val2.GetComponent<Image>();
		CopyImageStyle(val, component3);
		((Graphic)component3).raycastTarget = false;
	}

	private void CreateArrowControls(RectTransform rowRect, string value, UnityAction previous, UnityAction next)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//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_00bc: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = CreateStyledButton(OptionButtonTemplate(), (Transform)(object)rowRect, "<", previous);
		SetRect(val.GetComponent<RectTransform>(), new Vector2(0.52f, 0f), new Vector2(0.6f, 1f), Vector2.zero, Vector2.zero);
		GameObject val2 = CreateStyledButton(OptionButtonTemplate(), (Transform)(object)rowRect, value, next);
		SetRect(val2.GetComponent<RectTransform>(), new Vector2(0.61f, 0f), new Vector2(0.9f, 1f), Vector2.zero, Vector2.zero);
		GameObject val3 = CreateStyledButton(OptionButtonTemplate(), (Transform)(object)rowRect, ">", next);
		SetRect(val3.GetComponent<RectTransform>(), new Vector2(0.91f, 0f), Vector2.one, Vector2.zero, Vector2.zero);
	}

	private void CreateNumericSlider(RectTransform rowRect, ConfigEntryBase entry, string value, double min, double max)
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Expected O, but got Unknown
		//IL_0115: 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_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Expected O, but got Unknown
		GameObject val = Object.Instantiate<GameObject>(_nativeSliderTemplate, (Transform)(object)rowRect, false);
		((Object)val).name = "ModMenuSlider_" + entry.Definition.Key;
		val.SetActive(false);
		DisableClonedLocalization(val);
		Slider component = val.GetComponent<Slider>();
		component.onValueChanged = new SliderEvent();
		component.minValue = (float)min;
		component.maxValue = (float)max;
		component.wholeNumbers = entry.SettingType == typeof(byte) || entry.SettingType == typeof(short) || entry.SettingType == typeof(int) || entry.SettingType == typeof(long);
		component.value = Convert.ToSingle(entry.BoxedValue, CultureInfo.InvariantCulture);
		SetRect(val.GetComponent<RectTransform>(), new Vector2(0.53f, 0.08f), new Vector2(0.84f, 0.92f), Vector2.zero, Vector2.zero);
		GameObject valueBox = CreateStyledButton(OptionButtonTemplate(), (Transform)(object)rowRect, value, (UnityAction)delegate
		{
		});
		SetRect(valueBox.GetComponent<RectTransform>(), new Vector2(0.85f, 0f), Vector2.one, Vector2.zero, Vector2.zero);
		((UnityEvent<float>)(object)component.onValueChanged).AddListener((UnityAction<float>)delegate(float newValue)
		{
			try
			{
				object obj = Convert.ChangeType(Math.Round(newValue, 4), entry.SettingType, CultureInfo.InvariantCulture);
				AcceptableValueBase acceptableValues = entry.Description.AcceptableValues;
				entry.BoxedValue = ((acceptableValues == null) ? obj : acceptableValues.Clamp(obj));
				entry.ConfigFile.Save();
				SetButtonText(valueBox, entry.GetSerializedValue());
			}
			catch (Exception ex)
			{
				((TMP_Text)_notice).text = "Could not apply setting: " + ex.Message;
			}
		});
		val.SetActive(true);
	}

	private void CreateBooleanToggle(RectTransform rowRect, ConfigEntryBase entry)
	{
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Expected O, but got Unknown
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Object.Instantiate<GameObject>(_nativeToggleTemplate, (Transform)(object)rowRect, false);
		((Object)val).name = "ModMenuToggle_" + entry.Definition.Key;
		val.SetActive(false);
		DisableClonedLocalization(val);
		Toggle component = val.GetComponent<Toggle>();
		component.onValueChanged = new ToggleEvent();
		component.isOn = (bool)entry.BoxedValue;
		SetRect(val.GetComponent<RectTransform>(), new Vector2(0.7f, 0f), new Vector2(0.78f, 1f), Vector2.zero, Vector2.zero);
		((UnityEvent<bool>)(object)component.onValueChanged).AddListener((UnityAction<bool>)delegate(bool enabled)
		{
			entry.BoxedValue = enabled;
			entry.ConfigFile.Save();
		});
		val.SetActive(true);
	}

	private GameObject CreateAnchoredButton(RectTransform parent, string text, Vector2 min, Vector2 max, UnityAction action, GameObject template)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = CreateStyledButton(template, (Transform)(object)parent, text, action);
		RectTransform component = val.GetComponent<RectTransform>();
		SetRect(component, min, max, Vector2.zero, Vector2.zero);
		return val;
	}

	private static GameObject CreateStyledButton(GameObject styleSource, Transform parent, string value, UnityAction action)
	{
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected O, but got Unknown
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Object.Instantiate<GameObject>(styleSource, parent, false);
		((Object)val).name = "ModMenuButton_" + value;
		val.SetActive(false);
		DisableClonedLocalization(val);
		Button component = val.GetComponent<Button>();
		if ((Object)(object)component == (Object)null)
		{
			throw new InvalidOperationException("Native Options template has no Button component.");
		}
		component.onClick = new ButtonClickedEvent();
		((UnityEvent)component.onClick).AddListener(action);
		Navigation navigation = default(Navigation);
		((Navigation)(ref navigation)).mode = (Mode)3;
		((Selectable)component).navigation = navigation;
		UIButton component2 = val.GetComponent<UIButton>();
		FieldInfo field = typeof(UIButton).GetField("_selectOnSubmit", BindingFlags.Instance | BindingFlags.NonPublic);
		if ((Object)(object)component2 != (Object)null && field != null)
		{
			field.SetValue(component2, null);
		}
		SetButtonText(val, value);
		val.SetActive(true);
		return val;
	}

	private static void CopyGraphicEffects(Component source, GameObject target)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)source == (Object)null))
		{
			Shadow[] components = source.GetComponents<Shadow>();
			foreach (Shadow val in components)
			{
				Shadow val2 = (Shadow)((val is Outline) ? ((object)target.AddComponent<Outline>()) : ((object)target.AddComponent<Shadow>()));
				val2.effectColor = val.effectColor;
				val2.effectDistance = val.effectDistance;
				val2.useGraphicAlpha = val.useGraphicAlpha;
			}
		}
	}

	private static Image CreateInsetFill(Transform parent, Image source, float inset, Color fallbackColor)
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Expected O, but got Unknown
		//IL_0052: 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_0085: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("NativeFill", new Type[3]
		{
			typeof(RectTransform),
			typeof(CanvasRenderer),
			typeof(Image)
		});
		RectTransform component = val.GetComponent<RectTransform>();
		((Transform)component).SetParent(parent, false);
		Stretch(component);
		component.offsetMin = new Vector2(inset, inset);
		component.offsetMax = new Vector2(0f - inset, 0f - inset);
		Image component2 = val.GetComponent<Image>();
		if ((Object)(object)source != (Object)null)
		{
			CopyImageStyle(source, component2);
		}
		else
		{
			((Graphic)component2).color = fallbackColor;
		}
		((Graphic)component2).raycastTarget = false;
		return component2;
	}

	private static Image FindButtonStyleImage(GameObject styleSource, Button sourceButton)
	{
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		UIButton component = styleSource.GetComponent<UIButton>();
		if ((Object)(object)component != (Object)null)
		{
			FieldInfo field = typeof(UIButton).GetField("_effectOnGraphic", BindingFlags.Instance | BindingFlags.NonPublic);
			Graphic val = (Graphic)((field == null) ? null : /*isinst with value type is only supported in some contexts*/);
			Image val2 = (Image)(object)((val is Image) ? val : null);
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
		}
		Image val3 = (Image)(((Object)(object)sourceButton == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/);
		if ((Object)(object)val3 != (Object)null && ((Graphic)val3).color.a > 0.01f)
		{
			return val3;
		}
		Image result = null;
		float num = float.MinValue;
		Image[] componentsInChildren = styleSource.GetComponentsInChildren<Image>(true);
		foreach (Image val4 in componentsInChildren)
		{
			Rect rect = ((Graphic)val4).rectTransform.rect;
			float num2 = Math.Abs(((Rect)(ref rect)).width * ((Rect)(ref rect)).height);
			float num3 = num2 + (((Object)(object)val4.sprite == (Object)null) ? 0f : 1000000f) + ((Graphic)val4).color.a * 10000f;
			if (!(num3 <= num))
			{
				result = val4;
				num = num3;
			}
		}
		return result;
	}

	private static void DisableClonedLocalization(GameObject clone)
	{
		Component[] componentsInChildren = clone.GetComponentsInChildren<Component>(true);
		foreach (Component val in componentsInChildren)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			Type type = ((object)val).GetType();
			string text = type.FullName ?? type.Name;
			if (text.IndexOf("Localiz", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null);
				if ((Object)(object)val2 != (Object)null)
				{
					val2.enabled = false;
				}
			}
		}
	}

	private TextMeshProUGUI CreateText(string name, Transform parent, string value, float size, TextAlignmentOptions alignment)
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Expected O, but got Unknown
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: 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)
		TextMeshProUGUI componentInChildren = _buttonTemplate.GetComponentInChildren<TextMeshProUGUI>(true);
		GameObject val = new GameObject(name, new Type[3]
		{
			typeof(RectTransform),
			typeof(CanvasRenderer),
			typeof(TextMeshProUGUI)
		});
		val.transform.SetParent(parent, false);
		TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>();
		((TMP_Text)component).text = value;
		((TMP_Text)component).fontSize = size;
		((TMP_Text)component).alignment = alignment;
		((TMP_Text)component).enableWordWrapping = true;
		((Graphic)component).raycastTarget = false;
		if ((Object)(object)componentInChildren != (Object)null)
		{
			((TMP_Text)component).font = ((TMP_Text)componentInChildren).font;
			((TMP_Text)component).fontSharedMaterial = ((TMP_Text)componentInChildren).fontSharedMaterial;
			((Graphic)component).color = ((Graphic)componentInChildren).color;
			((TMP_Text)component).outlineColor = ((TMP_Text)componentInChildren).outlineColor;
			((TMP_Text)component).outlineWidth = ((TMP_Text)componentInChildren).outlineWidth;
		}
		return component;
	}

	private void CaptureMainMenuObjects(CanvasManager manager)
	{
		BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic;
		FieldInfo field = typeof(CanvasManager).GetField("_allMainMenuButtons", bindingAttr);
		IList list = ((field == null) ? null : (field.GetValue(manager) as IList));
		if (list != null && list.Count > 0)
		{
			ref GameObject mainMenuPage = ref _mainMenuPage;
			object? obj = list[0];
			mainMenuPage = (GameObject)((obj is GameObject) ? obj : null);
		}
		FieldInfo field2 = typeof(CanvasManager).GetField("_howToFishTitle", bindingAttr);
		_mainMenuTitle = (GameObject)((field2 == null) ? null : /*isinst with value type is only supported in some contexts*/);
		FieldInfo field3 = typeof(CanvasManager).GetField("_discordButton", bindingAttr);
		_discordButton = (GameObject)((field3 == null) ? null : /*isinst with value type is only supported in some contexts*/);
	}

	private void HideMainMenu()
	{
		_mainMenuHidden = true;
		if ((Object)(object)_mainMenuPage != (Object)null)
		{
			_mainMenuPageWasActive = _mainMenuPage.activeSelf;
			_mainMenuPage.SetActive(false);
		}
		if ((Object)(object)_mainMenuTitle != (Object)null)
		{
			_mainMenuTitleWasActive = _mainMenuTitle.activeSelf;
			_mainMenuTitle.SetActive(false);
		}
		if ((Object)(object)_discordButton != (Object)null)
		{
			_discordButtonWasActive = _discordButton.activeSelf;
			_discordButton.SetActive(false);
		}
	}

	private void RestoreMainMenu()
	{
		if (_mainMenuHidden)
		{
			if ((Object)(object)_mainMenuPage != (Object)null)
			{
				_mainMenuPage.SetActive(_mainMenuPageWasActive);
			}
			if ((Object)(object)_mainMenuTitle != (Object)null)
			{
				_mainMenuTitle.SetActive(_mainMenuTitleWasActive);
			}
			if ((Object)(object)_discordButton != (Object)null)
			{
				_discordButton.SetActive(_discordButtonWasActive);
			}
			_mainMenuHidden = false;
		}
	}

	private void DiscoverNativeOptionsStyle(Transform mainCanvas)
	{
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: 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)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0214: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_028a: Unknown result type (might be due to invalid IL or missing references)
		//IL_029a: Unknown result type (might be due to invalid IL or missing references)
		Button val = FindLoadedButton("Gameplay");
		Button val2 = FindLoadedButton("Graphics");
		if ((Object)(object)val == (Object)null)
		{
			_log.LogInfo((object)"Native Options page was not loaded yet; using a matching built-in button fallback.");
			return;
		}
		Transform val3 = (((Object)(object)val2 == (Object)null) ? ((Component)val).transform.parent : CommonAncestor(((Component)val).transform, ((Component)val2).transform));
		if ((Object)(object)val3 == (Object)null)
		{
			val3 = mainCanvas;
		}
		while ((Object)(object)val3 != (Object)(object)mainCanvas && (Object)(object)FindMenuText(val3, "Back") == (Object)null && (Object)(object)val3.parent != (Object)null)
		{
			val3 = val3.parent;
		}
		Transform val4 = val3;
		PauseManager val5 = Object.FindObjectOfType<PauseManager>(true);
		if ((Object)(object)val5 != (Object)null)
		{
			FieldInfo field = typeof(PauseManager).GetField("_optionsScreen", BindingFlags.Instance | BindingFlags.NonPublic);
			GameObject val6 = (GameObject)((field == null) ? null : /*isinst with value type is only supported in some contexts*/);
			if ((Object)(object)val6 != (Object)null)
			{
				val4 = val6.transform;
			}
		}
		Slider val7 = ((Component)val3).GetComponentsInChildren<Slider>(true).FirstOrDefault();
		Toggle val8 = ((Component)val3).GetComponentsInChildren<Toggle>(true).FirstOrDefault();
		TMP_InputField val9 = ((Component)val3).GetComponentsInChildren<TMP_InputField>(true).FirstOrDefault();
		_nativeSliderTemplate = (((Object)(object)val7 == (Object)null) ? null : ((Component)val7).gameObject);
		_nativeToggleTemplate = (((Object)(object)val8 == (Object)null) ? null : ((Component)val8).gameObject);
		_nativeInputTemplate = (((Object)(object)val9 == (Object)null) ? null : ((Component)val9).gameObject);
		RectTransform val10 = (RectTransform)(object)((mainCanvas is RectTransform) ? mainCanvas : null);
		float num;
		if (!((Object)(object)val10 == (Object)null))
		{
			Rect rect = val10.rect;
			num = Math.Abs(((Rect)(ref rect)).width);
		}
		else
		{
			num = 1920f;
		}
		float num2 = num;
		float num3;
		if (!((Object)(object)val10 == (Object)null))
		{
			Rect rect2 = val10.rect;
			num3 = Math.Abs(((Rect)(ref rect2)).height);
		}
		else
		{
			num3 = 1200f;
		}
		float num4 = num3;
		float num5 = 0f;
		Image[] componentsInChildren = ((Component)val4).GetComponentsInChildren<Image>(true);
		foreach (Image val11 in componentsInChildren)
		{
			if ((Object)(object)((Component)val11).GetComponent<Button>() != (Object)null || (Object)(object)((Component)val11).GetComponentInParent<Button>() != (Object)null)
			{
				continue;
			}
			RectTransform rectTransform = ((Graphic)val11).rectTransform;
			Rect rect3 = rectTransform.rect;
			float num6 = Math.Abs(((Rect)(ref rect3)).width);
			Rect rect4 = rectTransform.rect;
			float num7 = Math.Abs(((Rect)(ref rect4)).height);
			if (num6 < 400f || num7 < 280f)
			{
				continue;
			}
			if (num2 > 0f && num4 > 0f && num6 > num2 * 0.92f && num7 > num4 * 0.92f)
			{
				if ((Object)(object)_nativeBackdropStyle == (Object)null || ((Graphic)val11).color.a > ((Graphic)_nativeBackdropStyle).color.a)
				{
					_nativeBackdropStyle = val11;
				}
				continue;
			}
			float num8 = num6 * num7;
			if (!(num8 <= num5))
			{
				num5 = num8;
				_nativePanelStyle = val11;
			}
		}
		if ((Object)(object)_nativePanelStyle != (Object)null)
		{
			_log.LogInfo((object)"Native Options button and panel styles discovered from the loaded Gameplay tab.");
		}
		else
		{
			_log.LogInfo((object)"Native Options button style discovered; using the matching framed-panel fallback.");
		}
	}

	private static Button FindLoadedButton(string label)
	{
		TextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll<TextMeshProUGUI>();
		foreach (TextMeshProUGUI val in array)
		{
			if (string.Equals((((TMP_Text)val).text ?? string.Empty).Trim(), label, StringComparison.OrdinalIgnoreCase))
			{
				Button componentInParent = ((Component)val).GetComponentInParent<Button>(true);
				if ((Object)(object)componentInParent != (Object)null)
				{
					return componentInParent;
				}
			}
		}
		return null;
	}

	private static Transform CommonAncestor(Transform first, Transform second)
	{
		HashSet<Transform> hashSet = new HashSet<Transform>();
		Transform val = first;
		while ((Object)(object)val != (Object)null)
		{
			hashSet.Add(val);
			val = val.parent;
		}
		Transform val2 = second;
		while ((Object)(object)val2 != (Object)null)
		{
			if (hashSet.Contains(val2))
			{
				return val2;
			}
			val2 = val2.parent;
		}
		return null;
	}

	private GameObject OptionButtonTemplate()
	{
		return _buttonTemplate;
	}

	private RectTransform CreatePanel(string name, RectTransform parent, Vector2 min, Vector2 max)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Expected O, but got Unknown
		//IL_004b: 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_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name, new Type[3]
		{
			typeof(RectTransform),
			typeof(CanvasRenderer),
			typeof(Image)
		});
		RectTransform component = val.GetComponent<RectTransform>();
		((Transform)component).SetParent((Transform)(object)parent, false);
		SetRect(component, min, max, Vector2.zero, Vector2.zero);
		Image component2 = val.GetComponent<Image>();
		if ((Object)(object)_nativePanelStyle != (Object)null)
		{
			CopyImageStyle(_nativePanelStyle, component2);
			((Graphic)component2).color = Color.white;
			CreateInsetFill(val.transform, _nativePanelStyle, 5f, new Color(0.39f, 0.59f, 0.74f, 0.72f));
			if (((Component)_nativePanelStyle).GetComponents<Shadow>().Length > 0)
			{
				CopyGraphicEffects((Component)(object)_nativePanelStyle, val);
			}
			else
			{
				AddRectBorder(val.transform, 3f);
			}
		}
		else
		{
			GameObject val2 = OptionButtonTemplate();
			Image val3 = FindButtonStyleImage(val2, val2.GetComponent<Button>());
			if ((Object)(object)val3 != (Object)null)
			{
				CopyImageStyle(val3, component2);
			}
			((Graphic)component2).color = Color.white;
			CreateInsetFill(val.transform, val3, 5f, new Color(0.39f, 0.59f, 0.74f, 0.72f));
			AddRectBorder(val.transform, 3f);
		}
		((Graphic)component2).raycastTarget = true;
		return component;
	}

	private static void AddRectBorder(Transform parent, float thickness)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: 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_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: 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_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: 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)
		CreateBorderEdge(parent, "Top", new Vector2(0f, 1f), Vector2.one, new Vector2(0f, 0f - thickness), Vector2.zero);
		CreateBorderEdge(parent, "Bottom", Vector2.zero, new Vector2(1f, 0f), Vector2.zero, new Vector2(0f, thickness));
		CreateBorderEdge(parent, "Left", Vector2.zero, new Vector2(0f, 1f), Vector2.zero, new Vector2(thickness, 0f));
		CreateBorderEdge(parent, "Right", new Vector2(1f, 0f), Vector2.one, new Vector2(0f - thickness, 0f), Vector2.zero);
	}

	private static void CreateBorderEdge(Transform parent, string name, Vector2 min, Vector2 max, Vector2 offsetMin, Vector2 offsetMax)
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Expected O, but got Unknown
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("NativeFrame_" + name, new Type[3]
		{
			typeof(RectTransform),
			typeof(CanvasRenderer),
			typeof(Image)
		});
		RectTransform component = val.GetComponent<RectTransform>();
		((Transform)component).SetParent(parent, false);
		SetRect(component, min, max, offsetMin, offsetMax);
		Image component2 = val.GetComponent<Image>();
		((Graphic)component2).color = Color.white;
		((Graphic)component2).raycastTarget = false;
	}

	private static void CopyImageStyle(Image source, Image target)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		target.sprite = source.sprite;
		target.overrideSprite = source.overrideSprite;
		((Graphic)target).material = ((Graphic)source).material;
		((Graphic)target).color = ((Graphic)source).color;
		target.type = source.type;
		target.preserveAspect = source.preserveAspect;
		target.fillCenter = source.fillCenter;
	}

	private static TextMeshProUGUI FindMenuText(Transform root, string value)
	{
		TextMeshProUGUI[] componentsInChildren = ((Component)root).GetComponentsInChildren<TextMeshProUGUI>(true);
		foreach (TextMeshProUGUI val in componentsInChildren)
		{
			if (string.Equals((((TMP_Text)val).text ?? string.Empty).Trim(), value, StringComparison.OrdinalIgnoreCase))
			{
				return val;
			}
		}
		return null;
	}

	private static void InsertAfter(RectTransform source, RectTransform clone)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: 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_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
		((Transform)clone).SetSiblingIndex(((Transform)source).GetSiblingIndex() + 1);
		if ((Object)(object)((Component)((Transform)source).parent).GetComponent<LayoutGroup>() != (Object)null)
		{
			return;
		}
		Rect rect = source.rect;
		float num = Math.Max(44f, Math.Abs(((Rect)(ref rect)).height) * 1.12f);
		Vector2 anchoredPosition = source.anchoredPosition;
		anchoredPosition.y -= num;
		clone.anchoredPosition = anchoredPosition;
		RectTransform[] componentsInChildren = ((Component)((Transform)source).parent).GetComponentsInChildren<RectTransform>(true);
		foreach (RectTransform val in componentsInChildren)
		{
			if ((Object)(object)((Transform)val).parent == (Object)(object)((Transform)source).parent && (Object)(object)val != (Object)(object)source && (Object)(object)val != (Object)(object)clone && val.anchoredPosition.y < source.anchoredPosition.y)
			{
				Vector2 anchoredPosition2 = val.anchoredPosition;
				anchoredPosition2.y -= num;
				val.anchoredPosition = anchoredPosition2;
			}
		}
	}

	private static RectTransform CreateScrollArea(string name, RectTransform parent, Vector2 min, Vector2 max)
	{
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Expected O, but got Unknown
		//IL_0071: 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_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Expected O, but got Unknown
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name + "Viewport", new Type[5]
		{
			typeof(RectTransform),
			typeof(CanvasRenderer),
			typeof(Image),
			typeof(RectMask2D),
			typeof(ScrollRect)
		});
		RectTransform component = val.GetComponent<RectTransform>();
		((Transform)component).SetParent((Transform)(object)parent, false);
		SetRect(component, min, max, Vector2.zero, Vector2.zero);
		Image component2 = val.GetComponent<Image>();
		((Graphic)component2).color = Color.clear;
		((Graphic)component2).raycastTarget = true;
		GameObject val2 = new GameObject(name + "Content", new Type[1] { typeof(RectTransform) });
		RectTransform component3 = val2.GetComponent<RectTransform>();
		((Transform)component3).SetParent((Transform)(object)component, false);
		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;
		ScrollRect component4 = val.GetComponent<ScrollRect>();
		component4.content = component3;
		component4.viewport = component;
		component4.horizontal = false;
		component4.vertical = true;
		component4.movementType = (MovementType)2;
		component4.scrollSensitivity = 42f;
		return component3;
	}

	private static void PositionAt(RectTransform rect, float y, float height)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: 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_0047: 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)
		rect.anchorMin = new Vector2(0f, 1f);
		rect.anchorMax = new Vector2(1f, 1f);
		rect.pivot = new Vector2(0.5f, 1f);
		rect.anchoredPosition = new Vector2(0f, 0f - y);
		rect.sizeDelta = new Vector2(0f, height);
	}

	private static void SetScrollContentHeight(RectTransform content, float height)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		content.sizeDelta = new Vector2(0f, Math.Max(1f, height));
	}

	private static void Stretch(RectTransform rect)
	{
		//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_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		rect.anchorMin = Vector2.zero;
		rect.anchorMax = Vector2.one;
		rect.offsetMin = Vector2.zero;
		rect.offsetMax = Vector2.zero;
	}

	private static void SetRect(RectTransform rect, Vector2 min, Vector2 max, Vector2 offsetMin, Vector2 offsetMax)
	{
		//IL_0001: 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_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		rect.anchorMin = min;
		rect.anchorMax = max;
		rect.offsetMin = offsetMin;
		rect.offsetMax = offsetMax;
	}

	private static void Clear(Transform root)
	{
		for (int num = root.childCount - 1; num >= 0; num--)
		{
			Object.Destroy((Object)(object)((Component)root.GetChild(num)).gameObject);
		}
	}

	private static void SetButtonText(GameObject button, string value)
	{
		TextMeshProUGUI componentInChildren = button.GetComponentInChildren<TextMeshProUGUI>(true);
		if ((Object)(object)componentInChildren != (Object)null)
		{
			((TMP_Text)componentInChildren).text = value;
		}
	}

	private static bool IsNumber(Type t)
	{
		if (!(t == typeof(byte)) && !(t == typeof(short)) && !(t == typeof(int)) && !(t == typeof(long)) && !(t == typeof(float)) && !(t == typeof(double)))
		{
			return t == typeof(decimal);
		}
		return true;
	}
}
[BepInPlugin("community.howtofish.modmenu", "How to Fish Mod Menu", "0.3.2")]
public sealed class Plugin : BaseUnityPlugin
{
	public const string PluginGuid = "community.howtofish.modmenu";

	public const string PluginName = "How to Fish Mod Menu";

	public const string PluginVersion = "0.3.2";

	private NativeModMenu _menu;

	private void Awake()
	{
		_menu = new NativeModMenu(((BaseUnityPlugin)this).Logger);
		((BaseUnityPlugin)this).Logger.LogInfo((object)("Mod Menu initialized for game " + Application.version + ". Settings-only mode; plugin file management is not supported."));
	}

	private void Update()
	{
		if (_menu != null)
		{
			_menu.Tick();
		}
	}

	private void OnDestroy()
	{
		if (_menu != null)
		{
			_menu.Dispose();
		}
	}
}