Decompiled source of FishyUI v0.1.1

FishyUI.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("FishyUI")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("FishyUI")]
[assembly: AssemblyTitle("FishyUI")]
[assembly: AssemblyVersion("0.1.0.0")]
namespace FishyUI;

internal static class Options
{
	public static Page Page(string title)
	{
		if (string.IsNullOrWhiteSpace(title))
		{
			title = "Unnamed";
		}
		Page page = Registry.Find(title);
		if (page == null)
		{
			page = new Page(title.Trim());
			Registry.Add(page);
		}
		return page;
	}

	public static void Remove(string title)
	{
		Page page = Registry.Find(title);
		if (page != null)
		{
			Registry.Remove(page);
		}
	}

	public static void Remove(Page page)
	{
		Registry.Remove(page);
	}

	public static Page AutoPage(ConfigFile config, string title)
	{
		Page page = Page(title);
		if (config != null)
		{
			AutoPages.Fill(page, config);
		}
		return page;
	}
}
public class Page
{
	internal readonly string Title;

	internal readonly List<Row> Rows = new List<Row>();

	internal int Version;

	public int RowCount => Rows.Count;

	internal Page(string title)
	{
		Title = title;
	}

	public Page Search(string hint = "Search")
	{
		return Add(new Row
		{
			Kind = RowKind.Search,
			Label = hint,
			Height = 0.9f
		});
	}

	public Page Header(string text)
	{
		return Add(new Row
		{
			Kind = RowKind.Header,
			Label = text,
			Height = 0.7f
		});
	}

	public Page Label(string text)
	{
		return Add(new Row
		{
			Kind = RowKind.Label,
			Label = text,
			Height = 0.6f
		});
	}

	public Page Space(float rows = 0.5f)
	{
		return Add(new Row
		{
			Kind = RowKind.Space,
			Height = Mathf.Clamp(rows, 0.1f, 3f)
		});
	}

	public Page Toggle(string label, ConfigEntry<bool> entry)
	{
		return Add(new Row
		{
			Kind = RowKind.Toggle,
			Label = label,
			Get = () => entry.Value,
			Set = delegate(object v)
			{
				entry.Value = (bool)v;
			}
		});
	}

	public Page Toggle(string label, bool value, Action<bool> onChanged)
	{
		return Add(new Row
		{
			Kind = RowKind.Toggle,
			Label = label,
			Get = () => value,
			Set = delegate(object v)
			{
				value = (bool)v;
				onChanged?.Invoke(value);
			}
		});
	}

	public Page Slider(string label, ConfigEntry<float> entry)
	{
		float min = 0f;
		float max = 1f;
		AutoPages.TryRange((ConfigEntryBase)(object)entry, ref min, ref max);
		return Slider(label, entry, min, max);
	}

	public Page Slider(string label, ConfigEntry<float> entry, float min, float max)
	{
		return Add(new Row
		{
			Kind = RowKind.Slider,
			Label = label,
			Min = min,
			Max = max,
			Get = () => entry.Value,
			Set = delegate(object v)
			{
				entry.Value = (float)v;
			}
		});
	}

	public Page Slider(string label, ConfigEntry<int> entry)
	{
		float min = 0f;
		float max = 10f;
		AutoPages.TryRange((ConfigEntryBase)(object)entry, ref min, ref max);
		return Slider(label, entry, (int)min, (int)max);
	}

	public Page Slider(string label, ConfigEntry<int> entry, int min, int max)
	{
		return Add(new Row
		{
			Kind = RowKind.Slider,
			Label = label,
			Min = min,
			Max = max,
			Whole = true,
			Get = () => (float)entry.Value,
			Set = delegate(object v)
			{
				entry.Value = Mathf.RoundToInt((float)v);
			}
		});
	}

	public Page Slider(string label, float value, float min, float max, Action<float> onChanged)
	{
		return Add(new Row
		{
			Kind = RowKind.Slider,
			Label = label,
			Min = min,
			Max = max,
			Get = () => value,
			Set = delegate(object v)
			{
				value = (float)v;
				onChanged?.Invoke(value);
			}
		});
	}

	public Page Dropdown<T>(string label, ConfigEntry<T> entry) where T : Enum
	{
		string[] names = Enum.GetNames(typeof(T));
		Array values = Enum.GetValues(typeof(T));
		return Add(new Row
		{
			Kind = RowKind.Cycle,
			Label = label,
			OptionsF = () => names,
			Get = () => Mathf.Max(0, ((IList)values).IndexOf((object?)entry.Value)),
			Set = delegate(object v)
			{
				entry.Value = (T)values.GetValue((int)v);
			}
		});
	}

	public Page Dropdown(string label, string[] options, int index, Action<int> onChanged)
	{
		if (options == null || options.Length == 0)
		{
			options = new string[1] { "-" };
		}
		int cur = Mathf.Clamp(index, 0, options.Length - 1);
		return Add(new Row
		{
			Kind = RowKind.Cycle,
			Label = label,
			OptionsF = () => options,
			Get = () => cur,
			Set = delegate(object v)
			{
				cur = (int)v;
				onChanged?.Invoke(cur);
			}
		});
	}

	public Page Input(string label, ConfigEntry<string> entry)
	{
		return Add(new Row
		{
			Kind = RowKind.Input,
			Label = label,
			Get = () => entry.Value,
			Set = delegate(object v)
			{
				entry.Value = (string)v;
			}
		});
	}

	public Page Input(string label, string value, Action<string> onChanged)
	{
		string cur = value ?? "";
		return Add(new Row
		{
			Kind = RowKind.Input,
			Label = label,
			Get = () => cur,
			Set = delegate(object v)
			{
				cur = (string)v;
				onChanged?.Invoke(cur);
			}
		});
	}

	public Page Colour(string label, ConfigEntry<Color> entry)
	{
		return Add(new Row
		{
			Kind = RowKind.Colour,
			Label = label,
			Get = () => entry.Value,
			Set = delegate(object v)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				entry.Value = (Color)v;
			},
			GetDefault = () => ((ConfigEntryBase)entry).DefaultValue
		});
	}

	public Page Colour(string label, Color value, Action<Color> onChanged)
	{
		//IL_000e: 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_0015: 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)
		Color cur = value;
		Color def = value;
		return Add(new Row
		{
			Kind = RowKind.Colour,
			Label = label,
			Get = () => cur,
			Set = delegate(object v)
			{
				//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_0018: Unknown result type (might be due to invalid IL or missing references)
				cur = (Color)v;
				onChanged?.Invoke(cur);
			},
			GetDefault = () => def
		});
	}

	public Page Keybind(string label, ConfigEntry<KeyboardShortcut> entry)
	{
		return Add(new Row
		{
			Kind = RowKind.Keybind,
			Label = label,
			Get = () => entry.Value,
			Set = delegate(object v)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				entry.Value = (KeyboardShortcut)v;
			}
		});
	}

	public Page Keybind(string label, ConfigEntry<KeyCode> entry)
	{
		return Add(new Row
		{
			Kind = RowKind.Keybind,
			Label = label,
			KeyOnly = true,
			Get = () => entry.Value,
			Set = delegate(object v)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				entry.Value = (KeyCode)v;
			}
		});
	}

	public Page Bar(string label, Func<float> value)
	{
		return Add(new Row
		{
			Kind = RowKind.Bar,
			Label = label,
			Live = () => value()
		});
	}

	public Page Readout(string label, Func<string> value)
	{
		return Add(new Row
		{
			Kind = RowKind.Readout,
			Label = label,
			Live = () => value()
		});
	}

	public Page Button(string label, Action onClick)
	{
		return Add(new Row
		{
			Kind = RowKind.Button,
			Label = label,
			Click = onClick
		});
	}

	public Page Buttons(params (string label, Action onClick)[] buttons)
	{
		return Add(new Row
		{
			Kind = RowKind.Buttons,
			Multi = buttons
		});
	}

	public Page Custom(string label, float heightRows, Action<RectTransform> build)
	{
		return Add(new Row
		{
			Kind = RowKind.Custom,
			Label = label,
			Height = Mathf.Clamp(heightRows, 0.3f, 10f),
			CustomBuild = build
		});
	}

	public Page Tip(ConfigEntryBase entry)
	{
		string text = ((entry != null && entry.Description != null) ? entry.Description.Description : null);
		if (!string.IsNullOrEmpty(text))
		{
			return Tip(text);
		}
		return this;
	}

	public Page Tip(string text)
	{
		if (Rows.Count > 0)
		{
			Rows[Rows.Count - 1].Tip = text;
		}
		return this;
	}

	public Page Clear()
	{
		Rows.Clear();
		Version++;
		Registry.MarkDirty();
		return this;
	}

	internal Page AddRow(Row r)
	{
		return Add(r);
	}

	private Page Add(Row r)
	{
		Rows.Add(r);
		Version++;
		Registry.MarkDirty();
		return this;
	}
}
internal enum RowKind
{
	Header,
	Label,
	Space,
	Toggle,
	Slider,
	Cycle,
	Input,
	Colour,
	Keybind,
	Button,
	Buttons,
	Bar,
	Readout,
	Search,
	Custom
}
internal class Row
{
	public RowKind Kind;

	public string Label;

	public Func<object> Get;

	public Action<object> Set;

	public Func<object> GetDefault;

	public Func<object> Live;

	public string Tip;

	public Action<RectTransform> CustomBuild;

	public float Min;

	public float Max;

	public bool Whole;

	public bool KeyOnly;

	public Func<string[]> OptionsF;

	public Action Click;

	public (string label, Action act)[] Multi;

	public float Height = 1f;
}
internal static class Registry
{
	private static readonly List<Page> Pages = new List<Page>();

	public static bool Dirty;

	public static List<Page> All => Pages;

	public static int Count => Pages.Count;

	public static void Add(Page p)
	{
		Pages.Add(p);
		MarkDirty();
	}

	public static void Remove(Page p)
	{
		if (p != null && Pages.Remove(p))
		{
			MarkDirty();
		}
	}

	public static Page Find(string title)
	{
		foreach (Page page in Pages)
		{
			if (string.Equals(page.Title, title, StringComparison.OrdinalIgnoreCase))
			{
				return page;
			}
		}
		return null;
	}

	public static void MarkDirty()
	{
		Dirty = true;
		Injector.OnRegistryChanged();
	}

	public static Dictionary<KeyCode, int> KeyUse()
	{
		//IL_0061: 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_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		Dictionary<KeyCode, int> dictionary = new Dictionary<KeyCode, int>();
		foreach (Page page in Pages)
		{
			foreach (Row row in page.Rows)
			{
				if (row.Kind == RowKind.Keybind && row.Get != null)
				{
					object obj;
					try
					{
						obj = row.Get();
					}
					catch
					{
						continue;
					}
					KeyCode val = (KeyCode)((!(obj is KeyboardShortcut val2)) ? ((obj is KeyCode val3) ? ((int)val3) : 0) : ((int)((KeyboardShortcut)(ref val2)).MainKey));
					if ((int)val != 0)
					{
						dictionary.TryGetValue(val, out var value);
						dictionary[val] = value + 1;
					}
				}
			}
		}
		return dictionary;
	}
}
internal static class AutoPages
{
	public static void Fill(Page p, ConfigFile cfg)
	{
		List<string> list = new List<string>();
		Dictionary<string, List<ConfigEntryBase>> dictionary = new Dictionary<string, List<ConfigEntryBase>>();
		foreach (ConfigDefinition key in cfg.Keys)
		{
			ConfigEntryBase val = cfg[key];
			if (val != null)
			{
				string text = key.Section ?? "";
				if (!dictionary.TryGetValue(text, out var value))
				{
					value = (dictionary[text] = new List<ConfigEntryBase>());
					list.Add(text);
				}
				value.Add(val);
			}
		}
		bool flag = list.Count > 1;
		foreach (string item in list)
		{
			if (flag)
			{
				p.Header(string.IsNullOrEmpty(item) ? "General" : item);
			}
			foreach (ConfigEntryBase item2 in dictionary[item])
			{
				AddEntry(p, item2);
			}
		}
	}

	private static void AddEntry(Page p, ConfigEntryBase e)
	{
		int count = p.Rows.Count;
		AddRowFor(p, e);
		string text = ((e.Description != null) ? e.Description.Description : null);
		if (!string.IsNullOrEmpty(text) && p.Rows.Count > count)
		{
			p.Tip(text);
		}
	}

	private static void AddRowFor(Page p, ConfigEntryBase e)
	{
		Type settingType = e.SettingType;
		string key = e.Definition.Key;
		if (settingType == typeof(bool))
		{
			p.Toggle(key, (ConfigEntry<bool>)(object)e);
		}
		else if (settingType == typeof(string))
		{
			if (TryListOptions(e, out var opts))
			{
				p.AddRow(new Row
				{
					Kind = RowKind.Cycle,
					Label = key,
					OptionsF = () => opts,
					Get = () => Mathf.Max(0, Array.IndexOf(opts, (string)e.BoxedValue)),
					Set = delegate(object v)
					{
						e.BoxedValue = opts[(int)v];
					}
				});
			}
			else
			{
				p.Input(key, (ConfigEntry<string>)(object)e);
			}
		}
		else if (settingType == typeof(float) || settingType == typeof(int) || settingType == typeof(double))
		{
			float min = 0f;
			float max = 0f;
			if (TryRange(e, ref min, ref max))
			{
				if (settingType == typeof(float))
				{
					p.Slider(key, (ConfigEntry<float>)(object)e, min, max);
				}
				else if (settingType == typeof(int))
				{
					p.Slider(key, (ConfigEntry<int>)(object)e, (int)min, (int)max);
				}
				else
				{
					NumberInput(p, key, e, min, max, clamp: true);
				}
			}
			else
			{
				NumberInput(p, key, e, float.MinValue, float.MaxValue, clamp: false);
			}
		}
		else if (settingType.IsEnum)
		{
			string[] names = Enum.GetNames(settingType);
			Array values = Enum.GetValues(settingType);
			p.AddRow(new Row
			{
				Kind = RowKind.Cycle,
				Label = key,
				OptionsF = () => names,
				Get = () => Mathf.Max(0, ((IList)values).IndexOf(e.BoxedValue)),
				Set = delegate(object v)
				{
					e.BoxedValue = values.GetValue((int)v);
				}
			});
		}
		else if (settingType == typeof(Color))
		{
			p.Colour(key, (ConfigEntry<Color>)(object)e);
		}
		else if (settingType == typeof(KeyboardShortcut))
		{
			p.Keybind(key, (ConfigEntry<KeyboardShortcut>)(object)e);
		}
		else if (settingType == typeof(KeyCode))
		{
			p.Keybind(key, (ConfigEntry<KeyCode>)(object)e);
		}
		else
		{
			Plugin.Log.LogDebug((object)("AutoPage skipped '" + key + "' (" + settingType.Name + ")"));
		}
	}

	private static void NumberInput(Page p, string label, ConfigEntryBase e, float min, float max, bool clamp)
	{
		Type t = e.SettingType;
		p.AddRow(new Row
		{
			Kind = RowKind.Input,
			Label = label,
			Get = () => Convert.ToDouble(e.BoxedValue).ToString("0.###", CultureInfo.InvariantCulture),
			Set = delegate(object v)
			{
				if (double.TryParse((((string)v) ?? "").Trim().Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
				{
					if (clamp)
					{
						result = Math.Min(max, Math.Max(min, result));
					}
					if (t == typeof(int))
					{
						e.BoxedValue = (int)Math.Round(result);
					}
					else if (t == typeof(float))
					{
						e.BoxedValue = (float)result;
					}
					else
					{
						e.BoxedValue = result;
					}
				}
			}
		});
	}

	public static bool TryRange(ConfigEntryBase e, ref float min, ref float max)
	{
		AcceptableValueBase val = ((e.Description != null) ? e.Description.AcceptableValues : null);
		if (val is AcceptableValueRange<float> val2)
		{
			min = val2.MinValue;
			max = val2.MaxValue;
		}
		else if (val is AcceptableValueRange<int> val3)
		{
			min = val3.MinValue;
			max = val3.MaxValue;
		}
		else
		{
			if (!(val is AcceptableValueRange<double> val4))
			{
				return false;
			}
			min = (float)val4.MinValue;
			max = (float)val4.MaxValue;
		}
		return max > min;
	}

	private static bool TryListOptions(ConfigEntryBase e, out string[] options)
	{
		options = null;
		if (((e.Description != null) ? e.Description.AcceptableValues : null) is AcceptableValueList<string> val && val.AcceptableValues != null && val.AcceptableValues.Length != 0)
		{
			options = val.AcceptableValues;
			return true;
		}
		return false;
	}
}
internal static class Chooser
{
	private static GameObject _open;

	private static Window _plain;

	private static readonly Dictionary<Graphic, Material> Mats = new Dictionary<Graphic, Material>();

	private static readonly Dictionary<Graphic, Color> Cols = new Dictionary<Graphic, Color>();

	public static void Close()
	{
		if ((Object)(object)_open != (Object)null)
		{
			Object.Destroy((Object)(object)_open);
		}
		_open = null;
		_plain = null;
		Mats.Clear();
		Cols.Clear();
	}

	public static void Open(Widgets w, RectTransform anchor, string[] options, int current, Action<int> pick)
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Expected O, but got Unknown
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Expected O, but got Unknown
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: 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_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Expected O, but got Unknown
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Expected O, but got Unknown
		//IL_013a: 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_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: 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_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: 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_0233: 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_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_024f: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0262: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: 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_02ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_030d: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e3: Expected O, but got Unknown
		//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_040f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0425: Unknown result type (might be due to invalid IL or missing references)
		//IL_0445: Unknown result type (might be due to invalid IL or missing references)
		//IL_046b: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0495: Unknown result type (might be due to invalid IL or missing references)
		//IL_049a: Unknown result type (might be due to invalid IL or missing references)
		//IL_049f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0533: Unknown result type (might be due to invalid IL or missing references)
		//IL_053d: Unknown result type (might be due to invalid IL or missing references)
		Close();
		if (w == null || (Object)(object)anchor == (Object)null || options == null || options.Length == 0)
		{
			return;
		}
		Canvas componentInParent = ((Component)anchor).GetComponentInParent<Canvas>();
		if ((Object)(object)componentInParent == (Object)null)
		{
			return;
		}
		RectTransform val = (RectTransform)((Component)componentInParent).transform;
		GameObject val2 = new GameObject("ChooserBack", new Type[1] { typeof(RectTransform) });
		RectTransform val3 = (RectTransform)val2.transform;
		((Transform)val3).SetParent((Transform)(object)val, false);
		val3.anchorMin = Vector2.zero;
		val3.anchorMax = Vector2.one;
		val3.offsetMin = Vector2.zero;
		val3.offsetMax = Vector2.zero;
		((Graphic)val2.AddComponent<Image>()).color = Color.clear;
		Button obj = val2.AddComponent<Button>();
		((Selectable)obj).transition = (Transition)0;
		((UnityEvent)obj.onClick).AddListener(new UnityAction(Close));
		((Transform)val3).SetAsLastSibling();
		_open = val2;
		RectTransform val4 = Widgets.CloneFrame((Transform)val3);
		if ((Object)(object)val4 == (Object)null)
		{
			Close();
			return;
		}
		((Object)val4).name = "Chooser";
		float num = Mathf.Max(42f, w.Fs * 1.25f);
		int num2 = Mathf.Min(options.Length, 8);
		float num3 = (float)num2 * num + 16f;
		Rect rect = anchor.rect;
		float num4 = Mathf.Max(240f, ((Rect)(ref rect)).width);
		Vector3[] array = (Vector3[])(object)new Vector3[4];
		anchor.GetWorldCorners(array);
		Vector2 val5 = RectTransformUtility.WorldToScreenPoint(componentInParent.worldCamera, array[0]);
		Vector2 val6 = default(Vector2);
		RectTransformUtility.ScreenPointToLocalPointInRectangle(val, val5, componentInParent.worldCamera, ref val6);
		Vector2 val7 = default(Vector2);
		((Vector2)(ref val7))..ctor(0.5f, 0.5f);
		val4.anchorMax = val7;
		val4.anchorMin = val7;
		val4.pivot = new Vector2(0f, 1f);
		val4.sizeDelta = new Vector2(num4, num3);
		rect = val.rect;
		float num5 = ((Rect)(ref rect)).height * 0.5f;
		if (val6.y - num3 < 0f - num5)
		{
			float num6 = val6.y + num3;
			rect = anchor.rect;
			val6.y = Mathf.Min(num6 + ((Rect)(ref rect)).height, num5);
		}
		rect = val.rect;
		float num7 = ((Rect)(ref rect)).width * 0.5f;
		if (val6.x + num4 > num7)
		{
			val6.x = num7 - num4;
		}
		val4.anchoredPosition = val6;
		RectTransform val8 = Widgets.Area((Transform)(object)val4, "View", Vector2.zero, Vector2.one);
		val8.offsetMin = new Vector2(8f, 8f);
		val8.offsetMax = new Vector2(-8f, -8f);
		((Graphic)((Component)val8).gameObject.AddComponent<Image>()).color = Color.clear;
		((Component)val8).gameObject.AddComponent<RectMask2D>();
		RectTransform val9 = Widgets.Area((Transform)(object)val8, "Content", new Vector2(0f, 1f), new Vector2(1f, 1f));
		val9.pivot = new Vector2(0.5f, 1f);
		val9.sizeDelta = new Vector2(0f, (float)options.Length * num);
		if (options.Length > num2)
		{
			ScrollRect val10 = ((Component)val8).gameObject.AddComponent<ScrollRect>();
			val10.viewport = val8;
			val10.content = val9;
			val10.horizontal = false;
			val10.movementType = (MovementType)2;
			val10.scrollSensitivity = num;
			w.MakeScrollbar(val8, val10);
		}
		WindowFocus componentInParent2 = ((Component)anchor).GetComponentInParent<WindowFocus>();
		_plain = (((Object)(object)componentInParent2 != (Object)null && componentInParent2.Owner != null && !componentInParent2.Owner.Frosted) ? componentInParent2.Owner : null);
		for (int i = 0; i < options.Length; i++)
		{
			int idx = i;
			RectTransform val11 = (RectTransform)new GameObject("Option", new Type[1] { typeof(RectTransform) }).transform;
			((Transform)val11).SetParent((Transform)(object)val9, false);
			val11.anchorMin = new Vector2(0f, 1f);
			val11.anchorMax = new Vector2(1f, 1f);
			val11.pivot = new Vector2(0.5f, 1f);
			val11.offsetMin = new Vector2(0f, (float)(-(i + 1)) * num + 4f);
			val11.offsetMax = new Vector2((options.Length > num2) ? (-16f) : 0f, (float)(-i) * num);
			if (idx == current)
			{
				((Graphic)Widgets.MakeImage((Transform)(object)val11, new Color(1f, 1f, 1f, 0.1f), Vector2.zero, Vector2.one)).raycastTarget = false;
			}
			w.MakeButton((Transform)(object)val11, options[i], w.Fs * 0.42f, Vector2.zero, Vector2.one, delegate
			{
				Close();
				if (pick != null)
				{
					pick(idx);
				}
			});
		}
		if (_plain != null)
		{
			List<Graphic> list = new List<Graphic>();
			Graphic[] components = ((Component)val4).GetComponents<Graphic>();
			foreach (Graphic item in components)
			{
				list.Add(item);
			}
			Frost.Apply((Transform)(object)val4, list, frosted: false, _plain.PanelColour, _plain.ControlColour, Mats, Cols);
		}
	}
}
internal static class Toast
{
	public static bool Frosted;

	public static Color PanelColour = Frost.Panel;

	public static Corner Where = Corner.BottomRight;

	public static float Seconds = 3f;

	private static readonly List<ToastBox> Live = new List<ToastBox>();

	public static void Show(string text)
	{
		Show(text, Seconds, Frosted);
	}

	public static void Show(string text, float seconds)
	{
		Show(text, seconds, Frosted);
	}

	public static void Show(string text, float seconds, bool frosted)
	{
		//IL_004a: 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_00b2: 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_00f2: 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)
		Widgets w = Injector.W;
		if (w == null)
		{
			Plugin.Log.LogInfo((object)("toast before any menu existed: " + text));
			return;
		}
		RectTransform val = Widgets.CloneFrame((Transform)(object)Hud.Root);
		if (!((Object)(object)val == (Object)null))
		{
			((Object)val).name = "Toast";
			val.sizeDelta = new Vector2(300f, 52f);
			List<Graphic> list = new List<Graphic>();
			Graphic[] componentsInChildren = ((Component)val).GetComponentsInChildren<Graphic>(true);
			foreach (Graphic item in componentsInChildren)
			{
				list.Add(item);
			}
			TMP_Text obj = w.MakeLabel((Transform)(object)val, text, w.Fs * 0.34f, (TextAlignmentOptions)514, new Vector2(0.06f, 0f), new Vector2(0.94f, 1f));
			obj.textWrappingMode = (TextWrappingModes)0;
			obj.overflowMode = (TextOverflowModes)1;
			float num = obj.GetPreferredValues(text).x + 34f;
			val.sizeDelta = new Vector2(Mathf.Clamp(num, 180f, 460f), 52f);
			if (!frosted)
			{
				Frost.Apply((Transform)(object)val, list, frosted: false, PanelColour, PanelColour, new Dictionary<Graphic, Material>(), new Dictionary<Graphic, Color>());
			}
			ToastBox toastBox = ((Component)val).gameObject.AddComponent<ToastBox>();
			toastBox.Life = Mathf.Max(0.5f, seconds);
			Live.Add(toastBox);
			Restack();
		}
	}

	public static void Clear()
	{
		for (int num = Live.Count - 1; num >= 0; num--)
		{
			if ((Object)(object)Live[num] != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)Live[num]).gameObject);
			}
		}
		Live.Clear();
	}

	internal static void Gone(ToastBox box)
	{
		Live.Remove(box);
		Restack();
	}

	private static void Restack()
	{
		//IL_0005: 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_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: 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_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Expected O, but got Unknown
		//IL_0083: 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_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
		Vector2 val = HudElement.AnchorOf(Where);
		bool flag = val.y > 0.6f;
		float num = ((val.x > 0.6f) ? (-28f) : ((val.x < 0.4f) ? 28f : 0f));
		float num2 = (flag ? (-28f) : 28f);
		for (int num3 = Live.Count - 1; num3 >= 0; num3--)
		{
			RectTransform val2 = (RectTransform)((Component)Live[num3]).transform;
			Vector2 anchorMin = (val2.anchorMax = val);
			val2.anchorMin = anchorMin;
			val2.pivot = val;
			val2.anchoredPosition = new Vector2(num, num2);
			num2 += (flag ? (-1f) : 1f) * (val2.sizeDelta.y + 8f);
		}
	}
}
internal class ToastBox : MonoBehaviour
{
	public float Life = 3f;

	private float _age;

	private CanvasGroup _group;

	private void Awake()
	{
		_group = ((Component)this).gameObject.AddComponent<CanvasGroup>();
		_group.blocksRaycasts = false;
		_group.interactable = false;
	}

	private void Update()
	{
		_age += Time.unscaledDeltaTime;
		float num = Life - _age;
		if ((Object)(object)_group != (Object)null)
		{
			_group.alpha = ((num < 0.5f) ? Mathf.Clamp01(num / 0.5f) : 1f);
		}
		if (!(_age < Life))
		{
			Toast.Gone(this);
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
	}

	private void OnDestroy()
	{
		Toast.Gone(this);
	}
}
internal static class Dialog
{
	public static void Confirm(string title, string message, Action onYes, Action onNo = null)
	{
		Build(title, message, onYes, onNo, askKind: true);
	}

	public static void Info(string title, string message, Action onClose = null)
	{
		Build(title, message, onClose, null, askKind: false);
	}

	public static void Prompt(string title, string message, string start, Action<string> onOk)
	{
		//IL_005c: 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_0099: 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_00df: 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_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: 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_0192: Unknown result type (might be due to invalid IL or missing references)
		Widgets w = Injector.W;
		Window win = Window.Create("dialog:" + title, title, 620f, 360f);
		if (win == null || w == null)
		{
			return;
		}
		win.Resizable = false;
		win.MinSize = new Vector2(620f, 360f);
		win.Center();
		w.MakeLabel((Transform)(object)win.Body, message, w.Fs * 0.42f, (TextAlignmentOptions)514, new Vector2(0.04f, 0.62f), new Vector2(0.96f, 1f)).textWrappingMode = (TextWrappingModes)1;
		string typed = start ?? "";
		TMP_InputField box = w.MakeInput((Transform)(object)win.Body, new Vector2(0.08f, 0.38f), new Vector2(0.92f, 0.56f), typed, delegate(string v)
		{
			typed = v;
		});
		w.MakeButton((Transform)(object)win.Body, "OK", w.Fs * 0.45f, new Vector2(0.08f, 0.06f), new Vector2(0.47f, 0.3f), delegate
		{
			if ((Object)(object)box != (Object)null)
			{
				typed = box.text;
			}
			win.Destroy();
			if (onOk != null)
			{
				Run(delegate
				{
					onOk(typed);
				});
			}
		});
		w.MakeButton((Transform)(object)win.Body, "Cancel", w.Fs * 0.45f, new Vector2(0.53f, 0.06f), new Vector2(0.92f, 0.3f), win.Destroy);
		win.Show();
	}

	private static void Build(string title, string message, Action yes, Action no, bool askKind)
	{
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: 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_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_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		Widgets w = Injector.W;
		Window win = Window.Create("dialog:" + title, title, 620f, 340f);
		if (win == null || w == null)
		{
			return;
		}
		win.Resizable = false;
		win.MinSize = new Vector2(620f, 340f);
		win.Center();
		w.MakeLabel((Transform)(object)win.Body, message, w.Fs * 0.45f, (TextAlignmentOptions)514, new Vector2(0.04f, 0.42f), new Vector2(0.96f, 1f)).textWrappingMode = (TextWrappingModes)1;
		if (askKind)
		{
			w.MakeButton((Transform)(object)win.Body, "Yes", w.Fs * 0.45f, new Vector2(0.08f, 0.08f), new Vector2(0.47f, 0.32f), delegate
			{
				win.Destroy();
				Run(yes);
			});
			w.MakeButton((Transform)(object)win.Body, "No", w.Fs * 0.45f, new Vector2(0.53f, 0.08f), new Vector2(0.92f, 0.32f), delegate
			{
				win.Destroy();
				Run(no);
			});
		}
		else
		{
			w.MakeButton((Transform)(object)win.Body, "OK", w.Fs * 0.45f, new Vector2(0.3f, 0.08f), new Vector2(0.7f, 0.32f), delegate
			{
				win.Destroy();
				Run(yes);
			});
		}
		win.Show();
	}

	private static void Run(Action a)
	{
		if (a == null)
		{
			return;
		}
		try
		{
			a();
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("dialog callback failed: " + ex));
		}
	}
}
internal class TooltipHover : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
{
	public string Text;

	private static GameObject _box;

	private static TMP_Text _label;

	private static TooltipHover _owner;

	public void OnPointerEnter(PointerEventData e)
	{
		_owner = this;
		if ((Object)(object)_box == (Object)null)
		{
			MakeBox();
		}
		if (!((Object)(object)_box == (Object)null))
		{
			_label.text = Text;
			_box.SetActive(true);
			_box.transform.SetAsLastSibling();
		}
	}

	public void OnPointerExit(PointerEventData e)
	{
		if (!((Object)(object)_owner != (Object)(object)this))
		{
			_owner = null;
			if ((Object)(object)_box != (Object)null)
			{
				_box.SetActive(false);
			}
		}
	}

	private void OnDisable()
	{
		OnPointerExit(null);
	}

	private void MakeBox()
	{
		//IL_003c: 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_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: 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)
		Widgets w = Injector.W;
		RectTransform val = Widgets.CloneFrame((Transform)(object)Hud.Root);
		if (!((Object)(object)val == (Object)null) && w != null)
		{
			((Object)val).name = "Tooltip";
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0f, 0f);
			val.anchorMax = val2;
			val.anchorMin = val2;
			val.pivot = new Vector2(0f, 0f);
			val.sizeDelta = new Vector2(420f, 74f);
			((Component)val).gameObject.AddComponent<CanvasGroup>().blocksRaycasts = false;
			_label = w.MakeLabel((Transform)(object)val, "", w.Fs * 0.4f, (TextAlignmentOptions)514, new Vector2(0.05f, 0f), new Vector2(0.95f, 1f));
			_label.textWrappingMode = (TextWrappingModes)1;
			_box = ((Component)val).gameObject;
			_box.AddComponent<TooltipFollow>();
		}
	}
}
internal class TooltipFollow : MonoBehaviour
{
	private void Update()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: 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_0038: 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_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: 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_0061: 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_0076: 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)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00b6: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
		RectTransform val = (RectTransform)((Component)this).transform;
		RectTransform root = Hud.Root;
		Vector2 val2 = default(Vector2);
		if (RectTransformUtility.ScreenPointToLocalPointInRectangle(root, Vector2.op_Implicit(Input.mousePosition), (Camera)null, ref val2))
		{
			val2 += new Vector2(18f, 18f);
			Rect rect = root.rect;
			float num = ((Rect)(ref rect)).width * 0.5f - val.sizeDelta.x;
			rect = root.rect;
			float num2 = ((Rect)(ref rect)).height * 0.5f - val.sizeDelta.y;
			val2.x = Mathf.Min(val2.x, num);
			val2.y = Mathf.Min(val2.y, num2);
			Vector2 val3 = val2;
			rect = root.rect;
			val.anchoredPosition = val3 + ((Rect)(ref rect)).size * 0.5f;
		}
	}
}
internal static class Frost
{
	public static readonly Color Panel = new Color(0.09f, 0.14f, 0.22f, 0.96f);

	public static readonly Color Control = new Color(0.17f, 0.25f, 0.37f, 1f);

	public static void Apply(Transform root, List<Graphic> frameBits, bool frosted, Color panel, Color control, Dictionary<Graphic, Material> mats, Dictionary<Graphic, Color> cols)
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)root == (Object)null)
		{
			return;
		}
		Graphic[] componentsInChildren = ((Component)root).GetComponentsInChildren<Graphic>(true);
		foreach (Graphic val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null))
			{
				if (!mats.ContainsKey(val))
				{
					mats[val] = val.material;
					cols[val] = val.color;
				}
				val.material = (frosted ? mats[val] : null);
				if (frosted)
				{
					val.color = cols[val];
				}
			}
		}
		if (frosted)
		{
			return;
		}
		foreach (Graphic frameBit in frameBits)
		{
			if ((Object)(object)frameBit != (Object)null)
			{
				frameBit.color = panel;
			}
		}
		Selectable[] componentsInChildren2 = ((Component)root).GetComponentsInChildren<Selectable>(true);
		for (int i = 0; i < componentsInChildren2.Length; i++)
		{
			Graphic val2 = BackgroundOf(componentsInChildren2[i]);
			if ((Object)(object)val2 != (Object)null)
			{
				val2.color = control;
			}
		}
	}

	private static Graphic BackgroundOf(Selectable s)
	{
		Slider val = (Slider)(object)((s is Slider) ? s : null);
		if ((Object)(object)val == (Object)null)
		{
			return s.targetGraphic;
		}
		Image[] componentsInChildren = ((Component)val).GetComponentsInChildren<Image>(true);
		foreach (Image val2 in componentsInChildren)
		{
			if ((!((Object)(object)val.fillRect != (Object)null) || !((Transform)((Graphic)val2).rectTransform).IsChildOf((Transform)(object)val.fillRect)) && (!((Object)(object)val.handleRect != (Object)null) || !((Transform)((Graphic)val2).rectTransform).IsChildOf((Transform)(object)val.handleRect)))
			{
				return (Graphic)(object)val2;
			}
		}
		return null;
	}
}
internal static class Hud
{
	private static Canvas _canvas;

	public static RectTransform Root
	{
		get
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			if ((Object)(object)_canvas == (Object)null)
			{
				Build();
			}
			return (RectTransform)((Component)_canvas).transform;
		}
	}

	public static float Scale
	{
		get
		{
			if ((Object)(object)_canvas == (Object)null)
			{
				Build();
			}
			if (!(_canvas.scaleFactor > 0f))
			{
				return 1f;
			}
			return _canvas.scaleFactor;
		}
	}

	private static void Build()
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("FishyUIHud", new Type[1] { typeof(RectTransform) });
		Object.DontDestroyOnLoad((Object)(object)val);
		_canvas = val.AddComponent<Canvas>();
		_canvas.renderMode = (RenderMode)0;
		_canvas.sortingOrder = 5000;
		CanvasScaler scaler = val.AddComponent<CanvasScaler>();
		CanvasScaler val2 = ((IEnumerable<CanvasScaler>)Resources.FindObjectsOfTypeAll<CanvasScaler>()).FirstOrDefault((Func<CanvasScaler, bool>)((CanvasScaler s) => (Object)(object)s != (Object)(object)scaler && (int)s.uiScaleMode == 1));
		if ((Object)(object)val2 != (Object)null)
		{
			scaler.uiScaleMode = val2.uiScaleMode;
			scaler.referenceResolution = val2.referenceResolution;
			scaler.screenMatchMode = val2.screenMatchMode;
			scaler.matchWidthOrHeight = val2.matchWidthOrHeight;
		}
		else
		{
			scaler.uiScaleMode = (ScaleMode)1;
			scaler.referenceResolution = new Vector2(1920f, 1080f);
			scaler.matchWidthOrHeight = 0.5f;
		}
		val.AddComponent<GraphicRaycaster>();
		val.AddComponent<InputGuard>();
		val.AddComponent<WindowManager>();
	}

	public static RectTransform Panel(string name, Vector2 anchor, float width, float height)
	{
		//IL_001f: 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_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: 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_0042: Unknown result type (might be due to invalid IL or missing references)
		RectTransform val = Widgets.CloneFrame((Transform)(object)Root);
		if ((Object)(object)val == (Object)null)
		{
			return null;
		}
		((Object)val).name = name;
		Vector2 anchorMin = (val.anchorMax = anchor);
		val.anchorMin = anchorMin;
		val.pivot = anchor;
		val.anchoredPosition = Vector2.zero;
		val.sizeDelta = new Vector2(width, height);
		return val;
	}
}
internal class InputGuard : MonoBehaviour
{
	internal static int Holds;

	private FieldInfo _field;

	private bool _looked;

	private bool _setIt;

	private bool _menuOpen;

	private bool _lastMenu;

	private bool _lastArranging;

	private bool _cursorSaved;

	private CursorLockMode _prevLock;

	private bool _prevVisible;

	private void Update()
	{
		_menuOpen = Injector.GameMenuOpen();
		int num = 0;
		bool arranging = HudPage.Arranging;
		if (arranging)
		{
			num++;
		}
		if (_menuOpen != _lastMenu || arranging != _lastArranging)
		{
			_lastMenu = _menuOpen;
			_lastArranging = arranging;
			foreach (HudElement item in HudElement.All)
			{
				item.Apply();
			}
		}
		foreach (HudElement item2 in HudElement.All)
		{
			item2.Tick();
		}
		HudPage.Tick();
		foreach (Window item3 in Window.All)
		{
			if (!((Object)(object)item3.Root == (Object)null))
			{
				bool flag = item3.WantsVisible && (!_menuOpen || item3.OpenInMenus);
				if (item3.Root.activeSelf != flag)
				{
					item3.Root.SetActive(flag);
				}
				if (flag)
				{
					num++;
				}
			}
		}
		Holds = num;
		bool flag2 = false;
		GameObject val = (((Object)(object)EventSystem.current != (Object)null) ? EventSystem.current.currentSelectedGameObject : null);
		if ((Object)(object)val != (Object)null && val.transform.IsChildOf(((Component)this).transform))
		{
			TMP_InputField component = val.GetComponent<TMP_InputField>();
			flag2 = (Object)(object)component != (Object)null && component.isFocused;
			if (flag2 && (Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)) && Input.GetKeyDown((KeyCode)97))
			{
				Widgets.SelectAll(val.GetComponent<TMP_InputField>());
			}
		}
		SetTypingFlag(flag2 || Holds > 0);
		PadSeed(val);
	}

	private void PadSeed(GameObject selected)
	{
		if (Holds == 0 || (Object)(object)selected != (Object)null || (Object)(object)EventSystem.current == (Object)null || (!(Mathf.Abs(Input.GetAxisRaw("Vertical")) > 0.4f) && !(Mathf.Abs(Input.GetAxisRaw("Horizontal")) > 0.4f)))
		{
			return;
		}
		foreach (Window item in Window.All)
		{
			if (!((Object)(object)item.Root == (Object)null) && item.Root.activeInHierarchy)
			{
				Selectable componentInChildren = item.Root.GetComponentInChildren<Selectable>();
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					EventSystem.current.SetSelectedGameObject(((Component)componentInChildren).gameObject);
					break;
				}
			}
		}
	}

	private void LateUpdate()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		if (Holds > 0)
		{
			if (!_cursorSaved)
			{
				_cursorSaved = true;
				_prevLock = Cursor.lockState;
				_prevVisible = Cursor.visible;
			}
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
		}
		else if (_cursorSaved)
		{
			_cursorSaved = false;
			if (!_menuOpen)
			{
				Cursor.lockState = _prevLock;
				Cursor.visible = _prevVisible;
			}
		}
	}

	private static FieldInfo FindTypingField()
	{
		FieldInfo fieldInfo = AccessTools.Field(typeof(ChatManager), "<IsTyping>k__BackingField");
		if (fieldInfo != null)
		{
			return fieldInfo;
		}
		foreach (FieldInfo declaredField in AccessTools.GetDeclaredFields(typeof(ChatManager)))
		{
			if (declaredField.FieldType == typeof(bool) && declaredField.Name.IndexOf("typing", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return declaredField;
			}
		}
		return null;
	}

	private void SetTypingFlag(bool on)
	{
		if (on == _setIt)
		{
			return;
		}
		if (!_looked)
		{
			_looked = true;
			_field = FindTypingField();
			if (_field == null)
			{
				Plugin.Log.LogWarning((object)"chat typing flag not found, keys may leak into the game");
			}
		}
		if (_field == null)
		{
			return;
		}
		try
		{
			object obj = null;
			if (!_field.IsStatic)
			{
				obj = Resources.FindObjectsOfTypeAll<ChatManager>().FirstOrDefault();
				if (obj == null)
				{
					return;
				}
			}
			_field.SetValue(obj, on);
			_setIt = on;
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("chat typing flag failed: " + ex.Message));
			_field = null;
		}
	}
}
internal enum Corner
{
	TopLeft,
	Top,
	TopRight,
	Left,
	Middle,
	Right,
	BottomLeft,
	Bottom,
	BottomRight
}
internal class HudElement
{
	internal static readonly List<HudElement> All = new List<HudElement>();

	public GameObject Root;

	public RectTransform Body;

	public string Id;

	public string Title;

	public bool AutoHeight = true;

	internal Corner Where;

	internal Vector2 Offset;

	internal float Size = 1f;

	internal float Fade = 1f;

	internal bool On = true;

	internal bool Framed = true;

	public bool ShowInMenus;

	private RectTransform _rt;

	private CanvasGroup _group;

	private RowBuilder _rows;

	private Page _page;

	private int _builtVersion = -1;

	private readonly List<Graphic> _frameBits = new List<Graphic>();

	private readonly Dictionary<Graphic, Material> _mats = new Dictionary<Graphic, Material>();

	private readonly Dictionary<Graphic, Color> _cols = new Dictionary<Graphic, Color>();

	private bool _frosted = true;

	private Color _panelColour = Frost.Panel;

	private Color _controlColour = Frost.Control;

	public bool Visible => On;

	public bool ShowFrame
	{
		get
		{
			return Framed;
		}
		set
		{
			Framed = value;
			Apply();
		}
	}

	public bool Frosted
	{
		get
		{
			return _frosted;
		}
		set
		{
			_frosted = value;
			ApplyFrost();
		}
	}

	public Color PanelColour
	{
		get
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return _panelColour;
		}
		set
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			_panelColour = value;
			ApplyFrost();
		}
	}

	public Color ControlColour
	{
		get
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return _controlColour;
		}
		set
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			_controlColour = value;
			ApplyFrost();
		}
	}

	public static HudElement Create(string id, string title, float width, float height, Corner corner = Corner.TopLeft)
	{
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//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_011c: 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)
		if (Injector.W == null)
		{
			Plugin.Log.LogWarning((object)"FishyUI.HudElement before any menu existed, try again once the game has shown one");
			return null;
		}
		RectTransform val = Widgets.CloneFrame((Transform)(object)Hud.Root);
		if ((Object)(object)val == (Object)null)
		{
			return null;
		}
		HudElement hudElement = new HudElement();
		hudElement.Id = (string.IsNullOrEmpty(id) ? title : id);
		hudElement.Title = (string.IsNullOrEmpty(title) ? hudElement.Id : title);
		hudElement.Root = ((Component)val).gameObject;
		hudElement._rt = val;
		hudElement.Where = corner;
		((Object)val).name = "Hud_" + hudElement.Id;
		val.sizeDelta = new Vector2(width, height);
		Graphic[] componentsInChildren = ((Component)val).GetComponentsInChildren<Graphic>(true);
		foreach (Graphic item in componentsInChildren)
		{
			hudElement._frameBits.Add(item);
		}
		hudElement._group = ((Component)val).gameObject.AddComponent<CanvasGroup>();
		hudElement._group.blocksRaycasts = false;
		((Component)val).gameObject.AddComponent<HudDrag>().Owner = hudElement;
		hudElement.Body = Widgets.Area((Transform)(object)val, "Body", Vector2.zero, Vector2.one);
		hudElement.Body.offsetMin = new Vector2(12f, 12f);
		hudElement.Body.offsetMax = new Vector2(-12f, -12f);
		All.Add(hudElement);
		HudStore.Restore(hudElement);
		HudPage.Register(hudElement);
		hudElement.Apply();
		return hudElement;
	}

	public Page Rows()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		if (_page == null)
		{
			_page = new Page(Title);
			RectTransform viewport = Widgets.Area((Transform)(object)Body, "Rows", Vector2.zero, Vector2.one);
			_rows = new RowBuilder(Injector.W, viewport, null);
			_rows.Page = _page;
		}
		return _page;
	}

	internal void Tick()
	{
		if (_rows != null && _page != null && _page.Version != _builtVersion)
		{
			_builtVersion = _page.Version;
			Refresh();
		}
	}

	public void Refresh()
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		if (_rows != null)
		{
			_rows.Build();
			ApplyFrost();
			if (AutoHeight && (Object)(object)_rt != (Object)null)
			{
				_rt.sizeDelta = new Vector2(_rt.sizeDelta.x, _rows.ContentHeight + 24f);
			}
			Apply();
		}
	}

	public void Destroy()
	{
		All.Remove(this);
		if ((Object)(object)Root != (Object)null)
		{
			Object.Destroy((Object)(object)Root);
		}
		Root = null;
		_rt = null;
	}

	public void Show()
	{
		On = true;
		Apply();
		HudStore.Remember(this);
	}

	public void Hide()
	{
		On = false;
		Apply();
		HudStore.Remember(this);
	}

	internal void ApplyFrost()
	{
		//IL_0038: 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 (!_frosted || _mats.Count != 0)
		{
			Frost.Apply((Transform)(object)_rt, Framed ? _frameBits : new List<Graphic>(), _frosted, _panelColour, _controlColour, _mats, _cols);
		}
	}

	internal void Apply()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_rt == (Object)null)
		{
			return;
		}
		Vector2 val = AnchorOf(Where);
		RectTransform rt = _rt;
		Vector2 anchorMin = (_rt.anchorMax = val);
		rt.anchorMin = anchorMin;
		_rt.pivot = val;
		_rt.anchoredPosition = Offset;
		((Transform)_rt).localScale = Vector3.one * Mathf.Clamp(Size, 0.4f, 3f);
		bool arranging = HudPage.Arranging;
		if ((Object)(object)_group != (Object)null)
		{
			_group.alpha = Mathf.Clamp(Fade, 0.1f, 1f);
			_group.blocksRaycasts = arranging;
		}
		foreach (Graphic frameBit in _frameBits)
		{
			if ((Object)(object)frameBit != (Object)null)
			{
				((Behaviour)frameBit).enabled = Framed || arranging;
			}
		}
		if ((Object)(object)Root != (Object)null)
		{
			Root.SetActive(On && (ShowInMenus || !Injector.GameMenuOpen()));
		}
		ClampToScreen();
	}

	internal void Drag(Vector2 delta)
	{
		//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_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)
		Offset += delta;
		ClampToScreen();
	}

	private void ClampToScreen()
	{
		//IL_001b: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: 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_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: 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)
		//IL_00a9: 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_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_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: 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_0121: 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_013a: 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_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_rt == (Object)null))
		{
			RectTransform root = Hud.Root;
			Vector2 val = AnchorOf(Where);
			Vector2 val2 = _rt.sizeDelta * Mathf.Clamp(Size, 0.4f, 3f);
			float num = val.x - 0.5f;
			Rect rect = root.rect;
			float num2 = num * ((Rect)(ref rect)).width;
			float num3 = val.y - 0.5f;
			rect = root.rect;
			float num4 = num3 * ((Rect)(ref rect)).height;
			float num5 = num2 + Offset.x - val2.x * val.x;
			float num6 = num4 + Offset.y - val2.y * val.y;
			rect = root.rect;
			float num7 = (0f - ((Rect)(ref rect)).width) * 0.5f;
			rect = root.rect;
			float num8 = (0f - ((Rect)(ref rect)).height) * 0.5f;
			Vector2 offset = Offset;
			rect = root.rect;
			float num9 = Mathf.Clamp(num5, num7, num7 + ((Rect)(ref rect)).width - val2.x) - num5;
			rect = root.rect;
			Offset = offset + new Vector2(num9, Mathf.Clamp(num6, num8, num8 + ((Rect)(ref rect)).height - val2.y) - num6);
			_rt.anchoredPosition = Offset;
		}
	}

	internal void ResetPlace()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		Offset = Vector2.zero;
		Size = 1f;
		Fade = 1f;
		Apply();
		HudStore.Remember(this);
	}

	internal static Vector2 AnchorOf(Corner c)
	{
		//IL_0037: 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_0057: 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_0077: 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_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		return (Vector2)(c switch
		{
			Corner.Top => new Vector2(0.5f, 1f), 
			Corner.TopRight => new Vector2(1f, 1f), 
			Corner.Left => new Vector2(0f, 0.5f), 
			Corner.Middle => new Vector2(0.5f, 0.5f), 
			Corner.Right => new Vector2(1f, 0.5f), 
			Corner.BottomLeft => new Vector2(0f, 0f), 
			Corner.Bottom => new Vector2(0.5f, 0f), 
			Corner.BottomRight => new Vector2(1f, 0f), 
			_ => new Vector2(0f, 1f), 
		});
	}
}
internal class HudDrag : MonoBehaviour, IDragHandler, IEventSystemHandler, IEndDragHandler, IPointerDownHandler
{
	public HudElement Owner;

	public void OnPointerDown(PointerEventData e)
	{
		if (HudPage.Arranging)
		{
			HudPage.Last = Owner;
		}
	}

	public void OnDrag(PointerEventData e)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		if (Owner != null && HudPage.Arranging)
		{
			HudPage.Last = Owner;
			Owner.Drag(e.delta / Hud.Scale);
		}
	}

	public void OnEndDrag(PointerEventData e)
	{
		HudStore.Remember(Owner);
	}
}
internal static class HudPage
{
	public static bool Arranging;

	public static HudElement Last;

	private static Page _page;

	private static readonly string[] CornerNames = new string[9] { "Top left", "Top", "Top right", "Left", "Middle", "Right", "Bottom left", "Bottom", "Bottom right" };

	public static void Tick()
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: 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)
		if (Arranging && Last != null)
		{
			float num = ((Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)) ? 10f : 1f);
			Vector2 val = default(Vector2);
			if (Input.GetKey((KeyCode)276))
			{
				val.x -= num;
			}
			if (Input.GetKey((KeyCode)275))
			{
				val.x += num;
			}
			if (Input.GetKey((KeyCode)273))
			{
				val.y += num;
			}
			if (Input.GetKey((KeyCode)274))
			{
				val.y -= num;
			}
			if (!(val == Vector2.zero))
			{
				Last.Drag(val);
				HudStore.Remember(Last);
			}
		}
	}

	public static void Register(HudElement el)
	{
		if (_page == null)
		{
			_page = Options.Page("HUD");
			_page.Header("Arranging").Toggle("Move hud pieces", value: false, delegate(bool on)
			{
				Arranging = on;
				foreach (HudElement item in HudElement.All)
				{
					item.Apply();
				}
				if (on)
				{
					Toast.Show("Leave the menu, then drag. arrow keys nudge");
				}
			}).Label("turn this on, close the menu, then drag. arrows nudge, shift is faster");
		}
		_page.Header(el.Title).Toggle("Show", el.On, delegate(bool v)
		{
			el.On = v;
			el.Apply();
			HudStore.Remember(el);
		}).Slider("Size", el.Size, 0.5f, 2f, delegate(float v)
		{
			el.Size = v;
			el.Apply();
			HudStore.Remember(el);
		})
			.Slider("Fade", el.Fade, 0.2f, 1f, delegate(float v)
			{
				el.Fade = v;
				el.Apply();
				HudStore.Remember(el);
			})
			.Dropdown("Corner", CornerNames, (int)el.Where, delegate(int i)
			{
				//IL_0012: 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)
				el.Where = (Corner)i;
				el.Offset = Vector2.zero;
				el.Apply();
				HudStore.Remember(el);
			})
			.Button("Put it back", el.ResetPlace);
	}
}
internal static class HudStore
{
	private static readonly Dictionary<string, string> Lines = new Dictionary<string, string>();

	private static bool _loaded;

	private static bool _dirty;

	private static string FilePath => Path.Combine(Paths.ConfigPath, "fishyui.hud.cfg");

	private static void Load()
	{
		if (_loaded)
		{
			return;
		}
		_loaded = true;
		try
		{
			if (!File.Exists(FilePath))
			{
				return;
			}
			string[] array = File.ReadAllLines(FilePath);
			foreach (string text in array)
			{
				int num = text.IndexOf('=');
				if (num > 0)
				{
					Lines[text.Substring(0, num).Trim()] = text.Substring(num + 1).Trim();
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("could not read saved hud spots: " + ex.Message));
		}
	}

	public static void Restore(HudElement el)
	{
		//IL_00aa: 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)
		if (el == null)
		{
			return;
		}
		Load();
		if (!Lines.TryGetValue(el.Id, out var value))
		{
			return;
		}
		string[] array = value.Split(new char[1] { ',' });
		if (array.Length >= 6 && int.TryParse(array[0], out var result))
		{
			float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2);
			float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3);
			float.TryParse(array[3], NumberStyles.Float, CultureInfo.InvariantCulture, out var result4);
			float.TryParse(array[4], NumberStyles.Float, CultureInfo.InvariantCulture, out var result5);
			el.Where = (Corner)Mathf.Clamp(result, 0, 8);
			el.Offset = new Vector2(result2, result3);
			if (result4 > 0.1f)
			{
				el.Size = result4;
			}
			if (result5 > 0.05f)
			{
				el.Fade = result5;
			}
			el.On = array[5] != "0";
		}
	}

	public static void Remember(HudElement el)
	{
		if (el != null)
		{
			Load();
			Lines[el.Id] = string.Format(CultureInfo.InvariantCulture, "{0},{1:0},{2:0},{3:0.##},{4:0.##},{5}", (int)el.Where, el.Offset.x, el.Offset.y, el.Size, el.Fade, el.On ? "1" : "0");
			_dirty = true;
		}
	}

	public static void Save()
	{
		if (!_dirty)
		{
			return;
		}
		_dirty = false;
		try
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (KeyValuePair<string, string> line in Lines)
			{
				stringBuilder.AppendLine(line.Key + " = " + line.Value);
			}
			File.WriteAllText(FilePath, stringBuilder.ToString());
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("could not save hud spots: " + ex.Message));
		}
	}
}
internal static class Injector
{
	private class RowFit
	{
		public List<RectTransform> Order;

		public float Left;

		public float Width;

		public float Gap;
	}

	private static PauseManager _pm;

	private static GameObject _screen;

	private static GameObject _modsButton;

	private static RectTransform _frame;

	private static Transform _tabRow;

	private static PanelHost _panel;

	internal static Widgets W;

	private static readonly List<GameObject> ContentPanels = new List<GameObject>();

	private static readonly HashSet<Button> HookedButtons = new HashSet<Button>();

	private static bool _flagsGone;

	internal static Transform PanelRoot
	{
		get
		{
			if (!((Object)(object)_panel != (Object)null))
			{
				return null;
			}
			return ((Component)_panel).transform;
		}
	}

	public static void TryInject(PauseManager pm)
	{
		_pm = pm;
		try
		{
			Inject(pm);
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("options inject failed: " + ex));
		}
	}

	public static void OnRegistryChanged()
	{
		if ((Object)(object)_pm == (Object)null || (Object)(object)_modsButton != (Object)null || Registry.Count == 0)
		{
			return;
		}
		try
		{
			Inject(_pm);
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("late options inject failed: " + ex));
		}
	}

	private static void Inject(PauseManager pm)
	{
		//IL_0429: Unknown result type (might be due to invalid IL or missing references)
		//IL_0433: Expected O, but got Unknown
		//IL_00ac: 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_04a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ae: Expected O, but got Unknown
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Refl.Get<GameObject>(pm, typeof(PauseManager), "_optionsScreen");
		if ((Object)(object)val == (Object)null)
		{
			Plugin.Log.LogWarning((object)"PauseManager._optionsScreen is null");
		}
		else
		{
			if ((Object)(object)val == (Object)(object)_screen && (Object)(object)_modsButton != (Object)null)
			{
				return;
			}
			_screen = val;
			_modsButton = null;
			_panel = null;
			ContentPanels.Clear();
			HookedButtons.Clear();
			Canvas.ForceUpdateCanvases();
			Transform val2 = null;
			int num = 0;
			float num2 = float.MinValue;
			Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>(true);
			foreach (Transform val3 in componentsInChildren)
			{
				int num3 = 0;
				foreach (Transform item in val3)
				{
					Button component = ((Component)item).GetComponent<Button>();
					if ((Object)(object)component != (Object)null && SwitchTargets(component, val.transform, val3).Count > 0)
					{
						num3++;
					}
				}
				if (num3 >= 2)
				{
					float y = val3.position.y;
					if (num3 > num || (num3 == num && y > num2))
					{
						num = num3;
						num2 = y;
						val2 = val3;
					}
				}
			}
			if ((Object)(object)val2 == (Object)null)
			{
				Plugin.Log.LogWarning((object)"no tab row found in options screen");
				return;
			}
			_tabRow = val2;
			List<Button> list = new List<Button>();
			foreach (Transform item2 in val2)
			{
				Button component2 = ((Component)item2).GetComponent<Button>();
				if ((Object)(object)component2 != (Object)null)
				{
					list.Add(component2);
				}
			}
			Button val4 = null;
			foreach (Button item3 in list)
			{
				List<GameObject> list2 = SwitchTargets(item3, val.transform, val2);
				if (list2.Count == 0)
				{
					continue;
				}
				val4 = item3;
				foreach (GameObject item4 in list2)
				{
					if (!ContentPanels.Contains(item4))
					{
						ContentPanels.Add(item4);
					}
				}
			}
			if (ContentPanels.Count == 0)
			{
				Plugin.Log.LogWarning((object)"no content panels discovered");
				return;
			}
			Button val5 = (((Object)(object)val4 != (Object)null) ? val4 : list[list.Count - 1]);
			RectTransform val6 = null;
			float num4 = 0f;
			foreach (GameObject contentPanel in ContentPanels)
			{
				Transform transform = contentPanel.transform;
				RectTransform val7 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if (!((Object)(object)val7 == (Object)null))
				{
					Rect rect = val7.rect;
					float width = ((Rect)(ref rect)).width;
					rect = val7.rect;
					float num5 = width * ((Rect)(ref rect)).height;
					if (num5 > num4)
					{
						num4 = num5;
						val6 = val7;
					}
				}
			}
			if ((Object)(object)val6 == (Object)null)
			{
				Plugin.Log.LogWarning((object)"no content frame found");
				return;
			}
			_frame = val6;
			try
			{
				W = Widgets.Harvest(val5, val);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("widget donors missing: " + ex.Message));
				W = null;
			}
			try
			{
				Widgets.StockFrame(val6);
			}
			catch (Exception ex2)
			{
				Plugin.Log.LogWarning((object)("frame donor missing: " + ex2.Message));
			}
			Place.Rebuild();
			if (Registry.Count == 0 || W == null)
			{
				return;
			}
			Placement placement = Plugin.PlacementCfg.Value;
			GameObject val8 = null;
			GameObject holder = null;
			RowFit fit = null;
			if (placement == Placement.Tabs)
			{
				try
				{
					val8 = MakeTab(val2, list, val5, out fit);
				}
				catch (Exception ex3)
				{
					Plugin.Log.LogWarning((object)("could not add a tab, using the screen edge: " + ex3.Message));
					val8 = null;
					fit = null;
				}
				if ((Object)(object)val8 == (Object)null)
				{
					placement = Placement.RightEdge;
				}
			}
			if ((Object)(object)val8 == (Object)null)
			{
				val8 = MakeEdgeButton(val, val6, val5, placement == Placement.LeftEdge, out holder);
			}
			Button component3 = val8.GetComponent<Button>();
			Widgets.KillPersistent((UnityEventBase)(object)component3.onClick);
			((UnityEvent)component3.onClick).AddListener(new UnityAction(OnModsClicked));
			GameObject val9 = Object.Instantiate<GameObject>(((Component)val6).gameObject, ((Transform)val6).parent);
			((Object)val9).name = "ModsPanel";
			val9.SetActive(false);
			Widgets.StripLocalization(val9);
			LayoutGroup[] components = val9.GetComponents<LayoutGroup>();
			for (int i = 0; i < components.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)components[i]);
			}
			List<GameObject> list3 = new List<GameObject>();
			foreach (Transform item5 in val9.transform)
			{
				Transform val10 = item5;
				if ((Object)(object)((Component)val10).GetComponentInChildren<TMP_Text>(true) != (Object)null || (Object)(object)((Component)val10).GetComponentInChildren<Selectable>(true) != (Object)null)
				{
					list3.Add(((Component)val10).gameObject);
				}
			}
			foreach (GameObject item6 in list3)
			{
				Object.DestroyImmediate((Object)(object)item6);
			}
			try
			{
				_panel = val9.AddComponent<PanelHost>();
				_panel.Init(W);
			}
			catch (Exception ex4)
			{
				Plugin.Log.LogWarning((object)("panel build failed, removing the Mods entry: " + ex4));
				Object.Destroy((Object)(object)val9);
				Object.Destroy((Object)(object)val8);
				if ((Object)(object)holder != (Object)null)
				{
					Object.Destroy((Object)(object)holder);
				}
				_panel = null;
				return;
			}
			if (fit != null)
			{
				FitRow(val2, fit);
			}
			_modsButton = val8;
			Plugin.Log.LogInfo((object)$"Mods entry added ({Registry.Count} page(s) registered)");
		}
	}

	private static GameObject MakeTab(Transform tabRow, List<Button> tabs, Button template, out RowFit fit)
	{
		//IL_0029: 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_0042: 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_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: 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_0065: 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_0146: Expected O, but got Unknown
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Expected O, but got Unknown
		Vector3[] array = (Vector3[])(object)new Vector3[4];
		float num = float.MaxValue;
		float num2 = float.MinValue;
		foreach (Button tab in tabs)
		{
			((RectTransform)((Component)tab).transform).GetWorldCorners(array);
			for (int i = 0; i < 4; i++)
			{
				Vector3 val = tabRow.InverseTransformPoint(array[i]);
				if (val.x < num)
				{
					num = val.x;
				}
				if (val.x > num2)
				{
					num2 = val.x;
				}
			}
		}
		float num3 = num2 - num;
		if (num3 < 100f)
		{
			throw new Exception("tab row span looks wrong: " + num3);
		}
		GameObject val2 = Object.Instantiate<GameObject>(((Component)template).gameObject, tabRow);
		((Object)val2).name = "ModsTab";
		Widgets.StripLocalization(val2);
		TMP_Text componentInChildren = val2.GetComponentInChildren<TMP_Text>(true);
		if ((Object)(object)componentInChildren != (Object)null)
		{
			componentInChildren.text = "Mods";
		}
		List<RectTransform> list = new List<RectTransform>();
		foreach (Button item in tabs.OrderBy((Button t) => ((Component)t).transform.position.x))
		{
			list.Add((RectTransform)((Component)item).transform);
		}
		list.Add((RectTransform)val2.transform);
		int count = list.Count;
		float num4 = num3 * 0.02f;
		fit = new RowFit
		{
			Order = list,
			Left = num,
			Gap = num4,
			Width = (num3 - num4 * (float)(count - 1)) / (float)count
		};
		return val2;
	}

	private static void FitRow(Transform tabRow, RowFit fit)
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: 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_005a: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < fit.Order.Count; i++)
		{
			RectTransform val = fit.Order[i];
			float num = fit.Left + fit.Width * 0.5f + (float)i * (fit.Width + fit.Gap);
			Vector3 val2 = tabRow.InverseTransformPoint(((Transform)val).position);
			((Transform)val).position = tabRow.TransformPoint(new Vector3(num, val2.y, val2.z));
			val.SetSizeWithCurrentAnchors((Axis)0, fit.Width);
			TMP_Text[] componentsInChildren = ((Component)val).GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val3 in componentsInChildren)
			{
				val3.textWrappingMode = (TextWrappingModes)0;
				if (!val3.enableAutoSizing)
				{
					val3.enableAutoSizing = true;
					val3.fontSizeMax = val3.fontSize;
					val3.fontSizeMin = val3.fontSize * 0.4f;
				}
			}
		}
	}

	private static GameObject MakeEdgeButton(GameObject screen, RectTransform frame, Button template, bool preferLeft, out GameObject holder)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Expected O, but got Unknown
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Expected O, but got Unknown
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: 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_00ef: Expected O, but got Unknown
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: 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_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: 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_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		holder = new GameObject("ModsButtonHolder", new Type[1] { typeof(RectTransform) });
		RectTransform val = (RectTransform)holder.transform;
		((Transform)val).SetParent(((Transform)frame).parent, false);
		val.anchorMin = frame.anchorMin;
		val.anchorMax = frame.anchorMax;
		val.offsetMin = frame.offsetMin;
		val.offsetMax = frame.offsetMax;
		((Transform)val).SetAsLastSibling();
		GameObject val2 = Object.Instantiate<GameObject>(((Component)template).gameObject, (Transform)(object)val);
		((Object)val2).name = "ModsButton";
		Widgets.StripLocalization(val2);
		TMP_Text componentInChildren = val2.GetComponentInChildren<TMP_Text>(true);
		if ((Object)(object)componentInChildren != (Object)null)
		{
			componentInChildren.text = "Mods";
			if (!componentInChildren.enableAutoSizing)
			{
				componentInChildren.enableAutoSizing = true;
				componentInChildren.fontSizeMax = componentInChildren.fontSize;
				componentInChildren.fontSizeMin = componentInChildren.fontSize * 0.5f;
			}
		}
		RectTransform val3 = (RectTransform)((Component)template).transform;
		RectTransform val4 = (RectTransform)val2.transform;
		Rect rect = val3.rect;
		float num = Mathf.Clamp(((Rect)(ref rect)).width, 160f, 300f);
		rect = val3.rect;
		float num2 = Mathf.Clamp(((Rect)(ref rect)).height, 50f, 110f);
		float num3 = num2 * 0.5f + 10f;
		Vector2 val5 = default(Vector2);
		((Vector2)(ref val5))..ctor(preferLeft ? 0f : 1f, 0.62f);
		val4.anchorMax = val5;
		val4.anchorMin = val5;
		val4.pivot = new Vector2(0.5f, 0.5f);
		val4.sizeDelta = new Vector2(num, num2);
		((Transform)val4).localRotation = Quaternion.Euler(0f, 0f, -90f);
		val4.anchoredPosition = new Vector2(preferLeft ? (0f - num3) : num3, 0f);
		EdgeSlot edgeSlot = val2.AddComponent<EdgeSlot>();
		edgeSlot.Frame = frame;
		edgeSlot.Root = screen.transform;
		edgeSlot.OutOffset = num3;
		edgeSlot.PreferLeft = preferLeft;
		return val2;
	}

	private static List<GameObject> SwitchTargets(Button b, Transform screen, Transform row)
	{
		List<GameObject> list = new List<GameObject>();
		UnityEvent onClick = (UnityEvent)(object)b.onClick;
		int persistentEventCount = ((UnityEventBase)onClick).GetPersistentEventCount();
		for (int i = 0; i < persistentEventCount; i++)
		{
			if (((UnityEventBase)onClick).GetPersistentMethodName(i) != "SetActive")
			{
				continue;
			}
			Object persistentTarget = ((UnityEventBase)onClick).GetPersistentTarget(i);
			GameObject val = (GameObject)(object)((persistentTarget is GameObject) ? persistentTarget : null);
			if ((Object)(object)val == (Object)null)
			{
				Component val2 = (Component)(object)((persistentTarget is Component) ? persistentTarget : null);
				if (val2 != null)
				{
					val = val2.gameObject;
				}
			}
			if (!((Object)(object)val == (Object)null) && val.transform.IsChildOf(screen) && (!((Object)(object)row != (Object)null) || !val.transform.IsChildOf(row)) && !list.Contains(val))
			{
				list.Add(val);
			}
		}
		return list;
	}

	private static void OnModsClicked()
	{
		if ((Object)(object)_panel == (Object)null)
		{
			return;
		}
		foreach (GameObject contentPanel in ContentPanels)
		{
			if ((Object)(object)contentPanel != (Object)null)
			{
				contentPanel.SetActive(false);
			}
		}
		HideOtherPanels();
		_panel.Show();
		HookOutsideButtons();
	}

	private static void HideOtherPanels()
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected O, but got Unknown
		//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_00c5: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_panel == (Object)null || (Object)(object)_frame == (Object)null)
		{
			return;
		}
		Transform parent = ((Component)_panel).transform.parent;
		if ((Object)(object)parent == (Object)null)
		{
			return;
		}
		foreach (Transform item in parent)
		{
			Transform val = item;
			if ((Object)(object)val == (Object)(object)((Component)_panel).transform || (Object)(object)val == (Object)(object)_tabRow || !((Component)val).gameObject.activeSelf || ((Object)(object)_modsButton != (Object)null && _modsButton.transform.IsChildOf(val)))
			{
				continue;
			}
			RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null);
			if ((Object)(object)val2 == (Object)null)
			{
				continue;
			}
			Rect rect = val2.rect;
			float width = ((Rect)(ref rect)).width;
			rect = _frame.rect;
			if (!(width < ((Rect)(ref rect)).width * 0.5f))
			{
				rect = val2.rect;
				float height = ((Rect)(ref rect)).height;
				rect = _frame.rect;
				if (!(height < ((Rect)(ref rect)).height * 0.5f) && !((Object)(object)((Component)val).GetComponentInChildren<Selectable>(true) == (Object)null))
				{
					((Component)val).gameObject.SetActive(false);
				}
			}
		}
	}

	private static void HookOutsideButtons()
	{
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Expected O, but got Unknown
		if ((Object)(object)_screen == (Object)null || (Object)(object)_panel == (Object)null)
		{
			return;
		}
		Button[] componentsInChildren = _screen.GetComponentsInChildren<Button>(true);
		foreach (Button val in componentsInChildren)
		{
			if (!HookedButtons.Contains(val) && !((Object)(object)((Component)val).gameObject == (Object)(object)_modsButton) && !((Component)val).transform.IsChildOf(((Component)_panel).transform))
			{
				HookedButtons.Add(val);
				((UnityEvent)val.onClick).AddListener(new UnityAction(HidePanel));
			}
		}
	}

	private static void HidePanel()
	{
		if ((Object)(object)_panel != (Object)null)
		{
			_panel.Hide();
		}
	}

	internal static GameObject ScreenOf(GameScreen which)
	{
		if ((Object)(object)_pm == (Object)null)
		{
			return null;
		}
		string text = which switch
		{
			GameScreen.ServerSettings => "_serverSettingsScreen", 
			GameScreen.Options => "_optionsScreen", 
			GameScreen.Pause => "_mainScreen", 
			_ => null, 
		};
		if (text != null)
		{
			return Refl.Get<GameObject>(_pm, typeof(PauseManager), text);
		}
		return null;
	}

	internal static bool GameMenuOpen()
	{
		try
		{
			if (GameFlags())
			{
				return true;
			}
		}
		catch (Exception ex)
		{
			if (!_flagsGone)
			{
				_flagsGone = true;
				Plugin.Log.LogWarning((object)("pause flags unavailable, watching the screen instead: " + ex.Message));
			}
		}
		if ((Object)(object)_screen != (Object)null)
		{
			return _screen.activeInHierarchy;
		}
		return false;
	}

	[MethodImpl(MethodImplOptions.NoInlining)]
	private static bool GameFlags()
	{
		if (!PauseManager.IsPaused)
		{
			return MainMenuManager.IsInMenu;
		}
		return true;
	}
}
internal class EdgeSlot : MonoBehaviour
{
	public const float Preferred = 0.62f;

	public RectTransform Frame;

	public Transform Root;

	public float OutOffset;

	public bool PreferLeft;

	private bool _done;

	private void OnEnable()
	{
		_done = false;
	}

	private void LateUpdate()
	{
		if (_done)
		{
			return;
		}
		_done = true;
		try
		{
			Place();
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("edge button placement failed: " + ex.Message));
		}
	}

	private void Place()
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: 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_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Frame == (Object)null || (Object)(object)Root == (Object)null)
		{
			return;
		}
		RectTransform val = (RectTransform)((Component)this).transform;
		Vector3[] array = (Vector3[])(object)new Vector3[4];
		Frame.GetWorldCorners(array);
		float y = array[0].y;
		float y2 = array[1].y;
		float x = array[0].x;
		float x2 = array[2].x;
		float num = y2 - y;
		if (num <= 1f)
		{
			return;
		}
		Rect rect = Frame.rect;
		float num2 = num / Mathf.Max(1f, ((Rect)(ref rect)).height);
		float num3 = val.sizeDelta.y * 0.5f * num2;
		float num4 = val.sizeDelta.x * 0.5f * num2;
		float num5 = 12f * num2;
		Vector2 val3 = default(Vector2);
		for (int i = 0; i < 2; i++)
		{
			bool flag = ((i == 0) ? PreferLeft : (!PreferLeft));
			float x3 = (flag ? (x - OutOffset * num2) : (x2 + OutOffset * num2));
			float num6 = y + 0.62f * num;
			bool flag2 = true;
			for (int j = 0; j < 30; j++)
			{
				RectTransform val2 = FirstHit(val, x3, num6, num3 + num5, num4 + num5, array);
				if ((Object)(object)val2 == (Object)null)
				{
					break;
				}
				val2.GetWorldCorners(array);
				num6 = Mathf.Min(new float[4]
				{
					array[0].y,
					array[1].y,
					array[2].y,
					array[3].y
				}) - num5 - num4;
				if (num6 - num4 < y + 0.03f * num)
				{
					flag2 = false;
					break;
				}
			}
			if (flag2)
			{
				((Vector2)(ref val3))..ctor(flag ? 0f : 1f, (num6 - y) / num);
				val.anchorMax = val3;
				val.anchorMin = val3;
				val.anchoredPosition = new Vector2(flag ? (0f - OutOffset) : OutOffset, 0f);
				if (i == 1)
				{
					Plugin.Log.LogInfo((object)"edge was crowded, Mods button moved to the other side");
				}
				return;
			}
		}
		Plugin.Log.LogWarning((object)"no room on either edge for the Mods button, leaving it at the default spot");
	}

	private RectTransform FirstHit(RectTransform self, float x, float y, float halfW, float halfH, Vector3[] c)
	{
		Transform panelRoot = Injector.PanelRoot;
		Selectable[] componentsInChildren = ((Component)Root).GetComponentsInChildren<Selectable>(false);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			Transform transform = ((Component)componentsInChildren[i]).transform;
			RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)self || ((Transform)val).IsChildOf(((Transform)self).parent) || ((Object)(object)panelRoot != (Object)null && ((Transform)val).IsChildOf(panelRoot)))
			{
				continue;
			}
			val.GetWorldCorners(c);
			float num = Mathf.Min(new float[4]
			{
				c[0].x,
				c[1].x,
				c[2].x,
				c[3].x
			});
			float num2 = Mathf.Max(new float[4]
			{
				c[0].x,
				c[1].x,
				c[2].x,
				c[3].x
			});
			if (!(x + halfW < num) && !(x - halfW > num2))
			{
				float num3 = Mathf.Min(new float[4]
				{
					c[0].y,
					c[1].y,
					c[2].y,
					c[3].y
				});
				float num4 = Mathf.Max(new float[4]
				{
					c[0].y,
					c[1].y,
					c[2].y,
					c[3].y
				});
				if (!(y + halfH < num3) && !(y - halfH > num4))
				{
					return val;
				}
			}
		}
		return null;
	}
}
internal static class Insert
{
	public static GameObject Into(Transform screen, string neighbour, bool before, string label, Action onClick)
	{
		//IL_006b: 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_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: 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_00e0: Expected O, but got Unknown
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		Button val = Find(screen, neighbour);
		if ((Object)(object)val == (Object)null)
		{
			Trouble.Note("could not find a button called '" + neighbour + "' to sit next to");
			return null;
		}
		Transform parent = ((Component)val).transform.parent;
		if ((Object)(object)parent == (Object)null)
		{
			return null;
		}
		List<RectTransform> list = Buttons(parent);
		Vector2 first = ((list.Count > 0) ? list[0].anchoredPosition : Vector2.zero);
		Vector2 last = ((list.Count > 0) ? list[list.Count - 1].anchoredPosition : Vector2.zero);
		GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, parent);
		((Object)val2).name = "Placed";
		Widgets.StripLocalization(val2);
		Button component = val2.GetComponent<Button>();
		Widgets.KillPersistent((UnityEventBase)(object)component.onClick);
		((UnityEvent)component.onClick).AddListener((UnityAction)delegate
		{
			try
			{
				if (onClick != null)
				{
					onClick();
				}
			}
			catch (Exception ex)
			{
				Trouble.Note("a button placed in a menu threw: " + ex.Message);
			}
		});
		TMP_Text[] componentsInChildren = val2.GetComponentsInChildren<TMP_Text>(true);
		foreach (TMP_Text val3 in componentsInChildren)
		{
			val3.text = Text.Say(label);
			if (!val3.enableAutoSizing)
			{
				val3.enableAutoSizing = true;
				val3.fontSizeMax = val3.fontSize;
				val3.fontSizeMin = val3.fontSize * 0.5f;
			}
		}
		int siblingIndex = ((Component)val).transform.GetSiblingIndex() + ((!before) ? 1 : 0);
		val2.transform.SetSiblingIndex(siblingIndex);
		if ((Object)(object)((Component)parent).GetComponent<LayoutGroup>() == (Object)null)
		{
			Spread(parent, first, last);
		}
		return val2;
	}

	private static Button Find(Transform screen, string label)
	{
		if (string.IsNullOrEmpty(label))
		{
			return null;
		}
		Button[] componentsInChildren = ((Component)screen).GetComponentsInChildren<Button>(true);
		foreach (Button val in componentsInChildren)
		{
			TMP_Text[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val2 in componentsInChildren2)
			{
				if (!string.IsNullOrEmpty(val2.text) && val2.text.IndexOf(label, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return val;
				}
			}
		}
		return null;
	}

	private static List<RectTransform> Buttons(Transform parent)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		List<RectTransform> list = new List<RectTransform>();
		foreach (Transform item in parent)
		{
			Transform val = item;
			if (!((Object)(object)((Component)val).GetComponent<Button>() == (Object)null))
			{
				RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null);
				if ((Object)(object)val2 != (Object)null)
				{
					list.Add(val2);
				}
			}
		}
		list.Sort(delegate(RectTransform a, RectTransform b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			int num = b.anchoredPosition.y.CompareTo(a.anchoredPosition.y);
			return (num == 0) ? a.anchoredPosition.x.CompareTo(b.anchoredPosition.x) : num;
		});
		return list;
	}

	private static void Spread(Transform parent, Vector2 first, Vector2 last)
	{
		//IL_0011: 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_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: 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_0089: 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_00c5: 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_0095: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
		List<RectTransform> list = Buttons(parent);
		if (list.Count >= 2)
		{
			bool flag = Mathf.Abs(first.y - last.y) >= Mathf.Abs(first.x - last.x);
			list.Sort((RectTransform a, RectTransform b) => ((Transform)a).GetSiblingIndex().CompareTo(((Transform)b).GetSiblingIndex()));
			for (int num = 0; num < list.Count; num++)
			{
				float num2 = ((list.Count == 1) ? 0f : ((float)num / (float)(list.Count - 1)));
				Vector2 val = Vector2.Lerp(first, last, num2);
				list[num].anchoredPosition = (flag ? new Vector2(list[num].anchoredPosition.x, val.y) : new Vector2(val.x, list[num].anchoredPosition.y));
			}
		}
	}
}
public static class Native
{
	public class Stack
	{
		private readonly Transform _parent;

		private readonly float _rowHeight;

		private readonly int _columns;

		private int _next;

		public float Gap = 4f;

		public float Height => Mathf.Ceil((float)_next / (float)_columns) * _rowHeight;

		internal Stack(Transform parent, float rowHeight, int columns)
		{
			_parent = parent;
			_rowHeight = rowHeight;
			_columns = columns;
		}

		public RectTransform Next()
		{
			//IL_0050: 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)
			//IL_005f: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0