Decompiled source of ModSettingsMenu v1.0.0

ModSettingsMenu.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ModSettingsMenu")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+9216262562752f35e0cfab6e46c12d350e7419e3")]
[assembly: AssemblyProduct("ModSettingsMenu")]
[assembly: AssemblyTitle("ModSettingsMenu")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ModSettingsMenu
{
	[BepInPlugin("com.github.antigravity.modsettingsmenu", "Mod Settings Menu", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public static ManualLogSource? Log;

		private Harmony? _harmony;

		private void Awake()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"Mod Settings Menu initializing...");
			try
			{
				GameObject val = new GameObject("ModSettingsController");
				Object.DontDestroyOnLoad((Object)val);
				val.AddComponent<ModSettingsController>();
				_harmony = new Harmony("com.github.antigravity.modsettingsmenu");
				_harmony.PatchAll();
				Log.LogInfo((object)"Mod Settings Menu ready.");
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to initialize Mod Settings Menu: " + ex));
			}
		}

		private void OnDestroy()
		{
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public class CfgEntry
	{
		public string Key { get; set; } = "";

		public string RawValue { get; set; } = "";

		public string PendingValue { get; set; } = "";

		public string Section { get; set; } = "";

		public string Description { get; set; } = "";

		public string SettingType { get; set; } = "";

		public string DefaultValue { get; set; } = "";

		public bool IsDirty => PendingValue != RawValue;
	}
	public class CfgSection
	{
		public string Name { get; set; } = "";

		public List<CfgEntry> Entries { get; set; } = new List<CfgEntry>();
	}
	public class ModConfig
	{
		public string FilePath { get; set; } = "";

		public string ModName { get; set; } = "";

		public string PluginGuid { get; set; } = "";

		public List<CfgSection> Sections { get; set; } = new List<CfgSection>();
	}
	public static class CfgParser
	{
		public static List<ModConfig> LoadAll(string configDir)
		{
			List<ModConfig> list = new List<ModConfig>();
			if (!Directory.Exists(configDir))
			{
				return list;
			}
			string[] files = Directory.GetFiles(configDir, "*.cfg");
			foreach (string text in files)
			{
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text);
				if (fileNameWithoutExtension.Equals("BepInEx", StringComparison.OrdinalIgnoreCase))
				{
					continue;
				}
				try
				{
					ModConfig modConfig = Parse(text);
					if (modConfig == null)
					{
						continue;
					}
					if (IsModLoaded(modConfig))
					{
						list.Add(modConfig);
						continue;
					}
					ManualLogSource? log = Plugin.Log;
					if (log != null)
					{
						log.LogInfo((object)("Skipping config file for unloaded mod: " + fileNameWithoutExtension));
					}
				}
				catch (Exception ex)
				{
					ManualLogSource? log2 = Plugin.Log;
					if (log2 != null)
					{
						log2.LogError((object)("Parse error " + text + ": " + ex.Message));
					}
				}
			}
			return list;
		}

		private static bool IsModLoaded(ModConfig cfg)
		{
			Dictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos;
			if (!string.IsNullOrEmpty(cfg.PluginGuid) && pluginInfos.ContainsKey(cfg.PluginGuid))
			{
				return true;
			}
			string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(cfg.FilePath);
			if (pluginInfos.ContainsKey(fileNameWithoutExtension))
			{
				return true;
			}
			foreach (KeyValuePair<string, PluginInfo> item in pluginInfos)
			{
				PluginInfo value = item.Value;
				if (value != null && value.Metadata != null)
				{
					if (value.Metadata.GUID.Equals(cfg.PluginGuid, StringComparison.OrdinalIgnoreCase))
					{
						return true;
					}
					if (value.Metadata.GUID.Equals(fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
					{
						return true;
					}
					if (value.Metadata.Name.Equals(cfg.ModName, StringComparison.OrdinalIgnoreCase))
					{
						return true;
					}
					if (value.Metadata.Name.Equals(fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
					{
						return true;
					}
					if (!string.IsNullOrEmpty(value.Location) && Path.GetFileNameWithoutExtension(value.Location).Equals(fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
					{
						return true;
					}
				}
			}
			return false;
		}

		private static ModConfig? Parse(string path)
		{
			string[] array = File.ReadAllLines(path, Encoding.UTF8);
			ModConfig modConfig = new ModConfig
			{
				FilePath = path
			};
			CfgSection cfgSection = null;
			string text = "";
			string settingType = "";
			string defaultValue = "";
			string[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				string text2 = array2[i].Trim();
				if (text2.StartsWith("## Settings file was created by plugin "))
				{
					modConfig.ModName = text2.Substring("## Settings file was created by plugin ".Length).Trim();
				}
				else if (text2.StartsWith("## Plugin GUID:"))
				{
					modConfig.PluginGuid = text2.Substring("## Plugin GUID:".Length).Trim();
				}
				else if (text2.StartsWith("[") && text2.EndsWith("]") && text2.Length > 2)
				{
					cfgSection = new CfgSection
					{
						Name = text2.Substring(1, text2.Length - 2)
					};
					modConfig.Sections.Add(cfgSection);
					text = "";
					settingType = "";
					defaultValue = "";
				}
				else if (text2.StartsWith("## "))
				{
					text = text + ((text.Length > 0) ? " " : "") + text2.Substring(3).Trim();
				}
				else if (text2.StartsWith("# Setting type:"))
				{
					settingType = text2.Substring("# Setting type:".Length).Trim();
				}
				else if (text2.StartsWith("# Default value:"))
				{
					defaultValue = text2.Substring("# Default value:".Length).Trim();
				}
				else if (!text2.StartsWith("#"))
				{
					int num = text2.IndexOf('=');
					if (num > 0 && cfgSection != null)
					{
						string key = text2.Substring(0, num).Trim();
						string text3 = text2.Substring(num + 1).Trim();
						cfgSection.Entries.Add(new CfgEntry
						{
							Key = key,
							RawValue = text3,
							PendingValue = text3,
							Section = cfgSection.Name,
							Description = text,
							SettingType = settingType,
							DefaultValue = defaultValue
						});
						text = "";
						settingType = "";
						defaultValue = "";
					}
				}
			}
			if (modConfig.ModName.Length == 0)
			{
				modConfig.ModName = Path.GetFileNameWithoutExtension(path);
			}
			if (modConfig.Sections.Count <= 0)
			{
				return null;
			}
			return modConfig;
		}

		public static void Save(ModConfig mod)
		{
			Dictionary<string, Dictionary<string, string>> dictionary = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
			foreach (CfgSection section in mod.Sections)
			{
				Dictionary<string, string> dictionary2 = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
				foreach (CfgEntry entry in section.Entries)
				{
					dictionary2[entry.Key] = entry.PendingValue;
				}
				dictionary[section.Name] = dictionary2;
			}
			string[] array = File.ReadAllLines(mod.FilePath, Encoding.UTF8);
			List<string> list = new List<string>(array.Length);
			string text = "";
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				string text3 = text2.Trim();
				if (text3.StartsWith("[") && text3.EndsWith("]") && text3.Length > 2)
				{
					text = text3.Substring(1, text3.Length - 2);
					list.Add(text2);
					continue;
				}
				int num = text3.IndexOf('=');
				if (num > 0 && !text3.StartsWith("#") && dictionary.TryGetValue(text, out var value) && value.TryGetValue(text3.Substring(0, num).Trim(), out var value2))
				{
					list.Add(text3.Substring(0, num).Trim() + " = " + value2);
					foreach (CfgSection section2 in mod.Sections)
					{
						foreach (CfgEntry entry2 in section2.Entries)
						{
							if (section2.Name == text && entry2.Key == text3.Substring(0, num).Trim())
							{
								entry2.RawValue = value2;
							}
						}
					}
				}
				else
				{
					list.Add(text2);
				}
			}
			File.WriteAllLines(mod.FilePath, list.ToArray(), Encoding.UTF8);
		}
	}
	public class ModSettingsController : MonoBehaviour
	{
		private bool _visible;

		private List<ModConfig> _configs = new List<ModConfig>();

		private int _selMod;

		private Vector2 _leftScroll;

		private Vector2 _rightScroll;

		private string _status = "";

		private float _statusUntil;

		private bool _stylesBuilt;

		private readonly List<GraphicRaycaster> _disabledRaycasters = new List<GraphicRaycaster>();

		private GUIStyle? _header;

		private GUIStyle? _subHeader;

		private GUIStyle? _label;

		private GUIStyle? _desc;

		private GUIStyle? _btn;

		private GUIStyle? _btnGreen;

		private GUIStyle? _btnRed;

		private GUIStyle? _tf;

		private GUIStyle? _cardStyle;

		private GUIStyle? _secStyle;

		private GUIStyle? _labelClean;

		private GUIStyle? _labelDirty;

		private GUIStyle? _descWrap;

		private GUIStyle? _toggleEnabled;

		private GUIStyle? _toggleDisabled;

		private GUIStyle? _typeStyle;

		private GUIStyle? _defStyle;

		private static readonly Color BgPanel = new Color(0.1f, 0.1f, 0.15f, 0.99f);

		private static readonly Color Accent = new Color(0.4f, 0.65f, 1f, 1f);

		private static readonly Color AccentDark = new Color(0.16f, 0.28f, 0.52f, 1f);

		private static readonly Color SectionBg = new Color(0.13f, 0.13f, 0.2f, 1f);

		private static readonly Color TextMain = new Color(0.92f, 0.92f, 0.96f, 1f);

		private static readonly Color TextSub = new Color(0.85f, 0.88f, 0.94f, 1f);

		private static readonly Color Dirty = new Color(1f, 0.78f, 0.2f, 1f);

		private static readonly Color Green = new Color(0.22f, 0.72f, 0.38f, 1f);

		private static readonly Color Red = new Color(0.75f, 0.2f, 0.2f, 1f);

		public static ModSettingsController? Instance { get; private set; }

		public bool IsVisible => _visible;

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Reload();
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		public void Show()
		{
			_visible = true;
			Reload();
			_disabledRaycasters.Clear();
			GraphicRaycaster[] array = Resources.FindObjectsOfTypeAll<GraphicRaycaster>();
			foreach (GraphicRaycaster val in array)
			{
				if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeInHierarchy && ((Behaviour)val).enabled)
				{
					((Behaviour)val).enabled = false;
					_disabledRaycasters.Add(val);
				}
			}
			ManualLogSource? log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"Disabled {_disabledRaycasters.Count} GraphicRaycaster(s) to block click-through.");
			}
		}

		public void Hide()
		{
			_visible = false;
			int num = 0;
			foreach (GraphicRaycaster disabledRaycaster in _disabledRaycasters)
			{
				if ((Object)(object)disabledRaycaster != (Object)null)
				{
					((Behaviour)disabledRaycaster).enabled = true;
					num++;
				}
			}
			_disabledRaycasters.Clear();
			ManualLogSource? log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"Restored {num} GraphicRaycaster(s).");
			}
		}

		private void Reload()
		{
			_configs = CfgParser.LoadAll(Path.Combine(Paths.BepInExRootPath, "config"));
			if (_selMod >= _configs.Count)
			{
				_selMod = 0;
			}
		}

		private void DoApply()
		{
			bool flag = false;
			foreach (ModConfig config in _configs)
			{
				if (!HasDirty(config))
				{
					continue;
				}
				try
				{
					CfgParser.Save(config);
				}
				catch (Exception ex)
				{
					ManualLogSource? log = Plugin.Log;
					if (log != null)
					{
						log.LogError((object)("Save failed: " + ex));
					}
					flag = true;
				}
			}
			SetStatus(flag ? "✗ Some saves failed — check BepInEx log." : "✔ Saved! Restart may be needed for changes to apply.");
		}

		private void DoDiscard()
		{
			foreach (ModConfig config in _configs)
			{
				foreach (CfgSection section in config.Sections)
				{
					foreach (CfgEntry entry in section.Entries)
					{
						entry.PendingValue = entry.RawValue;
					}
				}
			}
			SetStatus("↩ Changes discarded.");
		}

		private void SetStatus(string msg)
		{
			_status = msg;
			_statusUntil = Time.unscaledTime + 5f;
		}

		private static bool HasDirty(ModConfig m)
		{
			foreach (CfgSection section in m.Sections)
			{
				foreach (CfgEntry entry in section.Entries)
				{
					if (entry.IsDirty)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static int EntryCount(ModConfig m)
		{
			int num = 0;
			foreach (CfgSection section in m.Sections)
			{
				num += section.Entries.Count;
			}
			return num;
		}

		private void Update()
		{
			if (_visible && Input.GetKeyDown((KeyCode)27))
			{
				Hide();
				Input.ResetInputAxes();
			}
		}

		private void OnGUI()
		{
			//IL_0038: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			if (_visible)
			{
				GUISkin skin = GUI.skin;
				GUI.skin = null;
				if (!_stylesBuilt)
				{
					BuildStyles();
				}
				DrawRect(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), new Color(0f, 0f, 0f, 0.65f));
				float num = Mathf.Min(1200f, (float)Screen.width * 0.92f);
				float num2 = Mathf.Min(800f, (float)Screen.height * 0.9f);
				float num3 = ((float)Screen.width - num) * 0.5f;
				float num4 = ((float)Screen.height - num2) * 0.5f;
				DrawPanel(new Rect(num3, num4, num, num2));
				GUI.skin = skin;
			}
		}

		private void DrawPanel(Rect r)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_0035: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: 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_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: 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_0420: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_045b: Unknown result type (might be due to invalid IL or missing references)
			//IL_047b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0498: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			DrawRect(r, BgPanel);
			DrawBorder(r, AccentDark, 2f);
			DrawRect(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, 50f), new Color(0.1f, 0.12f, 0.2f, 1f));
			DrawRect(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + 48f, ((Rect)(ref r)).width, 2f), Accent);
			SetColor(Accent);
			GUI.Label(new Rect(((Rect)(ref r)).x + 18f, ((Rect)(ref r)).y + 12f, 500f, 28f), "⚙  Mod Settings", _header);
			SetColor(Color.white);
			SetColor(new Color(0.75f, 0.25f, 0.25f));
			if (GUI.Button(new Rect(((Rect)(ref r)).x + ((Rect)(ref r)).width - 44f, ((Rect)(ref r)).y + 10f, 32f, 30f), "✕", _btn))
			{
				Hide();
			}
			SetColor(Color.white);
			float num = ((Rect)(ref r)).y + 52f;
			float num2 = ((Rect)(ref r)).height - 52f - 56f;
			float num3 = 240f;
			DrawRect(new Rect(((Rect)(ref r)).x, num, num3, num2), new Color(0.07f, 0.07f, 0.1f, 1f));
			float num4 = Mathf.Max(num2, (float)_configs.Count * 58f);
			_leftScroll = GUI.BeginScrollView(new Rect(((Rect)(ref r)).x, num, num3, num2), _leftScroll, new Rect(0f, 0f, num3 - 16f, num4));
			for (int i = 0; i < _configs.Count; i++)
			{
				DrawModListItem(i, num3);
			}
			GUI.EndScrollView();
			DrawRect(new Rect(((Rect)(ref r)).x + num3, num, 2f, num2), AccentDark);
			float num5 = ((Rect)(ref r)).x + num3 + 2f;
			float num6 = ((Rect)(ref r)).width - num3 - 2f;
			if (_configs.Count == 0)
			{
				SetColor(TextSub);
				GUI.Label(new Rect(num5 + 20f, num + 20f, num6 - 40f, 40f), "No mod config files found in BepInEx/config/.", _label);
				SetColor(Color.white);
			}
			else if (_selMod < _configs.Count)
			{
				DrawModDetail(new Rect(num5, num, num6, num2), _configs[_selMod]);
			}
			float num7 = ((Rect)(ref r)).y + ((Rect)(ref r)).height - 54f;
			DrawRect(new Rect(((Rect)(ref r)).x, num7, ((Rect)(ref r)).width, 54f), new Color(0.09f, 0.09f, 0.13f, 1f));
			DrawRect(new Rect(((Rect)(ref r)).x, num7, ((Rect)(ref r)).width, 2f), AccentDark);
			if (_status.Length > 0 && Time.unscaledTime < _statusUntil)
			{
				SetColor(_status.StartsWith("✗") ? new Color(1f, 0.35f, 0.35f) : new Color(0.3f, 0.95f, 0.5f));
				GUI.Label(new Rect(((Rect)(ref r)).x + 18f, num7 + 18f, ((Rect)(ref r)).width - 340f, 22f), _status, _label);
				SetColor(Color.white);
			}
			float num8 = num7 + 10f;
			float num9 = 34f;
			float num10 = 100f;
			float num11 = ((Rect)(ref r)).x + ((Rect)(ref r)).width - 16f;
			SetColor(Green);
			if (GUI.Button(new Rect(num11 - num10, num8, num10, num9), "Apply", _btnGreen))
			{
				DoApply();
			}
			SetColor(Color.white);
			SetColor(Red);
			if (GUI.Button(new Rect(num11 - num10 * 2f - 8f, num8, num10, num9), "Discard", _btnRed))
			{
				DoDiscard();
			}
			SetColor(Color.white);
			SetColor(TextSub);
			if (GUI.Button(new Rect(num11 - num10 * 3f - 18f, num8, num10, num9), "Reload", _btn))
			{
				Reload();
				SetStatus("↻ Reloaded from disk.");
			}
			SetColor(Color.white);
		}

		private void DrawModListItem(int i, float lW)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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)
			//IL_006b: 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)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: 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_0107: 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_0152: 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_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			ModConfig modConfig = _configs[i];
			bool flag = i == _selMod;
			bool num = HasDirty(modConfig);
			Rect r = default(Rect);
			((Rect)(ref r))..ctor(4f, (float)i * 58f + 4f, lW - 22f, 50f);
			DrawRect(r, (Color)(flag ? AccentDark : new Color(0.12f, 0.12f, 0.18f)));
			if (flag)
			{
				DrawBorder(r, Accent, 1.5f);
			}
			string text = ((modConfig.ModName.Length > 30) ? (modConfig.ModName.Substring(0, 28) + "..") : modConfig.ModName);
			SetColor(flag ? Accent : TextMain);
			GUI.Label(new Rect(((Rect)(ref r)).x + 8f, ((Rect)(ref r)).y + 7f, ((Rect)(ref r)).width - 22f, 20f), text, _label);
			SetColor(Color.white);
			if (num)
			{
				SetColor(Dirty);
				GUI.Label(new Rect(((Rect)(ref r)).x + ((Rect)(ref r)).width - 18f, ((Rect)(ref r)).y + 7f, 18f, 20f), "●", _label);
				SetColor(Color.white);
			}
			int num2 = EntryCount(modConfig);
			SetColor(TextSub);
			GUI.Label(new Rect(((Rect)(ref r)).x + 8f, ((Rect)(ref r)).y + 28f, ((Rect)(ref r)).width, 18f), string.Format("{0} setting{1}", num2, (num2 != 1) ? "s" : ""), _desc);
			SetColor(Color.white);
			if ((int)Event.current.type == 0 && ((Rect)(ref r)).Contains(Event.current.mousePosition))
			{
				_selMod = i;
				_rightScroll = Vector2.zero;
				Event.current.Use();
			}
		}

		private void DrawModDetail(Rect r, ModConfig mod)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: 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_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_044d: Invalid comparison between Unknown and I4
			//IL_044f: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			DrawRect(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, 38f), new Color(0.11f, 0.13f, 0.21f, 0.9f));
			SetColor(Accent);
			GUI.Label(new Rect(((Rect)(ref r)).x + 14f, ((Rect)(ref r)).y + 9f, ((Rect)(ref r)).width - 28f, 22f), mod.ModName, _subHeader);
			SetColor(Color.white);
			if (mod.PluginGuid.Length > 0)
			{
				SetColor(TextSub);
				GUI.Label(new Rect(((Rect)(ref r)).x + 14f, ((Rect)(ref r)).y + 26f, ((Rect)(ref r)).width, 14f), mod.PluginGuid, _desc);
				SetColor(Color.white);
			}
			float num = ((Rect)(ref r)).y + 40f;
			float num2 = ((Rect)(ref r)).height - 40f;
			GUILayout.BeginArea(new Rect(((Rect)(ref r)).x + 10f, num, ((Rect)(ref r)).width - 20f, num2 - 8f));
			_rightScroll = GUILayout.BeginScrollView(_rightScroll, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(((Rect)(ref r)).width - 20f),
				GUILayout.Height(num2 - 8f)
			});
			foreach (CfgSection section in mod.Sections)
			{
				GUILayout.Space(6f);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Space(4f);
				GUILayout.Label(section.Name, _secStyle, Array.Empty<GUILayoutOption>());
				GUILayout.EndHorizontal();
				DrawRect(GUILayoutUtility.GetRect(((Rect)(ref r)).width - 24f, 2f), AccentDark);
				GUILayout.Space(6f);
				foreach (CfgEntry entry in section.Entries)
				{
					bool isDirty = entry.IsDirty;
					GUILayout.BeginVertical(_cardStyle, Array.Empty<GUILayoutOption>());
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width((((Rect)(ref r)).width - 60f) * 0.58f) });
					GUILayout.Label(entry.Key, isDirty ? _labelDirty : _labelClean, Array.Empty<GUILayoutOption>());
					if (entry.Description.Length > 0)
					{
						GUILayout.Label(entry.Description, _descWrap, Array.Empty<GUILayoutOption>());
					}
					GUILayout.EndVertical();
					GUILayout.Space(14f);
					GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width((((Rect)(ref r)).width - 60f) * 0.37f) });
					if (entry.SettingType == "Boolean")
					{
						bool flag = entry.PendingValue.Equals("true", StringComparison.OrdinalIgnoreCase);
						GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
						bool flag2 = GUILayout.Toggle(flag, "", Array.Empty<GUILayoutOption>());
						GUILayout.Label(flag ? "Enabled" : "Disabled", flag ? _toggleEnabled : _toggleDisabled, Array.Empty<GUILayoutOption>());
						GUILayout.EndHorizontal();
						if (flag2 != flag)
						{
							entry.PendingValue = (flag2 ? "true" : "false");
						}
					}
					else
					{
						GUI.SetNextControlName("tf_" + entry.Section + "_" + entry.Key);
						string text = GUILayout.TextField(entry.PendingValue, _tf, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinWidth(180f) });
						if (text != entry.PendingValue)
						{
							entry.PendingValue = text;
						}
					}
					GUILayout.Space(6f);
					if (entry.SettingType.Length > 0)
					{
						GUILayout.Label("Type: " + entry.SettingType, _typeStyle, Array.Empty<GUILayoutOption>());
					}
					if (entry.DefaultValue.Length > 0)
					{
						GUILayout.Label("Default: " + entry.DefaultValue, _defStyle, Array.Empty<GUILayoutOption>());
					}
					GUILayout.EndVertical();
					GUILayout.EndHorizontal();
					GUILayout.EndVertical();
					if ((int)Event.current.type == 7)
					{
						DrawBorder(GUILayoutUtility.GetLastRect(), isDirty ? Dirty : AccentDark, 1f);
					}
					GUILayout.Space(4f);
				}
				GUILayout.Space(6f);
			}
			GUILayout.EndScrollView();
			GUILayout.EndArea();
		}

		private static void DrawRect(Rect r, Color c)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Color color = GUI.color;
			GUI.color = c;
			GUI.DrawTexture(r, (Texture)(object)Texture2D.whiteTexture);
			GUI.color = color;
		}

		private static void DrawBorder(Rect r, Color c, float t)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			DrawRect(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, t), c);
			DrawRect(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + ((Rect)(ref r)).height - t, ((Rect)(ref r)).width, t), c);
			DrawRect(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, t, ((Rect)(ref r)).height), c);
			DrawRect(new Rect(((Rect)(ref r)).x + ((Rect)(ref r)).width - t, ((Rect)(ref r)).y, t, ((Rect)(ref r)).height), c);
		}

		private static void SetColor(Color c)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			GUI.color = c;
		}

		private static void SetStyleTextColors(GUIStyle style, Color color)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			style.normal.textColor = color;
			style.hover.textColor = color;
			style.active.textColor = color;
			style.focused.textColor = color;
			style.onNormal.textColor = color;
			style.onHover.textColor = color;
			style.onActive.textColor = color;
			style.onFocused.textColor = color;
		}

		private void BuildStyles()
		{
			//IL_0008: 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_0015: 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)
			//IL_0028: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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)
			//IL_0046: 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: Expected O, but got Unknown
			//IL_005f: 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)
			//IL_006f: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00c1: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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)
			//IL_00f8: Expected O, but got Unknown
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: 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_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Expected O, but got Unknown
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: 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_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Expected O, but got Unknown
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: 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_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Expected O, but got Unknown
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Expected O, but got Unknown
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Expected O, but got Unknown
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Expected O, but got Unknown
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Expected O, but got Unknown
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Expected O, but got Unknown
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Expected O, but got Unknown
			//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Expected O, but got Unknown
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Expected O, but got Unknown
			//IL_0402: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_0424: Expected O, but got Unknown
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_043b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0445: Expected O, but got Unknown
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0466: Expected O, but got Unknown
			//IL_046c: Unknown result type (might be due to invalid IL or missing references)
			//IL_047d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Expected O, but got Unknown
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Expected O, but got Unknown
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			_stylesBuilt = true;
			_header = new GUIStyle
			{
				fontSize = 20,
				fontStyle = (FontStyle)1,
				alignment = (TextAnchor)3
			};
			SetStyleTextColors(_header, Accent);
			_subHeader = new GUIStyle
			{
				fontSize = 14,
				fontStyle = (FontStyle)1,
				alignment = (TextAnchor)3
			};
			SetStyleTextColors(_subHeader, Accent);
			_label = new GUIStyle
			{
				fontSize = 12,
				wordWrap = false,
				alignment = (TextAnchor)3
			};
			SetStyleTextColors(_label, TextMain);
			_desc = new GUIStyle
			{
				fontSize = 11,
				wordWrap = true,
				alignment = (TextAnchor)0
			};
			SetStyleTextColors(_desc, TextSub);
			GUIStyle val = new GUIStyle(GUI.skin.button)
			{
				fontSize = 12,
				fontStyle = (FontStyle)1,
				padding = new RectOffset(8, 8, 4, 4),
				border = new RectOffset(4, 4, 4, 4)
			};
			val.normal.background = Mk(new Color(0.18f, 0.18f, 0.28f));
			val.hover.background = Mk(new Color(0.24f, 0.24f, 0.38f));
			val.active.background = Mk(AccentDark);
			GUIStyle val2 = (_btn = val);
			SetStyleTextColors(_btn, TextMain);
			GUIStyle val3 = new GUIStyle(val2);
			val3.normal.background = Mk(Green);
			val3.hover.background = Mk(new Color(0.28f, 0.82f, 0.44f));
			val3.active.background = Mk(new Color(0.16f, 0.55f, 0.28f));
			_btnGreen = val3;
			SetStyleTextColors(_btnGreen, new Color(0.08f, 0.08f, 0.12f, 1f));
			GUIStyle val4 = new GUIStyle(val2);
			val4.normal.background = Mk(Red);
			val4.hover.background = Mk(new Color(0.88f, 0.28f, 0.28f));
			val4.active.background = Mk(new Color(0.58f, 0.14f, 0.14f));
			_btnRed = val4;
			SetStyleTextColors(_btnRed, new Color(0.08f, 0.08f, 0.12f, 1f));
			GUIStyle val5 = new GUIStyle(GUI.skin.textField)
			{
				fontSize = 12,
				padding = new RectOffset(6, 6, 4, 4)
			};
			val5.normal.background = Mk(new Color(0.07f, 0.07f, 0.12f));
			val5.focused.background = Mk(new Color(0.1f, 0.1f, 0.22f));
			val5.hover.background = Mk(new Color(0.09f, 0.09f, 0.15f));
			_tf = val5;
			SetStyleTextColors(_tf, TextMain);
			Texture2D background = Mk(new Color(0.12f, 0.12f, 0.18f, 0.65f));
			GUIStyle val6 = new GUIStyle
			{
				padding = new RectOffset(10, 10, 8, 8),
				margin = new RectOffset(4, 4, 4, 4)
			};
			val6.normal.background = background;
			_cardStyle = val6;
			_secStyle = new GUIStyle(_label)
			{
				fontStyle = (FontStyle)1
			};
			SetStyleTextColors(_secStyle, Accent);
			_labelClean = new GUIStyle(_label)
			{
				fontStyle = (FontStyle)1
			};
			SetStyleTextColors(_labelClean, TextMain);
			_labelDirty = new GUIStyle(_label)
			{
				fontStyle = (FontStyle)1
			};
			SetStyleTextColors(_labelDirty, Dirty);
			_descWrap = new GUIStyle(_desc)
			{
				wordWrap = true
			};
			SetStyleTextColors(_descWrap, TextSub);
			_toggleEnabled = new GUIStyle(_label);
			SetStyleTextColors(_toggleEnabled, Green);
			_toggleDisabled = new GUIStyle(_label);
			SetStyleTextColors(_toggleDisabled, TextSub);
			_typeStyle = new GUIStyle(_desc);
			SetStyleTextColors(_typeStyle, TextSub);
			_defStyle = new GUIStyle(_desc);
			SetStyleTextColors(_defStyle, new Color(0.78f, 0.82f, 0.9f, 1f));
			static Texture2D Mk(Color c)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Expected O, but got Unknown
				Texture2D val7 = new Texture2D(1, 1);
				val7.SetPixel(0, 0, c);
				val7.Apply();
				((Object)val7).hideFlags = (HideFlags)52;
				return val7;
			}
		}
	}
	[HarmonyPatch(typeof(UISettingsScreen), "OnEnable")]
	public static class Patch_SettingsScreen_OnEnable
	{
		[HarmonyPostfix]
		public static void Postfix(UISettingsScreen __instance)
		{
			try
			{
				ButtonInjector.InjectSettingsScreen(__instance);
			}
			catch (Exception ex)
			{
				ManualLogSource? log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)("SettingsScreen OnEnable inject: " + ex));
				}
			}
		}
	}
	[HarmonyPatch(typeof(UIEscapeMenu), "ShowMainPanel")]
	public static class Patch_EscapeMenu_ShowMainPanel
	{
		[HarmonyPostfix]
		public static void Postfix(UIEscapeMenu __instance)
		{
			try
			{
				ButtonInjector.InjectEscapeMenu(__instance);
			}
			catch (Exception ex)
			{
				ManualLogSource? log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)("EscapeMenu inject: " + ex));
				}
			}
		}
	}
	[HarmonyPatch(typeof(MainMenuManager), "ShowMainMenu")]
	public static class Patch_MainMenu_ShowMainMenu
	{
		[HarmonyPostfix]
		public static void Postfix(MainMenuManager __instance)
		{
			try
			{
				ButtonInjector.InjectMainMenu(__instance);
			}
			catch (Exception ex)
			{
				ManualLogSource? log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)("MainMenu inject: " + ex));
				}
			}
		}
	}
	public static class ButtonInjector
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__1_0;

			public static UnityAction <>9__2_0;

			public static UnityAction <>9__3_0;

			internal void <InjectSettingsScreen>b__1_0()
			{
				ModSettingsController.Instance?.Show();
			}

			internal void <InjectEscapeMenu>b__2_0()
			{
				ModSettingsController.Instance?.Show();
			}

			internal void <InjectMainMenu>b__3_0()
			{
				ModSettingsController.Instance?.Show();
			}
		}

		public const string BtnName = "ModSettingsMenuButton";

		public static void InjectSettingsScreen(UISettingsScreen screen)
		{
			//IL_00ae: 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_00b9: Expected O, but got Unknown
			Button field = GetField<Button>(screen, "applyButtonControl");
			if ((Object)(object)field == (Object)null)
			{
				return;
			}
			Transform parent = ((Component)field).transform.parent;
			if ((Object)(object)parent == (Object)null || (Object)(object)parent.Find("ModSettingsMenuButton") != (Object)null)
			{
				return;
			}
			Button val = FindDefaultsButton(screen);
			int num = ((Component)field).transform.GetSiblingIndex() + 1;
			if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).transform.parent == (Object)(object)parent)
			{
				int siblingIndex = ((Component)field).transform.GetSiblingIndex();
				int siblingIndex2 = ((Component)val).transform.GetSiblingIndex();
				num = Mathf.Min(siblingIndex, siblingIndex2) + 1;
			}
			int siblingIndex3 = num;
			object obj = <>c.<>9__1_0;
			if (obj == null)
			{
				UnityAction val2 = delegate
				{
					ModSettingsController.Instance?.Show();
				};
				<>c.<>9__1_0 = val2;
				obj = (object)val2;
			}
			CloneButton((Component)(object)field, parent, siblingIndex3, "Mod Settings", (UnityAction)obj, (Component?)(object)val);
			ManualLogSource? log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"Mod Settings button injected into UISettingsScreen between Apply/Defaults.");
			}
		}

		public static void InjectEscapeMenu(UIEscapeMenu menu)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			GameObject field = GetField<GameObject>(menu, "mainPanel");
			if ((Object)(object)field == (Object)null)
			{
				return;
			}
			Button val = FindTemplateButton(field.transform);
			if ((Object)(object)val == (Object)null)
			{
				ManualLogSource? log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"No suitable template button found in EscapeMenu.");
				}
				return;
			}
			Transform parent = ((Component)val).transform.parent;
			if ((Object)(object)parent == (Object)null || (Object)(object)parent.Find("ModSettingsMenuButton") != (Object)null)
			{
				return;
			}
			int siblingIndex = ((Component)val).transform.GetSiblingIndex() + 1;
			object obj = <>c.<>9__2_0;
			if (obj == null)
			{
				UnityAction val2 = delegate
				{
					ModSettingsController.Instance?.Show();
				};
				<>c.<>9__2_0 = val2;
				obj = (object)val2;
			}
			CloneButton((Component)(object)val, parent, siblingIndex, "Mod Settings", (UnityAction)obj);
			ManualLogSource? log2 = Plugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)("Mod Settings button added to EscapeMenu using '" + ((Object)val).name + "' template."));
			}
		}

		public static void InjectMainMenu(MainMenuManager mgr)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			Button field = GetField<Button>(mgr, "settingsButton");
			if ((Object)(object)field == (Object)null)
			{
				return;
			}
			Transform parent = ((Component)field).transform.parent;
			if ((Object)(object)parent == (Object)null || (Object)(object)parent.Find("ModSettingsMenuButton") != (Object)null)
			{
				return;
			}
			int siblingIndex = ((Component)field).transform.GetSiblingIndex() + 1;
			object obj = <>c.<>9__3_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					ModSettingsController.Instance?.Show();
				};
				<>c.<>9__3_0 = val;
				obj = (object)val;
			}
			CloneButton((Component)(object)field, parent, siblingIndex, "Mod Settings", (UnityAction)obj);
			ManualLogSource? log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"Mod Settings button added to MainMenu.");
			}
		}

		private static Button? FindDefaultsButton(UISettingsScreen screen)
		{
			Button[] componentsInChildren = ((Component)screen).GetComponentsInChildren<Button>(true);
			foreach (Button val in componentsInChildren)
			{
				string text = ((Object)val).name.ToLower();
				if (text.Contains("default") || text.Contains("restore") || text.Contains("reset"))
				{
					return val;
				}
				TMP_Text componentInChildren = ((Component)val).GetComponentInChildren<TMP_Text>(true);
				if ((Object)(object)componentInChildren != (Object)null && componentInChildren.text.ToLower().Contains("default"))
				{
					return val;
				}
				Text componentInChildren2 = ((Component)val).GetComponentInChildren<Text>(true);
				if ((Object)(object)componentInChildren2 != (Object)null && componentInChildren2.text.ToLower().Contains("default"))
				{
					return val;
				}
			}
			return null;
		}

		private static void CloneButton(Component source, Transform parent, int siblingIndex, string label, UnityAction onClick, Component? defaultsBtn = null)
		{
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: 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_0110: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(source.gameObject, parent);
			((Object)val).name = "ModSettingsMenuButton";
			val.transform.SetSiblingIndex(siblingIndex);
			val.SetActive(true);
			RectTransform component = source.GetComponent<RectTransform>();
			RectTransform component2 = val.GetComponent<RectTransform>();
			if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null && (Object)(object)((Component)parent).GetComponent<LayoutGroup>() == (Object)null)
			{
				RectTransform val2 = ((defaultsBtn != null) ? defaultsBtn.GetComponent<RectTransform>() : null);
				if ((Object)(object)val2 != (Object)null && (Object)(object)defaultsBtn != (Object)null && (Object)(object)defaultsBtn.transform.parent == (Object)(object)parent)
				{
					component2.anchoredPosition = new Vector2((component.anchoredPosition.x + val2.anchoredPosition.x) * 0.5f, (component.anchoredPosition.y + val2.anchoredPosition.y) * 0.5f);
					ManualLogSource? log = Plugin.Log;
					if (log != null)
					{
						log.LogInfo((object)$"[ModSettingsMenu] Positioned button absolutely at midpoint: {component2.anchoredPosition} between Apply ({component.anchoredPosition}) and Defaults ({val2.anchoredPosition})");
					}
				}
				else
				{
					component2.anchoredPosition = new Vector2(component.anchoredPosition.x + 170f, component.anchoredPosition.y);
					ManualLogSource? log2 = Plugin.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)$"[ModSettingsMenu] Positioned button absolutely with right-shift: {component2.anchoredPosition} from Apply ({component.anchoredPosition})");
					}
				}
			}
			Image[] componentsInChildren = val.GetComponentsInChildren<Image>(true);
			foreach (Image val3 in componentsInChildren)
			{
				if ((Object)(object)((Component)val3).gameObject != (Object)(object)val && (((Object)val3).name.ToLower().Contains("avatar") || ((Object)val3).name.ToLower().Contains("hero") || ((Object)val3).name.ToLower().Contains("portrait")))
				{
					((Component)val3).gameObject.SetActive(false);
				}
			}
			MonoBehaviour[] componentsInChildren2 = val.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val4 in componentsInChildren2)
			{
				if ((Object)(object)val4 == (Object)null)
				{
					continue;
				}
				string text = ((object)val4).GetType().Namespace ?? "";
				string name = ((object)val4).GetType().Name;
				if (!text.StartsWith("UnityEngine") && !text.StartsWith("TMPro"))
				{
					switch (name)
					{
					case "Button":
					case "Image":
					case "Text":
					case "TMP_Text":
						break;
					default:
					{
						ManualLogSource? log3 = Plugin.Log;
						if (log3 != null)
						{
							log3.LogInfo((object)("Destroyed custom game script: " + ((object)val4).GetType().FullName));
						}
						Object.Destroy((Object)(object)val4);
						continue;
					}
					}
				}
				string text2 = name.ToLower();
				if (text2.Contains("localize") || text2.Contains("localizer") || text2.Contains("localization") || text2.Contains("translation"))
				{
					ManualLogSource? log4 = Plugin.Log;
					if (log4 != null)
					{
						log4.LogInfo((object)("Destroyed localization component: " + ((object)val4).GetType().FullName));
					}
					Object.Destroy((Object)(object)val4);
				}
			}
			Transform[] componentsInChildren3 = val.GetComponentsInChildren<Transform>(true);
			foreach (Transform val5 in componentsInChildren3)
			{
				if ((Object)(object)val5 == (Object)(object)val.transform)
				{
					continue;
				}
				string text3 = ((Object)val5).name.ToLower();
				if ((text3.Length <= 2 || text3.Contains("circle") || text3.Contains("glyph") || text3.Contains("icon") || text3.Contains("gamepad") || text3.Contains("controller") || text3.Contains("keyboard") || text3.Contains("key") || text3.Contains("hint") || text3.Contains("prompt") || text3.Contains("button") || text3.Contains("image")) && !(text3 == "text (tmp)") && !(text3 == "text") && !(text3 == "label") && !text3.Contains("background") && !text3.Contains("highlight") && !text3.Contains("frame") && !text3.Contains("border") && !text3.Contains("base") && !text3.Contains("visual"))
				{
					ManualLogSource? log5 = Plugin.Log;
					if (log5 != null)
					{
						log5.LogInfo((object)("Disabling shortcut icon component/child: " + ((Object)val5).name));
					}
					((Component)val5).gameObject.SetActive(false);
					continue;
				}
				TMP_Text component3 = ((Component)val5).GetComponent<TMP_Text>();
				if ((Object)(object)component3 != (Object)null && text3 != "text (tmp)" && text3 != "text" && text3 != "label")
				{
					ManualLogSource? log6 = Plugin.Log;
					if (log6 != null)
					{
						log6.LogInfo((object)("Disabling extra text child: " + ((Object)val5).name + " (Text: '" + component3.text + "')"));
					}
					((Component)val5).gameObject.SetActive(false);
					if ((Object)(object)val5.parent != (Object)null && (Object)(object)val5.parent != (Object)(object)val.transform)
					{
						ManualLogSource? log7 = Plugin.Log;
						if (log7 != null)
						{
							log7.LogInfo((object)("Disabling extra text child parent: " + ((Object)val5.parent).name));
						}
						((Component)val5.parent).gameObject.SetActive(false);
					}
				}
				Text component4 = ((Component)val5).GetComponent<Text>();
				if (!((Object)(object)component4 != (Object)null) || !(text3 != "text (tmp)") || !(text3 != "text") || !(text3 != "label"))
				{
					continue;
				}
				ManualLogSource? log8 = Plugin.Log;
				if (log8 != null)
				{
					log8.LogInfo((object)("Disabling extra text child: " + ((Object)val5).name + " (Text: '" + component4.text + "')"));
				}
				((Component)val5).gameObject.SetActive(false);
				if ((Object)(object)val5.parent != (Object)null && (Object)(object)val5.parent != (Object)(object)val.transform)
				{
					ManualLogSource? log9 = Plugin.Log;
					if (log9 != null)
					{
						log9.LogInfo((object)("Disabling extra text child parent: " + ((Object)val5.parent).name));
					}
					((Component)val5.parent).gameObject.SetActive(false);
				}
			}
			TMP_Text[] componentsInChildren4 = val.GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val6 in componentsInChildren4)
			{
				string text4 = ((Object)((Component)val6).gameObject).name.ToLower();
				switch (text4)
				{
				case "text (tmp)":
				case "text":
				case "label":
					if (!text4.Contains("keyboard") && !text4.Contains("key") && !text4.Contains("shortcut"))
					{
						val6.text = label;
					}
					break;
				}
			}
			Text[] componentsInChildren5 = val.GetComponentsInChildren<Text>(true);
			foreach (Text val7 in componentsInChildren5)
			{
				string text5 = ((Object)((Component)val7).gameObject).name.ToLower();
				switch (text5)
				{
				case "text (tmp)":
				case "text":
				case "label":
					if (!text5.Contains("keyboard") && !text5.Contains("key") && !text5.Contains("shortcut"))
					{
						val7.text = label;
					}
					break;
				}
			}
			Button component5 = val.GetComponent<Button>();
			((UnityEventBase)component5.onClick).RemoveAllListeners();
			((UnityEvent)component5.onClick).AddListener(onClick);
		}

		public static T? GetField<T>(object obj, string name) where T : class
		{
			return obj.GetType().GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj) as T;
		}

		private static Button? FindTemplateButton(Transform root)
		{
			Button[] componentsInChildren = ((Component)root).GetComponentsInChildren<Button>(true);
			Button[] array = componentsInChildren;
			foreach (Button val in array)
			{
				string text = ((Object)val).name.ToLower();
				if ((text.Contains("settings") || text.Contains("option") || text.Contains("config")) && !text.Contains("hero") && !text.Contains("portrait") && !text.Contains("avatar"))
				{
					return val;
				}
			}
			array = componentsInChildren;
			foreach (Button val2 in array)
			{
				string text2 = ((Object)val2).name.ToLower();
				if ((text2.Contains("resume") || text2.Contains("continue")) && !text2.Contains("hero") && !text2.Contains("portrait") && !text2.Contains("avatar"))
				{
					return val2;
				}
			}
			array = componentsInChildren;
			foreach (Button val3 in array)
			{
				string text3 = ((Object)val3).name.ToLower();
				if ((text3.Contains("menu") || text3.Contains("quit") || text3.Contains("exit") || text3.Contains("back")) && !text3.Contains("hero") && !text3.Contains("portrait") && !text3.Contains("avatar"))
				{
					return val3;
				}
			}
			array = componentsInChildren;
			foreach (Button val4 in array)
			{
				string text4 = ((Object)val4).name.ToLower();
				if (!text4.Contains("hero") && !text4.Contains("portrait") && !text4.Contains("avatar") && !text4.Contains("kick") && !text4.Contains("close") && !text4.Contains("player"))
				{
					return val4;
				}
			}
			return null;
		}
	}
}