Decompiled source of HostControl v1.0.0

BepInEx/plugins/HostControl/HostControl.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FishNet;
using FishNet.Connection;
using FishNet.Managing.Logging;
using FishNet.Managing.Server;
using FishNet.Object;
using FishNet.Transporting;
using HarmonyLib;
using HostControl.Configuration;
using HostControl.Localization;
using HostControl.Runtime;
using HostControl.UI;
using HowtoFishLocalizationAPI.Api;
using Newtonsoft.Json;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("HostControl")]
[assembly: AssemblyDescription("Host control tools for How to Fish by Ice Box Studio")]
[assembly: AssemblyCompany("Ice Box Studio")]
[assembly: AssemblyProduct("HostControl")]
[assembly: AssemblyCopyright("Copyright © 2026 Ice Box Studio All rights reserved.")]
[assembly: ComVisible(false)]
[assembly: Guid("d83eb5ec-c32f-44cb-88e0-bfbcae1741d4")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace HostControl
{
	[BepInPlugin("IceBoxStudio.HowToFish.HostControl", "HostControl", "1.0.0")]
	[BepInDependency("IceBoxStudio.HowToFish.LocalizationAPI", "1.0.0")]
	public sealed class HostControlPlugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			try
			{
				Log.LogInfo((object)"=============================================");
				Log.LogInfo((object)("HostControl " + I18n.Text("plugin.initializing")));
				Log.LogInfo((object)(I18n.Text("plugin.author_prefix") + "Ice Box Studio(https://steamcommunity.com/id/ibox666/)"));
				ConfigManager.Init(((BaseUnityPlugin)this).Config);
				ControlRuntime.Init(((BaseUnityPlugin)this).Logger);
				_harmony = new Harmony("IceBoxStudio.HowToFish.HostControl");
				_harmony.PatchAll(Assembly.GetExecutingAssembly());
				Log.LogInfo((object)("HostControl " + I18n.Text("plugin.initialized")));
				Log.LogInfo((object)"=============================================");
			}
			catch (Exception arg)
			{
				Log.LogError((object)string.Format("Failed to initialize {0}: {1}", "HostControl", arg));
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "IceBoxStudio.HowToFish.HostControl";

		public const string PLUGIN_NAME = "HostControl";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace HostControl.UI
{
	internal sealed class ControlUi : MonoBehaviour
	{
		private enum PendingAction
		{
			None,
			Kick,
			BanShort,
			BanForever,
			Kill,
			Unban
		}

		private static ControlUi _current;

		private static int _inputFrame = -1;

		private GameObject _mainScreen;

		private GameObject _optionsScreen;

		private GameObject _serverScreen;

		private GameObject _pauseButton;

		private GameObject _root;

		private GameObject _mainPage;

		private GameObject _confirmPage;

		private GameObject _bansPage;

		private GameObject _buttonTemplate;

		private Transform _rows;

		private Transform _bannedRows;

		private TextMeshProUGUI _title;

		private TextMeshProUGUI _selected;

		private TextMeshProUGUI _status;

		private TextMeshProUGUI _confirmTitle;

		private TextMeshProUGUI _confirmText;

		private TextMeshProUGUI _bansTitle;

		private TextMeshProUGUI _bansStatus;

		private TextMeshProUGUI _closeLabel;

		private TextMeshProUGUI _kickLabel;

		private TextMeshProUGUI _banShortLabel;

		private TextMeshProUGUI _banForeverLabel;

		private TextMeshProUGUI _killLabel;

		private TextMeshProUGUI _reviveLabel;

		private TextMeshProUGUI _teleportLabel;

		private TextMeshProUGUI _bansLabel;

		private TextMeshProUGUI _confirmLabel;

		private TextMeshProUGUI _cancelLabel;

		private TextMeshProUGUI _confirmBackLabel;

		private TextMeshProUGUI _bansBackLabel;

		private TextMeshProUGUI _pauseButtonLabel;

		private Button _closeButton;

		private Button _kickButton;

		private Button _banShortButton;

		private Button _banForeverButton;

		private Button _killButton;

		private Button _reviveButton;

		private Button _teleportButton;

		private Button _bansButton;

		private Button _confirmButton;

		private Button _cancelButton;

		private Button _bansBackButton;

		private Player _target;

		private ulong _pendingSteamId;

		private string _pendingBanName;

		private bool _returnToBans;

		private PendingAction _pending;

		private bool _built;

		private bool _open;

		internal static void Attach()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_current) && ControlRuntime.IsHost)
			{
				Transform fXCanvasTrans = PlayerUI.FXCanvasTrans;
				if (Object.op_Implicit((Object)(object)fXCanvasTrans))
				{
					GameObject val = new GameObject("HostControl UI");
					val.transform.SetParent(fXCanvasTrans, false);
					_current = val.AddComponent<ControlUi>();
					_current.Setup();
				}
			}
		}

		internal static void Tick()
		{
			if (_inputFrame == Time.frameCount)
			{
				return;
			}
			_inputFrame = Time.frameCount;
			if (!ControlRuntime.IsHost || ChatManager.IsTyping || !ConfigManager.IsOpenPressed())
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)_current))
			{
				Attach();
			}
			if (Object.op_Implicit((Object)(object)_current))
			{
				if (_current._open)
				{
					_current.Hide();
				}
				else
				{
					_current.Show();
				}
			}
		}

		internal static void RefreshAll()
		{
			if (Object.op_Implicit((Object)(object)_current) && _current._open)
			{
				_current.Refresh();
			}
		}

		internal static void Destroy()
		{
			if (Object.op_Implicit((Object)(object)_current))
			{
				if (Object.op_Implicit((Object)(object)_current._root))
				{
					Object.Destroy((Object)(object)_current._root);
				}
				if (Object.op_Implicit((Object)(object)_current._confirmPage))
				{
					Object.Destroy((Object)(object)_current._confirmPage);
				}
				if (Object.op_Implicit((Object)(object)_current._bansPage))
				{
					Object.Destroy((Object)(object)_current._bansPage);
				}
				if (Object.op_Implicit((Object)(object)_current._pauseButton))
				{
					Object.Destroy((Object)(object)_current._pauseButton);
				}
				Object.Destroy((Object)(object)((Component)_current).gameObject);
			}
			_current = null;
		}

		private bool Build(PauseManager pause, GameObject holder)
		{
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Expected O, but got Unknown
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Expected O, but got Unknown
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Expected O, but got Unknown
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cf: Expected O, but got Unknown
			//IL_058d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0597: Expected O, but got Unknown
			//IL_05a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b3: Expected O, but got Unknown
			//IL_05c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cf: Expected O, but got Unknown
			//IL_05e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05eb: Expected O, but got Unknown
			//IL_05fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0607: Expected O, but got Unknown
			//IL_0619: Unknown result type (might be due to invalid IL or missing references)
			//IL_0623: Expected O, but got Unknown
			//IL_0635: Unknown result type (might be due to invalid IL or missing references)
			//IL_063f: Expected O, but got Unknown
			_mainScreen = GetObject(pause, "_mainScreen");
			_optionsScreen = GetObject(pause, "_optionsScreen");
			_serverScreen = GetObject(pause, "_serverSettingsScreen");
			if (!Object.op_Implicit((Object)(object)_serverScreen))
			{
				return false;
			}
			_root = Object.Instantiate<GameObject>(_serverScreen, holder.transform, false);
			((Object)_root).name = "HostControlScreen";
			_root.SetActive(false);
			_mainPage = _root;
			Transform val = _root.transform.Find("PausedText");
			Transform val2 = _root.transform.Find("ServerDisplay");
			Transform val3 = _root.transform.Find("LowerButtonHolder/BackButton");
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val3))
			{
				return false;
			}
			_title = ((Component)val).GetComponent<TextMeshProUGUI>();
			MoveTitle(val);
			_buttonTemplate = ((Component)val3).gameObject;
			DisableOther(_buttonTemplate);
			_closeButton = SetupButton(_buttonTemplate);
			_closeLabel = FindText(_buttonTemplate);
			if ((Object)(object)_title == (Object)null || (Object)(object)_closeButton == (Object)null || (Object)(object)_closeLabel == (Object)null)
			{
				return false;
			}
			SetupButtonText(_buttonTemplate, _closeLabel);
			((UnityEvent)_closeButton.onClick).AddListener(new UnityAction(Hide));
			DisableOther(((Component)_title).gameObject);
			GameObject gameObject = ((Component)val2).gameObject;
			TextMeshProUGUI componentInChildren = ((Component)val2).GetComponentInChildren<TextMeshProUGUI>(true);
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return false;
			}
			foreach (Transform item in _root.transform)
			{
				Transform val4 = item;
				if ((Object)(object)val4 != (Object)(object)val && (Object)(object)val4 != (Object)(object)val2 && (Object)(object)val4 != (Object)(object)val3.parent)
				{
					((Component)val4).gameObject.SetActive(false);
				}
			}
			foreach (Transform item2 in val2)
			{
				Transform val5 = item2;
				if (((Object)val5).name != "Outline")
				{
					((Component)val5).gameObject.SetActive(false);
				}
			}
			RectTransform component = gameObject.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = Vector2.zero;
			component.sizeDelta = new Vector2(900f, 640f);
			GameObject val6 = new GameObject("AdminContent");
			val6.transform.SetParent(val2, false);
			RectTransform val7 = val6.AddComponent<RectTransform>();
			val7.anchorMin = Vector2.zero;
			val7.anchorMax = Vector2.one;
			val7.offsetMin = new Vector2(28f, 24f);
			val7.offsetMax = new Vector2(-28f, -24f);
			((Transform)val7).localScale = Vector3.one;
			((Transform)val7).SetAsLastSibling();
			VerticalLayoutGroup obj = val6.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 7f;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			_selected = AddText(componentInChildren, (Transform)(object)val7, "Selected", 20f, 32f, (TextAlignmentOptions)513);
			_status = AddText(componentInChildren, (Transform)(object)val7, "Status", 18f, 30f, (TextAlignmentOptions)513);
			GameObject val8 = new GameObject("Players");
			val8.transform.SetParent((Transform)(object)val7, false);
			val8.AddComponent<LayoutElement>().preferredHeight = 370f;
			_rows = val8.transform;
			VerticalLayoutGroup obj2 = val8.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 4f;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
			Transform parent = MakeRow((Transform)(object)val7, "Actions");
			_kickButton = AddButton(_buttonTemplate, parent, "Kick", out _kickLabel);
			_banShortButton = AddButton(_buttonTemplate, parent, "BanShort", out _banShortLabel);
			_banForeverButton = AddButton(_buttonTemplate, parent, "BanForever", out _banForeverLabel);
			_killButton = AddButton(_buttonTemplate, parent, "Kill", out _killLabel);
			Transform parent2 = MakeRow((Transform)(object)val7, "Actions2");
			_reviveButton = AddButton(_buttonTemplate, parent2, "Revive", out _reviveLabel);
			_teleportButton = AddButton(_buttonTemplate, parent2, "Teleport", out _teleportLabel);
			_bansButton = AddButton(_buttonTemplate, parent2, "Bans", out _bansLabel);
			if ((Object)(object)_kickButton == (Object)null || (Object)(object)_banShortButton == (Object)null || (Object)(object)_banForeverButton == (Object)null || (Object)(object)_killButton == (Object)null || (Object)(object)_reviveButton == (Object)null || (Object)(object)_teleportButton == (Object)null || (Object)(object)_bansButton == (Object)null)
			{
				return false;
			}
			((UnityEvent)_kickButton.onClick).AddListener((UnityAction)delegate
			{
				Ask(PendingAction.Kick);
			});
			((UnityEvent)_banShortButton.onClick).AddListener((UnityAction)delegate
			{
				Ask(PendingAction.BanShort);
			});
			((UnityEvent)_banForeverButton.onClick).AddListener((UnityAction)delegate
			{
				Ask(PendingAction.BanForever);
			});
			((UnityEvent)_killButton.onClick).AddListener((UnityAction)delegate
			{
				Ask(PendingAction.Kill);
			});
			((UnityEvent)_reviveButton.onClick).AddListener(new UnityAction(Revive));
			((UnityEvent)_teleportButton.onClick).AddListener(new UnityAction(Teleport));
			((UnityEvent)_bansButton.onClick).AddListener(new UnityAction(ShowBans));
			if (!BuildConfirm(holder, componentInChildren) || !BuildBans(holder, componentInChildren))
			{
				return false;
			}
			if (!AddPauseButton())
			{
				return false;
			}
			LocalizationApi.LanguageChanged += OnLanguageChanged;
			PlayerManager.OnPlayerAmountChange += RefreshAll;
			Refresh();
			return true;
		}

		private bool BuildConfirm(GameObject holder, TextMeshProUGUI nativeText)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Expected O, but got Unknown
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Expected O, but got Unknown
			_confirmPage = Object.Instantiate<GameObject>(_serverScreen, holder.transform, false);
			if (!PreparePage(_confirmPage, "HostControlConfirmScreen", out var title, out var display, out var back, out var nativeText2))
			{
				return false;
			}
			_confirmTitle = title;
			GameObject val = new GameObject("ConfirmContent");
			val.transform.SetParent(display, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = new Vector2(40f, 70f);
			val2.offsetMax = new Vector2(-40f, -70f);
			VerticalLayoutGroup obj = val.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 18f;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			_confirmText = AddText(nativeText2, (Transform)(object)val2, "ConfirmText", 28f, 150f, (TextAlignmentOptions)514);
			Transform parent = MakeRow((Transform)(object)val2, "ConfirmActions");
			_confirmButton = AddButton(_buttonTemplate, parent, "Confirm", out _confirmLabel);
			_cancelButton = AddButton(_buttonTemplate, parent, "Cancel", out _cancelLabel);
			((UnityEvent)_confirmButton.onClick).AddListener(new UnityAction(Confirm));
			((UnityEvent)_cancelButton.onClick).AddListener(new UnityAction(Cancel));
			Button val3 = SetupButton(back);
			TextMeshProUGUI val4 = FindText(back);
			if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null)
			{
				return false;
			}
			((TMP_Text)val4).text = string.Empty;
			SetupButtonText(back, val4);
			_confirmBackLabel = val4;
			((UnityEvent)val3.onClick).AddListener(new UnityAction(Cancel));
			if ((Object)(object)back.transform.parent != (Object)null)
			{
				((Component)back.transform.parent).gameObject.SetActive(false);
			}
			return true;
		}

		private bool BuildBans(GameObject holder, TextMeshProUGUI nativeText)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Expected O, but got Unknown
			_bansPage = Object.Instantiate<GameObject>(_serverScreen, holder.transform, false);
			if (!PreparePage(_bansPage, "HostControlBansScreen", out var title, out var display, out var back, out var nativeText2))
			{
				return false;
			}
			_bansTitle = title;
			GameObject val = new GameObject("BansContent");
			val.transform.SetParent(display, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = new Vector2(32f, 28f);
			val2.offsetMax = new Vector2(-32f, -28f);
			VerticalLayoutGroup obj = val.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 8f;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			_bansStatus = AddText(nativeText2, (Transform)(object)val2, "BansStatus", 20f, 38f, (TextAlignmentOptions)513);
			GameObject val3 = new GameObject("BannedPlayers");
			val3.transform.SetParent((Transform)(object)val2, false);
			val3.AddComponent<LayoutElement>().preferredHeight = 470f;
			_bannedRows = val3.transform;
			VerticalLayoutGroup obj2 = val3.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 5f;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
			Button val4 = (_bansBackButton = SetupButton(back));
			_bansBackLabel = FindText(back);
			if ((Object)(object)val4 == (Object)null || (Object)(object)_bansBackLabel == (Object)null)
			{
				return false;
			}
			SetupButtonText(back, _bansBackLabel);
			((UnityEvent)val4.onClick).AddListener(new UnityAction(BackToMain));
			return true;
		}

		private static bool PreparePage(GameObject page, string name, out TextMeshProUGUI title, out Transform display, out GameObject back, out TextMeshProUGUI nativeText)
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Expected O, but got Unknown
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			title = null;
			display = null;
			back = null;
			nativeText = null;
			if (!Object.op_Implicit((Object)(object)page))
			{
				return false;
			}
			((Object)page).name = name;
			page.SetActive(false);
			Transform val = page.transform.Find("PausedText");
			display = page.transform.Find("ServerDisplay");
			Transform val2 = page.transform.Find("LowerButtonHolder/BackButton");
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)display) || !Object.op_Implicit((Object)(object)val2))
			{
				return false;
			}
			title = ((Component)val).GetComponent<TextMeshProUGUI>();
			nativeText = ((Component)display).GetComponentInChildren<TextMeshProUGUI>(true);
			back = ((Component)val2).gameObject;
			if (!Object.op_Implicit((Object)(object)title) || !Object.op_Implicit((Object)(object)nativeText))
			{
				return false;
			}
			DisableOther(((Component)title).gameObject);
			MoveTitle(val);
			foreach (Transform item in page.transform)
			{
				Transform val3 = item;
				if ((Object)(object)val3 != (Object)(object)val && (Object)(object)val3 != (Object)(object)display && (Object)(object)val3 != (Object)(object)val2.parent)
				{
					((Component)val3).gameObject.SetActive(false);
				}
			}
			foreach (Transform item2 in display)
			{
				Transform val4 = item2;
				if (((Object)val4).name != "Outline")
				{
					((Component)val4).gameObject.SetActive(false);
				}
			}
			RectTransform component = ((Component)display).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = Vector2.zero;
			component.sizeDelta = new Vector2(900f, 640f);
			return true;
		}

		private static void MoveTitle(Transform title)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (((Object)(object)title == (Object)null) ? null : ((Component)title).GetComponent<RectTransform>());
			if ((Object)(object)val != (Object)null)
			{
				val.anchoredPosition += new Vector2(0f, 35f);
			}
		}

		private bool Setup()
		{
			if (_built)
			{
				return true;
			}
			PauseManager val = Object.FindAnyObjectByType<PauseManager>();
			GameObject val2 = (Object.op_Implicit((Object)(object)val) ? GetObject(val, "_pauseHolder") : null);
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2))
			{
				return false;
			}
			if (Object.op_Implicit((Object)(object)_root))
			{
				Object.Destroy((Object)(object)_root);
				_root = null;
			}
			if (Object.op_Implicit((Object)(object)_confirmPage))
			{
				Object.Destroy((Object)(object)_confirmPage);
				_confirmPage = null;
			}
			if (Object.op_Implicit((Object)(object)_bansPage))
			{
				Object.Destroy((Object)(object)_bansPage);
				_bansPage = null;
			}
			if (Object.op_Implicit((Object)(object)_pauseButton))
			{
				Object.Destroy((Object)(object)_pauseButton);
				_pauseButton = null;
			}
			if (!Build(val, val2))
			{
				if (Object.op_Implicit((Object)(object)_root))
				{
					Object.Destroy((Object)(object)_root);
					_root = null;
				}
				if (Object.op_Implicit((Object)(object)_confirmPage))
				{
					Object.Destroy((Object)(object)_confirmPage);
					_confirmPage = null;
				}
				if (Object.op_Implicit((Object)(object)_bansPage))
				{
					Object.Destroy((Object)(object)_bansPage);
					_bansPage = null;
				}
				if (Object.op_Implicit((Object)(object)_pauseButton))
				{
					Object.Destroy((Object)(object)_pauseButton);
					_pauseButton = null;
				}
				return false;
			}
			_built = true;
			return true;
		}

		private void Update()
		{
			if (ControlRuntime.IsHost && (_built || Setup()) && _open && Input.GetKeyDown((KeyCode)27))
			{
				if (Object.op_Implicit((Object)(object)_confirmPage) && _confirmPage.activeSelf)
				{
					Cancel();
				}
				else if (Object.op_Implicit((Object)(object)_bansPage) && _bansPage.activeSelf)
				{
					BackToMain();
				}
				else
				{
					Hide();
				}
			}
		}

		private void OnDestroy()
		{
			PlayerManager.OnPlayerAmountChange -= RefreshAll;
			LocalizationApi.LanguageChanged -= OnLanguageChanged;
			if ((Object)(object)_current == (Object)(object)this)
			{
				_current = null;
			}
		}

		private void OnLanguageChanged(string language)
		{
			Refresh();
		}

		private bool AddPauseButton()
		{
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Expected O, but got Unknown
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_mainScreen))
			{
				return false;
			}
			Transform val = _mainScreen.transform.Find("ServerSettingsButton");
			Transform val2 = _mainScreen.transform.Find("OptionsButton");
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2))
			{
				return false;
			}
			_pauseButton = Object.Instantiate<GameObject>(((Component)val).gameObject, _mainScreen.transform, false);
			((Object)_pauseButton).name = "HostControlPauseButton";
			_pauseButton.SetActive(true);
			DisableOther(_pauseButton);
			Button val3 = SetupButton(_pauseButton);
			TextMeshProUGUI val4 = FindText(_pauseButton);
			if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null)
			{
				Object.Destroy((Object)(object)_pauseButton);
				_pauseButton = null;
				return false;
			}
			RectTransform component = _pauseButton.GetComponent<RectTransform>();
			RectTransform component2 = ((Component)val2).GetComponent<RectTransform>();
			if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component2))
			{
				Object.Destroy((Object)(object)_pauseButton);
				_pauseButton = null;
				return false;
			}
			((Transform)component).SetSiblingIndex(((Transform)component2).GetSiblingIndex() + 1);
			Rect rect = component2.rect;
			float num = Mathf.Max(44f, Mathf.Abs(((Rect)(ref rect)).height) * 1.12f);
			Vector2 anchoredPosition = component2.anchoredPosition;
			anchoredPosition.y -= num;
			component.anchoredPosition = anchoredPosition;
			if ((Object)(object)((Component)val2.parent).GetComponent<LayoutGroup>() == (Object)null)
			{
				RectTransform[] componentsInChildren = ((Component)val2.parent).GetComponentsInChildren<RectTransform>(true);
				foreach (RectTransform val5 in componentsInChildren)
				{
					if ((Object)(object)((Transform)val5).parent == (Object)(object)val2.parent && (Object)(object)val5 != (Object)(object)component2 && (Object)(object)val5 != (Object)(object)component && val5.anchoredPosition.y < component2.anchoredPosition.y)
					{
						Vector2 anchoredPosition2 = val5.anchoredPosition;
						anchoredPosition2.y -= num;
						val5.anchoredPosition = anchoredPosition2;
					}
				}
			}
			SetupButtonText(_pauseButton, val4);
			_pauseButtonLabel = val4;
			((TMP_Text)_pauseButtonLabel).text = I18n.Text("admin.ui.pause_button");
			((UnityEvent)val3.onClick).AddListener(new UnityAction(Show));
			return true;
		}

		private void Show()
		{
			if (!_built && !Setup())
			{
				return;
			}
			if (_open)
			{
				Refresh();
				return;
			}
			_open = true;
			_root.SetActive(true);
			_confirmPage.SetActive(false);
			_bansPage.SetActive(false);
			HideNative();
			PauseManager.TogglePause(true);
			HideNative();
			_root.SetActive(true);
			Refresh();
			if ((Object)(object)EventSystem.current != (Object)null && (Object)(object)_closeButton != (Object)null)
			{
				EventSystem.current.SetSelectedGameObject(((Component)_closeButton).gameObject);
			}
		}

		private void Hide()
		{
			if (_open)
			{
				_open = false;
				Cancel();
				if (Object.op_Implicit((Object)(object)_root))
				{
					_root.SetActive(false);
				}
				if (Object.op_Implicit((Object)(object)_bansPage))
				{
					_bansPage.SetActive(false);
				}
				PauseManager.TogglePause(false);
			}
		}

		private void HideNative()
		{
			if (Object.op_Implicit((Object)(object)_mainScreen))
			{
				_mainScreen.SetActive(false);
			}
			if (Object.op_Implicit((Object)(object)_optionsScreen))
			{
				_optionsScreen.SetActive(false);
			}
			if (Object.op_Implicit((Object)(object)_serverScreen))
			{
				_serverScreen.SetActive(false);
			}
		}

		private void Ask(PendingAction action)
		{
			if (!((action == PendingAction.Kick || action == PendingAction.BanShort || action == PendingAction.BanForever) ? CanModerate() : CanSelect()))
			{
				((TMP_Text)_status).text = I18n.Text("admin.ui.none");
				return;
			}
			_pending = action;
			_pendingSteamId = 0uL;
			_pendingBanName = ControlRuntime.DisplayName(_target);
			_returnToBans = false;
			ShowConfirm();
		}

		private void AskUnban(ControlRuntime.BanEntry entry)
		{
			if (ControlRuntime.IsHost && entry != null && entry.SteamID != 0L)
			{
				_pending = PendingAction.Unban;
				_pendingSteamId = entry.SteamID;
				_pendingBanName = ControlRuntime.DisplayName(entry);
				_returnToBans = true;
				ShowConfirm();
			}
		}

		private void ShowConfirm()
		{
			if (Object.op_Implicit((Object)(object)_confirmPage) && Object.op_Implicit((Object)(object)_confirmText))
			{
				_root.SetActive(false);
				_bansPage.SetActive(false);
				_confirmPage.SetActive(true);
				RefreshConfirm();
				if ((Object)(object)EventSystem.current != (Object)null && (Object)(object)_confirmButton != (Object)null)
				{
					EventSystem.current.SetSelectedGameObject(((Component)_confirmButton).gameObject);
				}
			}
		}

		private void RefreshConfirmText()
		{
			if (!((Object)(object)_confirmText == (Object)null))
			{
				string key = ((_pending == PendingAction.Kick) ? "admin.ui.confirm_kick" : ((_pending == PendingAction.Kill) ? "admin.ui.confirm_kill" : ((_pending == PendingAction.Unban) ? "admin.ui.confirm_unban" : "admin.ui.confirm_ban")));
				((TMP_Text)_confirmText).text = I18n.Text(key, _pendingBanName);
			}
		}

		private void RefreshConfirm()
		{
			if ((Object)(object)_confirmTitle != (Object)null)
			{
				((TMP_Text)_confirmTitle).text = I18n.Text("admin.ui.confirm_title");
			}
			if ((Object)(object)_confirmLabel != (Object)null)
			{
				((TMP_Text)_confirmLabel).text = I18n.Text("admin.ui.confirm");
			}
			if ((Object)(object)_cancelLabel != (Object)null)
			{
				((TMP_Text)_cancelLabel).text = I18n.Text("admin.ui.cancel");
			}
			if ((Object)(object)_confirmBackLabel != (Object)null)
			{
				((TMP_Text)_confirmBackLabel).text = I18n.Text("admin.ui.cancel");
			}
			RefreshConfirmText();
		}

		private void Confirm()
		{
			if (!CanConfirm())
			{
				Cancel();
				return;
			}
			bool flag = _pending switch
			{
				PendingAction.Kick => ControlRuntime.Kick(_target), 
				PendingAction.BanShort => ControlRuntime.Ban(_target, permanent: false), 
				PendingAction.BanForever => ControlRuntime.Ban(_target, permanent: true), 
				PendingAction.Kill => ControlRuntime.Kill(_target), 
				PendingAction.Unban => ControlRuntime.Unban(_pendingSteamId), 
				_ => false, 
			};
			_pending = PendingAction.None;
			_pendingSteamId = 0uL;
			_confirmPage.SetActive(false);
			if (_returnToBans)
			{
				_bansPage.SetActive(true);
				RefreshBans();
			}
			else
			{
				_root.SetActive(true);
				((TMP_Text)_status).text = I18n.Text(flag ? "admin.ui.done" : "admin.ui.denied");
				RefreshRows();
				RefreshButtons();
			}
			_returnToBans = false;
		}

		private void Cancel()
		{
			_pending = PendingAction.None;
			_pendingSteamId = 0uL;
			if ((Object)(object)_confirmPage != (Object)null)
			{
				_confirmPage.SetActive(false);
			}
			if (_returnToBans && (Object)(object)_bansPage != (Object)null)
			{
				_bansPage.SetActive(true);
				RefreshBans();
			}
			else if ((Object)(object)_root != (Object)null && _open)
			{
				_root.SetActive(true);
				Refresh();
			}
			_returnToBans = false;
		}

		private void ShowBans()
		{
			if (_open && Object.op_Implicit((Object)(object)_bansPage))
			{
				_root.SetActive(false);
				_confirmPage.SetActive(false);
				_bansPage.SetActive(true);
				RefreshBans();
				if ((Object)(object)EventSystem.current != (Object)null && (Object)(object)_bansBackButton != (Object)null)
				{
					EventSystem.current.SetSelectedGameObject(((Component)_bansBackButton).gameObject);
				}
			}
		}

		private void BackToMain()
		{
			Cancel();
			if (Object.op_Implicit((Object)(object)_bansPage))
			{
				_bansPage.SetActive(false);
			}
			if (Object.op_Implicit((Object)(object)_root) && _open)
			{
				_root.SetActive(true);
				Refresh();
			}
		}

		private void Revive()
		{
			bool flag = CanSelect() && ControlRuntime.Revive(_target);
			((TMP_Text)_status).text = I18n.Text(flag ? "admin.ui.done" : "admin.ui.denied");
			RefreshRows();
			RefreshButtons();
		}

		private void Teleport()
		{
			bool flag = CanSelect() && ControlRuntime.TeleportToHost(_target);
			((TMP_Text)_status).text = I18n.Text(flag ? "admin.ui.done" : "admin.ui.denied");
			RefreshRows();
			RefreshButtons();
		}

		private bool CanSelect()
		{
			if (ControlRuntime.IsHost && (Object)(object)_target != (Object)null && !((NetworkBehaviour)_target).IsDeinitializing)
			{
				return ((NetworkBehaviour)_target).Owner != (NetworkConnection)null;
			}
			return false;
		}

		private bool CanModerate()
		{
			if (CanSelect())
			{
				return (Object)(object)_target != (Object)(object)Player.LocalPlayer;
			}
			return false;
		}

		private bool CanConfirm()
		{
			if (_pending != PendingAction.Unban)
			{
				if (_pending != PendingAction.Kick && _pending != PendingAction.BanShort && _pending != PendingAction.BanForever)
				{
					return CanSelect();
				}
				return CanModerate();
			}
			if (ControlRuntime.IsHost)
			{
				return _pendingSteamId != 0;
			}
			return false;
		}

		private void Refresh()
		{
			if (!((Object)(object)_title == (Object)null) && !((Object)(object)_selected == (Object)null) && !((Object)(object)_status == (Object)null) && !((Object)(object)_closeLabel == (Object)null))
			{
				((TMP_Text)_title).text = I18n.Text("admin.ui.title");
				if ((Object)(object)_pauseButtonLabel != (Object)null)
				{
					((TMP_Text)_pauseButtonLabel).text = I18n.Text("admin.ui.pause_button");
				}
				((TMP_Text)_closeLabel).text = I18n.Text("admin.ui.close");
				((TMP_Text)_kickLabel).text = I18n.Text("admin.ui.kick");
				((TMP_Text)_banShortLabel).text = I18n.Text("admin.ui.ban_short");
				((TMP_Text)_banForeverLabel).text = I18n.Text("admin.ui.ban_forever");
				((TMP_Text)_killLabel).text = I18n.Text("admin.ui.kill");
				((TMP_Text)_reviveLabel).text = I18n.Text("admin.ui.revive");
				((TMP_Text)_teleportLabel).text = I18n.Text("admin.ui.to_host");
				((TMP_Text)_bansLabel).text = I18n.Text("admin.ui.bans");
				((TMP_Text)_status).text = I18n.Text("admin.ui.none");
				RefreshSelected();
				RefreshRows();
				RefreshButtons();
				if (Object.op_Implicit((Object)(object)_confirmPage) && _confirmPage.activeSelf)
				{
					RefreshConfirm();
				}
				if (Object.op_Implicit((Object)(object)_bansPage) && _bansPage.activeSelf)
				{
					RefreshBans();
				}
			}
		}

		private void RefreshSelected()
		{
			((TMP_Text)_selected).text = (((Object)(object)_target == (Object)null) ? I18n.Text("admin.ui.none") : I18n.Text("admin.ui.selected", ControlRuntime.DisplayName(_target)));
		}

		private void RefreshRows()
		{
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Expected O, but got Unknown
			if ((Object)(object)_rows == (Object)null)
			{
				return;
			}
			for (int num = _rows.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)_rows.GetChild(num)).gameObject);
			}
			bool flag = false;
			for (int i = 0; i < PlayerManager.Players.Count; i++)
			{
				Player val = PlayerManager.Players[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				string text = (((Object)(object)val.Dying != (Object)null && val.Dying.IsDead) ? I18n.Text("admin.ui.dead") : I18n.Text("admin.ui.alive"));
				if (val.IsAfk)
				{
					text = text + " / " + I18n.Text("admin.ui.afk");
				}
				string text2 = ControlRuntime.DisplayName(val);
				if ((Object)(object)val == (Object)(object)Player.LocalPlayer)
				{
					text2 = text2 + " " + I18n.Text("admin.ui.host");
				}
				GameObject val2 = MakeButton(_buttonTemplate, _rows, "Player " + val.SteamID);
				if (!SetupSplitRow(val2, text2, val.SteamID + "\n" + ((((NetworkBehaviour)val).Owner == (NetworkConnection)null) ? I18n.Text("admin.ui.disconnected") : I18n.Text("admin.ui.connected")) + " / " + text, 46f, out var row))
				{
					Object.Destroy((Object)(object)val2);
					continue;
				}
				Player selected = val;
				((UnityEvent)row.onClick).AddListener((UnityAction)delegate
				{
					Select(selected);
				});
				flag = true;
			}
			if (!flag)
			{
				((TMP_Text)AddText(FindText(_buttonTemplate), _rows, "Empty", 18f, 42f, (TextAlignmentOptions)514)).text = I18n.Text("admin.ui.empty");
			}
		}

		private void RefreshBans()
		{
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Expected O, but got Unknown
			if ((Object)(object)_bannedRows == (Object)null || (Object)(object)_bansStatus == (Object)null)
			{
				return;
			}
			((TMP_Text)_bansTitle).text = I18n.Text("admin.ui.bans");
			((TMP_Text)_bansBackLabel).text = I18n.Text("admin.ui.back");
			List<ControlRuntime.BanEntry> bans = ControlRuntime.GetBans();
			((TMP_Text)_bansStatus).text = I18n.Text((bans.Count == 0) ? "admin.ui.no_bans" : "admin.ui.bans_count", bans.Count);
			for (int num = _bannedRows.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)_bannedRows.GetChild(num)).gameObject);
			}
			if (bans.Count == 0)
			{
				((TMP_Text)AddText(FindText(_buttonTemplate), _bannedRows, "EmptyBans", 20f, 42f, (TextAlignmentOptions)514)).text = I18n.Text("admin.ui.empty_bans");
				return;
			}
			for (int i = 0; i < bans.Count; i++)
			{
				ControlRuntime.BanEntry banEntry = bans[i];
				GameObject val = MakeButton(_buttonTemplate, _bannedRows, "Ban " + banEntry.SteamID);
				if (!SetupSplitRow(val, ControlRuntime.DisplayName(banEntry), banEntry.SteamID + "\n" + ControlRuntime.BanExpiry(banEntry) + " / " + I18n.Text("admin.ui.unban"), 58f, out var row))
				{
					Object.Destroy((Object)(object)val);
					continue;
				}
				ControlRuntime.BanEntry selected = banEntry;
				((UnityEvent)row.onClick).AddListener((UnityAction)delegate
				{
					AskUnban(selected);
				});
			}
		}

		private void Select(Player player)
		{
			_target = player;
			Cancel();
			RefreshSelected();
			RefreshButtons();
		}

		private void RefreshButtons()
		{
			bool flag = CanSelect();
			bool flag2 = CanModerate();
			if ((Object)(object)_kickButton != (Object)null)
			{
				((Selectable)_kickButton).interactable = flag2;
			}
			bool interactable = flag2 && _target.SteamID != 0;
			if ((Object)(object)_banShortButton != (Object)null)
			{
				((Selectable)_banShortButton).interactable = interactable;
			}
			if ((Object)(object)_banForeverButton != (Object)null)
			{
				((Selectable)_banForeverButton).interactable = interactable;
			}
			if ((Object)(object)_killButton != (Object)null)
			{
				((Selectable)_killButton).interactable = flag && (Object)(object)_target.Vitals != (Object)null && _target.Vitals.Health > 0;
			}
			if ((Object)(object)_reviveButton != (Object)null)
			{
				((Selectable)_reviveButton).interactable = flag && (Object)(object)_target.Vitals != (Object)null && _target.Vitals.Health <= 0;
			}
			if ((Object)(object)_teleportButton != (Object)null)
			{
				((Selectable)_teleportButton).interactable = flag;
			}
		}

		private static Transform MakeRow(Transform parent, string name)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			val.AddComponent<LayoutElement>().preferredHeight = 48f;
			HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 6f;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			return val.transform;
		}

		private static bool SetupSplitRow(GameObject rowObject, string leftText, string rightText, float height, out Button row)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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)
			row = FindButton(rowObject);
			TextMeshProUGUI val = FindText(rowObject);
			if ((Object)(object)row == (Object)null || (Object)(object)val == (Object)null)
			{
				return false;
			}
			Button obj = row;
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)3;
			((Selectable)obj).navigation = navigation;
			(rowObject.GetComponent<LayoutElement>() ?? rowObject.AddComponent<LayoutElement>()).preferredHeight = height;
			((TMP_Text)val).transform.SetParent(rowObject.transform, false);
			SetupRowText(val, leftText, new Vector2(0.04f, 0.08f), new Vector2(0.58f, 0.92f), (TextAlignmentOptions)4097, 13f, 23f);
			TextMeshProUGUI obj2 = Object.Instantiate<TextMeshProUGUI>(val, rowObject.transform, false);
			((Object)((Component)obj2).gameObject).name = "Right";
			SetupRowText(obj2, rightText, new Vector2(0.6f, 0.08f), new Vector2(0.96f, 0.92f), (TextAlignmentOptions)4100, 11f, 19f);
			return true;
		}

		private static void SetupRowText(TextMeshProUGUI text, string value, Vector2 anchorMin, Vector2 anchorMax, TextAlignmentOptions alignment, float minSize, float maxSize)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			RectTransform rectTransform = ((TMP_Text)text).rectTransform;
			rectTransform.anchorMin = anchorMin;
			rectTransform.anchorMax = anchorMax;
			rectTransform.offsetMin = Vector2.zero;
			rectTransform.offsetMax = Vector2.zero;
			((TMP_Text)text).text = value;
			((TMP_Text)text).alignment = alignment;
			((TMP_Text)text).enableAutoSizing = true;
			((TMP_Text)text).fontSizeMin = minSize;
			((TMP_Text)text).fontSizeMax = maxSize;
			((TMP_Text)text).textWrappingMode = (TextWrappingModes)1;
			((TMP_Text)text).overflowMode = (TextOverflowModes)1;
			((Graphic)text).raycastTarget = false;
		}

		private static Button AddButton(GameObject template, Transform parent, string name, out TextMeshProUGUI label)
		{
			GameObject val = MakeButton(template, parent, name);
			Button obj = FindButton(val);
			label = FindText(val);
			if ((Object)(object)obj != (Object)null)
			{
				(val.GetComponent<LayoutElement>() ?? val.AddComponent<LayoutElement>()).preferredHeight = 46f;
				SetupButtonText(val, label);
			}
			return obj;
		}

		private static void SetupButtonText(GameObject buttonObject, TextMeshProUGUI text)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)buttonObject == (Object)null) && !((Object)(object)text == (Object)null))
			{
				((TMP_Text)text).transform.SetParent(buttonObject.transform, false);
				RectTransform rectTransform = ((TMP_Text)text).rectTransform;
				rectTransform.anchorMin = new Vector2(0.04f, 0.06f);
				rectTransform.anchorMax = new Vector2(0.96f, 0.94f);
				rectTransform.offsetMin = Vector2.zero;
				rectTransform.offsetMax = Vector2.zero;
				((TMP_Text)text).alignment = (TextAlignmentOptions)514;
				((TMP_Text)text).enableAutoSizing = true;
				((TMP_Text)text).fontSizeMin = 12f;
				((TMP_Text)text).fontSizeMax = Mathf.Max(18f, Mathf.Min(32f, ((TMP_Text)text).fontSize));
				((TMP_Text)text).textWrappingMode = (TextWrappingModes)0;
				((TMP_Text)text).overflowMode = (TextOverflowModes)1;
				((Graphic)text).raycastTarget = false;
			}
		}

		private static TextMeshProUGUI AddText(TextMeshProUGUI template, Transform parent, string name, float size, float height, TextAlignmentOptions alignment)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = Object.Instantiate<TextMeshProUGUI>(template, parent, false);
			((Object)((Component)val).gameObject).name = name;
			((Component)val).gameObject.SetActive(true);
			DisableOther(((Component)val).gameObject);
			((TMP_Text)val).fontSize = size;
			((TMP_Text)val).alignment = alignment;
			((Graphic)val).raycastTarget = false;
			((TMP_Text)val).textWrappingMode = (TextWrappingModes)1;
			(((Component)val).GetComponent<LayoutElement>() ?? ((Component)val).gameObject.AddComponent<LayoutElement>()).preferredHeight = height;
			return val;
		}

		private static GameObject MakeButton(GameObject template, Transform parent, string name)
		{
			GameObject obj = Object.Instantiate<GameObject>(template, parent, false);
			((Object)obj).name = name;
			obj.SetActive(true);
			DisableOther(obj);
			SetupButton(obj);
			TextMeshProUGUI val = FindText(obj);
			if ((Object)(object)val != (Object)null)
			{
				((TMP_Text)val).text = string.Empty;
			}
			return obj;
		}

		private static Button SetupButton(GameObject buttonObject)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			Button val = (((Object)(object)buttonObject == (Object)null) ? null : buttonObject.GetComponent<Button>());
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			val.onClick = new ButtonClickedEvent();
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)3;
			((Selectable)val).navigation = navigation;
			return val;
		}

		private static Button FindButton(GameObject root)
		{
			Button[] array = (((Object)(object)root == (Object)null) ? Array.Empty<Button>() : root.GetComponents<Button>());
			for (int num = array.Length - 1; num >= 0; num--)
			{
				if (((Behaviour)array[num]).enabled)
				{
					return array[num];
				}
			}
			return null;
		}

		private static TextMeshProUGUI FindText(GameObject root)
		{
			if (!((Object)(object)root == (Object)null))
			{
				return root.GetComponentInChildren<TextMeshProUGUI>(true);
			}
			return null;
		}

		private static void DisableOther(GameObject root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if (!(val is Graphic) && !(val is Selectable) && !(val is TMP_Text) && !(val is UIButton) && !(val is Shadow) && !(val is LayoutGroup) && !(val is LayoutElement) && !(val is ContentSizeFitter) && !(val is RectMask2D))
				{
					((Behaviour)val).enabled = false;
				}
			}
		}

		private static GameObject GetObject(PauseManager pause, string field)
		{
			object? obj = AccessTools.Field(typeof(PauseManager), field)?.GetValue(pause);
			return (GameObject)((obj is GameObject) ? obj : null);
		}
	}
}
namespace HostControl.Runtime
{
	internal static class ControlRuntime
	{
		[Serializable]
		private sealed class BanSave
		{
			public List<BanEntry> Entries = new List<BanEntry>();
		}

		[Serializable]
		internal sealed class BanEntry
		{
			public ulong SteamID;

			public string Name;

			public string Reason;

			public long ExpiresUtcTicks;

			public long CreatedUtcTicks;
		}

		private static readonly Dictionary<ulong, BanEntry> Bans = new Dictionary<ulong, BanEntry>();

		private static ManualLogSource _log;

		private static bool _loaded;

		private static bool _eventsBound;

		private static string _savePath;

		internal static bool IsHost
		{
			get
			{
				if (InstanceFinder.IsServerStarted && (Object)(object)Player.LocalPlayer != (Object)null && ((NetworkBehaviour)Player.LocalPlayer).Owner != (NetworkConnection)null)
				{
					return ((NetworkBehaviour)Player.LocalPlayer).Owner.IsLocalClient;
				}
				return false;
			}
		}

		internal static void Init(ManualLogSource log)
		{
			_log = log;
		}

		internal static void ServerStarted()
		{
			if (InstanceFinder.IsServerStarted)
			{
				EnsureLoaded();
				BindEvents();
			}
		}

		internal static void ServerStopped()
		{
			Save();
			ControlUi.Destroy();
			if (_eventsBound && (Object)(object)InstanceFinder.ServerManager != (Object)null)
			{
				InstanceFinder.ServerManager.OnRemoteConnectionState -= OnRemoteConnectionState;
			}
			_eventsBound = false;
			_loaded = false;
			_savePath = null;
			Bans.Clear();
		}

		internal static void PlayerStarted(Player player)
		{
			if (InstanceFinder.IsServerStarted)
			{
				EnsureLoaded();
			}
			if (IsHost)
			{
				ControlUi.RefreshAll();
			}
		}

		internal static void PlayerStopped(Player player)
		{
			if ((Object)(object)player != (Object)null && ((NetworkBehaviour)player).Owner != (NetworkConnection)null && ((NetworkBehaviour)player).Owner.IsLocalClient)
			{
				ControlUi.Destroy();
			}
			else if (IsHost)
			{
				ControlUi.RefreshAll();
			}
		}

		internal static bool AllowSpawn(NetworkConnection connection)
		{
			if (!InstanceFinder.IsServerStarted || connection == (NetworkConnection)null)
			{
				return true;
			}
			EnsureLoaded();
			if (!TryGetSteamId(connection, out var steamId) || !TryGetActiveBan(steamId, out var ban))
			{
				return true;
			}
			connection.Kick((KickReason)5, (LoggingType)3, ban.Reason);
			return false;
		}

		internal static bool Kick(Player target)
		{
			if (!CanAct(target) || (Object)(object)target == (Object)(object)Player.LocalPlayer || ((NetworkBehaviour)target).Owner == (NetworkConnection)null)
			{
				return false;
			}
			((NetworkBehaviour)target).Owner.Kick((KickReason)5, (LoggingType)3, I18n.Text("admin.reason.kick"));
			return true;
		}

		internal static bool Ban(Player target, bool permanent)
		{
			if (!CanAct(target) || (Object)(object)target == (Object)(object)Player.LocalPlayer || ((NetworkBehaviour)target).Owner == (NetworkConnection)null || target.SteamID == 0L)
			{
				return false;
			}
			EnsureLoaded();
			DateTime utcNow = DateTime.UtcNow;
			Bans[target.SteamID] = new BanEntry
			{
				SteamID = target.SteamID,
				Name = DisplayName(target),
				Reason = I18n.Text("admin.reason.ban"),
				CreatedUtcTicks = utcNow.Ticks,
				ExpiresUtcTicks = (permanent ? 0 : utcNow.AddMinutes(10.0).Ticks)
			};
			Save();
			((NetworkBehaviour)target).Owner.Kick((KickReason)5, (LoggingType)3, I18n.Text("admin.reason.ban"));
			return true;
		}

		internal static List<BanEntry> GetBans()
		{
			EnsureLoaded();
			DateTime utcNow = DateTime.UtcNow;
			List<ulong> list = new List<ulong>();
			List<BanEntry> list2 = new List<BanEntry>();
			foreach (BanEntry value in Bans.Values)
			{
				if (value.ExpiresUtcTicks != 0L && utcNow.Ticks >= value.ExpiresUtcTicks)
				{
					list.Add(value.SteamID);
				}
				else
				{
					list2.Add(value);
				}
			}
			for (int i = 0; i < list.Count; i++)
			{
				Bans.Remove(list[i]);
			}
			if (list.Count > 0)
			{
				Save();
			}
			list2.Sort((BanEntry left, BanEntry right) => string.Compare(DisplayName(left), DisplayName(right), StringComparison.OrdinalIgnoreCase));
			return list2;
		}

		internal static bool Unban(ulong steamId)
		{
			if (!IsHost || steamId == 0L)
			{
				return false;
			}
			EnsureLoaded();
			if (!Bans.TryGetValue(steamId, out var _))
			{
				return false;
			}
			Bans.Remove(steamId);
			Save();
			return true;
		}

		internal static void DeleteSaveData(string serverName)
		{
			if (string.IsNullOrWhiteSpace(serverName))
			{
				return;
			}
			string text = SafeServerName(serverName);
			string path = Path.Combine(Application.persistentDataPath, "Saves");
			string path2 = Path.Combine(path, text + ".HostControl.json");
			string path3 = Path.Combine(path, text + ".HostControl.audit.log");
			try
			{
				if (File.Exists(path2))
				{
					File.Delete(path2);
				}
				if (File.Exists(path3))
				{
					File.Delete(path3);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogError((object)("Failed to delete HostControl save data: " + ex));
				}
			}
		}

		internal static string DisplayName(BanEntry entry)
		{
			if (entry == null || string.IsNullOrWhiteSpace(entry.Name))
			{
				return entry?.SteamID.ToString() ?? string.Empty;
			}
			return entry.Name;
		}

		internal static string BanExpiry(BanEntry entry)
		{
			if (entry == null || entry.ExpiresUtcTicks == 0L)
			{
				return I18n.Text("admin.ui.permanent");
			}
			return I18n.Text("admin.ui.until", new DateTime(entry.ExpiresUtcTicks, DateTimeKind.Utc).ToLocalTime().ToString("g"));
		}

		internal static bool Kill(Player target)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (!CanAct(target) || (Object)(object)target.Vitals == (Object)null || target.Vitals.Health <= 0)
			{
				return false;
			}
			target.Vitals.TakeDamage(999999, Vector3.zero, Vector3.zero, true);
			return true;
		}

		internal static bool Revive(Player target)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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)
			if (!CanAct(target) || (Object)(object)target.Vitals == (Object)null || target.Vitals.Health > 0 || (Object)(object)Server.Instance == (Object)null || (Object)(object)target.Transform == (Object)null)
			{
				return false;
			}
			Quaternion val = Quaternion.Euler(0f, target.Transform.eulerAngles.y, 0f);
			Server.Instance.RpcLogic___RespawnPlayer___2210451296(target, target.Transform.position, val);
			return true;
		}

		internal static bool TeleportToHost(Player target)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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)
			if (!CanAct(target) || (Object)(object)Server.Instance == (Object)null || (Object)(object)Player.LocalPlayer.Transform == (Object)null)
			{
				return false;
			}
			Vector3 position = Player.LocalPlayer.Transform.position;
			float y = Player.LocalPlayer.Transform.eulerAngles.y;
			Server.Instance.RpcLogic___TeleportPlayer___3852204532(target, position, y);
			return true;
		}

		internal static string DisplayName(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return string.Empty;
			}
			if (!string.IsNullOrWhiteSpace(player.SteamName))
			{
				return player.SteamName;
			}
			return player.SteamID.ToString();
		}

		private static bool CanAct(Player target)
		{
			if (IsHost && (Object)(object)target != (Object)null && !((NetworkBehaviour)target).IsDeinitializing)
			{
				return ((NetworkBehaviour)target).Owner != (NetworkConnection)null;
			}
			return false;
		}

		private static void BindEvents()
		{
			if (!_eventsBound && !((Object)(object)InstanceFinder.ServerManager == (Object)null))
			{
				InstanceFinder.ServerManager.OnRemoteConnectionState += OnRemoteConnectionState;
				_eventsBound = true;
			}
		}

		private static void OnRemoteConnectionState(NetworkConnection connection, RemoteConnectionStateArgs args)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)args.ConnectionState == 2 && !(connection == (NetworkConnection)null))
			{
				EnsureLoaded();
				if (TryGetSteamId(connection, out var steamId) && TryGetActiveBan(steamId, out var ban))
				{
					connection.Kick((KickReason)5, (LoggingType)3, ban.Reason);
				}
			}
		}

		private static bool TryGetSteamId(NetworkConnection connection, out ulong steamId)
		{
			steamId = 0uL;
			if (ConnectionManager.IsUsingSteam && connection != (NetworkConnection)null && ulong.TryParse(connection.GetAddress(), out steamId))
			{
				return steamId != 0;
			}
			return false;
		}

		private static bool TryGetActiveBan(ulong steamId, out BanEntry ban)
		{
			ban = null;
			if (steamId == 0L || !Bans.TryGetValue(steamId, out var value))
			{
				return false;
			}
			if (value.ExpiresUtcTicks != 0L && DateTime.UtcNow.Ticks >= value.ExpiresUtcTicks)
			{
				Bans.Remove(steamId);
				Save();
				return false;
			}
			ban = value;
			return true;
		}

		private static void EnsureLoaded()
		{
			string text = SavePath();
			if (_loaded && string.Equals(_savePath, text, StringComparison.OrdinalIgnoreCase))
			{
				BindEvents();
				return;
			}
			_loaded = true;
			_savePath = text;
			Bans.Clear();
			if (!File.Exists(_savePath))
			{
				BindEvents();
				return;
			}
			try
			{
				BanSave banSave = JsonConvert.DeserializeObject<BanSave>(File.ReadAllText(_savePath));
				if (banSave != null && banSave.Entries != null)
				{
					foreach (BanEntry entry in banSave.Entries)
					{
						if (entry != null && entry.SteamID != 0L)
						{
							Bans[entry.SteamID] = entry;
						}
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogError((object)("Failed to load host admin bans: " + ex));
				}
			}
			BindEvents();
		}

		private static void Save()
		{
			if (!_loaded || string.IsNullOrEmpty(_savePath))
			{
				return;
			}
			try
			{
				string directoryName = Path.GetDirectoryName(_savePath);
				if (!Directory.Exists(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				BanSave banSave = new BanSave();
				foreach (BanEntry value in Bans.Values)
				{
					banSave.Entries.Add(value);
				}
				File.WriteAllText(_savePath, JsonConvert.SerializeObject((object)banSave));
			}
			catch (Exception ex)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogError((object)("Failed to save host admin bans: " + ex));
				}
			}
		}

		private static string SavePath()
		{
			return Path.Combine(Application.persistentDataPath, "Saves", SafeServerName() + ".HostControl.json");
		}

		private static string SafeServerName()
		{
			return SafeServerName((SaveManager.CurServerSave == null) ? "HostControl" : SaveManager.CurServerSave.Name);
		}

		private static string SafeServerName(string name)
		{
			char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
			foreach (char oldChar in invalidFileNameChars)
			{
				name = name.Replace(oldChar, '_');
			}
			return name;
		}
	}
}
namespace HostControl.Patches
{
	[HarmonyPatch(typeof(PlayerUI), "Update")]
	internal static class ControlInputPatch
	{
		private static void Postfix()
		{
			ControlUi.Tick();
		}
	}
	[HarmonyPatch(typeof(Server), "OnStartClient")]
	internal static class ServerStartPatch
	{
		private static void Postfix()
		{
			ControlRuntime.ServerStarted();
		}
	}
	[HarmonyPatch(typeof(Server), "OnStopServer")]
	internal static class ServerStopPatch
	{
		private static void Postfix()
		{
			ControlRuntime.ServerStopped();
		}
	}
	[HarmonyPatch(typeof(SaveManager), "DeleteServer")]
	internal static class SaveDeletePatch
	{
		private static void Prefix(out string __state)
		{
			__state = ((SaveManager.CurServerSave == null) ? null : SaveManager.CurServerSave.Name);
		}

		private static void Postfix(string __state)
		{
			ControlRuntime.DeleteSaveData(__state);
		}
	}
	[HarmonyPatch(typeof(Server), "RpcLogic___SpawnPlayer___1871804056")]
	internal static class SpawnGuardPatch
	{
		private static bool Prefix(NetworkConnection __14)
		{
			return ControlRuntime.AllowSpawn(__14);
		}
	}
	[HarmonyPatch(typeof(Player), "OnStartClient")]
	internal static class PlayerStartPatch
	{
		private static void Postfix(Player __instance)
		{
			ControlRuntime.PlayerStarted(__instance);
		}
	}
	[HarmonyPatch(typeof(Player), "OnStopClient")]
	internal static class PlayerStopPatch
	{
		private static void Postfix(Player __instance)
		{
			ControlRuntime.PlayerStopped(__instance);
		}
	}
}
namespace HostControl.Localization
{
	internal static class I18n
	{
		private const string FileName = "HostControl.Localization.json";

		private static readonly ModLocalizer _localizer = Load();

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

		private static ModLocalizer Load()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			ModLocalizer obj = LocalizationApi.For("IceBoxStudio.HowToFish.HostControl");
			obj.RegisterJson(Path.Combine(directoryName, "HostControl.Localization.json"));
			return obj;
		}
	}
}
namespace HostControl.Configuration
{
	internal static class ConfigManager
	{
		private static ConfigEntry<KeyboardShortcut> _openKey;

		internal static void Init(ConfigFile config)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			_openKey = config.Bind<KeyboardShortcut>("Controls", "OpenControl", new KeyboardShortcut((KeyCode)107, Array.Empty<KeyCode>()), I18n.Text("admin.config.open_key"));
		}

		internal static bool IsOpenPressed()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (_openKey != null)
			{
				KeyboardShortcut value = _openKey.Value;
				return ((KeyboardShortcut)(ref value)).IsDown();
			}
			return false;
		}
	}
}