Decompiled source of Quick Restart v2.4.0

tony4twentys-Quick Restart.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Newtonsoft.Json;
using Photon.Pun;
using Photon.Realtime;
using PhotonCustomPropsUtils;
using QuickRestart;
using Steamworks;
using TMPro;
using TerrainRandomiser;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyTitle("Quick Restart")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Quick Restart")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("89a2838d-6516-48d0-bfaf-bda1077942b6")]
[assembly: AssemblyFileVersion("2.4.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.4.0.0")]
[module: UnverifiableCode]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("tony4twentys.quickrestart", "Quick Restart", "2.4.0")]
public class QuickRestartPlugin : BaseUnityPlugin, IOnEventCallback, IInRoomCallbacks, IMatchmakingCallbacks
{
	[HarmonyPatch(typeof(BoardingPass), "StartGame")]
	private static class Patch_BoardingPassStartGame
	{
		private static bool Prefix(BoardingPass __instance)
		{
			//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)
			QuickRestartPlugin instance = Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return true;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name == "Airport")
			{
				return true;
			}
			if (!instance.boardingPassOpenedByQuickRestart)
			{
				return true;
			}
			TrCompat.SaveUiSettings();
			bool flag = instance.ShouldUseTerrainRandomizerFromBoardingPass();
			int num = (((Object)(object)__instance != (Object)null) ? __instance.ascentIndex : Ascents.currentAscent);
			instance.boardingPassOpenedByQuickRestart = false;
			GUIManager instance2 = GUIManager.instance;
			if (instance2 != null)
			{
				BoardingPass boardingPass = instance2.boardingPass;
				if (boardingPass != null)
				{
					((MenuWindow)boardingPass).ForceClose();
				}
			}
			((BaseUnityPlugin)instance).Logger.LogInfo((object)(flag ? $"Quick Restart: Mid-run boarding pass Start -> airport auto-board TR (ascent={num})." : $"Quick Restart: Mid-run boarding pass Start -> airport auto-board vanilla (ascent={num})."));
			instance.BeginQuickRestart(flag, num);
			return false;
		}
	}

	public const string ModVersion = "2.4.0";

	public const string RoomModPropertyKey = "QR_ModVersion";

	public const byte IslandRestartEventCode = 177;

	private const float ModPresenceGraceSeconds = 0.75f;

	private bool shouldAutoRestart;

	private bool restartWithTr;

	private bool hasAutoClickedMainMenuButton;

	private bool restartInProgress;

	private bool boardingPassOpenedByQuickRestart;

	private bool airportBoardRoutineRunning;

	private int requestedRestartAscent = -1;

	private Harmony harmony;

	private ConfigEntry<KeyCode> menuKey;

	private ConfigEntry<bool> skipAirportInMultiplayer;

	private ConfigEntry<bool> showPauseMenuButton;

	private ConfigEntry<bool> skipSplashScreen;

	private ConfigEntry<float> mainMenuClickDelay;

	private ConfigEntry<bool> enableMainMenuAutoClick;

	private ConfigEntry<string> mainMenuButtonChoice;

	private ConfigEntry<string> menuPanelColor;

	private ConfigEntry<string> menuButtonColor;

	private ConfigEntry<string> menuTextColor;

	private ConfigEntry<string> menuAccentColor;

	private ConfigEntry<bool> enableHotkeys;

	private ConfigEntry<KeyCode> hotkeyBoardingPass;

	private ConfigEntry<KeyCode> hotkeyQuickRestart;

	private ConfigEntry<KeyCode> hotkeyQuickRestartTr;

	private ConfigEntry<KeyCode> hotkeyReturnToAirport;

	public static QuickRestartPlugin Instance { get; private set; }

	public static ManualLogSource Log { get; private set; }

	public ConfigEntry<KeyCode> MenuKey => menuKey;

	public ConfigEntry<bool> SkipAirportInMultiplayer => skipAirportInMultiplayer;

	public ConfigEntry<bool> ShowPauseMenuButton => showPauseMenuButton;

	public ConfigEntry<bool> EnableHotkeys => enableHotkeys;

	public ConfigEntry<string> MenuPanelColor => menuPanelColor;

	public ConfigEntry<string> MenuButtonColor => menuButtonColor;

	public ConfigEntry<string> MenuTextColor => menuTextColor;

	public ConfigEntry<string> MenuAccentColor => menuAccentColor;

	public ConfigEntry<KeyCode> HotkeyBoardingPass => hotkeyBoardingPass;

	public ConfigEntry<KeyCode> HotkeyQuickRestart => hotkeyQuickRestart;

	public ConfigEntry<KeyCode> HotkeyQuickRestartTr => hotkeyQuickRestartTr;

	public ConfigEntry<KeyCode> HotkeyReturnToAirport => hotkeyReturnToAirport;

	private void Awake()
	{
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0279: Expected O, but got Unknown
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		menuKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "MenuKey", (KeyCode)291, "Key to open the Quick Restart menu.");
		skipAirportInMultiplayer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SkipAirportInMultiplayer", true, "MID-RUN MULTIPLAYER ONLY: when every connected player has Quick Restart, skip the airport and reload the island directly. If any player is missing this mod, the airport detour is used automatically. WARNING: Skipping the airport in multiplayer can cause a few seconds of movement/action desync after loading (especially with other mods). Set this to false to always return to the airport first in multiplayer (more reliable). Solo/offline always skips the airport regardless of this setting. Starting from the Airport scene always uses the vanilla kiosk.");
		showPauseMenuButton = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowPauseMenuButton", true, "Show a Quick Restart button on the pause menu, stacked above Leave Game.");
		skipSplashScreen = ((BaseUnityPlugin)this).Config.Bind<bool>("MainMenu", "SkipSplashScreen", true, "Skip the splash screen when the game starts.");
		enableMainMenuAutoClick = ((BaseUnityPlugin)this).Config.Bind<bool>("MainMenu", "EnableAutoClick", true, "Automatically click a button when reaching the main menu.");
		mainMenuButtonChoice = ((BaseUnityPlugin)this).Config.Bind<string>("MainMenu", "ButtonChoice", "Button_PlayWithFriends", "Which button to automatically click: 'Button_PlayWithFriends' or 'Button_PlaySolo'.");
		mainMenuClickDelay = ((BaseUnityPlugin)this).Config.Bind<float>("MainMenu", "MainMenuClickDelay", 1f, "Delay before clicking button when reaching main menu (seconds).");
		menuPanelColor = ((BaseUnityPlugin)this).Config.Bind<string>("Menu", "PanelColor", "140F0DF0", "Menu background color (hex RRGGBB or RRGGBBAA).");
		menuButtonColor = ((BaseUnityPlugin)this).Config.Bind<string>("Menu", "ButtonColor", "2E2017BA", "Menu button color (hex RRGGBB or RRGGBBAA).");
		menuTextColor = ((BaseUnityPlugin)this).Config.Bind<string>("Menu", "TextColor", "F2EDE0FF", "Menu text color (hex RRGGBB or RRGGBBAA).");
		menuAccentColor = ((BaseUnityPlugin)this).Config.Bind<string>("Menu", "AccentColor", "8C6B38F2", "Selected tab, sliders, and checkbox marks (hex RRGGBB or RRGGBBAA).");
		enableHotkeys = ((BaseUnityPlugin)this).Config.Bind<bool>("Hotkeys", "EnableHotkeys", false, "Enable hotkey functionality for quick actions.");
		hotkeyBoardingPass = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "OpenTerrainRandomizerKey", (KeyCode)286, "Hotkey to open the boarding pass.");
		hotkeyQuickRestart = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "QuickRestartKey", (KeyCode)283, "Hotkey for vanilla Quick Restart.");
		hotkeyQuickRestartTr = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "QuickRestartTrKey", (KeyCode)284, "Hotkey for Quick Restart TR.");
		hotkeyReturnToAirport = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "ReturnToAirportKey", (KeyCode)285, "Hotkey for Return to Airport.");
		SceneManager.sceneLoaded += OnSceneLoaded;
		PhotonNetwork.AddCallbackTarget((object)this);
		harmony = new Harmony("tony4twentys.quickrestart");
		harmony.PatchAll();
		QrMenu.EnsureCreated();
		if (skipSplashScreen.Value)
		{
			((MonoBehaviour)this).StartCoroutine(SkipSplashScreenCoroutine());
		}
	}

	private void OnDestroy()
	{
		PhotonNetwork.RemoveCallbackTarget((object)this);
		SceneManager.sceneLoaded -= OnSceneLoaded;
		Harmony obj = harmony;
		if (obj != null)
		{
			obj.UnpatchSelf();
		}
		QrMenu.DestroyInstance();
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}

	public void OnEvent(EventData photonEvent)
	{
		if (photonEvent.Code != 177)
		{
			return;
		}
		if (!(photonEvent.CustomData is object[] array) || array.Length < 3)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Quick Restart: Ignored restart event with invalid payload.");
			return;
		}
		string text = array[0] as string;
		if (string.IsNullOrEmpty(text))
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Quick Restart: Ignored restart event with empty scene name.");
			return;
		}
		int num = ((array[1] is int num2) ? num2 : ((array[1] is byte b) ? b : 0));
		byte[] serializedRunSettings = Array.Empty<byte>();
		if (array[2] is byte[] array2)
		{
			serializedRunSettings = array2;
		}
		else if (array[2] is string s)
		{
			try
			{
				serializedRunSettings = Convert.FromBase64String(s);
			}
			catch
			{
			}
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"Quick Restart: Restart event received (scene={text}, ascent={num}).");
		BeginIslandLoadLikeVanilla(text, num, serializedRunSettings, networked: true);
		restartInProgress = false;
	}

	void IInRoomCallbacks.OnPlayerEnteredRoom(Player newPlayer)
	{
		PublishModPresence();
	}

	void IInRoomCallbacks.OnPlayerLeftRoom(Player otherPlayer)
	{
	}

	void IInRoomCallbacks.OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
	{
	}

	void IInRoomCallbacks.OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
	{
	}

	void IInRoomCallbacks.OnMasterClientSwitched(Player newMasterClient)
	{
		PublishModPresence();
	}

	void IMatchmakingCallbacks.OnJoinedRoom()
	{
		PublishModPresence();
	}

	void IMatchmakingCallbacks.OnCreatedRoom()
	{
	}

	void IMatchmakingCallbacks.OnCreateRoomFailed(short returnCode, string message)
	{
	}

	void IMatchmakingCallbacks.OnFriendListUpdate(List<FriendInfo> friendList)
	{
	}

	void IMatchmakingCallbacks.OnJoinRandomFailed(short returnCode, string message)
	{
	}

	void IMatchmakingCallbacks.OnJoinRoomFailed(short returnCode, string message)
	{
	}

	void IMatchmakingCallbacks.OnLeftRoom()
	{
	}

	private void PublishModPresence()
	{
		//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_0033: Expected O, but got Unknown
		//IL_003b: Expected O, but got Unknown
		if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null)
		{
			Player localPlayer = PhotonNetwork.LocalPlayer;
			Hashtable val = new Hashtable();
			((Dictionary<object, object>)val).Add((object)"QR_ModVersion", (object)"2.4.0");
			localPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
		}
	}

	private IEnumerator SkipSplashScreenCoroutine()
	{
		yield return null;
		try
		{
			SplashScreen.Stop((StopBehavior)0);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Restart: Splash screen skipped successfully.");
		}
		catch (Exception ex)
		{
			Exception ex2 = ex;
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Quick Restart: Could not skip splash screen: " + ex2.Message));
		}
		((MonoBehaviour)this).StartCoroutine(ForceLoadTitleScene());
	}

	private IEnumerator ForceLoadTitleScene()
	{
		yield return (object)new WaitForSeconds(0.5f);
		try
		{
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name != "Title")
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Restart: Force loading Title scene to skip startup screens.");
				SceneManager.LoadScene("Title", (LoadSceneMode)0);
			}
		}
		catch (Exception ex)
		{
			Exception ex2 = ex;
			((BaseUnityPlugin)this).Logger.LogError((object)("Quick Restart: Error force loading Title scene: " + ex2.Message));
		}
	}

	public static bool GetShowPauseMenuButton()
	{
		return (Object)(object)Instance == (Object)null || Instance.showPauseMenuButton == null || Instance.showPauseMenuButton.Value;
	}

	public static void SetShowPauseMenuButton(bool enabled)
	{
		if (Instance?.showPauseMenuButton != null)
		{
			Instance.showPauseMenuButton.Value = enabled;
		}
	}

	public unsafe static string FormatKey(KeyCode key)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return ((int)key == 0) ? "Unbound" : ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString();
	}

	public void ResetMenuColors()
	{
		if (menuPanelColor != null)
		{
			menuPanelColor.Value = "140F0DF0";
		}
		if (menuButtonColor != null)
		{
			menuButtonColor.Value = "2E2017BA";
		}
		if (menuTextColor != null)
		{
			menuTextColor.Value = "F2EDE0FF";
		}
		if (menuAccentColor != null)
		{
			menuAccentColor.Value = "8C6B38F2";
		}
	}

	private void Update()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		if (!QrMenu.IsCapturingKey)
		{
			if (Input.GetKeyDown(menuKey.Value))
			{
				QrMenu.Toggle();
			}
			if (CanUseControls() && enableHotkeys.Value && !QrMenu.IsOpen)
			{
				HandleHotkeys();
			}
		}
	}

	public static bool CanUseControls()
	{
		if (PhotonNetwork.OfflineMode)
		{
			return true;
		}
		return PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient;
	}

	public static bool IsSoloSessionPublic()
	{
		return IsSoloSession();
	}

	private static bool IsSoloSession()
	{
		if (PhotonNetwork.OfflineMode)
		{
			return true;
		}
		if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null)
		{
			return true;
		}
		return PhotonNetwork.CurrentRoom.PlayerCount <= 1;
	}

	private void HandleHotkeys()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: 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)
		if (Input.GetKeyDown(hotkeyQuickRestart.Value))
		{
			BeginQuickRestart(withTerrainRandomizer: false);
		}
		if (Input.GetKeyDown(hotkeyQuickRestartTr.Value))
		{
			BeginQuickRestart(withTerrainRandomizer: true);
		}
		if (Input.GetKeyDown(hotkeyReturnToAirport.Value))
		{
			ReturnToAirportOnly();
		}
		if (Input.GetKeyDown(hotkeyBoardingPass.Value))
		{
			OpenBoardingPass();
		}
	}

	public void BeginQuickRestart(bool withTerrainRandomizer, int ascentOverride = -1)
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		if (restartInProgress)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Quick Restart: Restart already in progress.");
			return;
		}
		restartWithTr = withTerrainRandomizer;
		requestedRestartAscent = ((ascentOverride >= 0) ? ascentOverride : Ascents.currentAscent);
		boardingPassOpenedByQuickRestart = false;
		Scene activeScene = SceneManager.GetActiveScene();
		if (((Scene)(ref activeScene)).name == "Airport")
		{
			if (withTerrainRandomizer)
			{
				((MonoBehaviour)this).StartCoroutine(WaitAndStartGameFromAirport());
			}
			else
			{
				TryStartGameFromAirport();
			}
		}
		else
		{
			((MonoBehaviour)this).StartCoroutine(MidRunRestartRoutine());
		}
	}

	private void PrepareTerrainRandomiserForRestart(bool randomize = true)
	{
		if (TrCompat.IsPresent)
		{
			TrCompat.PrepareForRestart(restartWithTr ? TrRestartMode.ApplyUi : TrRestartMode.Vanilla, randomize);
		}
	}

	private IEnumerator MidRunRestartRoutine()
	{
		restartInProgress = true;
		PublishModPresence();
		if (restartWithTr)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Restart TR: returning to airport, then auto-boarding with current TR settings.");
			TrCompat.SaveUiSettings();
			ArmAirportAutoBoard();
			TriggerReturnToAirport(autoRestart: true);
			restartInProgress = false;
			yield break;
		}
		PrepareTerrainRandomiserForRestart();
		if (IsSoloSession())
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Restart: Solo/offline mid-run — vanilla terrain, skipping airport.");
			BeginIslandLoadLikeVanilla(ResolveIslandSceneName(), GetRequestedRestartAscent(), RunSettings.GetSerializedRunSettings(), PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode);
			restartInProgress = false;
			yield break;
		}
		yield return WaitForModPresence(0.75f);
		bool allHaveMod = AllConnectedPlayersHaveMod();
		if (skipAirportInMultiplayer.Value && allHaveMod)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Restart: All players have Quick Restart — skipping airport (synchronized island load).");
			if (!BroadcastSkipAirportRestart())
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Quick Restart: Skip-airport broadcast failed — falling back to airport detour.");
				TriggerReturnToAirport(autoRestart: true);
				restartInProgress = false;
			}
		}
		else
		{
			if (!allHaveMod)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Quick Restart: Missing mod on: " + DescribeMissingModPlayers() + ". Using airport detour."));
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Restart: SkipAirportInMultiplayer is OFF — using airport detour.");
			}
			TriggerReturnToAirport(autoRestart: true);
			restartInProgress = false;
		}
	}

	private bool BroadcastSkipAirportRestart()
	{
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Expected O, but got Unknown
		if (!PhotonNetwork.IsMasterClient)
		{
			return false;
		}
		if (restartWithTr)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Restart TR: skip-airport broadcast disabled; using airport boarding flow.");
			return false;
		}
		PrepareTerrainRandomiserForRestart();
		string text = ResolveIslandSceneName();
		int num = GetRequestedRestartAscent();
		byte[] inArray = RunSettings.GetSerializedRunSettings() ?? Array.Empty<byte>();
		bool flag = PhotonNetwork.RaiseEvent((byte)177, (object)new object[3]
		{
			text,
			num,
			Convert.ToBase64String(inArray)
		}, new RaiseEventOptions
		{
			Receivers = (ReceiverGroup)1
		}, SendOptions.SendReliable);
		if (flag)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Quick Restart: Sent skip-airport restart to all players for '" + text + "'."));
		}
		return flag;
	}

	private void BeginIslandLoadLikeVanilla(string sceneName, int ascent, byte[] serializedRunSettings, bool networked)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Expected O, but got Unknown
		if (LoadingScreenHandler.loading)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Quick Restart: Already loading — ignoring duplicate island load.");
			return;
		}
		MenuWindow.CloseAllWindows();
		GameHandler.AddStatus<SceneSwitchingStatus>((GameStatus)new SceneSwitchingStatus());
		Debug.Log((object)("Begin scene load RPC: " + sceneName));
		Ascents.currentAscent = ascent;
		try
		{
			if (serializedRunSettings != null && serializedRunSettings.Length != 0)
			{
				GameUtils.ApplySerializedRunSettings(serializedRunSettings);
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Quick Restart: ApplySerializedRunSettings failed (" + ex.Message + "); continuing load."));
		}
		LoadingScreenHandler instance = RetrievableResourceSingleton<LoadingScreenHandler>.Instance;
		instance.Load((LoadingScreenType)1, (Action)null, new IEnumerator[1] { instance.LoadSceneProcess(sceneName, networked, true, 0f) });
	}

	private static string ResolveIslandSceneName()
	{
		//IL_0035: 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)
		try
		{
			int nextLevelIndexOrFallback = GameHandler.GetService<NextLevelService>().NextLevelIndexOrFallback;
			string text = SingletonAsset<MapBaker>.Instance.GetLevel(nextLevelIndexOrFallback + NextLevelService.debugLevelIndexOffset);
			if (string.IsNullOrEmpty(text))
			{
				text = "WilIsland";
			}
			return text;
		}
		catch
		{
			Scene activeScene = SceneManager.GetActiveScene();
			return ((Scene)(ref activeScene)).name;
		}
	}

	public void ReturnToAirportOnly()
	{
		shouldAutoRestart = false;
		TriggerReturnToAirport(autoRestart: false);
	}

	private void TriggerReturnToAirport(bool autoRestart)
	{
		shouldAutoRestart = autoRestart;
		if (autoRestart)
		{
			ArmAirportAutoBoard();
		}
		GUIManager instance = GUIManager.instance;
		if (instance != null)
		{
			EndScreen endScreen = instance.endScreen;
			if (((endScreen != null) ? new bool?(((MenuWindow)endScreen).isOpen) : ((bool?)null)) == true)
			{
				((MenuWindow)GUIManager.instance.endScreen).Close();
			}
		}
		GameOverHandler val = Object.FindFirstObjectByType<GameOverHandler>();
		if ((Object)(object)val == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Quick Restart: GameOverHandler not found.");
			return;
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Restart: Forcing all players to close end screen...");
		val.ForceEveryPlayerDoneWithEndScreen();
		((BaseUnityPlugin)this).Logger.LogInfo((object)(autoRestart ? "Quick Restart: Returning to airport, will auto-restart." : "Quick Restart: Returning to airport."));
	}

	private void ArmAirportAutoBoard()
	{
		shouldAutoRestart = true;
		if (!airportBoardRoutineRunning)
		{
			((MonoBehaviour)this).StartCoroutine(AirportAutoRestartRoutine());
		}
	}

	private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		PublishModPresence();
		restartInProgress = false;
		QrMenu.OnAfterSceneLoad();
		boardingPassOpenedByQuickRestart = false;
		if (shouldAutoRestart)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"Quick Restart: SceneLoaded '{((Scene)(ref scene)).name}' autoRestart={shouldAutoRestart} boardRoutine={airportBoardRoutineRunning}");
		}
		if (((Scene)(ref scene)).name == "Airport" && shouldAutoRestart)
		{
			ArmAirportAutoBoard();
		}
		else if (((Scene)(ref scene)).name == "Title" && enableMainMenuAutoClick.Value && !hasAutoClickedMainMenuButton)
		{
			hasAutoClickedMainMenuButton = true;
			((MonoBehaviour)this).StartCoroutine(AutoClickMainMenuButton());
		}
	}

	private IEnumerator AirportAutoRestartRoutine()
	{
		if (airportBoardRoutineRunning)
		{
			yield break;
		}
		airportBoardRoutineRunning = true;
		shouldAutoRestart = true;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Restart: Auto-board armed — waiting for Airport (this survives the scene change).");
		Scene activeScene;
		for (float t = 0f; t < 60f; t += 0.25f)
		{
			int num;
			if (!LoadingScreenHandler.loading)
			{
				activeScene = SceneManager.GetActiveScene();
				if (((Scene)(ref activeScene)).name == "Airport" && (Object)(object)Character.localCharacter != (Object)null && Character.localCharacter.inAirport)
				{
					num = (((Object)(object)Object.FindFirstObjectByType<AirportCheckInKiosk>() != (Object)null) ? 1 : 0);
					goto IL_00d1;
				}
			}
			num = 0;
			goto IL_00d1;
			IL_00d1:
			if (num != 0)
			{
				break;
			}
			yield return (object)new WaitForSecondsRealtime(0.25f);
		}
		if ((Object)(object)Object.FindFirstObjectByType<AirportCheckInKiosk>() == (Object)null)
		{
			ManualLogSource logger = ((BaseUnityPlugin)this).Logger;
			activeScene = SceneManager.GetActiveScene();
			logger.LogWarning((object)("Quick Restart: Timed out waiting for airport readiness (scene=" + ((Scene)(ref activeScene)).name + ")."));
			airportBoardRoutineRunning = false;
			shouldAutoRestart = false;
			yield break;
		}
		if (!IsSoloSession())
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Restart: Host ready — waiting up to 10s for other players in airport...");
			for (float t = 0f; t < 10f; t += 0.25f)
			{
				if (AllPlayersReadyInAirport())
				{
					break;
				}
				yield return (object)new WaitForSecondsRealtime(0.25f);
			}
			if (!AllPlayersReadyInAirport())
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Quick Restart: Boarding anyway; still waiting on: " + DescribePlayersNotReadyInAirport()));
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Restart: All players ready in airport — boarding.");
			}
		}
		AirportCheckInKiosk kiosk = Object.FindFirstObjectByType<AirportCheckInKiosk>();
		if ((Object)(object)kiosk == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Quick Restart: Kiosk not found after airport wait.");
			airportBoardRoutineRunning = false;
			shouldAutoRestart = false;
		}
		else
		{
			boardingPassOpenedByQuickRestart = false;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Restart: Airport ready — boarding via kiosk + boarding pass Start.");
			yield return BoardFromAirportKiosk(kiosk);
			airportBoardRoutineRunning = false;
			shouldAutoRestart = false;
		}
	}

	private void TryStartGameFromAirport()
	{
		AirportCheckInKiosk val = Object.FindFirstObjectByType<AirportCheckInKiosk>();
		if ((Object)(object)val == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Quick Restart: No AirportCheckInKiosk found!");
			return;
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Restart: Starting from Airport via kiosk boarding pass.");
		((MonoBehaviour)this).StartCoroutine(BoardFromAirportKiosk(val));
	}

	private IEnumerator BoardFromAirportKiosk(AirportCheckInKiosk kiosk)
	{
		boardingPassOpenedByQuickRestart = false;
		PrepareTerrainRandomiserForRestart(randomize: false);
		Character local = Character.localCharacter;
		if ((Object)(object)kiosk == (Object)null || (Object)(object)local == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Quick Restart: Missing kiosk or local character — cannot board.");
			yield break;
		}
		kiosk.Interact_CastFinished(local);
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Restart: Triggered kiosk Interact_CastFinished (real boarding pass).");
		float t = 0f;
		BoardingPass pass = null;
		for (; t < 5f; t += 0.1f)
		{
			pass = GUIManager.instance?.boardingPass;
			if ((Object)(object)pass != (Object)null && ((MenuWindow)pass).isOpen)
			{
				break;
			}
			yield return (object)new WaitForSecondsRealtime(0.1f);
		}
		if ((Object)(object)pass == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Quick Restart: Boarding pass missing after kiosk interact.");
			yield break;
		}
		pass.ascentIndex = GetRequestedRestartAscent();
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"Quick Restart: Calling vanilla BoardingPass.StartGame (ascent={pass.ascentIndex}, tr={restartWithTr}).");
		pass.StartGame();
	}

	private IEnumerator WaitAndStartGameFromAirport()
	{
		yield return (object)new WaitForSeconds(0.5f);
		TryStartGameFromAirport();
	}

	public void OpenBoardingPass()
	{
		//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)
		Scene activeScene = SceneManager.GetActiveScene();
		if (((Scene)(ref activeScene)).name == "Airport")
		{
			OpenVanillaKioskBoardingPass();
			return;
		}
		GUIManager instance = GUIManager.instance;
		BoardingPass val = instance?.boardingPass;
		if ((Object)(object)val == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Quick Restart: Boarding pass is not available right now.");
			return;
		}
		try
		{
			if (!((MenuWindow)val).initialized)
			{
				((MenuWindow)val).Initialize();
			}
			boardingPassOpenedByQuickRestart = true;
			GameAccess.SetMenuWindowFlags(instance, blocking: true, showingCursor: true);
			((MenuWindow)val).Open();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Restart: Opened boarding pass (mid-run — Start returns to airport and auto-boards).");
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Quick Restart: Could not open boarding pass: " + ex.Message));
		}
	}

	private void OpenVanillaKioskBoardingPass()
	{
		boardingPassOpenedByQuickRestart = false;
		AirportCheckInKiosk val = Object.FindFirstObjectByType<AirportCheckInKiosk>();
		Character localCharacter = Character.localCharacter;
		if ((Object)(object)val == (Object)null || (Object)(object)localCharacter == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Quick Restart: Airport kiosk/character not ready — cannot open vanilla boarding pass.");
			return;
		}
		val.Interact_CastFinished(localCharacter);
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Restart: Opened real airport kiosk boarding pass.");
	}

	private int GetRequestedRestartAscent()
	{
		return (requestedRestartAscent >= 0) ? requestedRestartAscent : Ascents.currentAscent;
	}

	private bool ShouldUseTerrainRandomizerFromBoardingPass()
	{
		return TrCompat.IsRandomiserEnabledInUi();
	}

	private IEnumerator AutoClickMainMenuButton()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"Quick Restart: Waiting {mainMenuClickDelay.Value}s before clicking {mainMenuButtonChoice.Value}");
		yield return (object)new WaitForSeconds(mainMenuClickDelay.Value);
		try
		{
			GameObject obj = GameObject.Find(mainMenuButtonChoice.Value);
			Button button = ((obj != null) ? obj.GetComponent<Button>() : null);
			if ((Object)(object)button != (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Quick Restart: Clicking " + mainMenuButtonChoice.Value));
				((UnityEvent)button.onClick).Invoke();
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Quick Restart: " + mainMenuButtonChoice.Value + " not found"));
			}
		}
		catch (Exception ex)
		{
			Exception ex2 = ex;
			((BaseUnityPlugin)this).Logger.LogError((object)("Quick Restart: Error auto-clicking: " + ex2.Message));
		}
	}

	private static IEnumerator WaitForModPresence(float timeout)
	{
		if (!(timeout <= 0f) && !AllConnectedPlayersHaveMod())
		{
			float t = 0f;
			while (!AllConnectedPlayersHaveMod() && t < timeout)
			{
				yield return (object)new WaitForSecondsRealtime(0.15f);
				t += 0.15f;
			}
		}
	}

	private static bool AllConnectedPlayersHaveMod()
	{
		if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null)
		{
			return false;
		}
		Player[] playerList = PhotonNetwork.PlayerList;
		foreach (Player val in playerList)
		{
			Hashtable customProperties = val.CustomProperties;
			if (customProperties == null || !((Dictionary<object, object>)(object)customProperties).ContainsKey((object)"QR_ModVersion"))
			{
				return false;
			}
		}
		return true;
	}

	private static string DescribeMissingModPlayers()
	{
		if (!PhotonNetwork.InRoom)
		{
			return "not in room";
		}
		List<string> list = new List<string>();
		Player[] playerList = PhotonNetwork.PlayerList;
		foreach (Player val in playerList)
		{
			Hashtable customProperties = val.CustomProperties;
			if (customProperties == null || !((Dictionary<object, object>)(object)customProperties).ContainsKey((object)"QR_ModVersion"))
			{
				list.Add(string.IsNullOrEmpty(val.NickName) ? $"#{val.ActorNumber}" : val.NickName);
			}
		}
		return (list.Count == 0) ? "none" : string.Join(", ", list);
	}

	private static bool AllPlayersReadyInAirport()
	{
		if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null)
		{
			return (Object)(object)Character.localCharacter != (Object)null && Character.localCharacter.inAirport;
		}
		Player[] playerList = PhotonNetwork.PlayerList;
		foreach (Player val in playerList)
		{
			if (val != null && !val.IsInactive)
			{
				Character playerCharacter = PlayerHandler.GetPlayerCharacter(val);
				if ((Object)(object)playerCharacter == (Object)null || !playerCharacter.inAirport)
				{
					return false;
				}
			}
		}
		return true;
	}

	private static string DescribePlayersNotReadyInAirport()
	{
		if (!PhotonNetwork.InRoom)
		{
			return "not in room";
		}
		List<string> list = new List<string>();
		Player[] playerList = PhotonNetwork.PlayerList;
		foreach (Player val in playerList)
		{
			if (val != null && !val.IsInactive)
			{
				string text = (string.IsNullOrEmpty(val.NickName) ? $"#{val.ActorNumber}" : val.NickName);
				Character playerCharacter = PlayerHandler.GetPlayerCharacter(val);
				if ((Object)(object)playerCharacter == (Object)null)
				{
					list.Add(text + " (no character)");
				}
				else if (!playerCharacter.inAirport)
				{
					list.Add(text + " (not in airport)");
				}
			}
		}
		return (list.Count == 0) ? "none" : string.Join(", ", list);
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace QuickRestart
{
	internal static class GameAccess
	{
		public static void SetMenuWindowFlags(GUIManager gui, bool blocking, bool showingCursor)
		{
			if (!((Object)(object)gui == (Object)null))
			{
				gui.windowBlockingInput = blocking;
				gui.windowShowingCursor = showingCursor;
			}
		}
	}
	internal sealed class QrColorPicker : MonoBehaviour
	{
		private sealed class WheelHit : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IDragHandler
		{
			internal Action<Vector2> OnHit;

			public void OnPointerDown(PointerEventData eventData)
			{
				Hit(eventData);
			}

			public void OnDrag(PointerEventData eventData)
			{
				Hit(eventData);
			}

			private void Hit(PointerEventData eventData)
			{
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: 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_008f: Unknown result type (might be due to invalid IL or missing references)
				Transform transform = ((Component)this).transform;
				RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				Vector2 val2 = default(Vector2);
				if (!((Object)(object)val == (Object)null) && eventData != null && RectTransformUtility.ScreenPointToLocalPointInRectangle(val, eventData.position, eventData.pressEventCamera, ref val2))
				{
					Rect rect = val.rect;
					float num = Mathf.InverseLerp(((Rect)(ref rect)).xMin, ((Rect)(ref rect)).xMax, val2.x);
					float num2 = Mathf.InverseLerp(((Rect)(ref rect)).yMin, ((Rect)(ref rect)).yMax, val2.y);
					OnHit?.Invoke(new Vector2(num, num2));
				}
			}
		}

		private const float WheelSize = 168f;

		internal Action<Color> OnChanged;

		private RectTransform _wheelRt;

		private Image _preview;

		private RectTransform _marker;

		private Slider _brightness;

		private Slider _opacity;

		private TextMeshProUGUI _brightnessValue;

		private TextMeshProUGUI _opacityValue;

		private Texture2D _wheelTex;

		private Sprite _wheelSprite;

		private float _h;

		private float _s = 1f;

		private float _v = 1f;

		private float _a = 1f;

		private bool _suppress;

		private static Sprite _checkerSprite;

		internal Color Current => WithAlpha(Color.HSVToRGB(_h, _s, _v), _a);

		internal static QrColorPicker Create(Transform parent, Color start, Action<Color> onChanged)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ColorPicker", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			LayoutElement val2 = val.AddComponent<LayoutElement>();
			val2.minHeight = 292f;
			val2.preferredHeight = 292f;
			val2.flexibleWidth = 1f;
			((LayoutGroup)QrUi.AddVerticalLayout(val, 8f, new RectOffset(4, 4, 4, 4))).childAlignment = (TextAnchor)1;
			QrColorPicker qrColorPicker = val.AddComponent<QrColorPicker>();
			qrColorPicker.OnChanged = onChanged;
			qrColorPicker.Build();
			qrColorPicker.SetColor(start, notify: false);
			return qrColorPicker;
		}

		internal void SetColor(Color color, bool notify)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Color.RGBToHSV(color, ref _h, ref _s, ref _v);
			_a = color.a;
			_suppress = true;
			if ((Object)(object)_brightness != (Object)null)
			{
				_brightness.SetValueWithoutNotify(Mathf.Round(_v * 100f));
			}
			if ((Object)(object)_opacity != (Object)null)
			{
				_opacity.SetValueWithoutNotify(Mathf.Round(_a * 100f));
			}
			UpdateValueLabels();
			UpdateMarker();
			UpdatePreview();
			_suppress = false;
			if (notify)
			{
				RaiseChanged();
			}
		}

		private void Build()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Expected O, but got Unknown
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Wheel", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			val.transform.SetParent(((Component)this).transform, false);
			QrUi.Theme(val, QrThemePart.Ignore);
			LayoutElement val2 = val.AddComponent<LayoutElement>();
			val2.preferredWidth = 168f;
			val2.preferredHeight = 168f;
			val2.minWidth = 168f;
			val2.minHeight = 168f;
			_wheelRt = val.GetComponent<RectTransform>();
			_wheelRt.sizeDelta = new Vector2(168f, 168f);
			_wheelTex = MakeWheelTexture();
			_wheelSprite = Sprite.Create(_wheelTex, new Rect(0f, 0f, (float)((Texture)_wheelTex).width, (float)((Texture)_wheelTex).height), new Vector2(0.5f, 0.5f), 100f);
			((Object)_wheelSprite).name = "QR_ColorWheel";
			Image component = val.GetComponent<Image>();
			component.sprite = _wheelSprite;
			((Graphic)component).raycastTarget = true;
			component.preserveAspect = true;
			WheelHit wheelHit = val.AddComponent<WheelHit>();
			wheelHit.OnHit = OnWheelHit;
			GameObject val3 = new GameObject("Marker", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			val3.transform.SetParent(val.transform, false);
			QrUi.Theme(val3, QrThemePart.Ignore);
			_marker = val3.GetComponent<RectTransform>();
			RectTransform marker = _marker;
			RectTransform marker2 = _marker;
			Vector2 val4 = default(Vector2);
			((Vector2)(ref val4))..ctor(0.5f, 0.5f);
			marker2.anchorMax = val4;
			marker.anchorMin = val4;
			_marker.sizeDelta = new Vector2(14f, 14f);
			Image component2 = val3.GetComponent<Image>();
			component2.sprite = QrUi.WhiteSprite();
			((Graphic)component2).color = Color.white;
			((Graphic)component2).raycastTarget = false;
			Outline val5 = val3.AddComponent<Outline>();
			((Shadow)val5).effectColor = Color.black;
			((Shadow)val5).effectDistance = new Vector2(1.2f, -1.2f);
			_preview = MakePreview();
			AddSliderRow("Brightness", out _brightness, out _brightnessValue, delegate(float v)
			{
				if (!_suppress)
				{
					_v = Mathf.Clamp01(v / 100f);
					UpdatePreview();
					RaiseChanged();
				}
			});
			AddSliderRow("Opacity", out _opacity, out _opacityValue, delegate(float v)
			{
				if (!_suppress)
				{
					_a = Mathf.Clamp01(v / 100f);
					UpdatePreview();
					RaiseChanged();
				}
			});
		}

		private Image MakePreview()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			GameObject val = new GameObject("Preview", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(((Component)this).transform, false);
			QrUi.MakeNonCollapsing(val, 28f);
			((LayoutGroup)QrUi.AddHorizontalLayout(val, 8f)).childAlignment = (TextAnchor)4;
			GameObject val2 = new GameObject("Checker", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			val2.transform.SetParent(val.transform, false);
			QrUi.Theme(val2, QrThemePart.Ignore);
			LayoutElement val3 = val2.AddComponent<LayoutElement>();
			val3.flexibleWidth = 1f;
			val3.minHeight = 28f;
			val3.preferredHeight = 28f;
			Image component = val2.GetComponent<Image>();
			component.sprite = CheckerSprite();
			component.type = (Type)2;
			component.pixelsPerUnitMultiplier = 0.35f;
			((Graphic)component).raycastTarget = false;
			GameObject val4 = new GameObject("Color", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			val4.transform.SetParent(val2.transform, false);
			QrUi.Theme(val4, QrThemePart.Swatch);
			QrUi.Stretch(val4.GetComponent<RectTransform>(), 0f, 0f);
			Image component2 = val4.GetComponent<Image>();
			component2.sprite = QrUi.WhiteSprite();
			((Graphic)component2).raycastTarget = false;
			return component2;
		}

		private void AddSliderRow(string label, out Slider slider, out TextMeshProUGUI valueLabel, UnityAction<float> onChanged)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			GameObject val = new GameObject(label, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(((Component)this).transform, false);
			QrUi.MakeNonCollapsing(val, 24f);
			((LayoutGroup)QrUi.AddHorizontalLayout(val, 8f)).childAlignment = (TextAnchor)3;
			TextMeshProUGUI val2 = QrUi.CreateLabel(val.transform, "N", label, 14f, (FontStyles)0, (TextAlignmentOptions)513);
			QrUi.Theme<TextMeshProUGUI>(val2, QrThemePart.Hint);
			QrUi.MakeNonCollapsing(((Component)val2).gameObject, 22f, 90f);
			slider = QrUi.CreateSlider(val.transform, 0f, 100f, 100f, wholeNumbers: true, onChanged);
			valueLabel = QrUi.CreateLabel(val.transform, "V", "100%", 13f, (FontStyles)0, (TextAlignmentOptions)516);
			QrUi.Theme<TextMeshProUGUI>(valueLabel, QrThemePart.Hint);
			QrUi.MakeNonCollapsing(((Component)valueLabel).gameObject, 22f, 44f);
		}

		private void OnWheelHit(Vector2 local01)
		{
			//IL_0001: 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)
			float num = local01.x * 2f - 1f;
			float num2 = local01.y * 2f - 1f;
			float num3 = Mathf.Sqrt(num * num + num2 * num2);
			if (!(num3 > 1.05f))
			{
				if (num3 > 1f)
				{
					num3 = 1f;
				}
				_s = num3;
				float num4 = Mathf.Atan2(num2, num) / ((float)Math.PI * 2f);
				if (num4 < 0f)
				{
					num4 += 1f;
				}
				_h = num4;
				UpdateMarker();
				UpdatePreview();
				RaiseChanged();
			}
		}

		private void UpdateMarker()
		{
			//IL_0049: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_marker == (Object)null))
			{
				float num = _h * (float)Math.PI * 2f;
				float num2 = _s * 80f;
				_marker.anchoredPosition = new Vector2(Mathf.Cos(num) * num2, Mathf.Sin(num) * num2);
				((Graphic)((Component)_marker).GetComponent<Image>()).color = ((_v > 0.55f) ? Color.black : Color.white);
			}
		}

		private void UpdatePreview()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_preview != (Object)null)
			{
				((Graphic)_preview).color = Current;
			}
			UpdateValueLabels();
		}

		private void UpdateValueLabels()
		{
			if ((Object)(object)_brightnessValue != (Object)null)
			{
				((TMP_Text)_brightnessValue).text = Mathf.RoundToInt(_v * 100f) + "%";
			}
			if ((Object)(object)_opacityValue != (Object)null)
			{
				((TMP_Text)_opacityValue).text = Mathf.RoundToInt(_a * 100f) + "%";
			}
		}

		private void RaiseChanged()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (!_suppress)
			{
				OnChanged?.Invoke(Current);
			}
		}

		private static Color WithAlpha(Color color, float alpha)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			color.a = alpha;
			return color;
		}

		private static Texture2D MakeWheelTexture()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_0083: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false);
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Texture)val).filterMode = (FilterMode)1;
			Color[] array = (Color[])(object)new Color[16384];
			float num = 63.5f;
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					float num2 = ((float)j - num) / num;
					float num3 = ((float)i - num) / num;
					float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3);
					if (num4 > 1f)
					{
						array[i * 128 + j] = Color.clear;
						continue;
					}
					float num5 = Mathf.Atan2(num3, num2) / ((float)Math.PI * 2f);
					if (num5 < 0f)
					{
						num5 += 1f;
					}
					Color val2 = Color.HSVToRGB(num5, num4, 1f);
					val2.a = 1f;
					array[i * 128 + j] = val2;
				}
			}
			val.SetPixels(array);
			val.Apply(false, false);
			return val;
		}

		private static Sprite CheckerSprite()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_checkerSprite != (Object)null)
			{
				return _checkerSprite;
			}
			Texture2D val = new Texture2D(8, 8, (TextureFormat)3, false);
			((Texture)val).filterMode = (FilterMode)0;
			((Texture)val).wrapMode = (TextureWrapMode)0;
			for (int i = 0; i < 8; i++)
			{
				for (int j = 0; j < 8; j++)
				{
					bool flag = (j / 4 + i / 4) % 2 == 0;
					val.SetPixel(j, i, flag ? new Color(0.22f, 0.2f, 0.18f) : new Color(0.42f, 0.38f, 0.34f));
				}
			}
			val.Apply(false, false);
			_checkerSprite = Sprite.Create(val, new Rect(0f, 0f, 8f, 8f), new Vector2(0.5f, 0.5f), 8f);
			((Object)_checkerSprite).name = "QR_Checker";
			return _checkerSprite;
		}

		private void OnDestroy()
		{
			if ((Object)(object)_wheelSprite != (Object)null)
			{
				Object.Destroy((Object)(object)_wheelSprite);
			}
			if ((Object)(object)_wheelTex != (Object)null)
			{
				Object.Destroy((Object)(object)_wheelTex);
			}
		}
	}
	internal sealed class QrMenu : MonoBehaviour
	{
		private sealed class ColorTarget
		{
			public string Name;

			public ConfigEntry<string> Entry;

			public Color Fallback;

			public Image Swatch;

			public Button Button;
		}

		[HarmonyPatch(typeof(GUIManager), "UpdateWindowStatus")]
		private static class Patch_UpdateWindowStatus
		{
			private static void Postfix(GUIManager __instance)
			{
				if (!((Object)(object)__instance == (Object)null) && IsOpen)
				{
					GameAccess.SetMenuWindowFlags(__instance, blocking: true, showingCursor: true);
				}
			}
		}

		[HarmonyPatch(typeof(Character), "CanDoInput")]
		private static class Patch_CanDoInput
		{
			private static void Postfix(ref bool __result)
			{
				if (IsOpen)
				{
					__result = false;
				}
			}
		}

		[HarmonyPatch(typeof(CursorHandler), "Update")]
		private static class Patch_CursorHandler
		{
			private static void Postfix()
			{
				if (IsOpen)
				{
					Cursor.lockState = (CursorLockMode)0;
					Cursor.visible = true;
				}
			}
		}

		[HarmonyPatch(typeof(PauseMenuMainPage), "Start")]
		private static class Patch_PauseStart
		{
			private static void Postfix(PauseMenuMainPage __instance)
			{
				InjectPauseChip(__instance);
			}
		}

		[HarmonyPatch(typeof(PauseMenuMainPage), "OnEnable")]
		private static class Patch_PauseEnable
		{
			private static void Postfix(PauseMenuMainPage __instance)
			{
				InjectPauseChip(__instance);
			}
		}

		private const int SortOrder = 9200;

		private const string PauseChipName = "QR_PauseChip";

		private static QrMenu _instance;

		private static int _toggleFrame = -1;

		private static int _pauseReflowFrame = -1;

		private static KeyCode? _pendingBind;

		private RectTransform _panel;

		private GameObject _restartsPage;

		private GameObject _setupPage;

		private GameObject _colorsPage;

		private Button _restartsTab;

		private Button _setupTab;

		private Button _colorsTab;

		private int _activeTab;

		private TextMeshProUGUI _help;

		private TextMeshProUGUI _captureHint;

		private Toggle _skipMpToggle;

		private Toggle _hotkeysToggle;

		private Toggle _pauseButtonToggle;

		private readonly Dictionary<string, TextMeshProUGUI> _bindLabels = new Dictionary<string, TextMeshProUGUI>();

		private readonly List<ColorTarget> _colorTargets = new List<ColorTarget>();

		private ColorTarget _selectedColor;

		private QrColorPicker _colorPicker;

		private Action<KeyCode> _captureTarget;

		private TextMeshProUGUI _captureLabel;

		private bool _visible;

		private bool _built;

		private CursorLockMode _prevLock;

		private bool _prevCursorVisible;

		private Vector2 _frozenLookValues;

		private bool _hasFrozenLook;

		public static bool IsOpen => (Object)(object)_instance != (Object)null && _instance._visible && ((Component)_instance).gameObject.activeInHierarchy;

		public static bool IsCapturingKey => _pendingBind.HasValue;

		public static void EnsureCreated()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!((Object)(object)_instance != (Object)null))
			{
				GameObject val = new GameObject("QR_Menu");
				Object.DontDestroyOnLoad((Object)(object)val);
				_instance = val.AddComponent<QrMenu>();
				val.SetActive(false);
			}
		}

		public static void Toggle()
		{
			if (Time.frameCount != _toggleFrame)
			{
				_toggleFrame = Time.frameCount;
				EnsureCreated();
				if (_instance._visible)
				{
					_instance.CloseInternal();
				}
				else
				{
					_instance.Open();
				}
			}
		}

		public static void Close()
		{
			if ((Object)(object)_instance != (Object)null)
			{
				_instance.CloseInternal();
			}
		}

		public static void DestroyInstance()
		{
			if (!((Object)(object)_instance == (Object)null))
			{
				Object.Destroy((Object)(object)((Component)_instance).gameObject);
				_instance = null;
			}
		}

		public static void OnAfterSceneLoad()
		{
			QrUi.InvalidateButtonDonor();
			if ((Object)(object)_instance == (Object)null)
			{
				return;
			}
			try
			{
				if (_instance._visible)
				{
					_instance.CloseInternal();
				}
			}
			catch
			{
			}
		}

		public static void RefreshPauseChipVisibility()
		{
			try
			{
				PauseMenuMainPage val = null;
				if ((Object)(object)GUIManager.instance != (Object)null)
				{
					val = GUIManager.instance.pauseMenuMainPage;
				}
				if ((Object)(object)val == (Object)null)
				{
					val = Object.FindFirstObjectByType<PauseMenuMainPage>((FindObjectsInactive)1);
				}
				if ((Object)(object)val != (Object)null)
				{
					InjectPauseChip(val);
				}
			}
			catch
			{
			}
		}

		internal static void InjectPauseChip(PauseMenuMainPage page)
		{
			if ((Object)(object)page == (Object)null)
			{
				return;
			}
			try
			{
				PlacePauseChip(page);
				QueuePauseChipReflow(page);
			}
			catch (Exception ex)
			{
				ManualLogSource log = QuickRestartPlugin.Log;
				if (log != null)
				{
					log.LogDebug((object)("Pause chip inject failed: " + ex.Message));
				}
			}
		}

		private static void QueuePauseChipReflow(PauseMenuMainPage page)
		{
			if (!((Object)(object)page == (Object)null) && ((Behaviour)page).isActiveAndEnabled && _pauseReflowFrame != Time.frameCount)
			{
				_pauseReflowFrame = Time.frameCount;
				((MonoBehaviour)page).StartCoroutine(PauseChipReflowRoutine(page));
			}
		}

		private static IEnumerator PauseChipReflowRoutine(PauseMenuMainPage page)
		{
			yield return null;
			try
			{
				if ((Object)(object)page != (Object)null)
				{
					PlacePauseChip(page);
				}
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				ManualLogSource log = QuickRestartPlugin.Log;
				if (log != null)
				{
					log.LogDebug((object)("Pause chip reflow failed: " + ex2.Message));
				}
			}
		}

		private static void PlacePauseChip(PauseMenuMainPage page)
		{
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			if ((Object)(object)page == (Object)null)
			{
				return;
			}
			Button quitButton = page.m_quitButton;
			if ((Object)(object)quitButton == (Object)null)
			{
				return;
			}
			Transform parent = ((Component)quitButton).transform.parent;
			if ((Object)(object)parent == (Object)null)
			{
				return;
			}
			if ((Object)(object)GUIManager.instance != (Object)null && (Object)(object)GUIManager.instance.pauseMenu != (Object)null)
			{
				Transform val = GUIManager.instance.pauseMenu.transform.Find("QR_PauseChip");
				if ((Object)(object)val != (Object)null && (Object)(object)val.parent != (Object)(object)parent)
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
			}
			Transform val2 = parent.Find("QR_PauseChip");
			GameObject val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).gameObject : CreatePauseStackButton(quitButton, parent));
			Button component = val3.GetComponent<Button>();
			if ((Object)(object)component != (Object)null)
			{
				((UnityEventBase)component.onClick).RemoveAllListeners();
				((UnityEvent)component.onClick).AddListener(new UnityAction(Toggle));
			}
			bool showPauseMenuButton = QuickRestartPlugin.GetShowPauseMenuButton();
			val3.SetActive(showPauseMenuButton);
			if (showPauseMenuButton)
			{
				InsertImmediatelyAboveLeave(val3.GetComponent<RectTransform>(), ((Component)quitButton).GetComponent<RectTransform>(), parent);
			}
		}

		private static GameObject CreatePauseStackButton(Button donor, Transform parent)
		{
			GameObject val = Object.Instantiate<GameObject>(((Component)donor).gameObject, parent, false);
			((Object)val).name = "QR_PauseChip";
			val.SetActive(true);
			LocalizedText[] componentsInChildren = val.GetComponentsInChildren<LocalizedText>(true);
			foreach (LocalizedText val2 in componentsInChildren)
			{
				Object.Destroy((Object)(object)val2);
			}
			TextMeshProUGUI componentInChildren = val.GetComponentInChildren<TextMeshProUGUI>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((TMP_Text)componentInChildren).text = "Quick Restart";
			}
			return val;
		}

		private static void InsertImmediatelyAboveLeave(RectTransform chip, RectTransform leave, Transform parent)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)chip == (Object)null) && !((Object)(object)leave == (Object)null))
			{
				float num = EstimatePauseStackGap(parent, leave);
				chip.anchorMin = leave.anchorMin;
				chip.anchorMax = leave.anchorMax;
				chip.pivot = leave.pivot;
				chip.sizeDelta = leave.sizeDelta;
				float num2 = chip.anchoredPosition.y - leave.anchoredPosition.y;
				if (!(num2 > 8f) || !(num2 < num * 1.35f))
				{
					Vector2 val = (chip.anchoredPosition = leave.anchoredPosition);
					leave.anchoredPosition = val + new Vector2(0f, 0f - num);
				}
				int siblingIndex = ((Transform)leave).GetSiblingIndex();
				int siblingIndex2 = ((Transform)chip).GetSiblingIndex();
				((Transform)chip).SetSiblingIndex((siblingIndex2 < siblingIndex) ? (siblingIndex - 1) : siblingIndex);
				RectTransform val2 = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				if ((Object)(object)val2 != (Object)null)
				{
					LayoutRebuilder.ForceRebuildLayoutImmediate(val2);
				}
			}
		}

		private static float EstimatePauseStackGap(Transform parent, RectTransform leave)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)parent == (Object)null || (Object)(object)leave == (Object)null)
			{
				return 56f;
			}
			float num = float.MaxValue;
			Vector2 anchoredPosition = leave.anchoredPosition;
			for (int i = 0; i < parent.childCount; i++)
			{
				Transform child = parent.GetChild(i);
				RectTransform val = (RectTransform)(object)((child is RectTransform) ? child : null);
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)leave) && ((Component)val).gameObject.activeInHierarchy && !(((Object)val).name == "QR_PauseChip"))
				{
					float num2 = val.anchoredPosition.y - anchoredPosition.y;
					if (num2 > 24f && num2 < 90f && num2 < num)
					{
						num = num2;
					}
				}
			}
			return (num >= 24f && num <= 90f) ? num : 56f;
		}

		private void Open()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			Build();
			_visible = true;
			((Component)this).gameObject.SetActive(true);
			_prevLock = Cursor.lockState;
			_prevCursorVisible = Cursor.visible;
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			ApplyMenuInputBlock(block: true);
			CaptureFrozenLook();
			SyncFromConfig();
			RefreshHelp();
			QrUi.ApplyAllFonts(((Component)this).transform);
			ApplyMenuTheme();
		}

		private void CloseInternal()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (_visible)
			{
				_visible = false;
				_pendingBind = null;
				_hasFrozenLook = false;
				QrUi.ReleaseUiFocus();
				ApplyMenuInputBlock(block: false);
				Cursor.lockState = _prevLock;
				Cursor.visible = _prevCursorVisible;
				((Component)this).gameObject.SetActive(false);
			}
		}

		private void Update()
		{
			if (_visible)
			{
				if (_pendingBind.HasValue)
				{
					PollKeyCapture();
				}
				else if (Input.GetKeyDown((KeyCode)27))
				{
					CloseInternal();
				}
			}
		}

		private void LateUpdate()
		{
			if (_visible)
			{
				HoldFrozenLook();
			}
		}

		private void Build()
		{
			//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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Expected O, but got Unknown
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Expected O, but got Unknown
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Expected O, but got Unknown
			//IL_01c7: 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_01e0: Expected O, but got Unknown
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Expected O, but got Unknown
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Expected O, but got Unknown
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Expected O, but got Unknown
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Expected O, but got Unknown
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Expected O, but got Unknown
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Expected O, but got Unknown
			//IL_048e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0498: Expected O, but got Unknown
			//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d6: Expected O, but got Unknown
			if (!_built)
			{
				_built = true;
				QrUi.CreateOverlayCanvas(((Component)this).gameObject, 9200);
				_panel = QrUi.CreatePanel(((Component)this).transform, "Panel", new Vector2(480f, 600f), QrTheme.Panel);
				QrUi.AddVerticalLayout(((Component)_panel).gameObject, 6f, new RectOffset(16, 16, 12, 12));
				GameObject val = new GameObject("TitleBar", new Type[1] { typeof(RectTransform) });
				val.transform.SetParent((Transform)(object)_panel, false);
				QrUi.MakeNonCollapsing(val, 34f);
				TextMeshProUGUI val2 = QrUi.CreateLabel(val.transform, "Title", "Quick Restart   (drag)", 24f, (FontStyles)0, (TextAlignmentOptions)514);
				QrUi.Stretch(((TMP_Text)val2).rectTransform, 0f, 0f);
				QrUi.MakeDraggable(val, _panel);
				GameObject val3 = new GameObject("Tabs", new Type[1] { typeof(RectTransform) });
				val3.transform.SetParent((Transform)(object)_panel, false);
				QrUi.MakeNonCollapsing(val3, 36f);
				((LayoutGroup)QrUi.AddHorizontalLayout(val3, 6f)).childAlignment = (TextAnchor)4;
				_restartsTab = QrUi.CreatePlainButton(val3.transform, "Restarts", (UnityAction)delegate
				{
					ShowTab(0);
				}, new Vector2(142f, 34f));
				_setupTab = QrUi.CreatePlainButton(val3.transform, "Setup", (UnityAction)delegate
				{
					ShowTab(1);
				}, new Vector2(142f, 34f));
				_colorsTab = QrUi.CreatePlainButton(val3.transform, "Colors", (UnityAction)delegate
				{
					ShowTab(2);
				}, new Vector2(142f, 34f));
				GameObject val4 = new GameObject("Pages", new Type[1] { typeof(RectTransform) });
				val4.transform.SetParent((Transform)(object)_panel, false);
				LayoutElement val5 = val4.AddComponent<LayoutElement>();
				val5.flexibleHeight = 1f;
				val5.minHeight = 300f;
				_restartsPage = new GameObject("Restarts", new Type[1] { typeof(RectTransform) });
				_restartsPage.transform.SetParent(val4.transform, false);
				QrUi.Stretch(_restartsPage.GetComponent<RectTransform>(), 0f, 0f);
				QrUi.AddVerticalLayout(_restartsPage, 6f, new RectOffset(0, 0, 4, 4));
				_help = QrUi.CreateLabel(_restartsPage.transform, "Help", string.Empty, 14f, (FontStyles)0, (TextAlignmentOptions)514);
				QrUi.Theme<TextMeshProUGUI>(_help, QrThemePart.Hint);
				QrUi.MakeNonCollapsing(((Component)_help).gameObject, 44f);
				((TMP_Text)_help).enableWordWrapping = true;
				BuildActions(_restartsPage.transform);
				_setupPage = new GameObject("Setup", new Type[1] { typeof(RectTransform) });
				_setupPage.transform.SetParent(val4.transform, false);
				QrUi.Stretch(_setupPage.GetComponent<RectTransform>(), 0f, 0f);
				RectTransform content;
				ScrollRect val6 = QrUi.CreateScrollView(_setupPage.transform, out content);
				QrUi.Stretch(((Component)val6).GetComponent<RectTransform>(), 0f, 0f);
				QrUi.AddVerticalLayout(((Component)content).gameObject, 6f, new RectOffset(4, 4, 4, 4));
				ContentSizeFitter val7 = ((Component)content).gameObject.AddComponent<ContentSizeFitter>();
				val7.verticalFit = (FitMode)2;
				BuildOptions((Transform)(object)content);
				BuildKeybinds((Transform)(object)content);
				_captureHint = QrUi.CreateLabel((Transform)(object)content, "Capture", string.Empty, 14f, (FontStyles)0, (TextAlignmentOptions)514);
				QrUi.Theme<TextMeshProUGUI>(_captureHint, QrThemePart.Hint);
				QrUi.MakeNonCollapsing(((Component)_captureHint).gameObject, 22f);
				_colorsPage = new GameObject("Colors", new Type[1] { typeof(RectTransform) });
				_colorsPage.transform.SetParent(val4.transform, false);
				QrUi.Stretch(_colorsPage.GetComponent<RectTransform>(), 0f, 0f);
				QrUi.AddVerticalLayout(_colorsPage, 6f, new RectOffset(0, 0, 4, 4));
				BuildColors(_colorsPage.transform);
				QrUi.CreatePlainButton((Transform)(object)_panel, "Close", new UnityAction(CloseInternal), new Vector2(200f, 36f));
				ShowTab(0);
			}
		}

		private void ShowTab(int tab)
		{
			_activeTab = tab;
			if ((Object)(object)_restartsPage != (Object)null)
			{
				_restartsPage.SetActive(tab == 0);
			}
			if ((Object)(object)_setupPage != (Object)null)
			{
				_setupPage.SetActive(tab == 1);
			}
			if ((Object)(object)_colorsPage != (Object)null)
			{
				_colorsPage.SetActive(tab == 2);
			}
			RefreshTabColors();
		}

		private void RefreshTabColors()
		{
			StyleTabButton(_restartsTab, _activeTab == 0);
			StyleTabButton(_setupTab, _activeTab == 1);
			StyleTabButton(_colorsTab, _activeTab == 2);
			RefreshColorTargetButtons();
		}

		private static void StyleTabButton(Button button, bool selected)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)button == (Object)null))
			{
				Graphic targetGraphic = ((Selectable)button).targetGraphic;
				Image val = (Image)(((object)((targetGraphic is Image) ? targetGraphic : null)) ?? ((object)((Component)button).GetComponent<Image>()));
				Color val2 = (selected ? QrTheme.Accent : QrTheme.Button);
				Color highlightedColor = (selected ? QrTheme.Accent : QrTheme.ButtonHover);
				if ((Object)(object)val != (Object)null)
				{
					((Graphic)val).color = val2;
				}
				ColorBlock colors = ((Selectable)button).colors;
				((ColorBlock)(ref colors)).normalColor = val2;
				((ColorBlock)(ref colors)).highlightedColor = highlightedColor;
				((ColorBlock)(ref colors)).pressedColor = QrTheme.Accent;
				((ColorBlock)(ref colors)).selectedColor = val2;
				((Selectable)button).colors = colors;
			}
		}

		private void ApplyMenuTheme()
		{
			if ((Object)(object)_panel != (Object)null)
			{
				QrUi.ApplyTheme((Transform)(object)_panel);
			}
			RefreshTabColors();
			for (int i = 0; i < _colorTargets.Count; i++)
			{
				UpdateSwatch(_colorTargets[i]);
			}
		}

		private void BuildActions(Transform parent)
		{
			AddSectionLabel(parent, "Restart");
			AddActionButton(parent, "Quick Restart", delegate
			{
				RunHostAction(delegate(QuickRestartPlugin p)
				{
					p.BeginQuickRestart(withTerrainRandomizer: false);
				});
			});
			AddHint(parent, "Vanilla / daily terrain. Terrain Randomiser is turned off for the next load.");
			if (TrCompat.IsPresent)
			{
				AddActionButton(parent, "Quick Restart TR", delegate
				{
					RunHostAction(delegate(QuickRestartPlugin p)
					{
						p.BeginQuickRestart(withTerrainRandomizer: true);
					});
				});
				AddHint(parent, "Honors every TR setting: seed, Auto Pick Seed, Fully Random, override biome, biome + variant picks.");
			}
			else
			{
				AddHint(parent, "Install Snosz Terrain Randomiser for biome/seed control.");
			}
			AddSectionLabel(parent, "Travel");
			AddActionButton(parent, "Boarding Pass", delegate
			{
				RunHostAction(delegate(QuickRestartPlugin p)
				{
					p.OpenBoardingPass();
				});
			});
			AddHint(parent, "Airport: same as the check-in kiosk (vanilla). Mid-run: edit TR, press Start, auto-return to airport and board.");
			AddActionButton(parent, "Return to Airport", delegate
			{
				RunHostAction(delegate(QuickRestartPlugin p)
				{
					p.ReturnToAirportOnly();
				});
			});
		}

		private void BuildOptions(Transform parent)
		{
			AddSectionLabel(parent, "Options");
			_skipMpToggle = QrUi.CreateToggle(parent, "Skip airport in multiplayer (when everyone has QR)", isOn: true, delegate(bool v)
			{
				QuickRestartPlugin instance = QuickRestartPlugin.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.SkipAirportInMultiplayer.Value = v;
				}
				RefreshHelp();
			}, 32f);
			_hotkeysToggle = QrUi.CreateToggle(parent, "Enable action hotkeys", isOn: false, delegate(bool v)
			{
				QuickRestartPlugin instance = QuickRestartPlugin.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.EnableHotkeys.Value = v;
				}
			});
			_pauseButtonToggle = QrUi.CreateToggle(parent, "Show Quick Restart on pause menu", isOn: true, delegate(bool v)
			{
				QuickRestartPlugin.SetShowPauseMenuButton(v);
				RefreshPauseChipVisibility();
			});
		}

		private void BuildKeybinds(Transform parent)
		{
			AddSectionLabel(parent, "Keybinds");
			AddHint(parent, "Click Set, then press a key. Esc cancels. Clear unbinds.");
			AddBindRow(parent, "Open menu", () => QuickRestartPlugin.Instance.MenuKey, delegate(KeyCode k)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)QuickRestartPlugin.Instance != (Object)null)
				{
					QuickRestartPlugin.Instance.MenuKey.Value = k;
				}
			});
			AddBindRow(parent, "Quick Restart", () => QuickRestartPlugin.Instance.HotkeyQuickRestart, delegate(KeyCode k)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)QuickRestartPlugin.Instance != (Object)null)
				{
					QuickRestartPlugin.Instance.HotkeyQuickRestart.Value = k;
				}
			});
			AddBindRow(parent, "Quick Restart TR", () => QuickRestartPlugin.Instance.HotkeyQuickRestartTr, delegate(KeyCode k)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)QuickRestartPlugin.Instance != (Object)null)
				{
					QuickRestartPlugin.Instance.HotkeyQuickRestartTr.Value = k;
				}
			});
			AddBindRow(parent, "Return Airport", () => QuickRestartPlugin.Instance.HotkeyReturnToAirport, delegate(KeyCode k)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)QuickRestartPlugin.Instance != (Object)null)
				{
					QuickRestartPlugin.Instance.HotkeyReturnToAirport.Value = k;
				}
			});
			AddBindRow(parent, "Boarding Pass", () => QuickRestartPlugin.Instance.HotkeyBoardingPass, delegate(KeyCode k)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)QuickRestartPlugin.Instance != (Object)null)
				{
					QuickRestartPlugin.Instance.HotkeyBoardingPass.Value = k;
				}
			});
		}

		private void BuildColors(Transform parent)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Expected O, but got Unknown
			QuickRestartPlugin plugin = QuickRestartPlugin.Instance;
			AddSectionLabel(parent, "Menu colors");
			AddHint(parent, "Pick a part, then drag the wheel. Opacity is saved with the color.");
			if ((Object)(object)plugin == (Object)null)
			{
				return;
			}
			GameObject val = new GameObject("Targets", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			QrUi.MakeNonCollapsing(val, 36f);
			((LayoutGroup)QrUi.AddHorizontalLayout(val, 6f)).childAlignment = (TextAnchor)4;
			AddColorTarget(val.transform, "Background", plugin.MenuPanelColor, QrTheme.FallbackPanel);
			AddColorTarget(val.transform, "Buttons", plugin.MenuButtonColor, QrTheme.FallbackButton);
			AddColorTarget(val.transform, "Text", plugin.MenuTextColor, QrTheme.FallbackText);
			AddColorTarget(val.transform, "Accent", plugin.MenuAccentColor, QrTheme.FallbackAccent);
			Color start = ((_colorTargets.Count > 0) ? QrTheme.Parse(_colorTargets[0].Entry.Value, _colorTargets[0].Fallback) : QrTheme.FallbackPanel);
			_colorPicker = QrColorPicker.Create(parent, start, OnPickerColorChanged);
			QrUi.CreatePlainButton(parent, "Reset colors", (UnityAction)delegate
			{
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				plugin.ResetMenuColors();
				if (_selectedColor != null)
				{
					_colorPicker.SetColor(QrTheme.Parse(_selectedColor.Entry.Value, _selectedColor.Fallback), notify: false);
				}
				ApplyMenuTheme();
			}, new Vector2(200f, 34f));
			if (_colorTargets.Count > 0)
			{
				SelectColorTarget(_colorTargets[0], loadPicker: false);
			}
		}

		private void AddColorTarget(Transform parent, string title, ConfigEntry<string> entry, Color fallback)
		{
			//IL_0023: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_00d3: 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_0122: Expected O, but got Unknown
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Expected O, but got Unknown
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			ColorTarget target = new ColorTarget
			{
				Name = title,
				Entry = entry,
				Fallback = fallback
			};
			GameObject val = new GameObject("Target_" + title, new Type[4]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image),
				typeof(Button)
			});
			val.transform.SetParent(parent, false);
			LayoutElement val2 = val.AddComponent<LayoutElement>();
			val2.preferredWidth = 104f;
			val2.minWidth = 90f;
			val2.preferredHeight = 34f;
			val2.minHeight = 34f;
			Image component = val.GetComponent<Image>();
			component.sprite = QrUi.WhiteSprite();
			((Graphic)component).color = QrTheme.Button;
			target.Button = val.GetComponent<Button>();
			((Selectable)target.Button).targetGraphic = (Graphic)(object)component;
			((UnityEvent)target.Button.onClick).AddListener((UnityAction)delegate
			{
				SelectColorTarget(target, loadPicker: true);
			});
			((LayoutGroup)QrUi.AddHorizontalLayout(val, 6f)).childAlignment = (TextAnchor)4;
			HorizontalLayoutGroup component2 = val.GetComponent<HorizontalLayoutGroup>();
			((LayoutGroup)component2).padding = new RectOffset(8, 8, 4, 4);
			TextMeshProUGUI val3 = QrUi.CreateLabel(val.transform, "N", title, 12f, (FontStyles)0, (TextAlignmentOptions)514);
			LayoutElement val4 = ((Component)val3).gameObject.AddComponent<LayoutElement>();
			val4.flexibleWidth = 1f;
			val4.minHeight = 22f;
			GameObject val5 = new GameObject("Swatch", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			val5.transform.SetParent(val.transform, false);
			QrUi.Theme(val5, QrThemePart.Swatch);
			LayoutElement val6 = val5.AddComponent<LayoutElement>();
			val6.preferredWidth = 18f;
			val6.preferredHeight = 18f;
			val6.minWidth = 18f;
			val6.minHeight = 18f;
			target.Swatch = val5.GetComponent<Image>();
			target.Swatch.sprite = QrUi.WhiteSprite();
			((Graphic)target.Swatch).raycastTarget = false;
			((Graphic)target.Swatch).color = QrTheme.Parse(entry.Value, fallback);
			_colorTargets.Add(target);
		}

		private void SelectColorTarget(ColorTarget target, bool loadPicker)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			_selectedColor = target;
			if (loadPicker && (Object)(object)_colorPicker != (Object)null && target != null)
			{
				_colorPicker.SetColor(QrTheme.Parse(target.Entry.Value, target.Fallback), notify: false);
			}
			RefreshColorTargetButtons();
		}

		private void RefreshColorTargetButtons()
		{
			for (int i = 0; i < _colorTargets.Count; i++)
			{
				StyleTabButton(_colorTargets[i].Button, _colorTargets[i] == _selectedColor);
			}
		}

		private void OnPickerColorChanged(Color color)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (_selectedColor != null && _selectedColor.Entry != null)
			{
				_selectedColor.Entry.Value = QrTheme.ToHex(color);
				UpdateSwatch(_selectedColor);
				ApplyMenuTheme();
			}
		}

		private static void UpdateSwatch(ColorTarget target)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (target != null && !((Object)(object)target.Swatch == (Object)null) && target.Entry != null)
			{
				((Graphic)target.Swatch).color = QrTheme.Parse(target.Entry.Value, target.Fallback);
			}
		}

		private void AddSectionLabel(Transform parent, string text)
		{
			TextMeshProUGUI val = QrUi.CreateLabel(parent, "Sec_" + text, text, 16f, (FontStyles)0, (TextAlignmentOptions)513);
			QrUi.MakeNonCollapsing(((Component)val).gameObject, 22f);
		}

		private void AddHint(Transform parent, string text)
		{
			TextMeshProUGUI val = QrUi.CreateLabel(parent, "Hint", text, 13f, (FontStyles)0, (TextAlignmentOptions)513);
			QrUi.Theme<TextMeshProUGUI>(val, QrThemePart.Hint);
			QrUi.MakeNonCollapsing(((Component)val).gameObject, 40f);
			((TMP_Text)val).enableWordWrapping = true;
		}

		private void AddActionButton(Transform parent, string label, Action onClick)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			QrUi.CreatePlainButton(parent, label, (UnityAction)delegate
			{
				onClick?.Invoke();
			}, new Vector2(400f, 38f));
		}

		private void AddBindRow(Transform parent, string label, Func<ConfigEntry<KeyCode>> get, Action<KeyCode> set)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Expected O, but got Unknown
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Expected O, but got Unknown
			GameObject val = new GameObject("Bind_" + QrUi.Sanitize(label), new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			QrUi.MakeNonCollapsing(val, 34f);
			((LayoutGroup)QrUi.AddHorizontalLayout(val, 8f)).childAlignment = (TextAnchor)3;
			TextMeshProUGUI val2 = QrUi.CreateLabel(val.transform, "N", label, 15f, (FontStyles)0, (TextAlignmentOptions)513);
			QrUi.MakeNonCollapsing(((Component)val2).gameObject, 30f, 130f);
			ConfigEntry<KeyCode> obj = get();
			string text = QuickRestartPlugin.FormatKey((KeyCode)((obj != null) ? ((int)obj.Value) : 0));
			TextMeshProUGUI value = QrUi.CreateLabel(val.transform, "V", text, 15f, (FontStyles)0, (TextAlignmentOptions)513);
			QrUi.MakeNonCollapsing(((Component)value).gameObject, 30f, 110f);
			_bindLabels[label] = value;
			QrUi.CreatePlainButton(val.transform, "Set", (UnityAction)delegate
			{
				BeginCapture(label, set, value);
			}, new Vector2(64f, 30f));
			QrUi.CreatePlainButton(val.transform, "Clear", (UnityAction)delegate
			{
				set((KeyCode)0);
				((TMP_Text)value).text = QuickRestartPlugin.FormatKey((KeyCode)0);
			}, new Vector2(70f, 30f));
		}

		private void BeginCapture(string label, Action<KeyCode> set, TextMeshProUGUI value)
		{
			_pendingBind = (KeyCode)0;
			_captureTarget = set;
			_captureLabel = value;
			if ((Object)(object)_captureHint != (Object)null)
			{
				((TMP_Text)_captureHint).text = "Press a key for " + label + "  (Esc cancels)";
			}
		}

		private void PollKeyCapture()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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)
			//IL_006c: Invalid comparison between Unknown and I4
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Invalid comparison between Unknown and I4
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Invalid comparison between Unknown and I4
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown((KeyCode)27))
			{
				_pendingBind = null;
				if ((Object)(object)_captureHint != (Object)null)
				{
					((TMP_Text)_captureHint).text = string.Empty;
				}
				return;
			}
			foreach (KeyCode value in Enum.GetValues(typeof(KeyCode)))
			{
				if ((int)value == 0 || (int)value == 27 || ((int)value >= 323 && (int)value <= 329) || !Input.GetKeyDown(value))
				{
					continue;
				}
				_captureTarget?.Invoke(value);
				if ((Object)(object)_captureLabel != (Object)null)
				{
					((TMP_Text)_captureLabel).text = QuickRestartPlugin.FormatKey(value);
				}
				_pendingBind = null;
				if ((Object)(object)_captureHint != (Object)null)
				{
					((TMP_Text)_captureHint).text = string.Empty;
				}
				break;
			}
		}

		private void RunHostAction(Action<QuickRestartPlugin> action)
		{
			QuickRestartPlugin instance = QuickRestartPlugin.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			if (!QuickRestartPlugin.CanUseControls())
			{
				if ((Object)(object)_help != (Object)null)
				{
					((TMP_Text)_help).text = "Only the lobby host can use restart actions.";
				}
				ShowTab(0);
			}
			else
			{
				CloseInternal();
				action(instance);
			}
		}

		private void SyncFromConfig()
		{
			//IL_0068: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			QuickRestartPlugin instance = QuickRestartPlugin.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				QrUi.SetToggleVisual(_skipMpToggle, instance.SkipAirportInMultiplayer.Value);
				QrUi.SetToggleVisual(_hotkeysToggle, instance.EnableHotkeys.Value);
				QrUi.SetToggleVisual(_pauseButtonToggle, instance.ShowPauseMenuButton.Value);
				SyncBindLabel("Open menu", instance.MenuKey.Value);
				SyncBindLabel("Quick Restart", instance.HotkeyQuickRestart.Value);
				SyncBindLabel("Quick Restart TR", instance.HotkeyQuickRestartTr.Value);
				SyncBindLabel("Return Airport", instance.HotkeyReturnToAirport.Value);
				SyncBindLabel("Boarding Pass", instance.HotkeyBoardingPass.Value);
				if (_selectedColor != null && (Object)(object)_colorPicker != (Object)null)
				{
					_colorPicker.SetColor(QrTheme.Parse(_selectedColor.Entry.Value, _selectedColor.Fallback), notify: false);
				}
				for (int i = 0; i < _colorTargets.Count; i++)
				{
					UpdateSwatch(_colorTargets[i]);
				}
			}
		}

		private void SyncBindLabel(string label, KeyCode key)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (_bindLabels.TryGetValue(label, out var value) && (Object)(object)value != (Object)null)
			{
				((TMP_Text)value).text = QuickRestartPlugin.FormatKey(key);
			}
		}

		private void RefreshHelp()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_help == (Object)null))
			{
				Scene activeScene = SceneManager.GetActiveScene();
				string name = ((Scene)(ref activeScene)).name;
				bool flag = QuickRestartPlugin.IsSoloSessionPublic();
				bool flag2 = (Object)(object)QuickRestartPlugin.Instance != (Object)null && QuickRestartPlugin.Instance.SkipAirportInMultiplayer.Value;
				if (!QuickRestartPlugin.CanUseControls())
				{
					((TMP_Text)_help).text = "Host-only actions. Local options and keybinds still work.";
				}
				else if (name == "Airport")
				{
					((TMP_Text)_help).text = "Airport: Boarding Pass uses the normal airport flow. Quick Restart TR still honors TR settings.";
				}
				else if (flag)
				{
					((TMP_Text)_help).text = (TrCompat.IsPresent ? "Solo: open Boarding Pass to edit ascent or TR, then press Start or Quick Restart TR." : "Solo: skip airport. Quick Restart = vanilla terrain.");
				}
				else if (flag2)
				{
					((TMP_Text)_help).text = "Multiplayer: skip airport when everyone has QR.";
				}
				else
				{
					((TMP_Text)_help).text = "Multiplayer skip OFF — returns to airport first.";
				}
			}
		}

		private void CaptureFrozenLook()
		{
			//IL_0026: 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)
			Character localCharacter = Character.localCharacter;
			if (!((Object)(object)localCharacter?.data == (Object)null))
			{
				_frozenLookValues = localCharacter.data.lookValues;
				_hasFrozenLook = true;
			}
		}

		private void HoldFrozenLook()
		{
			//IL_0035: 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)
			if (_hasFrozenLook)
			{
				Character localCharacter = Character.localCharacter;
				if (!((Object)(object)localCharacter?.data == (Object)null))
				{
					localCharacter.data.lookValues = _frozenLookValues;
				}
			}
		}

		private static void ApplyMenuInputBlock(bool block)
		{
			GUIManager instance = GUIManager.instance;
			if (!((Object)(object)instance == (Object)null) && block)
			{
				GameAccess.SetMenuWindowFlags(instance, blocking: true, showingCursor: true);
			}
		}
	}
	internal enum QrThemePart
	{
		Default,
		Panel,
		TitleBar,
		Scroll,
		Hint,
		Swatch,
		Ignore
	}
	internal sealed class QrThemeTag : MonoBehaviour
	{
		public QrThemePart Part;
	}
	internal static class QrTheme
	{
		public const string DefaultPanelHex = "140F0DF0";

		public const string DefaultButtonHex = "2E2017BA";

		public const string DefaultTextHex = "F2EDE0FF";

		public const string DefaultAccentHex = "8C6B38F2";

		public static readonly Color FallbackPanel = new Color(0.08f, 0.06f, 0.05f, 0.94f);

		public static readonly Color FallbackButton = new Color(0.1792453f, 0.1253449f, 0.09046815f, 62f / 85f);

		public static readonly Color FallbackText = new Color(0.95f, 0.93f, 0.88f, 1f);

		public static readonly Color FallbackAccent = new Color(0.55f, 0.42f, 0.22f, 0.95f);

		public static Color Panel => Read((QuickRestartPlugin p) => p.MenuPanelColor?.Value, "140F0DF0", FallbackPanel);

		public static Color Button => Read((QuickRestartPlugin p) => p.MenuButtonColor?.Value, "2E2017BA", FallbackButton);

		public static Color Text => Read((QuickRestartPlugin p) => p.MenuTextColor?.Value, "F2EDE0FF", FallbackText);

		public static Color Accent => Read((QuickRestartPlugin p) => p.MenuAccentColor?.Value, "8C6B38F2", FallbackAccent);

		public static Color ButtonHover
		{
			get
			{
				//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_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: 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_0032: 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)
				Color result = Color.Lerp(Button, Accent, 0.45f);
				result.a = Mathf.Max(Button.a, 0.92f);
				return result;
			}
		}

		public static Color TextDim
		{
			get
			{
				//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_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				Color text = Text;
				text.a *= 0.85f;
				return text;
			}
		}

		public static Color CheckboxWell
		{
			get
			{
				//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_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: 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)
				Color result = Color.Lerp(Panel, Color.black, 0.25f);
				result.a = Mathf.Clamp01(Panel.a);
				return result;
			}
		}

		public static Color Parse(string hex, Color fallback)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			Color color;
			return TryParse(hex, out color) ? color : fallback;
		}

		public static string ToHex(Color color)
		{
			//IL_0001: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.Clamp(Mathf.RoundToInt(color.r * 255f), 0, 255);
			int num2 = Mathf.Clamp(Mathf.RoundToInt(color.g * 255f), 0, 255);
			int num3 = Mathf.Clamp(Mathf.RoundToInt(color.b * 255f), 0, 255);
			int num4 = Mathf.Clamp(Mathf.RoundToInt(color.a * 255f), 0, 255);
			return $"{num:X2}{num2:X2}{num3:X2}{num4:X2}";
		}

		public static bool TryParse(string hex, out Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			color = Color.white;
			if (string.IsNullOrEmpty(hex))
			{
				return false;
			}
			hex = hex.Trim();
			if (hex.StartsWith("#", StringComparison.Ordinal))
			{
				hex = hex.Substring(1);
			}
			if (hex.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
			{
				hex = hex.Substring(2);
			}
			if (hex.Length != 6 && hex.Length != 8)
			{
				return false;
			}
			try
			{
				byte b = Convert.ToByte(hex.Substring(0, 2), 16);
				byte b2 = Convert.ToByte(hex.Substring(2, 2), 16);
				byte b3 = Convert.ToByte(hex.Substring(4, 2), 16);
				byte b4 = ((hex.Length == 8) ? Convert.ToByte(hex.Substring(6, 2), 16) : byte.MaxValue);
				color = new Color((float)(int)b / 255f, (float)(int)b2 / 255f, (float)(int)b3 / 255f, (float)(int)b4 / 255f);
				return true;
			}
			catch
			{
				return false;
			}
		}

		private static Color Read(Func<QuickRestartPlugin, string> get, string defaultHex, Color fallback)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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)
			QuickRestartPlugin instance = QuickRestartPlugin.Instance;
			string text = (((Object)(object)instance != (Object)null) ? get(instance) : defaultHex);
			return Parse(string.IsNullOrEmpty(text) ? defaultHex : text, fallback);
		}
	}
	internal static class QrUi
	{
		private static Sprite _whiteSprite;

		private static TMP_FontAsset _cachedFont;

		private static int _cachedSceneHandle = -1;

		internal static T Theme<T>(T component, QrThemePart part) where T : Component
		{
			if ((Object)(object)component != (Object)null)
			{
				Theme(((Component)component).gameObject, part);
			}
			return component;
		}

		internal static GameObject Theme(GameObject go, QrThemePart part)
		{
			if ((Object)(object)go == (Object)null)
			{
				return null;
			}
			QrThemeTag qrThemeTag = go.GetComponent<QrThemeTag>() ?? go.AddComponent<QrThemeTag>();
			qrThemeTag.Part = part;
			return go;
		}

		internal static void ApplyTheme(Transform root)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be