Decompiled source of RyLib v1.0.0

BepInEx/plugins/RyLib/RyLib.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using HighlightPlus;
using HoldfastGame;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.TextCore;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace RyLib
{
	internal sealed class Driver : MonoBehaviour
	{
		internal RyLibPlugin Owner;

		internal static Driver Attach(RyLibPlugin owner)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			GameObject val = new GameObject("RyLib_Driver");
			Object.DontDestroyOnLoad((Object)(object)val);
			Driver driver = val.AddComponent<Driver>();
			driver.Owner = owner;
			return driver;
		}

		private void Update()
		{
			if (Owner != null)
			{
				Owner.Tick();
			}
		}
	}
	internal static class GameView
	{
		public static Camera ActiveCamera
		{
			get
			{
				ClientComponentReferenceManager clientInstance = ClientComponentReferenceManager.ClientInstance;
				if ((Object)(object)clientInstance != (Object)null && (Object)(object)clientInstance.ownerCameraManager != (Object)null)
				{
					Camera val = clientInstance.ownerCameraManager.ActiveCamera;
					if ((Object)(object)val == (Object)null)
					{
						val = clientInstance.ownerCameraManager.ownerCamera;
					}
					if ((Object)(object)val != (Object)null)
					{
						return val;
					}
				}
				return Camera.main;
			}
		}
	}
	internal static class Log
	{
		private static readonly ManualLogSource Source = Logger.CreateLogSource("RyLib");

		public static void Info(string message)
		{
			Source.LogInfo((object)message);
		}

		public static void Warn(string message)
		{
			Source.LogWarning((object)message);
		}

		public static void Error(string message)
		{
			Source.LogError((object)message);
		}
	}
	internal static class Owners
	{
		public static bool Valid(string owner, string call)
		{
			if (!string.IsNullOrEmpty(owner))
			{
				return true;
			}
			Log.Warn(call + " was called without an owner GUID, so it was ignored. Pass your plugin's GUID.");
			return false;
		}

		public static bool Same(string left, string right)
		{
			return string.Equals(left, right, StringComparison.OrdinalIgnoreCase);
		}

		public static void Run(string owner, string what, Action action)
		{
			try
			{
				action();
			}
			catch (Exception ex)
			{
				Log.Error(owner + ": " + what + " threw " + ex.GetType().Name + ": " + ex.Message);
			}
		}

		public static string Say(string owner, string what, Func<string> text, string fallback)
		{
			if (text == null)
			{
				return fallback;
			}
			try
			{
				return text() ?? fallback;
			}
			catch (Exception ex)
			{
				Log.Error(owner + ": " + what + " threw " + ex.GetType().Name + ": " + ex.Message);
				return fallback;
			}
		}

		public static bool Ask(string owner, string what, Func<bool> question, bool fallback)
		{
			if (question == null)
			{
				return fallback;
			}
			try
			{
				return question();
			}
			catch (Exception ex)
			{
				Log.Error(owner + ": " + what + " threw " + ex.GetType().Name + ": " + ex.Message);
				return fallback;
			}
		}
	}
	[BepInPlugin("com.ryannlt.rylib", "RyLib", "1.0.0")]
	public class RyLibPlugin : BaseUnityPlugin
	{
		public const string Guid = "com.ryannlt.rylib";

		private Driver _driver;

		private void Awake()
		{
			GlowStyle.Bind(((BaseUnityPlugin)this).Config);
			MapStyle.Bind(((BaseUnityPlugin)this).Config);
			SceneManager.sceneLoaded += OnSceneLoaded;
			EnsureDriver();
			try
			{
				Harmony.CreateAndPatchAll(typeof(RyLibPlugin).Assembly, "com.ryannlt.rylib");
			}
			catch (Exception ex)
			{
				Log.Error("patches could not be applied: " + ex.Message);
			}
			Log.Info("Ready.");
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			EnsureDriver();
		}

		private void EnsureDriver()
		{
			if (!((Object)(object)_driver != (Object)null))
			{
				_driver = Driver.Attach(this);
			}
		}

		internal void Tick()
		{
			GlowStyle.Poll();
			Menu.Tick();
			PlayerRow.Tick();
			World.Tick();
			Minimap.Tick();
			MapView.TickAll();
			KeyHints.Tick();
		}
	}
	internal sealed class ControlSpec
	{
		public string Owner;

		public string Key;

		public string Icon;

		public Func<string> Text;

		public Func<bool> IsOn;

		public Action Click;

		public Action RightClick;
	}
	internal sealed class RightClickRelay : MonoBehaviour, IPointerClickHandler, IEventSystemHandler
	{
		internal Action Clicked;

		public void OnPointerClick(PointerEventData eventData)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			if ((int)eventData.button == 1 && Clicked != null)
			{
				Clicked();
			}
		}
	}
	internal sealed class Control
	{
		public ControlSpec Spec;

		public GameObject Root;

		public TMP_Text Label;

		public Image Icon;
	}
	internal static class Controls
	{
		private static readonly List<Control> Live = new List<Control>();

		private static Color _labelOn = new Color(1f, 1f, 1f, 0.588f);

		private static Color _labelOff = new Color(0.855f, 0.753f, 0.612f, 1f);

		private static Color _iconOn = new Color(1f, 1f, 1f, 0.588f);

		private static Color _iconOff = new Color(0.859f, 0f, 0f, 1f);

		public static void SetPalette(UIRoundPlayersControlPanel players)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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)
			if (!((Object)(object)players == (Object)null))
			{
				_labelOn = players.enabledOptionColor;
				_labelOff = players.disabledOptionColor;
				_iconOn = players.voipUnmutedColor;
				_iconOff = players.voipMutedColor;
			}
		}

		public static ControlSpec Toggle(string owner, string label, ConfigEntry<bool> entry, string icon)
		{
			ControlSpec controlSpec = new ControlSpec();
			controlSpec.Owner = owner;
			controlSpec.Key = label;
			controlSpec.Icon = icon;
			controlSpec.Text = () => label + (entry.Value ? " On" : " Off");
			controlSpec.IsOn = () => entry.Value;
			controlSpec.Click = delegate
			{
				entry.Value = !entry.Value;
			};
			return controlSpec;
		}

		public static ControlSpec Cycle<T>(string owner, string label, ConfigEntry<T> entry, Func<T, string> text, Func<T, bool> isOn, string icon) where T : struct, Enum
		{
			Array values = Enum.GetValues(typeof(T));
			ControlSpec controlSpec = new ControlSpec();
			controlSpec.Owner = owner;
			controlSpec.Key = label;
			controlSpec.Icon = icon;
			controlSpec.Text = () => (text != null) ? text(entry.Value) : (label + " " + entry.Value);
			controlSpec.IsOn = () => isOn == null || isOn(entry.Value);
			controlSpec.Click = delegate
			{
				entry.Value = Next(values, entry.Value);
			};
			return controlSpec;
		}

		public static ControlSpec Button(string owner, string label, Action onClick, string icon)
		{
			ControlSpec controlSpec = new ControlSpec();
			controlSpec.Owner = owner;
			controlSpec.Key = label;
			controlSpec.Icon = icon;
			controlSpec.Text = () => label;
			controlSpec.IsOn = () => true;
			controlSpec.Click = onClick;
			return controlSpec;
		}

		public static ControlSpec Stepper(string owner, string label, ConfigEntry<float> entry, float step, string format, string icon)
		{
			ControlSpec controlSpec = new ControlSpec();
			controlSpec.Owner = owner;
			controlSpec.Key = label;
			controlSpec.Icon = icon;
			controlSpec.Text = () => label + "  " + entry.Value.ToString(format);
			controlSpec.IsOn = () => true;
			controlSpec.Click = delegate
			{
				Nudge(entry, step);
			};
			controlSpec.RightClick = delegate
			{
				Nudge(entry, 0f - step);
			};
			return controlSpec;
		}

		private static void Nudge(ConfigEntry<float> entry, float delta)
		{
			float num = (float)Math.Round(entry.Value + delta, 3);
			AcceptableValueBase acceptableValues = ((ConfigEntryBase)entry).Description.AcceptableValues;
			entry.Value = ((acceptableValues != null) ? ((float)acceptableValues.Clamp((object)num)) : num);
			GlowStyle.Saved();
		}

		private static T Next<T>(Array values, T current)
		{
			int num = Array.IndexOf(values, current);
			return (T)values.GetValue((num + 1) % values.Length);
		}

		public static Control Make(ControlSpec spec, Transform parent, GameObject template)
		{
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Expected O, but got Unknown
			if ((Object)(object)template == (Object)null || (Object)(object)parent == (Object)null)
			{
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(template, parent);
			((Object)val).name = "RyLib_" + spec.Owner + "_" + spec.Key;
			UiClone.Strip(val);
			Button componentInChildren = val.GetComponentInChildren<Button>(true);
			if ((Object)(object)componentInChildren == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				Log.Warn(spec.Owner + ": the control template carried no button, so '" + spec.Key + "' was skipped.");
				return null;
			}
			Control control = new Control();
			control.Spec = spec;
			control.Root = val;
			control.Label = val.GetComponentInChildren<TMP_Text>(true);
			control.Icon = FindIcon(val.transform);
			UiClone.Mute((UnityEventBase)(object)componentInChildren.onClick);
			((UnityEvent)componentInChildren.onClick).AddListener((UnityAction)delegate
			{
				Owners.Run(spec.Owner, spec.Key, spec.Click);
				Refresh(control);
			});
			if (spec.RightClick != null)
			{
				RightClickRelay rightClickRelay = ((Component)componentInChildren).gameObject.AddComponent<RightClickRelay>();
				rightClickRelay.Clicked = delegate
				{
					Owners.Run(spec.Owner, spec.Key, spec.RightClick);
					Refresh(control);
				};
			}
			if (!string.IsNullOrEmpty(spec.Icon) && (Object)(object)control.Icon != (Object)null)
			{
				Sprite val2 = Sprites.Find(spec.Icon, Menu.SpriteRoot);
				if ((Object)(object)val2 != (Object)null)
				{
					control.Icon.sprite = val2;
				}
			}
			val.SetActive(true);
			Live.Add(control);
			Refresh(control);
			return control;
		}

		public static void Refresh(Control control)
		{
			//IL_009a: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			if (control != null && !((Object)(object)control.Root == (Object)null))
			{
				ControlSpec spec = control.Spec;
				bool flag = Owners.Ask(spec.Owner, spec.Key + " state", spec.IsOn, fallback: true);
				if ((Object)(object)control.Label != (Object)null)
				{
					control.Label.text = Owners.Say(spec.Owner, spec.Key + " text", spec.Text, spec.Key);
					((Graphic)control.Label).color = (flag ? _labelOn : _labelOff);
				}
				if ((Object)(object)control.Icon != (Object)null)
				{
					((Graphic)control.Icon).color = (flag ? _iconOn : _iconOff);
				}
			}
		}

		public static void RefreshVisible()
		{
			for (int num = Live.Count - 1; num >= 0; num--)
			{
				Control control = Live[num];
				if ((Object)(object)control.Root == (Object)null)
				{
					Live.RemoveAt(num);
				}
				else if (control.Root.activeInHierarchy)
				{
					Refresh(control);
				}
			}
		}

		private static Image FindIcon(Transform root)
		{
			Transform val = root.Find("Icon");
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).GetComponent<Image>();
			}
			Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (((Object)componentsInChildren[i]).name.IndexOf("Icon", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return componentsInChildren[i];
				}
			}
			return null;
		}
	}
	public static class KeyHints
	{
		private sealed class Host
		{
			public string Name;

			public Func<GameObject> Find;

			public Func<GameObject, TMP_Text> Keys;

			public bool AtEnd;

			public GameObject Template;

			public TMP_Text KeySource;
		}

		private sealed class Copy
		{
			public GameObject Root;

			public TMP_Text Bind;

			public string Signature;
		}

		private sealed class Entry
		{
			public string Owner;

			public string Label;

			public Func<KeyCode[]> Keys;

			public Func<bool> Visible;

			public Copy[] Copies;

			public bool[] Skipped;
		}

		private const float RefreshSeconds = 0.5f;

		private const float SearchSeconds = 5f;

		private const float MaxSkew = 0.22f;

		private const float LooseGap = 40f;

		private const string Prefix = "RyLib_Hint_";

		private static readonly Regex SpriteIndex = new Regex("<sprite index=(\\d+)", RegexOptions.Compiled);

		private static readonly List<Entry> Entries = new List<Entry>();

		private static readonly List<Transform> Roots = new List<Transform>();

		private static readonly Host[] Hosts = new Host[2]
		{
			new Host
			{
				Name = "free roam",
				Find = FreeRoamTemplate,
				Keys = FirstBind
			},
			new Host
			{
				Name = "spectating",
				Find = SpectateTemplate,
				Keys = SquareBind,
				AtEnd = true
			}
		};

		private static UISpectatingPanel _spectating;

		private static GameObject _spectateEntry;

		private static float _nextSearch;

		private static float _nextRefresh;

		private static bool _warned;

		private static bool _dumped;

		public static bool Add(string owner, string label, Func<KeyCode[]> keys, Func<bool> visible = null)
		{
			if (!Owners.Valid(owner, "KeyHints.Add"))
			{
				return false;
			}
			if (string.IsNullOrEmpty(label) || keys == null)
			{
				Log.Warn(owner + ": KeyHints.Add needs a label and its keys.");
				return false;
			}
			for (int i = 0; i < Entries.Count; i++)
			{
				if (Owners.Same(Entries[i].Owner, owner) && Owners.Same(Entries[i].Label, label))
				{
					Log.Warn(owner + ": key hint '" + label + "' is already registered, so the second one was ignored.");
					return false;
				}
			}
			Entry entry = new Entry();
			entry.Owner = owner;
			entry.Label = label;
			entry.Keys = keys;
			entry.Visible = visible;
			entry.Copies = new Copy[Hosts.Length];
			entry.Skipped = new bool[Hosts.Length];
			Entries.Add(entry);
			Log.Info(owner + " added key hint '" + label + "'.");
			return true;
		}

		internal static void Tick()
		{
			if (Entries.Count == 0 || Time.unscaledTime < _nextRefresh)
			{
				return;
			}
			_nextRefresh = Time.unscaledTime + 0.5f;
			try
			{
				for (int i = 0; i < Hosts.Length; i++)
				{
					Refresh(i);
				}
			}
			catch (Exception ex)
			{
				if (!_warned)
				{
					_warned = true;
					Log.Error("key hints failed: " + ex.Message);
				}
			}
		}

		private static GameObject FreeRoamTemplate()
		{
			ClientComponentReferenceManager clientInstance = ClientComponentReferenceManager.ClientInstance;
			if ((Object)(object)clientInstance == (Object)null || (Object)(object)clientInstance.clientFreeflightCameraManager == (Object)null)
			{
				return null;
			}
			return clientInstance.clientFreeflightCameraManager.AdminRaygunHotkey;
		}

		private static GameObject SpectateTemplate()
		{
			if ((Object)(object)_spectateEntry != (Object)null)
			{
				return _spectateEntry;
			}
			if (Time.unscaledTime < _nextSearch)
			{
				return null;
			}
			_nextSearch = Time.unscaledTime + 5f;
			List<Transform> list = SpectateRoots();
			_spectateEntry = EntryFor(list, (PlayerInputAction)45);
			if ((Object)(object)_spectateEntry == (Object)null)
			{
				_spectateEntry = EntryFor(list, (PlayerInputAction)58);
			}
			if ((Object)(object)_spectateEntry == (Object)null && list.Count > 0 && !_dumped)
			{
				_dumped = true;
				Log.Warn("the spectating panel has no labelled key entry to copy, so key hints are skipped there.");
				for (int i = 0; i < list.Count; i++)
				{
					Probe.Dump(list[i], 6, "spectating panel");
				}
			}
			return _spectateEntry;
		}

		private static List<Transform> SpectateRoots()
		{
			ClientComponentReferenceManager clientInstance = ClientComponentReferenceManager.ClientInstance;
			CanvasGroup val = (((Object)(object)clientInstance == (Object)null || (Object)(object)clientInstance.clientSpectatorManager == (Object)null) ? null : clientInstance.clientSpectatorManager.SpectatePanel);
			if ((Object)(object)_spectating == (Object)null)
			{
				if ((Object)(object)val != (Object)null)
				{
					_spectating = ((Component)val).GetComponentInChildren<UISpectatingPanel>(true);
					if ((Object)(object)_spectating == (Object)null)
					{
						_spectating = ((Component)val).GetComponentInParent<UISpectatingPanel>();
					}
				}
				if ((Object)(object)_spectating == (Object)null)
				{
					_spectating = Object.FindObjectOfType<UISpectatingPanel>(true);
				}
			}
			Roots.Clear();
			if ((Object)(object)_spectating != (Object)null)
			{
				AddRoot(((Component)_spectating).transform);
				if ((Object)(object)_spectating.spectatingPanelRootTransform != (Object)null)
				{
					AddRoot((Transform)(object)_spectating.spectatingPanelRootTransform);
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				AddRoot(((Component)val).transform);
			}
			return Roots;
		}

		private static void AddRoot(Transform root)
		{
			for (int num = Roots.Count - 1; num >= 0; num--)
			{
				if (root.IsChildOf(Roots[num]))
				{
					return;
				}
				if (Roots[num].IsChildOf(root))
				{
					Roots.RemoveAt(num);
				}
			}
			Roots.Add(root);
		}

		private static GameObject EntryFor(List<Transform> roots, PlayerInputAction action)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < roots.Count; i++)
			{
				Hotkey[] componentsInChildren = ((Component)roots[i]).GetComponentsInChildren<Hotkey>(true);
				for (int j = 0; j < componentsInChildren.Length; j++)
				{
					if (Bound(componentsInChildren[j], action))
					{
						GameObject val = EntryOf(((Component)componentsInChildren[j]).transform, roots[i]);
						if ((Object)(object)val != (Object)null)
						{
							return val;
						}
					}
				}
			}
			return null;
		}

		private unsafe static bool Bound(Hotkey hotkey, PlayerInputAction action)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if ((int)hotkey.Type == 0)
			{
				return hotkey.PlayerAction == action;
			}
			return (int)hotkey.Type == 1 && !string.IsNullOrEmpty(hotkey.ActionName) && Flatten(hotkey.ActionName) == Flatten(((object)(*(PlayerInputAction*)(&action))/*cast due to .constrained prefix*/).ToString());
		}

		private static GameObject EntryOf(Transform bind, Transform root)
		{
			Transform val = bind;
			TMP_Text val2 = null;
			while ((Object)(object)val2 == (Object)null && (Object)(object)val.parent != (Object)null && (Object)(object)val.parent != (Object)(object)root)
			{
				val = val.parent;
				val2 = LabelIn(val, null, null);
			}
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			string same = val2.text.Trim();
			while ((Object)(object)val.parent != (Object)null && (Object)(object)val.parent != (Object)(object)root && (Object)(object)LabelIn(val.parent, val, same) == (Object)null)
			{
				val = val.parent;
			}
			return ((Component)val).gameObject;
		}

		private static TMP_Text LabelIn(Transform node, Transform skip, string same)
		{
			TMP_Text[] componentsInChildren = ((Component)node).GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val in componentsInChildren)
			{
				if (IsLabel(val) && (!((Object)(object)skip != (Object)null) || !val.transform.IsChildOf(skip)) && (same == null || !(val.text.Trim() == same)))
				{
					return val;
				}
			}
			return null;
		}

		private static bool IsLabel(TMP_Text text)
		{
			if ((Object)(object)text == (Object)null || text.text == null || (Object)(object)((Component)text).GetComponent<Hotkey>() != (Object)null)
			{
				return false;
			}
			return text.text.Trim().Length > 2 && text.text.IndexOf("<sprite", StringComparison.Ordinal) < 0;
		}

		private static TMP_Text SquareBind(GameObject template)
		{
			List<Transform> list = SpectateRoots();
			TMP_Text result = null;
			float num = 0.22f;
			for (int i = 0; i < list.Count; i++)
			{
				Hotkey[] componentsInChildren = ((Component)list[i]).GetComponentsInChildren<Hotkey>(true);
				for (int j = 0; j < componentsInChildren.Length; j++)
				{
					TMP_Text component = ((Component)componentsInChildren[j]).GetComponent<TMP_Text>();
					float num2 = Skew(component);
					if (!(num2 > num))
					{
						num = num2;
						result = component;
					}
				}
			}
			return result;
		}

		private static float Skew(TMP_Text text)
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)text == (Object)null || !((Component)text).gameObject.activeInHierarchy || (Object)(object)text.spriteAsset == (Object)null || string.IsNullOrEmpty(text.text))
			{
				return float.MaxValue;
			}
			MatchCollection matchCollection = SpriteIndex.Matches(text.text);
			if (matchCollection.Count != 1)
			{
				return float.MaxValue;
			}
			int num = int.Parse(matchCollection[0].Groups[1].Value);
			List<TMP_SpriteCharacter> spriteCharacterTable = text.spriteAsset.spriteCharacterTable;
			if (spriteCharacterTable == null || num >= spriteCharacterTable.Count || spriteCharacterTable[num] == null || ((TMP_TextElement)spriteCharacterTable[num]).glyph == null)
			{
				return float.MaxValue;
			}
			GlyphRect glyphRect = ((TMP_TextElement)spriteCharacterTable[num]).glyph.glyphRect;
			if (((GlyphRect)(ref glyphRect)).width <= 0 || ((GlyphRect)(ref glyphRect)).height <= 0)
			{
				return float.MaxValue;
			}
			return Mathf.Abs(Mathf.Log((float)((GlyphRect)(ref glyphRect)).width / (float)((GlyphRect)(ref glyphRect)).height));
		}

		private static void Refresh(int index)
		{
			Host host = Hosts[index];
			GameObject val = host.Find();
			if ((Object)(object)val != (Object)(object)host.Template)
			{
				host.Template = val;
				host.KeySource = null;
				for (int i = 0; i < Entries.Count; i++)
				{
					Entries[i].Copies[index] = null;
					Entries[i].Skipped[index] = false;
				}
			}
			if ((Object)(object)host.Template == (Object)null)
			{
				return;
			}
			bool flag = host.Template.activeInHierarchy && ClientRemoteConsoleAccessManager.loggedOn;
			if (flag && (Object)(object)host.KeySource == (Object)null)
			{
				host.KeySource = host.Keys(host.Template);
			}
			for (int j = 0; j < Entries.Count; j++)
			{
				Entry entry = Entries[j];
				if (entry.Skipped[index])
				{
					continue;
				}
				Copy copy = entry.Copies[index];
				if (copy == null || (Object)(object)copy.Root == (Object)null)
				{
					copy = Build(host, entry);
					entry.Copies[index] = copy;
					if (copy == null)
					{
						entry.Skipped[index] = true;
						continue;
					}
				}
				bool flag2 = flag && Owners.Ask(entry.Owner, entry.Label + " visibility", entry.Visible, fallback: true);
				if (copy.Root.activeSelf != flag2)
				{
					copy.Root.SetActive(flag2);
				}
				if (flag2)
				{
					UpdateKeys(host, entry, copy);
				}
			}
		}

		private static TMP_Text FirstBind(GameObject root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			Hotkey[] componentsInChildren = root.GetComponentsInChildren<Hotkey>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				TMP_Text component = ((Component)componentsInChildren[i]).GetComponent<TMP_Text>();
				if ((Object)(object)component != (Object)null)
				{
					return component;
				}
			}
			return null;
		}

		private static Copy Build(Host host, Entry entry)
		{
			GameObject val = Object.Instantiate<GameObject>(host.Template, host.Template.transform.parent);
			((Object)val).name = "RyLib_Hint_" + entry.Label;
			List<TMP_Text> list = new List<TMP_Text>();
			Hotkey[] componentsInChildren = val.GetComponentsInChildren<Hotkey>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				TMP_Text component = ((Component)componentsInChildren[i]).GetComponent<TMP_Text>();
				if ((Object)(object)component != (Object)null)
				{
					list.Add(component);
				}
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			UiClone.Strip(val);
			TMP_Text val2 = null;
			TMP_Text[] componentsInChildren2 = val.GetComponentsInChildren<TMP_Text>(true);
			for (int j = 0; j < componentsInChildren2.Length; j++)
			{
				if (!list.Contains(componentsInChildren2[j]) && componentsInChildren2[j].text != null && componentsInChildren2[j].text.Trim().Length > 2)
				{
					val2 = componentsInChildren2[j];
					break;
				}
			}
			TMP_Text val3 = ((list.Count > 0) ? list[0] : null);
			if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
			{
				Log.Warn("the " + host.Name + " panel's key entry has no label or key to copy, so hint '" + entry.Label + "' was skipped there.");
				Probe.Dump(host.Template.transform, 4, host.Name + " key entry");
				Object.Destroy((Object)(object)val);
				return null;
			}
			for (int k = 0; k < componentsInChildren2.Length; k++)
			{
				if ((Object)(object)componentsInChildren2[k] != (Object)(object)val2 && (Object)(object)componentsInChildren2[k] != (Object)(object)val3)
				{
					Collapse(val.transform, componentsInChildren2[k].transform, val2.transform, val3.transform);
				}
			}
			((Component)val2).gameObject.SetActive(true);
			((Component)val3).gameObject.SetActive(true);
			val2.text = entry.Label;
			Place(host, val);
			Copy copy = new Copy();
			copy.Root = val;
			copy.Bind = val3;
			val.SetActive(false);
			return copy;
		}

		private static void Place(Host host, GameObject clone)
		{
			//IL_0092: 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_0149: 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_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = clone.transform;
			Transform parent = transform.parent;
			if (host.AtEnd)
			{
				transform.SetAsLastSibling();
			}
			else
			{
				transform.SetSiblingIndex(host.Template.transform.GetSiblingIndex() + 1);
			}
			if ((Object)(object)parent == (Object)null || (Object)(object)((Component)parent).GetComponent<LayoutGroup>() != (Object)null)
			{
				return;
			}
			Transform val = null;
			Transform val2 = null;
			for (int i = 0; i < parent.childCount; i++)
			{
				Transform child = parent.GetChild(i);
				if (!((Object)(object)child == (Object)(object)transform))
				{
					if ((Object)(object)val == (Object)null || child.localPosition.x > val.localPosition.x)
					{
						val2 = val;
						val = child;
					}
					else if ((Object)(object)val2 == (Object)null || child.localPosition.x > val2.localPosition.x)
					{
						val2 = child;
					}
				}
			}
			if (!((Object)(object)val == (Object)null))
			{
				Vector3 val3 = (Vector3)(((Object)(object)val2 == (Object)null) ? new Vector3(Width(val) + 40f, 0f, 0f) : (val.localPosition - val2.localPosition));
				if (val3.x <= 0f)
				{
					((Vector3)(ref val3))..ctor(Width(val) + 40f, 0f, 0f);
				}
				transform.localPosition = val.localPosition + val3;
				Log.Info("the " + host.Name + " key bar has no layout group, so hints are placed by hand.");
				Probe.Dump(parent, 2, host.Name + " key bar");
			}
		}

		private static float Width(Transform node)
		{
			//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)
			RectTransform val = (RectTransform)(object)((node is RectTransform) ? node : null);
			float result;
			if (!((Object)(object)val == (Object)null))
			{
				Rect rect = val.rect;
				result = ((Rect)(ref rect)).width;
			}
			else
			{
				result = 0f;
			}
			return result;
		}

		private static void Collapse(Transform root, Transform node, Transform title, Transform bind)
		{
			Transform val = node;
			while ((Object)(object)val.parent != (Object)null && (Object)(object)val.parent != (Object)(object)root && !title.IsChildOf(val.parent) && !bind.IsChildOf(val.parent))
			{
				val = val.parent;
			}
			if (!title.IsChildOf(val) && !bind.IsChildOf(val))
			{
				((Component)val).gameObject.SetActive(false);
			}
		}

		private static void UpdateKeys(Host host, Entry entry, Copy copy)
		{
			KeyCode[] keys = null;
			Owners.Run(entry.Owner, entry.Label + " keys", delegate
			{
				keys = entry.Keys();
			});
			if (keys == null)
			{
				keys = (KeyCode[])(object)new KeyCode[0];
			}
			string text = (((Object)(object)host.KeySource == (Object)null) ? string.Empty : host.KeySource.text);
			string text2 = text + "|" + string.Join(",", Array.ConvertAll(keys, Name));
			if (text2 == copy.Signature)
			{
				return;
			}
			copy.Signature = text2;
			TMP_SpriteAsset val = (((Object)(object)host.KeySource == (Object)null) ? null : host.KeySource.spriteAsset);
			Match match = SpriteIndex.Match(text);
			int sourceIndex = (match.Success ? int.Parse(match.Groups[1].Value) : (-1));
			StringBuilder stringBuilder = new StringBuilder();
			bool flag = false;
			for (int num = 0; num < keys.Length; num++)
			{
				if (num > 0)
				{
					stringBuilder.Append(" / ");
				}
				string text3 = Token(val, sourceIndex, text, keys[num]);
				if (text3 == null)
				{
					stringBuilder.Append(Character(keys[num]));
					continue;
				}
				stringBuilder.Append(text3);
				flag = true;
			}
			if (flag)
			{
				copy.Bind.spriteAsset = val;
			}
			copy.Bind.text = stringBuilder.ToString();
		}

		private static string Token(TMP_SpriteAsset icons, int sourceIndex, string pattern, KeyCode key)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)icons == (Object)null || sourceIndex < 0)
			{
				return null;
			}
			int num = Glyph(icons, key);
			if (num >= 0)
			{
				return SpriteIndex.Replace(pattern, "<sprite index=" + num, 1);
			}
			string text = KeyCaps.Name(icons, sourceIndex, key);
			return (text == null) ? null : SpriteIndex.Replace(pattern, "<sprite name=\"" + text + "\"", 1);
		}

		private unsafe static int Glyph(TMP_SpriteAsset icons, KeyCode key)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			List<TMP_SpriteCharacter> spriteCharacterTable = icons.spriteCharacterTable;
			if (spriteCharacterTable == null)
			{
				return -1;
			}
			string value = Flatten(((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString());
			string text = Flatten(Character(key));
			for (int i = 0; i < spriteCharacterTable.Count; i++)
			{
				TMP_SpriteCharacter val = spriteCharacterTable[i];
				if (val != null && !string.IsNullOrEmpty(val.name))
				{
					string text2 = Flatten(val.name);
					if (text2.EndsWith(value, StringComparison.Ordinal) || text2 == text)
					{
						return i;
					}
				}
			}
			return -1;
		}

		private static string Flatten(string text)
		{
			return text.Replace(" ", string.Empty).Replace("_", string.Empty).Replace("-", string.Empty)
				.ToLowerInvariant();
		}

		private unsafe static string Name(KeyCode key)
		{
			return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString();
		}

		private unsafe static string Character(KeyCode key)
		{
			//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)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected I4, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected I4, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			KeyCode val = key;
			KeyCode val2 = val;
			if ((int)val2 <= 59)
			{
				switch (val2 - 39)
				{
				default:
					if ((int)val2 != 59)
					{
						break;
					}
					return ";";
				case 0:
					return "'";
				case 5:
					return ",";
				case 7:
					return ".";
				case 8:
					return "/";
				case 6:
					return "-";
				case 1:
				case 2:
				case 3:
				case 4:
					break;
				}
			}
			else
			{
				if ((int)val2 == 61)
				{
					return "=";
				}
				switch (val2 - 91)
				{
				case 0:
					return "[";
				case 2:
					return "]";
				case 1:
					return "\\";
				case 5:
					return "`";
				}
			}
			return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString();
		}
	}
	public static class KillLog
	{
		private sealed class Request
		{
			public string Owner;

			public Func<bool> Visible;
		}

		private static readonly List<Request> Requests = new List<Request>();

		internal static bool Requested => Requests.Count > 0;

		internal static bool ActionsOn
		{
			get
			{
				for (int i = 0; i < Requests.Count; i++)
				{
					if (Owners.Ask(Requests[i].Owner, "kill log actions visibility", Requests[i].Visible, fallback: true))
					{
						return true;
					}
				}
				return false;
			}
		}

		public static bool EnableActions(string owner, Func<bool> visible = null)
		{
			if (!Owners.Valid(owner, "KillLog.EnableActions"))
			{
				return false;
			}
			for (int i = 0; i < Requests.Count; i++)
			{
				if (Owners.Same(Requests[i].Owner, owner))
				{
					Log.Warn(owner + " already turned on the kill log actions, so the second call was ignored.");
					return false;
				}
			}
			Request request = new Request();
			request.Owner = owner;
			request.Visible = visible;
			Requests.Add(request);
			Log.Info(owner + " turned on the kill log actions.");
			return true;
		}
	}
	internal sealed class KillLogRowClick : MonoBehaviour, IPointerClickHandler, IEventSystemHandler
	{
		internal UIAdminPlayerKillLogPanelRow Row;

		public void OnPointerClick(PointerEventData eventData)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			if ((int)eventData.button != 0 || (Object)(object)Row == (Object)null)
			{
				return;
			}
			try
			{
				KillLogRows.Toggle(Row);
			}
			catch (Exception ex)
			{
				Log.Error("the kill log actions could not be opened: " + ex.Message);
			}
		}
	}
	internal static class KillLogRows
	{
		private sealed class Half
		{
			public TMP_Text Title;

			public RectTransform Grid;

			public int Buttons;
		}

		private const float ButtonWidth = 160f;

		private const float ButtonHeight = 36f;

		private const float Spacing = 6f;

		private const float Padding = 10f;

		private const float TitleHeight = 26f;

		private const float ArmSeconds = 4f;

		private const int Columns = 3;

		private static readonly Color PanelColour = new Color(0.04f, 0.05f, 0.06f, 0.94f);

		private static readonly Color Clear = new Color(0f, 0f, 0f, 0f);

		private static KillLogInfo _open;

		private static UIAdminPlayerKillLogPanel _log;

		private static GameObject _panel;

		private static LayoutElement _size;

		private static Half _killer;

		private static Half _victim;

		private static int _armedPlayer = -1;

		private static string _armedAction;

		private static float _armedUntil;

		internal static void Attach(UIAdminPlayerKillLogPanelRow row)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)row == (Object)null) && KillLog.Requested && !((Object)(object)((Component)row).GetComponent<KillLogRowClick>() != (Object)null))
			{
				if ((Object)(object)((Component)row).GetComponent<Graphic>() == (Object)null)
				{
					Image val = ((Component)row).gameObject.AddComponent<Image>();
					((Graphic)val).color = Clear;
				}
				((Component)row).gameObject.AddComponent<KillLogRowClick>().Row = row;
			}
		}

		internal static void Toggle(UIAdminPlayerKillLogPanelRow row)
		{
			if (!ClientRemoteConsoleAccessManager.loggedOn || !KillLog.ActionsOn)
			{
				return;
			}
			KillLogInfo currentInfo = row.CurrentInfo;
			if (currentInfo == null)
			{
				return;
			}
			if (_open == currentInfo && (Object)(object)_panel != (Object)null && _panel.activeSelf)
			{
				Close();
				return;
			}
			_log = ((Component)row).GetComponentInParent<UIAdminPlayerKillLogPanel>();
			_open = currentInfo;
			_armedPlayer = -1;
			if (!Ensure(row))
			{
				_open = null;
				return;
			}
			Fill(currentInfo);
			Place();
		}

		internal static void Place()
		{
			if ((Object)(object)_panel == (Object)null)
			{
				return;
			}
			UIAdminPlayerKillLogPanelRow val = ((_open == null || !KillLog.ActionsOn) ? null : FindRow(_open));
			if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeSelf)
			{
				Hide();
				return;
			}
			Transform parent = ((Component)val).transform.parent;
			if ((Object)(object)_panel.transform.parent != (Object)(object)parent)
			{
				_panel.transform.SetParent(parent, false);
			}
			int siblingIndex = ((Component)val).transform.GetSiblingIndex();
			int siblingIndex2 = _panel.transform.GetSiblingIndex();
			_panel.transform.SetSiblingIndex((siblingIndex2 < siblingIndex) ? siblingIndex : (siblingIndex + 1));
			if (!_panel.activeSelf)
			{
				_panel.SetActive(true);
			}
		}

		internal static void Close()
		{
			_open = null;
			_armedPlayer = -1;
			Hide();
		}

		private static void Hide()
		{
			if ((Object)(object)_panel != (Object)null && _panel.activeSelf)
			{
				_panel.SetActive(false);
			}
		}

		private static UIAdminPlayerKillLogPanelRow FindRow(KillLogInfo info)
		{
			if ((Object)(object)_log == (Object)null || (Object)(object)_log.rowsRootTransform == (Object)null)
			{
				return null;
			}
			Transform rowsRootTransform = _log.rowsRootTransform;
			for (int i = 0; i < rowsRootTransform.childCount; i++)
			{
				UIAdminPlayerKillLogPanelRow component = ((Component)rowsRootTransform.GetChild(i)).GetComponent<UIAdminPlayerKillLogPanelRow>();
				if ((Object)(object)component != (Object)null && component.CurrentInfo == info)
				{
					return component;
				}
			}
			return null;
		}

		private static bool Ensure(UIAdminPlayerKillLogPanelRow row)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_0083: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			if ((Object)(object)_panel != (Object)null)
			{
				return true;
			}
			if ((Object)(object)Menu.ControlTemplate == (Object)null)
			{
				return false;
			}
			GameObject val = new GameObject("RyLib_KillLogActions", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(((Component)row).transform.parent, false);
			RectTransform val2 = (RectTransform)val.transform;
			RectTransform val3 = (RectTransform)((Component)row).transform;
			val2.anchorMin = val3.anchorMin;
			val2.anchorMax = val3.anchorMax;
			val2.pivot = val3.pivot;
			val2.sizeDelta = new Vector2(val3.sizeDelta.x, val2.sizeDelta.y);
			Image val4 = val.AddComponent<Image>();
			((Graphic)val4).color = PanelColour;
			_size = val.AddComponent<LayoutElement>();
			_size.flexibleHeight = 0f;
			_size.flexibleWidth = 1f;
			HorizontalLayoutGroup val5 = val.AddComponent<HorizontalLayoutGroup>();
			((LayoutGroup)val5).padding = new RectOffset(10, 10, 10, 10);
			((HorizontalOrVerticalLayoutGroup)val5).spacing = 20f;
			((LayoutGroup)val5).childAlignment = (TextAnchor)0;
			((HorizontalOrVerticalLayoutGroup)val5).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val5).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val5).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)val5).childForceExpandHeight = true;
			_killer = BuildHalf(val2, "Killer");
			_victim = BuildHalf(val2, "Victim");
			_panel = val;
			val.SetActive(false);
			return true;
		}

		private static Half BuildHalf(RectTransform parent, string name)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent((Transform)(object)parent, false);
			VerticalLayoutGroup val2 = val.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val2).spacing = 6f;
			((LayoutGroup)val2).childAlignment = (TextAnchor)0;
			((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false;
			GameObject val3 = new GameObject("Title", new Type[1] { typeof(RectTransform) });
			val3.transform.SetParent(val.transform, false);
			TextMeshProUGUI val4 = val3.AddComponent<TextMeshProUGUI>();
			if ((Object)(object)Menu.FontAsset != (Object)null)
			{
				((TMP_Text)val4).font = Menu.FontAsset;
			}
			((TMP_Text)val4).fontSize = 18f;
			((Graphic)val4).color = Color.white;
			((TMP_Text)val4).alignment = (TextAlignmentOptions)4097;
			((TMP_Text)val4).enableWordWrapping = false;
			((TMP_Text)val4).overflowMode = (TextOverflowModes)0;
			((Graphic)val4).raycastTarget = false;
			LayoutElement val5 = val3.AddComponent<LayoutElement>();
			val5.minHeight = 26f;
			val5.preferredHeight = 26f;
			GameObject val6 = new GameObject("Actions", new Type[1] { typeof(RectTransform) });
			val6.transform.SetParent(val.transform, false);
			GridLayoutGroup val7 = val6.AddComponent<GridLayoutGroup>();
			val7.cellSize = new Vector2(160f, 36f);
			val7.spacing = new Vector2(6f, 6f);
			val7.startCorner = (Corner)0;
			val7.startAxis = (Axis)0;
			((LayoutGroup)val7).childAlignment = (TextAnchor)0;
			val7.constraint = (Constraint)1;
			val7.constraintCount = 3;
			Half half = new Half();
			half.Title = (TMP_Text)(object)val4;
			half.Grid = (RectTransform)val6.transform;
			return half;
		}

		private static void Fill(KillLogInfo info)
		{
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_00e0: 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)
			ClientRoundPlayer player = (info.KillerIsVictim ? null : info.Killer);
			SetHalf(_killer, info.KillerIsVictim ? "Killer: suicide" : ("Killer: " + Name(info.KillerName, player)), player);
			SetHalf(_victim, "Victim: " + Name(info.VictimName, info.Victim), info.Victim);
			int num = Mathf.Max(1, Mathf.CeilToInt((float)Mathf.Max(_killer.Buttons, _victim.Buttons) / 3f));
			float num2 = 52f + (float)num * 36f + (float)(num - 1) * 6f;
			_size.minHeight = num2;
			_size.preferredHeight = num2;
			RectTransform val = (RectTransform)_panel.transform;
			val.sizeDelta = new Vector2(val.sizeDelta.x, num2);
		}

		private static string Name(string shown, ClientRoundPlayer player)
		{
			if (!string.IsNullOrEmpty(shown))
			{
				return shown;
			}
			return (player == null) ? "none" : ("Player " + ((RoundPlayer)player).NetworkPlayerID);
		}

		private static void SetHalf(Half half, string title, ClientRoundPlayer player)
		{
			for (int num = ((Transform)half.Grid).childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)((Transform)half.Grid).GetChild(num)).gameObject);
			}
			half.Title.text = title;
			half.Buttons = 0;
			if (player == null)
			{
				return;
			}
			int id = ((RoundPlayer)player).NetworkPlayerID;
			Add(half, "Spectate", "hui-p-players-unspawned", delegate
			{
				PlayerActions.Spectate(id);
			});
			Add(half, "Go To", "hui-p-tab-maps", delegate
			{
				PlayerActions.GoTo(id);
			});
			Add(half, "Bring", "hui-p-tab-players", delegate
			{
				PlayerActions.Bring(id);
			});
			Confirmed(half, id, "Slay", "hui-p-slay", PlayerActions.Slay);
			Add(half, "Revive", "hui-p-revive", delegate
			{
				PlayerActions.Revive(id);
			});
			Add(half, "Heal", "hui-p-heal", delegate
			{
				PlayerActions.Heal(id);
			});
			Confirmed(half, id, "Slap", "hui-p-slap", PlayerActions.Slap);
			Confirmed(half, id, "Kick", "hui-p-kick", PlayerActions.Kick);
			for (int num2 = 0; num2 < PlayerRow.ActionCount; num2++)
			{
				if (PlayerRow.ActionVisible(num2))
				{
					int index = num2;
					Add(half, PlayerRow.ActionLabel(num2), "hui-p-tab-admin", delegate
					{
						PlayerRow.RunAction(index, id);
					}, PlayerRow.ActionOwner(num2));
				}
			}
		}

		private static void Add(Half half, string label, string icon, Action click, string owner = null)
		{
			Make(half, Controls.Button(owner ?? "com.ryannlt.rylib", label, click, icon));
		}

		private static void Confirmed(Half half, int id, string action, string icon, Action<int> run)
		{
			ControlSpec controlSpec = Controls.Button("com.ryannlt.rylib", action, delegate
			{
				if (Armed(id, action))
				{
					_armedPlayer = -1;
					run(id);
				}
				else
				{
					_armedPlayer = id;
					_armedAction = action;
					_armedUntil = Time.unscaledTime + 4f;
				}
			}, icon);
			controlSpec.Text = () => Armed(id, action) ? ("Confirm " + action) : action;
			Make(half, controlSpec);
		}

		private static bool Armed(int id, string action)
		{
			return _armedPlayer == id && _armedAction == action && Time.unscaledTime <= _armedUntil;
		}

		private static void Make(Half half, ControlSpec spec)
		{
			Control control = Controls.Make(spec, (Transform)(object)half.Grid, Menu.ControlTemplate);
			if (control != null)
			{
				half.Buttons++;
				if (!((Object)(object)control.Label == (Object)null))
				{
					control.Label.enableWordWrapping = false;
					control.Label.fontSizeMax = control.Label.fontSize;
					control.Label.fontSizeMin = 9f;
					control.Label.enableAutoSizing = true;
				}
			}
		}
	}
	[HarmonyPatch(typeof(UIAdminPlayerKillLogPanelRow), "Setup")]
	internal static class KillLogRowSetupPatch
	{
		private static void Postfix(UIAdminPlayerKillLogPanelRow __instance)
		{
			try
			{
				KillLogRows.Attach(__instance);
			}
			catch (Exception ex)
			{
				Log.Error("kill log row actions could not be attached: " + ex.Message);
			}
		}
	}
	[HarmonyPatch(typeof(UIAdminPlayerKillLogPanel), "PopulateKillLogRows")]
	internal static class KillLogPopulatePatch
	{
		private static void Postfix()
		{
			KillLogRows.Place();
		}
	}
	[HarmonyPatch(typeof(UIAdminPlayerKillLogPanel), "UpdateFilteredPlayers")]
	internal static class KillLogFilterPlacePatch
	{
		private static void Postfix()
		{
			KillLogRows.Place();
		}
	}
	[HarmonyPatch(typeof(UIAdminPlayerKillLogPanel), "_ResetObject")]
	internal static class KillLogResetClosePatch
	{
		private static void Postfix()
		{
			KillLogRows.Close();
		}
	}
	[HarmonyPatch(typeof(UIAdminPlayerKillLogPanel), "_ToggleShowing")]
	internal static class KillLogHideClosePatch
	{
		private static void Postfix(bool show)
		{
			if (!show)
			{
				KillLogRows.Close();
			}
		}
	}
	internal static class Menu
	{
		private struct Anchoring
		{
			public Vector2 Min;

			public Vector2 Max;

			public Vector2 Size;

			public Vector2 Position;
		}

		private const float RefreshSeconds = 0.25f;

		private const int FirstTabType = 100;

		private const float StripSpacing = 70f;

		private const float StripOffset = -25f;

		private const float HeaderFont = 18f;

		private const float MinHeaderFont = 12f;

		private const float HeaderPadding = 8f;

		private const float NavWidth = 240f;

		private const float NavGap = 20f;

		private const float NavButtonHeight = 48f;

		private static readonly PMenuTabType[] StockOrder;

		internal static readonly List<HeaderTab> Headers;

		private static readonly FieldRef<PMenuPanel, Dictionary<PMenuTabType, PMenuPanelTabBase>> TabsField;

		private static readonly MethodInfo SwitchTabMethod;

		private static readonly Dictionary<PMenuTabType, PMenuTabButton> StockHeaders;

		private static readonly List<HeaderTab> Visible;

		private static readonly List<Page> VisiblePages;

		private static readonly Dictionary<TMP_Text, Vector2> LabelHomes;

		private static PMenuPanel _panel;

		private static bool _dirty;

		private static bool _failed;

		private static bool _refreshFailed;

		private static float _nextRefresh;

		private static int _nextType;

		private static string _layout;

		private static RectTransform _banner;

		private static RectTransform _players;

		private static RectTransform _rules;

		private static RectTransform _adminTabs;

		private static Anchoring _playersHome;

		private static Anchoring _rulesHome;

		private static Anchoring _adminHome;

		private static GameObject _headerTemplate;

		private static GameObject _stripTemplate;

		private static GameObject _childTemplate;

		private static GameObject _headerBackground;

		private static GameObject _scrollView;

		private static GameObject _controlTemplate;

		private static Canvas _panelCanvas;

		private static TMP_FontAsset _font;

		internal static Transform SpriteRoot => ((Object)(object)_panel == (Object)null) ? null : ((Component)_panel).transform;

		internal static GameObject ControlTemplate => _controlTemplate;

		internal static Canvas PanelCanvas => _panelCanvas;

		internal static TMP_FontAsset FontAsset => _font;

		private static bool AdminTabsShowing => (Object)(object)_adminTabs != (Object)null && ((Component)_adminTabs).gameObject.activeSelf;

		internal static void MarkDirty()
		{
			_dirty = true;
		}

		internal static HeaderTab FindHeader(string name)
		{
			for (int i = 0; i < Headers.Count; i++)
			{
				if (Owners.Same(Headers[i].Name, name))
				{
					return Headers[i];
				}
			}
			return null;
		}

		internal static void Tick()
		{
			PMenuPanel val = CurrentPanel();
			if ((Object)(object)val != (Object)(object)_panel)
			{
				Forget();
				_panel = val;
				_dirty = true;
				_failed = false;
				_refreshFailed = false;
			}
			if ((Object)(object)_panel == (Object)null)
			{
				return;
			}
			if (_dirty && !_failed && Ready(_panel))
			{
				_dirty = false;
				try
				{
					Build();
				}
				catch (Exception ex)
				{
					_failed = true;
					Log.Error("P menu extensions could not be built: " + ex);
				}
			}
			if (Time.unscaledTime < _nextRefresh)
			{
				return;
			}
			_nextRefresh = Time.unscaledTime + 0.25f;
			try
			{
				Refresh();
			}
			catch (Exception ex2)
			{
				if (!_refreshFailed)
				{
					_refreshFailed = true;
					Log.Error("P menu refresh failed: " + ex2);
				}
			}
		}

		private static PMenuPanel CurrentPanel()
		{
			ClientComponentReferenceManager clientInstance = ClientComponentReferenceManager.ClientInstance;
			if ((Object)(object)clientInstance == (Object)null)
			{
				return null;
			}
			PMenuPanel pMenuPanel = clientInstance.pMenuPanel;
			return ((Object)(object)pMenuPanel == (Object)null) ? null : pMenuPanel;
		}

		private static bool Ready(PMenuPanel panel)
		{
			if ((Object)(object)panel.tabButtonsRootTransform == (Object)null || (Object)(object)panel.tabsRootTransform == (Object)null)
			{
				return false;
			}
			Dictionary<PMenuTabType, PMenuPanelTabBase> dictionary = TabsField.Invoke(panel);
			return dictionary != null && dictionary.Count > 0;
		}

		private static void Forget()
		{
			for (int i = 0; i < Headers.Count; i++)
			{
				HeaderTab headerTab = Headers[i];
				headerTab.Root = null;
				headerTab.Rect = null;
				headerTab.Switch = null;
				headerTab.Label = null;
				headerTab.Strip = null;
				headerTab.StripGroup = null;
				for (int j = 0; j < headerTab.Pages.Count; j++)
				{
					Page page = headerTab.Pages[j];
					page.Root = null;
					page.Tab = null;
					page.Button = null;
					page.Switch = null;
					page.Content = null;
					page.TitleTemplate = null;
					page.Map = null;
					page.Nav = null;
					page.Scroller = null;
					for (int k = 0; k < page.Sections.Count; k++)
					{
						page.Sections[k].Built = false;
					}
					for (int l = 0; l < page.ModTabs.Count; l++)
					{
						ModTab modTab = page.ModTabs[l];
						modTab.Content = null;
						modTab.Button = null;
						for (int m = 0; m < modTab.Sections.Count; m++)
						{
							modTab.Sections[m].Built = false;
						}
					}
				}
			}
			PlayersBar.Forget();
			StockHeaders.Clear();
			LabelHomes.Clear();
			_banner = null;
			_players = null;
			_rules = null;
			_adminTabs = null;
			_headerTemplate = null;
			_stripTemplate = null;
			_childTemplate = null;
			_headerBackground = null;
			_scrollView = null;
			_controlTemplate = null;
			_panelCanvas = null;
			_layout = null;
		}

		private static void Build()
		{
			if ((Object)(object)_banner == (Object)null)
			{
				Capture();
			}
			if ((Object)(object)_controlTemplate != (Object)null)
			{
				PlayersBar.Build(_controlTemplate);
			}
			for (int i = 0; i < Headers.Count; i++)
			{
				HeaderTab headerTab = Headers[i];
				if ((Object)(object)headerTab.Root == (Object)null && !BuildHeader(headerTab))
				{
					continue;
				}
				for (int j = 0; j < headerTab.Pages.Count; j++)
				{
					Page page = headerTab.Pages[j];
					if (!((Object)(object)page.Root == (Object)null) || BuildPage(headerTab, page))
					{
						if (page.Kind == PageKind.Mods)
						{
							BuildModTabs(page);
						}
						else
						{
							BuildSections(page);
						}
					}
				}
			}
			_layout = null;
			Refresh();
		}

		private static void Capture()
		{
			//IL_00ac: 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_00c1: Invalid comparison between Unknown and I4
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Invalid comparison between Unknown and I4
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Invalid comparison between Unknown and I4
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Invalid comparison between Unknown and I4
			_banner = _panel.tabButtonsRootTransform;
			Transform val = (Transform)(object)_banner;
			while ((Object)(object)val != (Object)null)
			{
				Canvas component = ((Component)val).GetComponent<Canvas>();
				if ((Object)(object)component != (Object)null)
				{
					_panelCanvas = component;
				}
				val = val.parent;
			}
			TMP_Text componentInChildren = ((Component)_panel.tabsRootTransform).GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.font != (Object)null)
			{
				_font = componentInChildren.font;
			}
			PMenuTabButton[] componentsInChildren = ((Component)_banner).GetComponentsInChildren<PMenuTabButton>(true);
			foreach (PMenuTabButton val2 in componentsInChildren)
			{
				StockHeaders[val2.tabType] = val2;
				if ((int)val2.tabType == 0)
				{
					Transform transform = ((Component)val2).transform;
					_players = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				}
				else if ((int)val2.tabType == 1)
				{
					Transform transform2 = ((Component)val2).transform;
					_rules = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
				}
				else if ((int)val2.tabType == 2)
				{
					Transform parent = ((Component)val2).transform.parent;
					_adminTabs = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				}
				if ((Object)(object)val2.toggle != (Object)null && !val2.toggle.isOn && ((Object)(object)_headerTemplate == (Object)null || (int)val2.tabType == 1))
				{
					_headerTemplate = ((Component)val2).gameObject;
				}
			}
			if ((Object)(object)_players != (Object)null)
			{
				_playersHome = Save(_players);
			}
			if ((Object)(object)_rules != (Object)null)
			{
				_rulesHome = Save(_rules);
			}
			if ((Object)(object)_adminTabs != (Object)null && (Object)(object)_adminTabs != (Object)(object)_banner)
			{
				_adminHome = Save(_adminTabs);
			}
			else
			{
				_adminTabs = null;
			}
			if ((Object)(object)_panel.playerChildTabButtonsRoot != (Object)null)
			{
				_stripTemplate = _panel.playerChildTabButtonsRoot;
				PMenuChildTabButton[] componentsInChildren2 = _stripTemplate.GetComponentsInChildren<PMenuChildTabButton>(true);
				for (int j = 0; j < componentsInChildren2.Length; j++)
				{
					if (!((Object)(object)componentsInChildren2[j].toggle != (Object)null) || !componentsInChildren2[j].toggle.isOn)
					{
						_childTemplate = ((Component)componentsInChildren2[j]).gameObject;
						break;
					}
				}
			}
			UIRoundPlayersControlPanel componentInChildren2 = ((Component)_panel.tabsRootTransform).GetComponentInChildren<UIRoundPlayersControlPanel>(true);
			if ((Object)(object)componentInChildren2 != (Object)null && (Object)(object)componentInChildren2.adminRaygunToggleButton != (Object)null)
			{
				Transform transform3 = ((Component)componentInChildren2.adminRaygunToggleButton).transform;
				_controlTemplate = (((Object)(object)transform3.parent != (Object)null) ? ((Component)transform3.parent).gameObject : ((Component)transform3).gameObject);
				Controls.SetPalette(componentInChildren2);
			}
			UIAdminPlayerKillLogPanel componentInChildren3 = ((Component)_panel.tabsRootTransform).GetComponentInChildren<UIAdminPlayerKillLogPanel>(true);
			if ((Object)(object)componentInChildren3 != (Object)null)
			{
				Transform val3 = ((Component)componentInChildren3).transform.Find("Header Background");
				Transform val4 = ((Component)componentInChildren3).transform.Find("Scroll View");
				_headerBackground = (((Object)(object)val3 == (Object)null) ? null : ((Component)val3).gameObject);
				_scrollView = (((Object)(object)val4 == (Object)null) ? null : ((Component)val4).gameObject);
			}
			StringBuilder stringBuilder = new StringBuilder();
			if ((Object)(object)_headerTemplate == (Object)null)
			{
				stringBuilder.Append(" header");
			}
			if ((Object)(object)_stripTemplate == (Object)null || (Object)(object)_childTemplate == (Object)null)
			{
				stringBuilder.Append(" child-tab");
			}
			if ((Object)(object)_controlTemplate == (Object)null)
			{
				stringBuilder.Append(" raygun");
			}
			if ((Object)(object)_headerBackground == (Object)null || (Object)(object)_scrollView == (Object)null)
			{
				stringBuilder.Append(" page-frame");
			}
			if ((Object)(object)_players == (Object)null || (Object)(object)_rules == (Object)null)
			{
				stringBuilder.Append(" stock-headers");
			}
			if (stringBuilder.Length > 0)
			{
				Log.Warn("P menu templates not found:" + stringBuilder?.ToString() + ". Those parts of the UI are skipped.");
			}
		}

		private static bool BuildHeader(HeaderTab header)
		{
			if ((Object)(object)_headerTemplate == (Object)null || (Object)(object)_banner == (Object)null)
			{
				return false;
			}
			GameObject val = Object.Instantiate<GameObject>(_headerTemplate, (Transform)(object)_banner);
			((Object)val).name = "RyLib_Header_" + header.Name;
			DropTabData(val);
			UiClone.Strip(val);
			Toggle component = val.GetComponent<Toggle>();
			if ((Object)(object)component == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return false;
			}
			UiClone.Mute((UnityEventBase)(object)component.onValueChanged);
			component.SetIsOnWithoutNotify(false);
			TMP_Text componentInChildren = val.GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.text = header.Name;
			}
			SetIcon(val.transform, header.IconName);
			HeaderTab captured = header;
			((UnityEvent<bool>)(object)component.onValueChanged).AddListener((UnityAction<bool>)delegate(bool on)
			{
				HeaderToggled(captured, on);
			});
			header.Root = val;
			ref RectTransform rect = ref header.Rect;
			Transform transform = val.transform;
			rect = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			header.Switch = component;
			header.Label = componentInChildren;
			if ((Object)(object)_stripTemplate != (Object)null)
			{
				GameObject val2 = Object.Instantiate<GameObject>(_stripTemplate, (Transform)(object)_banner);
				((Object)val2).name = "RyLib_Strip_" + header.Name;
				for (int num = val2.transform.childCount - 1; num >= 0; num--)
				{
					Object.DestroyImmediate((Object)(object)((Component)val2.transform.GetChild(num)).gameObject);
				}
				ToggleGroup val3 = val2.GetComponent<ToggleGroup>();
				if ((Object)(object)val3 == (Object)null)
				{
					val3 = val2.AddComponent<ToggleGroup>();
				}
				val3.allowSwitchOff = false;
				val2.SetActive(false);
				header.Strip = val2;
				header.StripGroup = val3;
			}
			return true;
		}

		private static bool BuildPage(HeaderTab header, Page page)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_047d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0484: Expected O, but got Unknown
			//IL_0486: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: 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_04be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Expected O, but got Unknown
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Expected O, but got Unknown
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_0580: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_headerBackground == (Object)null || (Object)(object)_scrollView == (Object)null || (Object)(object)header.Strip == (Object)null || (Object)(object)_childTemplate == (Object)null)
			{
				return false;
			}
			if (!page.HasType)
			{
				page.Type = (PMenuTabType)(_nextType++);
				page.HasType = true;
			}
			GameObject val = Object.Instantiate<GameObject>(_childTemplate, header.Strip.transform);
			((Object)val).name = "RyLib_PageButton_" + page.Name;
			DropTabData(val);
			UiClone.Strip(val);
			Toggle component = val.GetComponent<Toggle>();
			if ((Object)(object)component != (Object)null)
			{
				UiClone.Mute((UnityEventBase)(object)component.onValueChanged);
				component.group = header.StripGroup;
				component.SetIsOnWithoutNotify(false);
				Page captured = page;
				((UnityEvent<bool>)(object)component.onValueChanged).AddListener((UnityAction<bool>)delegate(bool on)
				{
					if (on)
					{
						OpenPage(captured);
					}
				});
			}
			SetIcon(val.transform, page.IconName);
			val.SetActive(true);
			GameObject val2 = new GameObject("RyLib_Page_" + header.Name + "_" + page.Name, new Type[1] { typeof(RectTransform) });
			val2.SetActive(false);
			val2.transform.SetParent((Transform)(object)_panel.tabsRootTransform, false);
			RectTransform val3 = (RectTransform)val2.transform;
			val3.anchorMin = Vector2.zero;
			val3.anchorMax = Vector2.one;
			val3.offsetMin = Vector2.zero;
			val3.offsetMax = Vector2.zero;
			val2.AddComponent<Canvas>();
			val2.AddComponent<GraphicRaycaster>();
			PageTab pageTab = val2.AddComponent<PageTab>();
			((PMenuPanelTabBase)pageTab).TabType = page.Type;
			pageTab.Page = page;
			((PMenuPanelTabBase)pageTab).ObjectToSelectOnOpen = header.Root;
			GameObject val4 = Object.Instantiate<GameObject>(_headerBackground, val2.transform);
			((Object)val4).name = "Header Background";
			Transform val5 = val4.transform.Find("Search");
			TMP_InputField val6 = null;
			if ((Object)(object)val5 != (Object)null && page.Kind == PageKind.Map)
			{
				val6 = ((Component)val5).GetComponentInChildren<TMP_InputField>(true);
			}
			if ((Object)(object)val5 != (Object)null && (Object)(object)val6 == (Object)null)
			{
				Object.DestroyImmediate((Object)(object)((Component)val5).gameObject);
			}
			UiClone.Strip(val4);
			Transform val7 = val4.transform.Find("Title");
			TMP_Text val8 = (((Object)(object)val7 == (Object)null) ? val4.GetComponentInChildren<TMP_Text>(true) : ((Component)val7).GetComponent<TMP_Text>());
			if ((Object)(object)val8 != (Object)null)
			{
				val8.text = page.Name;
			}
			if (page.Kind == PageKind.Map)
			{
				page.Map = new MapView(page, val3, val8, val6);
				TabsField.Invoke(_panel)[page.Type] = (PMenuPanelTabBase)(object)pageTab;
				page.Root = val2;
				page.Tab = pageTab;
				page.Button = val;
				page.Switch = component;
				page.TitleTemplate = val8;
				return true;
			}
			GameObject val9 = Object.Instantiate<GameObject>(_scrollView, val2.transform);
			((Object)val9).name = "Scroll View";
			UiClone.Strip(val9);
			float num = 25f;
			if (page.Kind == PageKind.Mods)
			{
				GameObject val10 = new GameObject("Mod Tabs", new Type[1] { typeof(RectTransform) });
				val10.transform.SetParent(val2.transform, false);
				RectTransform val11 = (RectTransform)val10.transform;
				val11.anchorMin = new Vector2(0f, 0f);
				val11.anchorMax = new Vector2(0f, 1f);
				val11.pivot = new Vector2(0f, 1f);
				val11.offsetMin = new Vector2(25f, 25f);
				val11.offsetMax = new Vector2(265f, -135f);
				VerticalLayoutGroup val12 = val10.AddComponent<VerticalLayoutGroup>();
				((HorizontalOrVerticalLayoutGroup)val12).spacing = 8f;
				((LayoutGroup)val12).childAlignment = (TextAnchor)0;
				((HorizontalOrVerticalLayoutGroup)val12).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)val12).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)val12).childForceExpandWidth = true;
				((HorizontalOrVerticalLayoutGroup)val12).childForceExpandHeight = false;
				page.Nav = val11;
				num = 285f;
			}
			RectTransform val13 = (RectTransform)val9.transform;
			val13.anchorMin = Vector2.zero;
			val13.anchorMax = Vector2.one;
			val13.offsetMin = new Vector2(num, 25f);
			val13.offsetMax = new Vector2(-25f, -135f);
			ScrollRect val14 = (page.Scroller = val9.GetComponent<ScrollRect>());
			RectTransform val15 = (((Object)(object)val14 == (Object)null) ? null : val14.content);
			if ((Object)(object)val15 == (Object)null)
			{
				Object.Destroy((Object)(object)val2);
				Object.Destroy((Object)(object)val);
				Log.Warn("the page frame has no scroll content, so page '" + page.Name + "' was skipped.");
				return false;
			}
			for (int num2 = ((Transform)val15).childCount - 1; num2 >= 0; num2--)
			{
				Object.DestroyImmediate((Object)(object)((Component)((Transform)val15).GetChild(num2)).gameObject);
			}
			PrepareContent(val15);
			TabsField.Invoke(_panel)[page.Type] = (PMenuPanelTabBase)(object)pageTab;
			page.Root = val2;
			page.Tab = pageTab;
			page.Button = val;
			page.Switch = component;
			page.Content = val15;
			page.TitleTemplate = val8;
			return true;
		}

		private static void PrepareContent(RectTransform content)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			LayoutGroup component = ((Component)content).GetComponent<LayoutGroup>();
			if ((Object)(object)component != (Object)null && !(component is VerticalLayoutGroup))
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			VerticalLayoutGroup val = ((Component)content).GetComponent<VerticalLayoutGroup>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)content).gameObject.AddComponent<VerticalLayoutGroup>();
			}
			((LayoutGroup)val).padding = new RectOffset(10, 10, 10, 10);
			((HorizontalOrVerticalLayoutGroup)val).spacing = 20f;
			((LayoutGroup)val).childAlignment = (TextAnchor)0;
			((HorizontalOrVerticalLayoutGroup)val).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandHeight = false;
			ContentSizeFitter val2 = ((Component)content).GetComponent<ContentSizeFitter>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = ((Component)content).gameObject.AddComponent<ContentSizeFitter>();
			}
			val2.horizontalFit = (FitMode)0;
			val2.verticalFit = (FitMode)2;
		}

		private static void BuildSections(Page page)
		{
			if (page.Kind == PageKind.Sections && !((Object)(object)page.Content == (Object)null) && !((Object)(object)_controlTemplate == (Object)null))
			{
				BuildSectionList(page, page.Sections, page.Content, 3);
			}
		}

		private static void BuildModTabs(Page page)
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			if (page.Kind != PageKind.Mods || (Object)(object)page.Content == (Object)null || (Object)(object)page.Nav == (Object)null || (Object)(object)_controlTemplate == (Object)null)
			{
				return;
			}
			for (int i = 0; i < page.ModTabs.Count; i++)
			{
				ModTab modTab = page.ModTabs[i];
				if ((Object)(object)modTab.Content == (Object)null)
				{
					GameObject val = new GameObject("RyLib_ModTab_" + modTab.Name, new Type[1] { typeof(RectTransform) });
					val.transform.SetParent((Transform)(object)page.Content, false);
					VerticalLayoutGroup val2 = val.AddComponent<VerticalLayoutGroup>();
					((HorizontalOrVerticalLayoutGroup)val2).spacing = 20f;
					((LayoutGroup)val2).childAlignment = (TextAnchor)0;
					((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true;
					((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true;
					((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = true;
					((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false;
					modTab.Content = (RectTransform)val.transform;
					ModTab captured = modTab;
					ControlSpec controlSpec = Controls.Button(modTab.Creator, modTab.Name, delegate
					{
						SelectModTab(page, captured);
					}, modTab.IconName ?? "hui-p-tab-admin");
					controlSpec.IsOn = () => page.CurrentModTab == captured;
					modTab.Button = Controls.Make(controlSpec, (Transform)(object)page.Nav, _controlTemplate);
					if (modTab.Button != null)
					{
						LayoutElement val3 = modTab.Button.Root.GetComponent<LayoutElement>();
						if ((Object)(object)val3 == (Object)null)
						{
							val3 = modTab.Button.Root.AddComponent<LayoutElement>();
						}
						val3.minHeight = 48f;
						val3.preferredHeight = 48f;
						val3.flexibleHeight = 0f;
						val3.minWidth = -1f;
						val3.preferredWidth = -1f;
						val3.flexibleWidth = 1f;
					}
				}
				BuildSectionList(page, modTab.Sections, modTab.Content, 2);
			}
			RefreshModTabs(page);
		}

		private static void SelectModTab(Page page, ModTab tab)
		{
			page.CurrentModTab = tab;
			ShowModTab(page);
		}

		private static void RefreshModTabs(Page page)
		{
			if (page.Kind != PageKind.Mods || (Object)(object)page.Nav == (Object)null)
			{
				return;
			}
			ModTab modTab = null;
			for (int i = 0; i < page.ModTabs.Count; i++)
			{
				ModTab modTab2 = page.ModTabs[i];
				bool visible = modTab2.Visible;
				if (visible && modTab == null)
				{
					modTab = modTab2;
				}
				if (modTab2.Button != null && (Object)(object)modTab2.Button.Root != (Object)null && modTab2.Button.Root.activeSelf != visible)
				{
					modTab2.Button.Root.SetActive(visible);
				}
			}
			if (page.CurrentModTab == null || !page.CurrentModTab.Visible)
			{
				page.CurrentModTab = modTab;
				ShowModTab(page);
			}
		}

		private static void ShowModTab(Page page)
		{
			for (int i = 0; i < page.ModTabs.Count; i++)
			{
				ModTab modTab = page.ModTabs[i];
				bool flag = modTab == page.CurrentModTab;
				if ((Object)(object)modTab.Content != (Object)null && ((Component)modTab.Content).gameObject.activeSelf != flag)
				{
					((Component)modTab.Content).gameObject.SetActive(flag);
				}
				if (modTab.Button != null)
				{
					Controls.Refresh(modTab.Button);
				}
			}
			if ((Object)(object)page.Scroller != (Object)null)
			{
				page.Scroller.verticalNormalizedPosition = 1f;
			}
		}

		private static void BuildSectionList(Page page, List<SectionSpec> sections, RectTransform parent, int columns)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Expected O, but got Unknown
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < sections.Count; i++)
			{
				SectionSpec spec = sections[i];
				if (spec.Built)
				{
					continue;
				}
				spec.Built = true;
				GameObject val = new GameObject("RyLib_Section_" + spec.Owner + "_" + spec.Title, new Type[1] { typeof(RectTransform) });
				val.transform.SetParent((Transform)(object)parent, false);
				VerticalLayoutGroup val2 = val.AddComponent<VerticalLayoutGroup>();
				((HorizontalOrVerticalLayoutGroup)val2).spacing = 10f;
				((LayoutGroup)val2).childAlignment = (TextAnchor)0;
				((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = true;
				((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false;
				if ((Object)(object)page.TitleTemplate != (Object)null)
				{
					TMP_Text val3 = Object.Instantiate<TMP_Text>(page.TitleTemplate, val.transform);
					((Object)val3).name = "Heading";
					val3.text = spec.Title;
					val3.fontSize = 24f;
					val3.enableAutoSizing = false;
					val3.alignment = (TextAlignmentOptions)4097;
					LayoutElement val4 = ((Component)val3).gameObject.AddComponent<LayoutElement>();
					val4.preferredHeight = 34f;
				}
				GameObject val5 = new GameObject("Controls", new Type[1] { typeof(RectTransform) });
				val5.transform.SetParent(val.transform, false);
				GridLayoutGroup val6 = val5.AddComponent<GridLayoutGroup>();
				val6.cellSize = new Vector2(330f, 48f);
				val6.spacing = new Vector2(15f, 10f);
				val6.startCorner = (Corner)0;
				val6.startAxis = (Axis)0;
				((LayoutGroup)val6).childAlignment = (TextAnchor)0;
				val6.constraint = (Constraint)1;
				val6.constraintCount = columns;
				Section builder = new Section(spec.Owner, val5.transform);
				Owners.Run(spec.Owner, "section '" + spec.Title + "'", delegate
				{
					spec.Build(builder);
				});
				if (builder.First != null && (Object)(object)page.Tab != (Object)null && (Object)(object)((PMenuPanelTabBase)page.Tab).ObjectToSelectOnOpen == (Object)(object)page.Header.Root)
				{
					Button componentInChildren = builder.First.Root.GetComponentInChildren<Button>(true);
					if ((Object)(object)componentInChildren != (Object)null)
					{
						((PMenuPanelTabBase)page.Tab).ObjectToSelectOnOpen = ((Component)componentInChildren).gameObject;
					}
				}
			}
		}

		private static void HeaderToggled(HeaderTab header, bool on)
		{
			if (on)
			{
				Page page = header.Selected;
				if (page == null || (Object)(object)page.Tab == (Object)null || !page.Visible)
				{
					page = FirstVisible(header);
				}
				if (page != null)
				{
					OpenPage(page);
				}
			}
			UpdateStrip(header);
		}

		private static Page FirstVisible(HeaderTab header)
		{
			for (int i = 0; i < header.Pages.Count; i++)
			{
				Page page = header.Pages[i];
				if ((Object)(object)page.Tab != (Object)null && page.Visible)
				{
					return page;
				}
			}
			return null;
		}

		private static void OpenPage(Page page)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_panel == (Object)null || (Object)(object)page.Tab == (Object)null || SwitchTabMethod == null)
			{
				return;
			}
			HeaderTab header = page.Header;
			header.Selected = page;
			for (int i = 0; i < header.Pages.Count; i++)
			{
				Toggle val = header.Pages[i].Switch;
				if ((Object)(object)val != (Object)null)
				{
					val.SetIsOnWithoutNotify(header.Pages[i] == page);
				}
			}
			SwitchTabMethod.Invoke(_panel, new object[1] { page.Type });
			UpdateStrip(header);
		}

		private static void Refresh()
		{
			Visible.Clear();
			for (int i = 0; i < Headers.Count; i++)
			{
				HeaderTab headerTab = Headers[i];
				if (!((Object)(object)headerTab.Root == (Object)null))
				{
					bool flag = FirstVisible(headerTab) != null;
					if (headerTab.Root.activeSelf != flag)
					{
						headerTab.Root.SetActive(flag);
					}
					if (flag)
					{
						Visible.Add(headerTab);
					}
				}
			}
			string text = Key();
			if (text != _layout)
			{
				_layout = text;
				Layout();
			}
			for (int j = 0; j < Headers.Count; j++)
			{
				UpdateStrip(Headers[j]);
				List<Page> pages = Headers[j].Pages;
				for (int k = 0; k < pages.Count; k++)
				{
					RefreshModTabs(pages[k]);
				}
			}
			PlayersBar.Refresh(_controlTemplate);
			Controls.RefreshVisible();
		}

		private static string Key()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(AdminTabsShowing ? 'A' : 'a');
			for (int i = 0; i < Visible.Count; i++)
			{
				stringBuilder.Append('|').Append(Visible[i].Name);
			}
			return stringBuilder.ToString();
		}

		private static void Layout()
		{
			if ((Object)(object)_banner == (Object)null || (Object)(object)_players == (Object)null || (Object)(object)_rules == (Object)null)
			{
				return;
			}
			if (Visible.Count == 0)
			{
				Load(_players, _playersHome);
				Load(_rules, _rulesHome);
				if ((Object)(object)_adminTabs != (Object)null)
				{
					Load(_adminTabs, _adminHome);
				}
				RestoreLabels();
				return;
			}
			bool adminTabsShowing = AdminTabsShowing;
			int num = (adminTabsShowing ? 6 : 2);
			int count = num + Visible.Count;
			Place(_players, 0, 1, count);
			Place(_rules, 1, 1, count);
			if (adminTabsShowing)
			{
				Place(_adminTabs, 2, 4, count);
			}
			for (int i = 0; i < Visible.Count; i++)
			{
				Place(Visible[i].Rect, num + i, 1, count);
			}
			foreach (KeyValuePair<PMenuTabType, PMenuTabButton> stockHeader in StockHeaders)
			{
				if (!((Object)(object)stockHeader.Value == (Object)null))
				{
					Transform transform = ((Component)stockHeader.Value).transform;
					FitHeader((RectTransform)(object)((transform is RectTransform) ? transform : null), ((Component)stockHeader.Value).GetComponentInChildren<TMP_Text>(true));
				}
			}
			for (int j = 0; j < Visible.Count; j++)
			{
				FitHeader(Visible[j].Rect, Visible[j].Label);
			}
		}

		private static void Place(RectTransform rect, int start, int span, int count)
		{
			//IL_003b: 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_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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_00ac: 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)
			if (!((Object)(object)rect == (Object)null))
			{
				float num = ((start == 0) ? 0f : 1f);
				float num2 = ((start + span >= count) ? 0f : 1f);
				rect.anchorMin = new Vector2((float)start / (float)count, rect.anchorMin.y);
				rect.anchorMax = new Vector2((float)(start + span) / (float)count, rect.anchorMax.y);
				rect.sizeDelta = new Vector2(0f - (num + num2), rect.sizeDelta.y);
				rect.anchoredPosition = new Vector2(num * (1f - rect.pivot.x) - num2 * rect.pivot.x, rect.anchoredPosition.y);
			}
		}

		private static void FitHeader(RectTransform button, TMP_Text label)
		{
			//IL_006e: 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_007f: 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_0098: 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_0050: 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_0101: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)button == (Object)null || (Object)(object)label == (Object)null)
			{
				return;
			}
			RectTransform rectTransform = label.rectTransform;
			if (!LabelHomes.TryGetValue(label, out var value))
			{
				((Vector2)(ref value))..ctor(Mathf.Min(label.fontSize, 18f), rectTransform.anchoredPosition.x);
				LabelHomes[label] = value;
			}
			rectTransform.anchoredPosition = new Vector2(value.y, rectTransform.anchoredPosition.y);
			RectTransform icon = HeaderIcon(label, button);
			Rect rect = button.rect;
			float num = ((Rect)(ref rect)).width - 16f;
			float num2 = value.x;
			label.enableAutoSizing = false;
			float left;
			float right;
			while (true)
			{
				label.fontSize = num2;
				Extent(label, icon, out left, out right);
				if (right - left <= num || num2 <= 12f)
				{
					break;
				}
				num2 -= 1f;
			}
			float x = ((Transform)button).InverseTransformPoint(((Transform)rectTransform).position).x;
			float num3 = 0.5f - button.pivot.x;
			rect = button.rect;
			float num4 = num3 * ((Rect)(ref rect)).width;
			float num5 = num4 - (x + (left + right) * 0.5f);
			rectTransform.anchoredPosition = new Vector2(value.y + num5, rectTransform.anchoredPosition.y);
		}

		private static void Extent(TMP_Text label, RectTransform icon, out float left, out float right)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_00aa: 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)
			RectTransform rectTransform = label.rectTransform;
			float x = label.GetPreferredValues(label.text).x;
			left = (0f - rectTransform.pivot.x) * x;
			right = (1f - rectTransform.pivot.x) * x;
			if (!((Object)(object)icon == (Object)null) && ((Component)icon).gameObject.activeSelf && !((Object)(object)((Transform)icon).parent != (Object)(object)rectTransform))
			{
				Rect rect = icon.rect;
				float width = ((Rect)(ref rect)).width;
				float num = (icon.anchorMin.x + icon.anchorMax.x) * 0.5f;
				float num2 = (num - rectTransform.pivot.x) * x + icon.anchoredPosition.x - icon.pivot.x * width;
				left = Mathf.Min(left, num2);
				right = Mathf.Max(right, num2 + width);
			}
		}

		private static RectTransform HeaderIcon(TMP_Text label, RectTransform button)
		{
			Transform val = label.transform.Find("Icon");
			if ((Object)(object)val == (Object)null)
			{
				val = ((Transform)button).Find("Icon");
			}
			return (RectTransform)(object)((val is RectTransform) ? val : null);
		}

		private static void RestoreLabels()
		{
			//IL_0034: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<TMP_Text, Vector2> labelHome in LabelHomes)
			{
				if (!((Object)(object)labelHome.Key == (Object)null))
				{
					labelHome.Key.fontSize = labelHome.Value.x;
					RectTransform rectTransform = labelHome.Key.rectTransform;
					rectTransform.anchoredPosition = new Vector2(labelHome.Value.y, rectTransform.anchoredPosition.y);
				}
			}
		}

		private static void UpdateStrip(HeaderTab header)
		{
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)header.Strip == (Object)null)
			{
				return;
			}
			VisiblePages.Clear();
			for (int i = 0; i < header.Pages.Count; i++)
			{
				Page page = header.Pages[i];
				if (!((Object)(object)page.Button == (Object)null))
				{
					bool visible = page.Visible;
					if (page.Button.activeSelf != visible)
					{
						page.Button.SetActive(visible);
					}
					if (visible)
					{
						VisiblePages.Add(page);
					}
				}
			}
			for (int j = 0; j < VisiblePages.Count; j++)
			{
				Transform transform = VisiblePages[j].Button.transform;
				RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if (!((Object)(object)val == (Object)null))
				{
					val.anchoredPosition = new Vector2(-25f - 70f * (float)(VisiblePages.Count - 1 - j), 0f);
				}
			}
			bool flag = (Object)(object)header.Root != (Object)null && header.Root.activeSelf && (Object)(object)header.Switch != (Object)null && header.Switch.isOn && VisiblePages.Count > 1;
			if (header.Strip.activeSelf != flag)
			{
				header.Strip.SetActive(flag);
			}
		}

		internal static bool Cycle(PMenuPanel panel, bool next)
		{
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)panel == (Object)null || (Object)(object)panel != (Object)(object)_panel || !panel.CurrentlyShowing)
			{
				return false;
			}
			Visible.Clear();
			for (int i = 0; i < Headers.Count; i++)
			{
				if ((Object)(object)Headers[i].Root != (Object)null && Headers[i].Root.activeSelf && (Object)(object)Headers[i].Switch != (Object)null)
				{
					Visible.Add(Headers[i]);
				}
			}
			if (Visible.Count == 0)
			{
				return false;
			}
			bool currentlyAdminMode = panel.currentlyAdminMode;
			int num = (currentlyAdminMode ? 6 : 2);
			int num2 = num + Visible.Count;
			int num3 = Slot(panel.CurrentActiveTabType, currentlyAdminMode, num);
			if (num3 < 0)
			{
				return false;
			}
			int num4 = (num3 + (next ? 1 : (num2 - 1))) % num2;
			if (num4 >= num)
			{
				Visible[num4 - num].Switch.isOn = true;
				return true;
			}
			if (!StockHeaders.TryGetValue(StockOrder[num4], out var value) || (Object)(object)value == (Object)null || (Object)(object)value.toggle == (Object)null)
			{
				return false;
			}
			value.toggle.isOn = true;
			return true;
		}

		private static int Slot(PMenuTabType type, bool admin, int stock)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Invalid comparison between I4 and Unknown
			//IL_00a3: 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)
			if ((int)type == 0 || (int)type == 6 || (int)type == 7 || (int)type == 8)
			{
				return 0;
			}
			if ((int)type == 1)
			{
				return 1;
			}
			if (admin)
			{
				for (int i = 2; i < StockOrder.Length; i++)
				{
					if ((int)StockOrder[i] == (int)type)
					{
						return i;
					}
				}
			}
			for (int j = 0; j < Visible.Count; j++)
			{
				List<Page> pages = Visible[j].Pages;
				for (int k = 0; k < pages.Count; k++)
				{
					if (pages[k].HasType && pages[k].Type == type)
					{
						return stock + j;
					}
				}
			}
			return -1;
		}

		private static void SetIcon(Transform root, string sprite)
		{
			if (string.IsNullOrEmpty(sprite))
			{
				return;
			}
			Image val = null;
			Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (!(((Object)componentsInChildren[i]).name != "Icon"))
				{
					val = componentsInChildren[i];
					break;
				}
			}
			if (!((Object)(object)val == (Object)null))
			{
				Sprite val2 = Sprites.Find(sprite, SpriteRoot);
				if ((Object)(object)val2 != (Object)null)
				{
					val.sprite = val2;
				}
			}
		}

		private static void DropTabData(GameObject root)
		{
			PMenuTabButton component = root.GetComponent<PMenuTabButton>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			PMenuChildTabButton component2 = root.GetComponent<PMenuChildTabButton>();
			if ((Object)(object)component2 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component2);
			}
		}

		private static Anchoring Save(RectTransform rect)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			Anchoring result = default(Anchoring);
			result.Min = rect.anchorMin;
			result.Max = rect.anchorMax;
			result.Size = rect.sizeDelta;
			result.Position = rect.anchoredPosition;
			return result;
		}

		private static void Load(RectTransform rect, Anchoring anchoring)
		{
			//IL_0010: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)rect == (Object)null))
			{
				rect.anchorMin = anchoring.Min;
				rect.anchorMax = anchoring.Max;
				rect.sizeDelta = anchoring.Size;
				rect.anchoredPosition = anchoring.Position;
			}
		}

		static Menu()
		{
			PMenuTabType[] array = new PMenuTabType[6];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			StockOrder = (PMenuTabType[])(object)array;
			Headers = new List<HeaderTab>();
			TabsField = AccessTools.FieldRefAccess<PMenuPanel, Dictionary<PMenuTabType, PMenuPanelTabBase>>("tabs");
			SwitchTabMethod = AccessTools.Method(typeof(PMenuPanel), "SwitchTab", new Type[1] { typeof(PMenuTabType) }, (Type[])null);
			StockHeaders = new Dictionary<PMenuTabType, PMenuTabButton>();
			Visible = new List<HeaderTab>();
			VisiblePages = new List<Page>();
			LabelHomes = new Dictionary<TMP_Text, Vector2>();
			_dirty = true;
			_nextType = 100;
		}
	}
	[HarmonyPatch(typeof(PMenuPanel), "SwitchToNextTab")]
	internal static class NextTabPatch
	{
		private static bool Prefix(PMenuPanel __instance)
		{
			return !Safe(__instance, next: true);
		}

		internal static bool Safe(PMenuPanel panel, bool next)
		{
			try
			{
				return Menu.Cycle(panel, next);
			}
			catch (Exception ex)
			{
				Log.Error("tab cycling failed: " + ex.Message);
				return false;
			}
		}
	}
	[HarmonyPatch(typeof(PMenuPanel), "SwitchToPreviousTab")]
	internal static class PreviousTabPatch
	{
		private static bool Prefix(PMenuPanel __instance)
		{
			return !NextTabPatch.Safe(__instance, next: false);
		}
	}
	internal sealed class PageTab : PMenuPanelTabBase
	{
		internal Page Page;

		public override void _InitializeOnMap(RoundGameDetails roundGameDetails)
		{
			if (Page != null && Page.Map != null)
			{
				Page.Map.Invalidate();
			}
		}

		public override void _Awake()
		{
		}

		public override void _ResetObject()
		{
			if (Page != null && Page.Map != null)
			{
				Page.Map.Invalidate();
			}
		}

		public override void _OnDestroy()
		{
		}

		public override void _ToggleShowing(bool show)
		{
			if (Page != null && Page.Map != null)
			{
				Page.Map.Show(show);
			}
			if (show)
			{
				Controls.RefreshVisible();
			}
		}
	}
	internal static class PlayerActions
	{
		private const int GroundMask = 8705;

		private const int HealAmount = 100;

		private static ClientComponentReferenceManager Client => ClientComponentReferenceManager.ClientInstance;

		internal static void Spectate(int id)
		{
			ClientComponentReferenceManager client = Client;
			if ((Object)(object)client != (Object)null && (Object)(object)client.clientSpectatorManager != (Object)null)
			{
				client.clientSpectatorManager.SpectateStartRequest(id);
			}
		}

		internal static void Slay(int id)
		{
			ClientComponentReferenceManager client = Client;
			if ((Object)(object)client != (Object)null && (Object)(object)client.clientBannedPlayersManager != (Object)null)
			{
				client.clientBannedPlayersManager.RequestPlayerSlay(id, string.Empty);
			}
		}

		internal static void Revive(int id)
		{
			ClientComponentReferenceManager client = Client;
			if ((Object)(object)client != (Object)null && (Object)(object)client.clientBannedPlayersManager != (Object)null)
			{
				client.clientBannedPlayersManager.RequestPlayerRevive(id, string.Empty);
			}
		}

		internal static void Heal(int id)
		{
			ClientComponentReferenceManager client = Client;
			if ((Object)(object)client != (Object)null && (Object)(object)client.clientBannedPlayersManager != (Object)null)
			{
				client.clientBannedPlayersManager.RequestPlayerSlap(id, string.Empty, -100);
			}
		}

		internal static void