Decompiled source of Custom Starter Kit v2.0.2

tony4twentys-Custom Starter Kit.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;
using Zorro.Core.Serizalization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Custom Starter Kit")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Custom Starter Kit")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("d95d122d-502e-48c2-8fe8-8c01135f1069")]
[assembly: AssemblyFileVersion("2.0.2.0")]
[assembly: AssemblyInformationalVersion("2.0.2")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("2.0.2.0")]
namespace Custom_Starter_Kit;

[BepInPlugin("tony4twentys.Custom_Starter_Kit", "Custom Starter Kit", "2.0.2")]
[BepInProcess("PEAK.exe")]
public class Plugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(PlayerHandler), "RegisterPlayer")]
	private static class Patch_RegisterPlayer
	{
		private static void Postfix(Player player)
		{
			if (!((Object)(object)((player != null) ? player.character : null) == (Object)null) && !StarterKitManager.ShouldSkipImmediateGrant(player.character))
			{
				StarterKitManager.TryGrantStarter(player.character);
			}
		}
	}

	[HarmonyPatch(typeof(Character), "UnPassOutDone")]
	private static class Patch_UnPassOutDone
	{
		private static void Postfix(Character __instance)
		{
			StarterKitManager.TryGrantStarter(__instance);
		}
	}

	[HarmonyPatch]
	private static class Patch_ReviveAtPosition
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			return DeclaredMethodsNamed(typeof(Character), "RPCA_ReviveAtPosition");
		}

		private static void Postfix(Character __instance)
		{
			StarterKitManager.TryGrantOnRevive(__instance);
		}
	}

	[HarmonyPatch]
	private static class Patch_CampfireLight
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			return DeclaredMethodsNamed(typeof(Campfire), "Light_Rpc");
		}

		private static void Prefix(Campfire __instance, out bool __state)
		{
			__state = (Object)(object)__instance != (Object)null && __instance.Lit;
		}

		private static void Postfix(Campfire __instance, bool __state)
		{
			if (!((Object)(object)__instance == (Object)null || __state) && __instance.Lit)
			{
				StarterKitManager.GiveStarterKitAtCampfire(__instance);
			}
		}
	}

	public const string PluginGuid = "tony4twentys.Custom_Starter_Kit";

	public const string PluginName = "Custom Starter Kit";

	public const string PluginVersion = "2.0.2";

	public static Plugin Instance;

	public ConfigEntry<bool> DebugLogs;

	public ConfigEntry<bool> ShowPauseMenuButton;

	public ConfigEntry<KeyCode> LoadoutMenuKey;

	public ConfigEntry<KeyCode> LoadoutMenuModifier;

	public ConfigEntry<KeyCode> DeleteRekitBagKey;

	private Harmony _harmony;

	private Coroutine _catalogCoroutine;

	private Coroutine _scanCoroutine;

	public ManualLogSource Logger => ((BaseUnityPlugin)this).Logger;

	public static bool IsDebug => (Object)(object)Instance != (Object)null && Instance.DebugLogs != null && Instance.DebugLogs.Value;

	private void Awake()
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		Instance = this;
		BindConfig();
		StarterKitMenu.EnsureCreated();
		_harmony = new Harmony("tony4twentys.Custom_Starter_Kit");
		_harmony.PatchAll(typeof(Plugin).Assembly);
		SceneManager.sceneLoaded += OnSceneLoaded;
		StarterKitManager.SubscribeEvents();
		_catalogCoroutine = ((MonoBehaviour)this).StartCoroutine(WaitForItemCatalog());
		Logger.LogInfo((object)"Custom Starter Kit v2.0.2 loaded (in-game loadout menu, host grants only).");
	}

	private void Update()
	{
		if (IsLoadoutHotkeyDown())
		{
			StarterKitMenu.Toggle();
		}
		RekitBagTracker.Tick();
	}

	internal bool IsLoadoutHotkeyDown()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Invalid comparison between Unknown and I4
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Invalid comparison between Unknown and I4
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Invalid comparison between Unknown and I4
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Invalid comparison between Unknown and I4
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Invalid comparison between Unknown and I4
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Invalid comparison between Unknown and I4
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Invalid comparison between Unknown and I4
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Invalid comparison between Unknown and I4
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		if (StarterKitMenu.IsListeningForHotkey)
		{
			return false;
		}
		KeyCode val = (KeyCode)((LoadoutMenuKey == null) ? 107 : ((int)LoadoutMenuKey.Value));
		if ((int)val == 0)
		{
			return false;
		}
		KeyCode val2 = (KeyCode)((LoadoutMenuModifier == null) ? 306 : ((int)LoadoutMenuModifier.Value));
		if ((int)val2 == 0)
		{
			return Input.GetKeyDown(val);
		}
		bool flag = Input.GetKey(val2);
		if ((int)val2 == 306 || (int)val2 == 305)
		{
			flag = Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305);
		}
		else if ((int)val2 == 308 || (int)val2 == 307)
		{
			flag = Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307);
		}
		else if ((int)val2 == 304 || (int)val2 == 303)
		{
			flag = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303);
		}
		return flag && Input.GetKeyDown(val);
	}

	private void OnDestroy()
	{
		try
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}
		catch
		{
		}
		try
		{
			StarterKitManager.UnsubscribeEvents();
		}
		catch
		{
		}
		try
		{
			StarterKitMenu.DestroyInstance();
		}
		catch
		{
		}
		try
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
		catch
		{
		}
		if (_catalogCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(_catalogCoroutine);
		}
		if (_scanCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(_scanCoroutine);
		}
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}

	private void BindConfig()
	{
		DebugLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLogs", false, "Verbose grant/scan logging. Leave off unless you are diagnosing a problem.");
		ShowPauseMenuButton = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowPauseMenuButton", true, "Show the Starter Kit button on the pause menu. The hotkey still works if this is off.");
		LoadoutMenuKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "LoadoutMenuKey", (KeyCode)107, "Open the in-game Starter Kit loadout menu (used with LoadoutMenuModifier). Also available from the pause menu.");
		LoadoutMenuModifier = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "LoadoutMenuModifier", (KeyCode)306, "Optional modifier for the loadout menu. Default LeftControl (Ctrl+K). Set to None to use LoadoutMenuKey alone. LeftControl also accepts RightControl.");
		DeleteRekitBagKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "DeleteRekitBagKey", (KeyCode)127, "Host only. While looking at a re-kit backpack on the ground, press this to delete it. Empty re-kit bags despawn on their own. Worn bags are not deleted.");
		LoadoutStore.Initialize(((BaseUnityPlugin)this).Config);
	}

	private IEnumerator WaitForItemCatalog()
	{
		if (ItemCatalog.TryRefresh())
		{
			OnCatalogReady();
			yield break;
		}
		float elapsed = 0f;
		while (!ItemCatalog.TryRefresh())
		{
			elapsed += 0.25f;
			if (elapsed > 120f)
			{
				Logger.LogWarning((object)"Item database never loaded. The loadout picker cannot list items.");
				yield break;
			}
			yield return (object)new WaitForSeconds(0.25f);
		}
		OnCatalogReady();
	}

	private void OnCatalogReady()
	{
		LoadoutStore.NormalizeSavedNames();
		StarterKitMenu.OnCatalogReady();
		Logger.LogInfo((object)$"Loaded {ItemCatalog.Count} live items for the Starter Kit menu.");
		if (ItemCatalog.TryGetPackId((BackpackType)1, out var itemId))
		{
			LogDebug("Backpack item ID: " + itemId);
		}
		if (ItemCatalog.TryGetPackId((BackpackType)2, out var itemId2))
		{
			LogDebug("Fannypack item ID: " + itemId2);
		}
	}

	private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Invalid comparison between Unknown and I4
		if ((int)mode != 1)
		{
			string sceneName = ((Scene)(ref scene)).name ?? string.Empty;
			bool flag = IsLevelSceneName(sceneName);
			if (IsHubSceneName(sceneName))
			{
				EndExpedition();
			}
			else if (flag)
			{
				BeginExpedition();
			}
		}
	}

	private void BeginExpedition()
	{
		StarterKitManager.ResetForScene();
		RestartGrantScan();
		LogDebug("Starter grants reset for a new expedition.");
	}

	private void EndExpedition()
	{
		StarterKitManager.ResetForScene();
		StopGrantScan();
	}

	private void RestartGrantScan()
	{
		StopGrantScan();
		_scanCoroutine = ((MonoBehaviour)this).StartCoroutine(StarterKitManager.PeriodicFallbackScan());
	}

	private void StopGrantScan()
	{
		if (_scanCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(_scanCoroutine);
			_scanCoroutine = null;
		}
	}

	private static bool IsLevelSceneName(string sceneName)
	{
		return !string.IsNullOrEmpty(sceneName) && sceneName.IndexOf("Level_", StringComparison.OrdinalIgnoreCase) >= 0;
	}

	private static bool IsHubSceneName(string sceneName)
	{
		if (string.IsNullOrEmpty(sceneName))
		{
			return false;
		}
		return sceneName.Equals("Airport", StringComparison.OrdinalIgnoreCase) || sceneName.Equals("Title", StringComparison.OrdinalIgnoreCase) || sceneName.Equals("Pretitle", StringComparison.OrdinalIgnoreCase) || sceneName.IndexOf("Main Menu", StringComparison.OrdinalIgnoreCase) >= 0;
	}

	public static bool IsGameplayLevel()
	{
		//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();
		return ((Scene)(ref activeScene)).name != null && ((Scene)(ref activeScene)).name.Contains("Level_");
	}

	public static bool CanHostGrant()
	{
		return PhotonNetwork.IsMasterClient && IsGameplayLevel();
	}

	public static void SetDebug(bool enabled)
	{
		if (!((Object)(object)Instance == (Object)null) && Instance.DebugLogs != null)
		{
			Instance.DebugLogs.Value = enabled;
			((BaseUnityPlugin)Instance).Config.Save();
			LogInfo("Debug logs " + (enabled ? "ON" : "OFF"));
		}
	}

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

	public static void SetShowPauseMenuButton(bool enabled)
	{
		if (!((Object)(object)Instance == (Object)null) && Instance.ShowPauseMenuButton != null)
		{
			Instance.ShowPauseMenuButton.Value = enabled;
			((BaseUnityPlugin)Instance).Config.Save();
			LogInfo("Pause menu button " + (enabled ? "ON" : "OFF"));
		}
	}

	public static KeyCode GetMenuKey()
	{
		//IL_002d: 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_0030: Unknown result type (might be due to invalid IL or missing references)
		return (KeyCode)((!((Object)(object)Instance != (Object)null) || Instance.LoadoutMenuKey == null) ? 107 : ((int)Instance.LoadoutMenuKey.Value));
	}

	public static KeyCode GetMenuModifier()
	{
		//IL_0030: 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_0033: Unknown result type (might be due to invalid IL or missing references)
		return (KeyCode)((!((Object)(object)Instance != (Object)null) || Instance.LoadoutMenuModifier == null) ? 306 : ((int)Instance.LoadoutMenuModifier.Value));
	}

	public static KeyCode GetDeleteRekitBagKey()
	{
		//IL_002d: 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_0030: Unknown result type (might be due to invalid IL or missing references)
		return (KeyCode)((!((Object)(object)Instance != (Object)null) || Instance.DeleteRekitBagKey == null) ? 127 : ((int)Instance.DeleteRekitBagKey.Value));
	}

	public static void SetMenuKey(KeyCode key)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Invalid comparison between Unknown and I4
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)Instance == (Object)null) && Instance.LoadoutMenuKey != null && (int)key != 0)
		{
			Instance.LoadoutMenuKey.Value = key;
			((BaseUnityPlugin)Instance).Config.Save();
			LogInfo("Menu key set to " + FormatHotkey());
		}
	}

	public static void SetMenuModifier(KeyCode key)
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)Instance == (Object)null) && Instance.LoadoutMenuModifier != null)
		{
			Instance.LoadoutMenuModifier.Value = key;
			((BaseUnityPlugin)Instance).Config.Save();
			LogInfo("Menu key set to " + FormatHotkey());
		}
	}

	public static void SetDeleteRekitBagKey(KeyCode key)
	{
		//IL_002e: 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)
		if (!((Object)(object)Instance == (Object)null) && Instance.DeleteRekitBagKey != null)
		{
			Instance.DeleteRekitBagKey.Value = key;
			((BaseUnityPlugin)Instance).Config.Save();
			LogInfo("Delete bag key set to " + PrettyKey(key));
		}
	}

	public static string FormatHotkey()
	{
		//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_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Invalid comparison between Unknown and I4
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		KeyCode menuKey = GetMenuKey();
		KeyCode menuModifier = GetMenuModifier();
		if ((int)menuModifier == 0)
		{
			return PrettyKey(menuKey);
		}
		return PrettyKey(menuModifier) + " + " + PrettyKey(menuKey);
	}

	public unsafe static string PrettyKey(KeyCode key)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Invalid comparison between Unknown and I4
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Invalid comparison between Unknown and I4
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Invalid comparison between Unknown and I4
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Expected I4, but got Unknown
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Invalid comparison between Unknown and I4
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Invalid comparison between Unknown and I4
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Expected I4, but got Unknown
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Invalid comparison between Unknown and I4
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Invalid comparison between Unknown and I4
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Invalid comparison between Unknown and I4
		KeyCode val = key;
		KeyCode val2 = val;
		if ((int)val2 <= 27)
		{
			if ((int)val2 <= 8)
			{
				if ((int)val2 == 0)
				{
					return "None";
				}
				if ((int)val2 == 8)
				{
					return "Backspace";
				}
			}
			else
			{
				if ((int)val2 == 13)
				{
					return "Enter";
				}
				if ((int)val2 == 27)
				{
					return "Esc";
				}
			}
		}
		else if ((int)val2 <= 127)
		{
			if ((int)val2 == 32)
			{
				return "Space";
			}
			if ((int)val2 == 127)
			{
				return "Delete";
			}
		}
		else
		{
			switch (val2 - 277)
			{
			case 0:
				return "Insert";
			case 1:
				return "Home";
			case 2:
				return "End";
			case 3:
				return "Page Up";
			case 4:
				return "Page Down";
			}
			switch (val2 - 303)
			{
			case 3:
				return "Left Ctrl";
			case 2:
				return "Right Ctrl";
			case 5:
				return "Left Alt";
			case 4:
				return "Right Alt";
			case 1:
				return "Left Shift";
			case 0:
				return "Right Shift";
			case 7:
				return "Left Cmd";
			case 6:
				return "Right Cmd";
			}
		}
		string text = ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString();
		if (text.StartsWith("Alpha", StringComparison.Ordinal) && text.Length == 6)
		{
			return text.Substring(5);
		}
		if (text.StartsWith("Keypad", StringComparison.Ordinal))
		{
			return "Num " + text.Substring("Keypad".Length);
		}
		return text;
	}

	public static void LogInfo(string message)
	{
		if ((Object)(object)Instance != (Object)null)
		{
			Instance.Logger.LogInfo((object)message);
		}
		else
		{
			Debug.Log((object)("[Custom Starter Kit] " + message));
		}
	}

	public static void LogDebug(string message)
	{
		if ((Object)(object)Instance != (Object)null && Instance.DebugLogs != null && Instance.DebugLogs.Value)
		{
			Instance.Logger.LogInfo((object)message);
		}
	}

	public static void LogError(string message)
	{
		if ((Object)(object)Instance != (Object)null)
		{
			Instance.Logger.LogError((object)message);
		}
		else
		{
			Debug.LogError((object)("[Custom Starter Kit] " + message));
		}
	}

	internal static IEnumerable<MethodBase> DeclaredMethodsNamed(Type type, string name)
	{
		List<MethodInfo> methods = AccessTools.GetDeclaredMethods(type);
		if (methods == null)
		{
			yield break;
		}
		bool found = false;
		for (int i = 0; i < methods.Count; i++)
		{
			MethodInfo method = methods[i];
			if (!(method == null) && !(method.Name != name))
			{
				found = true;
				yield return method;
			}
		}
		if (!found)
		{
			LogError("No method named " + name + " on " + type.Name + ". Campfire/revive patches may not apply (PEAKERRpcInfo?).");
		}
	}
}
internal sealed class CatalogItem
{
	public ushort Id;

	public string DisplayName;

	public string DropdownName;

	public string PrefabName;

	public Item Prefab;

	public BackpackType PackType;

	public int PackSlotCount;
}
internal static class ItemCatalog
{
	public const string EmptyLabel = "(empty)";

	private static readonly List<CatalogItem> _items = new List<CatalogItem>();

	private static readonly Dictionary<ushort, CatalogItem> _byId = new Dictionary<ushort, CatalogItem>();

	private static readonly Dictionary<string, CatalogItem> _byName = new Dictionary<string, CatalogItem>(StringComparer.OrdinalIgnoreCase);

	private static readonly Dictionary<string, CatalogItem> _byFold = new Dictionary<string, CatalogItem>(StringComparer.OrdinalIgnoreCase);

	private static readonly Dictionary<string, ushort> _byDropdown = new Dictionary<string, ushort>(StringComparer.OrdinalIgnoreCase);

	private static readonly Dictionary<BackpackType, ushort> _packIds = new Dictionary<BackpackType, ushort>();

	private static readonly HashSet<int> _seenInstances = new HashSet<int>();

	private static string[] _dropdownNames = new string[1] { "(empty)" };

	public static bool IsReady { get; private set; }

	public static int Count => _items.Count;

	public static string[] DropdownNames => _dropdownNames;

	public static bool TryRefresh()
	{
		ItemDatabase val = null;
		try
		{
			val = SingletonAsset<ItemDatabase>.Instance;
		}
		catch
		{
			return false;
		}
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		List<Item> list = new List<Item>();
		HashSet<int> seen = new HashSet<int>();
		if (val.itemLookup != null)
		{
			foreach (KeyValuePair<ushort, Item> item in val.itemLookup)
			{
				ConsiderItem(list, seen, item.Value);
			}
		}
		if (((DatabaseAsset<ItemDatabase, Item>)(object)val).Objects != null)
		{
			for (int i = 0; i < ((DatabaseAsset<ItemDatabase, Item>)(object)val).Objects.Count; i++)
			{
				ConsiderItem(list, seen, ((DatabaseAsset<ItemDatabase, Item>)(object)val).Objects[i]);
			}
		}
		if (list.Count == 0)
		{
			return IsReady;
		}
		int num = 0;
		for (int j = 0; j < list.Count; j++)
		{
			Item val2 = list[j];
			if (!((Object)(object)val2 == (Object)null) && _seenInstances.Add(((Object)val2).GetInstanceID()))
			{
				AddEntry(val2);
				num++;
			}
		}
		int count = _packIds.Count;
		TryRegisterPackByName((BackpackType)1, "Backpack");
		TryRegisterPackByName((BackpackType)2, "Fannypack");
		TryRegisterPackByName((BackpackType)3, "Jetpack");
		TryRegisterPackByName((BackpackType)4, "Rocketpack");
		if (num > 0 || _packIds.Count != count)
		{
			BuildDropdownNames();
		}
		IsReady = _items.Count > 0;
		return IsReady;
	}

	private static void AddEntry(Item prefab)
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: 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)
		CatalogItem catalogItem = new CatalogItem
		{
			Id = prefab.itemID,
			Prefab = prefab,
			PrefabName = SafePrefabName(prefab),
			DisplayName = SafeDisplayName(prefab)
		};
		Backpack val = (Backpack)(object)((prefab is Backpack) ? prefab : null);
		if (val != null)
		{
			catalogItem.PackType = val.backpackType;
			catalogItem.PackSlotCount = ((val.slotCount > 0) ? val.slotCount : 4);
			if (catalogItem.Id != 0 && !_packIds.ContainsKey(val.backpackType))
			{
				_packIds[val.backpackType] = catalogItem.Id;
			}
		}
		_items.Add(catalogItem);
		if (catalogItem.Id != 0 && !_byId.ContainsKey(catalogItem.Id))
		{
			_byId[catalogItem.Id] = catalogItem;
		}
	}

	private static void ConsiderItem(List<Item> found, HashSet<int> seen, Item item)
	{
		if (!((Object)(object)item == (Object)null))
		{
			int instanceID = ((Object)item).GetInstanceID();
			if (seen.Add(instanceID))
			{
				found.Add(item);
			}
		}
	}

	public static string DropdownNameForId(int rawId)
	{
		if (rawId <= 0 || rawId > 65535)
		{
			return "(empty)";
		}
		ushort key = (ushort)rawId;
		if (_byId.TryGetValue(key, out var value) && !string.IsNullOrEmpty(value.DropdownName))
		{
			return value.DropdownName;
		}
		return "(empty)";
	}

	public static bool IsEmptySlot(string value)
	{
		return string.IsNullOrEmpty(value) || string.Equals(value.Trim(), "(empty)", StringComparison.OrdinalIgnoreCase);
	}

	public static bool TryResolve(string value, out Item prefab)
	{
		prefab = null;
		if (!TryResolveCatalog(value, out var item))
		{
			return false;
		}
		prefab = item.Prefab;
		return (Object)(object)prefab != (Object)null;
	}

	public static bool TryResolveCatalog(string value, out CatalogItem item)
	{
		item = null;
		if (IsEmptySlot(value))
		{
			return false;
		}
		string text = value.Trim();
		if (text.Length >= 2 && text[0] == '"' && text[text.Length - 1] == '"')
		{
			text = text.Substring(1, text.Length - 2).Trim();
		}
		if (_byName.TryGetValue(text, out item) && (Object)(object)item?.Prefab != (Object)null)
		{
			return true;
		}
		string text2 = FoldName(text);
		if (text2.Length > 0 && _byFold.TryGetValue(text2, out item) && (Object)(object)item?.Prefab != (Object)null)
		{
			return true;
		}
		int num = text.LastIndexOf('|');
		if (num >= 0)
		{
			string raw = text.Substring(num + 1).Trim().TrimStart(new char[1] { '#' });
			if (TryResolveId(raw, out item))
			{
				return true;
			}
			text = text.Substring(0, num).Trim();
			if (_byName.TryGetValue(text, out item) && (Object)(object)item?.Prefab != (Object)null)
			{
				return true;
			}
		}
		int num2 = text.LastIndexOf("(#", StringComparison.Ordinal);
		if (num2 >= 0 && text.EndsWith(")", StringComparison.Ordinal))
		{
			string raw2 = text.Substring(num2 + 2, text.Length - num2 - 3).Trim();
			if (TryResolveId(raw2, out item))
			{
				return true;
			}
		}
		if (TryResolveId(text, out item))
		{
			return true;
		}
		Item val = default(Item);
		if (ItemDatabase.TryGetItem(text, ref val) && (Object)(object)val != (Object)null)
		{
			item = FindByPrefab(val) ?? WrapTransient(val);
			return (Object)(object)item?.Prefab != (Object)null;
		}
		return false;
	}

	public static ushort ParseSlotValue(string value)
	{
		if (!TryResolveCatalog(value, out var item) || item == null)
		{
			return 0;
		}
		return item.Id;
	}

	private static bool TryResolveId(string raw, out CatalogItem item)
	{
		item = null;
		if (!ushort.TryParse(raw, out var result) || result == 0)
		{
			return false;
		}
		if (_byId.TryGetValue(result, out item) && (Object)(object)item?.Prefab != (Object)null)
		{
			return true;
		}
		Item val = default(Item);
		if (ItemDatabase.TryGetItem(result, ref val) && (Object)(object)val != (Object)null)
		{
			item = FindByPrefab(val) ?? WrapTransient(val);
			return (Object)(object)item?.Prefab != (Object)null;
		}
		return false;
	}

	private static CatalogItem FindByPrefab(Item prefab)
	{
		if ((Object)(object)prefab == (Object)null)
		{
			return null;
		}
		for (int i = 0; i < _items.Count; i++)
		{
			if ((Object)(object)_items[i].Prefab == (Object)(object)prefab)
			{
				return _items[i];
			}
		}
		return null;
	}

	private static CatalogItem WrapTransient(Item prefab)
	{
		return new CatalogItem
		{
			Id = prefab.itemID,
			Prefab = prefab,
			PrefabName = SafePrefabName(prefab),
			DisplayName = SafeDisplayName(prefab),
			DropdownName = SafeDisplayName(prefab)
		};
	}

	private static string FoldName(string value)
	{
		if (string.IsNullOrEmpty(value))
		{
			return string.Empty;
		}
		StringBuilder stringBuilder = new StringBuilder(value.Length);
		foreach (char c in value)
		{
			if (char.IsLetterOrDigit(c))
			{
				stringBuilder.Append(char.ToLowerInvariant(c));
			}
		}
		return stringBuilder.ToString();
	}

	public static bool TryGet(ushort id, out CatalogItem item)
	{
		return _byId.TryGetValue(id, out item);
	}

	public static bool TryGetPrefab(ushort id, out Item prefab)
	{
		prefab = null;
		if (id == 0)
		{
			return false;
		}
		if (_byId.TryGetValue(id, out var value) && (Object)(object)value?.Prefab != (Object)null)
		{
			prefab = value.Prefab;
			return true;
		}
		return ItemDatabase.TryGetItem(id, ref prefab) && (Object)(object)prefab != (Object)null;
	}

	public static string GetName(ushort id)
	{
		if (id == 0)
		{
			return "(empty)";
		}
		if (_byId.TryGetValue(id, out var value) && value != null)
		{
			return value.DisplayName;
		}
		Item val = default(Item);
		if (ItemDatabase.TryGetItem(id, ref val) && (Object)(object)val != (Object)null)
		{
			return SafeDisplayName(val);
		}
		return "Unknown item " + id;
	}

	public unsafe static bool TryGetPackId(BackpackType type, out ushort itemId)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		if (_packIds.TryGetValue(type, out itemId))
		{
			return true;
		}
		if (IsReady)
		{
			itemId = 0;
			return false;
		}
		string text = ((object)(*(BackpackType*)(&type))/*cast due to .constrained prefix*/).ToString();
		Item val = default(Item);
		if (ItemDatabase.TryGetItem(text, ref val) && (Object)(object)val != (Object)null)
		{
			itemId = val.itemID;
			return true;
		}
		itemId = 0;
		return false;
	}

	public static int GetPackSlotCount(Player player)
	{
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		if (player?.backpackSlot == null || ((ItemSlot)player.backpackSlot).IsEmpty())
		{
			return 0;
		}
		Item prefab = ((ItemSlot)player.backpackSlot).prefab;
		Backpack val = (Backpack)(object)((prefab is Backpack) ? prefab : null);
		if (val != null && val.slotCount > 0)
		{
			return Mathf.Min(val.slotCount, 4);
		}
		if (TryGetPackId(player.backpackSlot.backpackType, out var itemId) && TryGet(itemId, out var item) && item.PackSlotCount > 0)
		{
			return Mathf.Min(item.PackSlotCount, 4);
		}
		return 4;
	}

	private static void BuildDropdownNames()
	{
		_byDropdown.Clear();
		_byName.Clear();
		_byFold.Clear();
		_byDropdown["(empty)"] = 0;
		Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
		for (int i = 0; i < _items.Count; i++)
		{
			CatalogItem catalogItem = _items[i];
			string text = Sanitize(catalogItem.DisplayName);
			if (string.IsNullOrEmpty(text))
			{
				text = Sanitize(catalogItem.PrefabName);
			}
			if (string.IsNullOrEmpty(text))
			{
				text = ((catalogItem.Id != 0) ? ("Item " + catalogItem.Id) : "Unnamed item");
			}
			if (!dictionary.ContainsKey(text))
			{
				dictionary[text] = 0;
			}
			dictionary[text]++;
		}
		List<string> list = new List<string>(_items.Count + 1) { "(empty)" };
		foreach (CatalogItem item in _items.OrderBy<CatalogItem, string>((CatalogItem catalogItem2) => catalogItem2.DisplayName, StringComparer.OrdinalIgnoreCase).ThenBy<CatalogItem, string>((CatalogItem catalogItem2) => catalogItem2.PrefabName, StringComparer.OrdinalIgnoreCase))
		{
			string text2 = Sanitize(item.DisplayName);
			if (string.IsNullOrEmpty(text2))
			{
				text2 = Sanitize(item.PrefabName);
			}
			if (string.IsNullOrEmpty(text2))
			{
				text2 = ((item.Id != 0) ? ("Item " + item.Id) : "Unnamed item");
			}
			string text3 = (item.DropdownName = ((dictionary[text2] > 1) ? (text2 + " (" + Sanitize(item.PrefabName) + ")") : text2));
			_byDropdown[text3] = item.Id;
			IndexName(text3, item);
			IndexName(item.DisplayName, item);
			IndexName(item.PrefabName, item);
			list.Add(text3);
		}
		_dropdownNames = list.ToArray();
	}

	private static void IndexName(string name, CatalogItem item)
	{
		if (item == null || string.IsNullOrEmpty(name))
		{
			return;
		}
		string text = name.Trim();
		if (text.Length != 0)
		{
			if (!_byName.ContainsKey(text))
			{
				_byName[text] = item;
			}
			string text2 = FoldName(text);
			if (text2.Length > 0 && !_byFold.ContainsKey(text2))
			{
				_byFold[text2] = item;
			}
		}
	}

	private static void TryRegisterPackByName(BackpackType type, string prefabName)
	{
		//IL_0006: 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)
		Item val = default(Item);
		if (!_packIds.ContainsKey(type) && ItemDatabase.TryGetItem(prefabName, ref val) && !((Object)(object)val == (Object)null))
		{
			_packIds[type] = val.itemID;
			_seenInstances.Add(((Object)val).GetInstanceID());
			if (val.itemID != 0 && !_byId.ContainsKey(val.itemID))
			{
				AddEntry(val);
			}
		}
	}

	private static string Sanitize(string value)
	{
		if (string.IsNullOrEmpty(value))
		{
			return string.Empty;
		}
		StringBuilder stringBuilder = new StringBuilder(value.Length);
		foreach (char c in value)
		{
			if (c == '=' || c == '[' || c == ']' || c == '\\' || c == '"' || c == '\n' || c == '\r' || c == '#')
			{
				stringBuilder.Append(' ');
			}
			else
			{
				stringBuilder.Append(c);
			}
		}
		return stringBuilder.ToString().Trim();
	}

	private static string SafePrefabName(Item item)
	{
		try
		{
			if ((Object)(object)item != (Object)null && (Object)(object)((Component)item).gameObject != (Object)null && !string.IsNullOrEmpty(((Object)((Component)item).gameObject).name))
			{
				string text = ((Object)((Component)item).gameObject).name;
				int num = text.IndexOf("(Clone)", StringComparison.Ordinal);
				if (num >= 0)
				{
					text = text.Substring(0, num).Trim();
				}
				return text;
			}
			if ((Object)(object)item != (Object)null && !string.IsNullOrEmpty(((Object)item).name))
			{
				return ((Object)item).name;
			}
		}
		catch
		{
		}
		return "unknown";
	}

	private static string SafeDisplayName(Item item)
	{
		try
		{
			if (item?.UIData != null && !string.IsNullOrEmpty(item.UIData.itemName))
			{
				try
				{
					string name = item.GetName();
					if (!string.IsNullOrEmpty(name) && name.IndexOf("NAME_", StringComparison.OrdinalIgnoreCase) < 0)
					{
						return name;
					}
				}
				catch
				{
				}
				return Prettify(item.UIData.itemName);
			}
		}
		catch
		{
		}
		return Prettify(SafePrefabName(item));
	}

	private static string Prettify(string name)
	{
		if (string.IsNullOrEmpty(name))
		{
			return "Unknown";
		}
		StringBuilder stringBuilder = new StringBuilder(name.Length + 8);
		for (int i = 0; i < name.Length; i++)
		{
			char c = name[i];
			if (c == '_' || c == '-')
			{
				stringBuilder.Append(' ');
				continue;
			}
			if (i > 0 && char.IsUpper(c) && !char.IsUpper(name[i - 1]) && name[i - 1] != ' ')
			{
				stringBuilder.Append(' ');
			}
			stringBuilder.Append(c);
		}
		return stringBuilder.ToString().Trim();
	}
}
internal static class StarterKitManager
{
	private const float FallbackScanIntervalSeconds = 8f;

	private const int CarePackageSlotCount = 4;

	private static readonly HashSet<int> _grantedStarter = new HashSet<int>();

	private static readonly HashSet<int> _warpWait = new HashSet<int>();

	private static readonly HashSet<int> _lateOrReconnect = new HashSet<int>();

	private static readonly HashSet<int> _reviveWait = new HashSet<int>();

	private static readonly HashSet<string> _disconnectedUserIds = new HashSet<string>();

	private static readonly Dictionary<int, ushort> _packIdForActor = new Dictionary<int, ushort>();

	private static readonly HashSet<int> _rekittedCampfires = new HashSet<int>();

	private static int _overflowAroundIndex;

	public static void InvalidatePackPicks()
	{
		_packIdForActor.Clear();
	}

	public static void ResetForScene()
	{
		_grantedStarter.Clear();
		_warpWait.Clear();
		_lateOrReconnect.Clear();
		_reviveWait.Clear();
		_disconnectedUserIds.Clear();
		_packIdForActor.Clear();
		_rekittedCampfires.Clear();
		RekitBagTracker.Clear();
	}

	public static void SubscribeEvents()
	{
		UnsubscribeEvents();
		PlayerHandler.CharacterRegistered = (Action<Character>)Delegate.Combine(PlayerHandler.CharacterRegistered, new Action<Character>(OnCharacterRegistered));
		GlobalEvents.OnPlayerConnected = (Action<Player>)Delegate.Combine(GlobalEvents.OnPlayerConnected, new Action<Player>(OnPlayerConnected));
		GlobalEvents.OnPlayerDisconnected = (Action<Player>)Delegate.Combine(GlobalEvents.OnPlayerDisconnected, new Action<Player>(OnPlayerDisconnected));
	}

	public static void UnsubscribeEvents()
	{
		PlayerHandler.CharacterRegistered = (Action<Character>)Delegate.Remove(PlayerHandler.CharacterRegistered, new Action<Character>(OnCharacterRegistered));
		GlobalEvents.OnPlayerConnected = (Action<Player>)Delegate.Remove(GlobalEvents.OnPlayerConnected, new Action<Player>(OnPlayerConnected));
		GlobalEvents.OnPlayerDisconnected = (Action<Player>)Delegate.Remove(GlobalEvents.OnPlayerDisconnected, new Action<Player>(OnPlayerDisconnected));
	}

	public static bool ShouldSkipImmediateGrant(Character character)
	{
		int actorNumber;
		return TryGetActorNumber(character, out actorNumber) && _lateOrReconnect.Contains(actorNumber);
	}

	private static void OnPlayerConnected(Player player)
	{
		if (player != null && Plugin.CanHostGrant() && (Object)(object)Character.localCharacter != (Object)null)
		{
			_lateOrReconnect.Add(player.ActorNumber);
		}
	}

	private static void OnPlayerDisconnected(Player player)
	{
		if (player != null)
		{
			if (!string.IsNullOrEmpty(player.UserId))
			{
				_disconnectedUserIds.Add(player.UserId);
			}
			_lateOrReconnect.Remove(player.ActorNumber);
			_grantedStarter.Remove(player.ActorNumber);
			_warpWait.Remove(player.ActorNumber);
			_reviveWait.Remove(player.ActorNumber);
			_packIdForActor.Remove(player.ActorNumber);
		}
	}

	private static void OnCharacterRegistered(Character character)
	{
		try
		{
			if (Plugin.CanHostGrant() && TryGetActorNumber(character, out var actorNumber))
			{
				Player val = (((Object)(object)((MonoBehaviourPun)character).photonView != (Object)null) ? ((MonoBehaviourPun)character).photonView.Owner : null);
				if (val != null && !string.IsNullOrEmpty(val.UserId) && _disconnectedUserIds.Remove(val.UserId))
				{
					_lateOrReconnect.Add(actorNumber);
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.LogError("OnCharacterRegistered failed: " + ex);
		}
	}

	public static IEnumerator PeriodicFallbackScan()
	{
		yield return (object)new WaitForSeconds(3f);
		while (true)
		{
			try
			{
				if (Plugin.CanHostGrant())
				{
					List<Character> characters = Character.AllCharacters;
					int count = characters?.Count ?? 0;
					for (int i = 0; i < count; i++)
					{
						Character character = characters[i];
						if (!ShouldSkipImmediateGrant(character))
						{
							TryGrantStarter(character);
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.LogError("Fallback scan failed: " + ex);
			}
			yield return (object)new WaitForSeconds(8f);
		}
	}

	public static void TryGrantStarter(Character character)
	{
		try
		{
			if (!Plugin.CanHostGrant() || !TryGetActorNumber(character, out var actorNumber) || _grantedStarter.Contains(actorNumber) || (Object)(object)character.data == (Object)null || character.data.dead)
			{
				return;
			}
			if (character.warping)
			{
				WaitForWarpThen(character, actorNumber, delegate
				{
					TryGrantStarter(character);
				});
			}
			else
			{
				GivePackAndKit(character, actorNumber);
			}
		}
		catch (Exception ex)
		{
			Plugin.LogError("TryGrantStarter failed: " + ex);
		}
	}

	public static void TryGrantOnRevive(Character character)
	{
		try
		{
			if (Plugin.CanHostGrant() && TryGetActorNumber(character, out var actorNumber) && !((Object)(object)character.data == (Object)null) && !character.data.dead)
			{
				bool flag = !_grantedStarter.Contains(actorNumber);
				if ((flag || WantsReviveRekit()) && !((Object)(object)Plugin.Instance == (Object)null) && _reviveWait.Add(actorNumber))
				{
					((MonoBehaviour)Plugin.Instance).StartCoroutine(CoReviveGrant(character, actorNumber, flag));
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.LogError("TryGrantOnRevive failed: " + ex);
		}
	}

	public static void GiveStarterKitAtCampfire(Campfire fire)
	{
		try
		{
			if (!Plugin.CanHostGrant() || LoadoutStore.RepeatOnCampfire == null || !LoadoutStore.RepeatOnCampfire.Value || GameAccess.IsMiniRunEndingCampfire(fire))
			{
				return;
			}
			int num = (((Object)(object)fire != (Object)null) ? ((Object)fire).GetInstanceID() : 0);
			if (num != 0 && !_rekittedCampfires.Add(num))
			{
				return;
			}
			Plugin.LogDebug("Campfire re-kit for fire instance " + num);
			List<Character> allCharacters = Character.AllCharacters;
			int num2 = allCharacters?.Count ?? 0;
			for (int i = 0; i < num2; i++)
			{
				Character val = allCharacters[i];
				if (TryGetActorNumber(val, out var _) && (!((Object)(object)val.data != (Object)null) || !val.data.dead))
				{
					SpawnRekitBags(val);
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.LogError("Campfire re-kit failed: " + ex);
		}
	}

	private static bool WantsReviveRekit()
	{
		if (LoadoutStore.GivePackOnAnyRevive != null && LoadoutStore.GivePackOnAnyRevive.Value)
		{
			return true;
		}
		return LoadoutStore.RepeatOnCampfire != null && LoadoutStore.RepeatOnCampfire.Value;
	}

	private static IEnumerator CoReviveGrant(Character character, int actorNumber, bool needsStarter)
	{
		try
		{
			float waited = 0f;
			while ((Object)(object)character != (Object)null && !character.warping && waited < 0.75f)
			{
				waited += Time.unscaledDeltaTime;
				yield return null;
			}
			while ((Object)(object)character != (Object)null && character.warping)
			{
				yield return null;
			}
			for (int i = 0; i < 2; i++)
			{
				yield return null;
			}
			waited = 0f;
			while ((Object)(object)character != (Object)null && waited < 15f)
			{
				if ((Object)(object)character.data != (Object)null && character.data.dead)
				{
					yield break;
				}
				if ((Object)(object)character.data != (Object)null && character.data.isGrounded)
				{
					break;
				}
				waited += Time.unscaledDeltaTime;
				yield return null;
			}
			yield return null;
			if (Plugin.CanHostGrant() && !((Object)(object)character == (Object)null) && (!((Object)(object)character.data != (Object)null) || !character.data.dead))
			{
				if (!_grantedStarter.Contains(actorNumber))
				{
					TryGrantStarter(character);
				}
				else if (!needsStarter && WantsReviveRekit())
				{
					SpawnRekitBags(character);
				}
			}
		}
		finally
		{
			_reviveWait.Remove(actorNumber);
		}
	}

	private static void WaitForWarpThen(Character character, int actorNumber, Action then)
	{
		if (_warpWait.Add(actorNumber))
		{
			character.WarpCompleted += OnWarpDone;
		}
		void OnWarpDone(Character warped)
		{
			try
			{
				warped.WarpCompleted -= OnWarpDone;
				_warpWait.Remove(actorNumber);
				then?.Invoke();
			}
			catch (Exception ex)
			{
				_warpWait.Remove(actorNumber);
				Plugin.LogError("WarpCompleted grant failed: " + ex);
			}
		}
	}

	private static void GivePackAndKit(Character character, int actorNumber)
	{
		Player player = character.player;
		if (!((Object)(object)player == (Object)null) && _grantedStarter.Add(actorNumber))
		{
			try
			{
				ItemCatalog.TryRefresh();
			}
			catch
			{
			}
			GiveConfiguredPack(player, actorNumber);
			AddConfiguredItems(character);
			_warpWait.Remove(actorNumber);
			_lateOrReconnect.Remove(actorNumber);
			Plugin.LogDebug("Gave starter kit to actor " + actorNumber + " (" + DescribeLoadout(character.player) + ")");
			LogUnresolvedSlots();
		}
	}

	private static void SpawnRekitBags(Character character)
	{
		if ((Object)(object)character == (Object)null || !TryGetActorNumber(character, out var actorNumber) || ((Object)(object)character.data != (Object)null && character.data.dead))
		{
			return;
		}
		if (character.warping)
		{
			WaitForWarpThen(character, actorNumber, delegate
			{
				SpawnRekitBags(character);
			});
			return;
		}
		Player player = character.player;
		if (!((Object)(object)player == (Object)null))
		{
			try
			{
				ItemCatalog.TryRefresh();
			}
			catch
			{
			}
			if (LoadoutStore.GivePack != null && LoadoutStore.GivePack.Value && !HasPackEquipped(player))
			{
				GiveConfiguredPack(player, actorNumber);
			}
			SpawnCarePackageBackpacks(character, CollectRekitPrefabs(player, actorNumber));
			Plugin.LogDebug("Re-kit bags for " + DescribeLoadout(player));
			LogUnresolvedSlots();
		}
	}

	private static void GiveConfiguredPack(Player player, int actorNumber)
	{
		if (player?.backpackSlot != null && !HasPackEquipped(player) && LoadoutStore.GivePack != null && LoadoutStore.GivePack.Value)
		{
			ushort packIdForActor = GetPackIdForActor(actorNumber);
			if (packIdForActor == 0)
			{
				Plugin.LogError("Could not find a pack item in the game database. Kit items will still be given.");
				return;
			}
			ItemSlot val = default(ItemSlot);
			if (!player.AddItem(packIdForActor, (ItemInstanceData)null, ref val) || !HasPackEquipped(player))
			{
				Plugin.LogDebug("AddItem failed for pack " + packIdForActor + " on actor " + actorNumber);
				return;
			}
			EnsurePackData(player);
			Plugin.LogDebug("Equipped " + ItemCatalog.GetName(packIdForActor) + " on actor " + actorNumber);
		}
	}

	private static List<Item> CollectRekitPrefabs(Player player, int actorNumber)
	{
		List<Item> list = new List<Item>(8);
		for (int i = 0; i < 4; i++)
		{
			AddIfResolved(list, LoadoutStore.Get(i));
		}
		if (!ShouldIncludePackRekitSlots(player))
		{
			return list;
		}
		if (UseFannyRekitSlots(player, actorNumber))
		{
			AddIfResolved(list, LoadoutStore.Get(8));
			AddIfResolved(list, LoadoutStore.Get(9));
		}
		else
		{
			for (int j = 4; j < 8; j++)
			{
				AddIfResolved(list, LoadoutStore.Get(j));
			}
		}
		return list;
	}

	private static bool ShouldIncludePackRekitSlots(Player player)
	{
		if (HasPackEquipped(player))
		{
			return true;
		}
		return LoadoutStore.GivePack != null && LoadoutStore.GivePack.Value;
	}

	private static bool UseFannyRekitSlots(Player player, int actorNumber)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Invalid comparison between Unknown and I4
		if (HasPackEquipped(player))
		{
			return (int)player.backpackSlot.backpackType == 2;
		}
		ushort packIdForActor = GetPackIdForActor(actorNumber);
		if (packIdForActor != 0 && ItemCatalog.TryGetPackId((BackpackType)2, out var itemId))
		{
			return packIdForActor == itemId;
		}
		return LoadoutStore.UseFannypack != null && LoadoutStore.UseFannypack.Value && (LoadoutStore.RandomPack == null || !LoadoutStore.RandomPack.Value);
	}

	private static void AddIfResolved(List<Item> prefabs, string slotValue)
	{
		if (ItemCatalog.TryResolve(slotValue, out var prefab) && (Object)(object)prefab != (Object)null)
		{
			prefabs.Add(prefab);
		}
	}

	private static void AddConfiguredItems(Character character)
	{
		Player val = ((character != null) ? character.player : null);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		List<Item> list = new List<Item>(8);
		for (int i = 0; i < 3; i++)
		{
			if (ItemCatalog.TryResolve(LoadoutStore.Get(i), out var prefab) && !TryAddItemToPocket(val, prefab, i) && !TryAddItemToAnyPocket(val, prefab) && !TryAddItemToPackAny(val, prefab))
			{
				list.Add(prefab);
			}
		}
		Item[] array = ResolvePackPrefabs(val);
		if (HasPackEquipped(val) && TryGetPackData(val, out var packData))
		{
			int packSlotCount = ItemCatalog.GetPackSlotCount(val);
			int num = Mathf.Min(new int[3]
			{
				array.Length,
				packSlotCount,
				(packData.itemSlots != null) ? packData.itemSlots.Length : 0
			});
			for (byte b = 0; b < array.Length; b++)
			{
				Item val2 = array[b];
				if (!((Object)(object)val2 == (Object)null) && (b >= num || !TryAddItemToPack(packData, val2, b)) && !TryAddItemToPackAny(val, val2) && !TryAddItemToAnyPocket(val, val2))
				{
					list.Add(val2);
				}
			}
		}
		else if (LoadoutStore.GivePack != null && LoadoutStore.GivePack.Value)
		{
			foreach (Item val3 in array)
			{
				if (!((Object)(object)val3 == (Object)null) && !TryAddItemToAnyPocket(val, val3))
				{
					list.Add(val3);
				}
			}
		}
		SyncInventory(val);
		SpawnCarePackageBackpacks(character, list);
	}

	private static Item[] ResolvePackPrefabs(Player player)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Invalid comparison between Unknown and I4
		if (player?.backpackSlot != null && !((ItemSlot)player.backpackSlot).IsEmpty() && (int)player.backpackSlot.backpackType == 2)
		{
			return (Item[])(object)new Item[2]
			{
				ResolveOrNull(LoadoutStore.Get(8)),
				ResolveOrNull(LoadoutStore.Get(9))
			};
		}
		return (Item[])(object)new Item[4]
		{
			ResolveOrNull(LoadoutStore.Get(4)),
			ResolveOrNull(LoadoutStore.Get(5)),
			ResolveOrNull(LoadoutStore.Get(6)),
			ResolveOrNull(LoadoutStore.Get(7))
		};
	}

	private static Item ResolveOrNull(string slotValue)
	{
		Item prefab;
		return ItemCatalog.TryResolve(slotValue, out prefab) ? prefab : null;
	}

	private static bool TryAddItemToPocket(Player player, Item prefab, int slotIndex)
	{
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Expected O, but got Unknown
		if (player?.itemSlots == null || (Object)(object)prefab == (Object)null)
		{
			return false;
		}
		if (slotIndex < 0 || slotIndex >= player.itemSlots.Length)
		{
			return false;
		}
		if (!player.itemSlots[slotIndex].IsEmpty())
		{
			return false;
		}
		ItemInstanceData val = new ItemInstanceData(Guid.NewGuid());
		ItemInstanceDataHandler.AddInstanceData(val);
		player.itemSlots[slotIndex].SetItem(prefab, val);
		return true;
	}

	private static bool TryAddItemToAnyPocket(Player player, Item prefab)
	{
		if (player?.itemSlots == null || (Object)(object)prefab == (Object)null)
		{
			return false;
		}
		for (int i = 0; i < player.itemSlots.Length; i++)
		{
			if (TryAddItemToPocket(player, prefab, i))
			{
				return true;
			}
		}
		return false;
	}

	private static bool TryAddItemToPack(BackpackData packData, Item prefab, byte slotIndex)
	{
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Expected O, but got Unknown
		if (packData?.itemSlots == null || (Object)(object)prefab == (Object)null)
		{
			return false;
		}
		if (slotIndex >= packData.itemSlots.Length)
		{
			return false;
		}
		if (!packData.itemSlots[slotIndex].IsEmpty())
		{
			return false;
		}
		ItemInstanceData val = new ItemInstanceData(Guid.NewGuid());
		ItemInstanceDataHandler.AddInstanceData(val);
		packData.AddItem(prefab, val, slotIndex);
		return !packData.itemSlots[slotIndex].IsEmpty();
	}

	private static bool TryAddItemToPackAny(Player player, Item prefab)
	{
		if ((Object)(object)prefab == (Object)null || !TryGetPackData(player, out var packData) || packData.itemSlots == null)
		{
			return false;
		}
		int packSlotCount = ItemCatalog.GetPackSlotCount(player);
		byte b = 0;
		while (b < packData.itemSlots.Length && b < packSlotCount)
		{
			if (TryAddItemToPack(packData, prefab, b))
			{
				return true;
			}
			b++;
		}
		return false;
	}

	private static bool TryGetPackData(Player player, out BackpackData packData)
	{
		packData = null;
		if (!HasPackEquipped(player) || ((ItemSlot)player.backpackSlot).data == null)
		{
			return false;
		}
		EnsurePackData(player);
		return ((ItemSlot)player.backpackSlot).data.TryGetDataEntry<BackpackData>((DataEntryKey)7, ref packData) && packData != null;
	}

	private static void EnsurePackData(Player player)
	{
		object obj;
		if (player == null)
		{
			obj = null;
		}
		else
		{
			BackpackSlot backpackSlot = player.backpackSlot;
			obj = ((backpackSlot != null) ? ((ItemSlot)backpackSlot).data : null);
		}
		BackpackData val = default(BackpackData);
		if (obj != null && (!((ItemSlot)player.backpackSlot).data.TryGetDataEntry<BackpackData>((DataEntryKey)7, ref val) || val == null))
		{
			((ItemSlot)player.backpackSlot).data.RegisterNewEntry<BackpackData>((DataEntryKey)7);
		}
	}

	private static bool HasPackEquipped(Player player)
	{
		return player?.backpackSlot != null && !((ItemSlot)player.backpackSlot).IsEmpty();
	}

	private static string DescribeLoadout(Player player)
	{
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Invalid comparison between Unknown and I4
		List<string> list = new List<string>(8);
		for (int i = 0; i < 3; i++)
		{
			if (ItemCatalog.TryResolveCatalog(LoadoutStore.Get(i), out var item))
			{
				list.Add("P" + (i + 1) + "=" + item.DisplayName);
			}
		}
		if (ItemCatalog.TryResolveCatalog(LoadoutStore.Get(3), out var item2))
		{
			list.Add("Rekit=" + item2.DisplayName);
		}
		bool flag = player?.backpackSlot != null && !((ItemSlot)player.backpackSlot).IsEmpty() && (int)player.backpackSlot.backpackType == 2;
		int num = (flag ? 8 : 4);
		int num2 = (flag ? 2 : 4);
		for (int j = 0; j < num2; j++)
		{
			if (ItemCatalog.TryResolveCatalog(LoadoutStore.Get(num + j), out var item3))
			{
				list.Add("Pack" + (j + 1) + "=" + item3.DisplayName);
			}
		}
		return (list.Count == 0) ? "empty" : string.Join(", ", list.ToArray());
	}

	private static void LogUnresolvedSlots()
	{
		for (int i = 0; i < 10; i++)
		{
			string text = LoadoutStore.Get(i);
			if (!ItemCatalog.IsEmptySlot(text) && !ItemCatalog.TryResolve(text, out var _))
			{
				Plugin.LogError("Loadout slot did not match any item: '" + text + "'");
			}
		}
	}

	private static ushort GetPackIdForActor(int actorNumber)
	{
		if (_packIdForActor.TryGetValue(actorNumber, out var value))
		{
			return value;
		}
		value = ResolveConfiguredPackId();
		_packIdForActor[actorNumber] = value;
		return value;
	}

	private static ushort ResolveConfiguredPackId()
	{
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		if (LoadoutStore.GivePack == null || !LoadoutStore.GivePack.Value)
		{
			return 0;
		}
		if (LoadoutStore.RandomPack != null && LoadoutStore.RandomPack.Value)
		{
			BackpackType type = (BackpackType)((!(Random.value < 0.5f)) ? 1 : 2);
			if (ItemCatalog.TryGetPackId(type, out var itemId))
			{
				return itemId;
			}
		}
		if (LoadoutStore.UseFannypack != null && LoadoutStore.UseFannypack.Value && ItemCatalog.TryGetPackId((BackpackType)2, out var itemId2))
		{
			return itemId2;
		}
		if (ItemCatalog.TryGetPackId((BackpackType)1, out var itemId3))
		{
			return itemId3;
		}
		return 0;
	}

	internal static bool TryGetActorNumber(Character character, out int actorNumber)
	{
		actorNumber = 0;
		if ((Object)(object)character == (Object)null || character.isBot)
		{
			return false;
		}
		PhotonView photonView = ((MonoBehaviourPun)character).photonView;
		if (((photonView != null) ? photonView.Owner : null) == null)
		{
			return false;
		}
		actorNumber = photonView.Owner.ActorNumber;
		return true;
	}

	private static void SyncInventory(Player player)
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			PhotonView playerView = GameAccess.GetPlayerView(player);
			if (!((Object)(object)playerView == (Object)null))
			{
				InventorySyncData val = default(InventorySyncData);
				((InventorySyncData)(ref val))..ctor(player.itemSlots, player.backpackSlot, player.tempFullSlot);
				playerView.RPC("SyncInventoryRPC", (RpcTarget)1, new object[2]
				{
					IBinarySerializable.ToManagedArray<InventorySyncData>(val),
					false
				});
			}
		}
		catch (Exception ex)
		{
			Plugin.LogDebug("Inventory sync failed: " + ex.Message);
		}
	}

	private static Vector3 GetBesidePlayerPos(Character character, float radius, float height, int packIndex)
	{
		//IL_0012: 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_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_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = (((Object)(object)character != (Object)null) ? character.Center : Vector3.zero);
		if (val == Vector3.zero && (Object)(object)character?.data != (Object)null)
		{
			val = character.data.groundPos;
		}
		float num = (float)((_overflowAroundIndex + packIndex) % 8) * 45f * ((float)Math.PI / 180f);
		Vector3 val2 = new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * radius;
		_overflowAroundIndex++;
		return val + val2 + Vector3.up * height;
	}

	private static void SpawnCarePackageBackpacks(Character character, List<Item> prefabs)
	{
		if ((Object)(object)character == (Object)null || prefabs == null || prefabs.Count == 0)
		{
			return;
		}
		int num = (prefabs.Count + 4 - 1) / 4;
		for (int i = 0; i < num; i++)
		{
			int num2 = i * 4;
			if (num2 >= prefabs.Count)
			{
				break;
			}
			int count = Mathf.Min(4, prefabs.Count - num2);
			SpawnFilledBackpack(character, prefabs.GetRange(num2, count), i);
		}
	}

	private static void SpawnFilledBackpack(Character character, List<Item> prefabs, int packIndex)
	{
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Expected O, but got Unknown
		try
		{
			if ((Object)(object)character == (Object)null || !PhotonNetwork.IsMasterClient || prefabs == null || prefabs.Count == 0)
			{
				return;
			}
			if (!ItemCatalog.TryGetPackId((BackpackType)1, out var itemId) || !ItemCatalog.TryGetPrefab(itemId, out var prefab) || (Object)(object)((Component)prefab).gameObject == (Object)null)
			{
				Plugin.LogError("Could not find a Backpack prefab for care-package overflow. Dropping items loose.");
				for (int i = 0; i < prefabs.Count; i++)
				{
					SpawnItemBesidePlayer(character, prefabs[i]);
				}
				return;
			}
			Vector3 besidePlayerPos = GetBesidePlayerPos(character, 2.4f, 0.45f, packIndex);
			GameObject val = PhotonNetwork.InstantiateItemRoom(((Object)((Component)prefab).gameObject).name, besidePlayerPos, Quaternion.identity);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			PhotonView component = val.GetComponent<PhotonView>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			ItemInstanceData val2 = new ItemInstanceData(Guid.NewGuid());
			ItemInstanceDataHandler.AddInstanceData(val2);
			BackpackData val3 = default(BackpackData);
			if (!val2.TryGetDataEntry<BackpackData>((DataEntryKey)7, ref val3) || val3 == null)
			{
				val2.RegisterNewEntry<BackpackData>((DataEntryKey)7);
			}
			if (!val2.TryGetDataEntry<BackpackData>((DataEntryKey)7, ref val3) || val3 == null)
			{
				Plugin.LogError("Failed to attach BackpackData to care-package backpack.");
				return;
			}
			int num = 0;
			byte b = 0;
			while (b < prefabs.Count && b < 4)
			{
				if (TryAddItemToPack(val3, prefabs[b], b))
				{
					num++;
				}
				b++;
			}
			component.RPC("SetItemInstanceDataRPC", (RpcTarget)0, new object[1] { val2 });
			RekitBagTracker.Register(val);
			Plugin.LogDebug("Spawned care-package backpack with " + num + " item(s) beside player");
		}
		catch (Exception ex)
		{
			Plugin.LogError("Care-package backpack spawn failed: " + ex);
		}
	}

	private static void SpawnItemBesidePlayer(Character character, Item prefab)
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!((Object)(object)character == (Object)null) && PhotonNetwork.IsMasterClient && !((Object)(object)prefab == (Object)null) && !((Object)(object)((Component)prefab).gameObject == (Object)null))
			{
				Vector3 besidePlayerPos = GetBesidePlayerPos(character, 1.2f, 0.35f, 0);
				PhotonNetwork.InstantiateItemRoom(((Object)((Component)prefab).gameObject).name, besidePlayerPos, Quaternion.identity);
				Plugin.LogDebug("Dropped overflow " + ((Object)prefab).name + " beside player");
			}
		}
		catch (Exception ex)
		{
			Plugin.LogDebug("Overflow drop failed: " + ex.Message);
		}
	}
}
internal sealed class StarterKitMenu : MonoBehaviour
{
	[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_PauseMenuStart
	{
		private static void Postfix(PauseMenuMainPage __instance)
		{
			InjectPauseButton(__instance);
		}
	}

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

	private const int SortOrder = 9300;

	private static readonly string[] SlotLabels = new string[10] { "Pocket 1", "Pocket 2", "Pocket 3", "Re-kit Only", "Backpack 1", "Backpack 2", "Backpack 3", "Backpack 4", "Fanny 1", "Fanny 2" };

	private static StarterKitMenu _instance;

	private Canvas _canvas;

	private RectTransform _panel;

	private GameObject _slotPage;

	private GameObject _pickerPage;

	private TextMeshProUGUI _pickerTitle;

	private TextMeshProUGUI _help;

	private TMP_InputField _search;

	private RectTransform _itemContent;

	private readonly List<KitItemRow> _itemRows = new List<KitItemRow>(256);

	private readonly TextMeshProUGUI[] _slotValueLabels = (TextMeshProUGUI[])(object)new TextMeshProUGUI[10];

	private Toggle _givePackToggle;

	private Toggle _fannyToggle;

	private Toggle _randomToggle;

	private Toggle _campfireToggle;

	private Toggle _reviveToggle;

	private Toggle _debugToggle;

	private Toggle _pauseButtonToggle;

	private ChoiceDropdown _hotkeyModDropdown;

	private Button _hotkeyKeyButton;

	private TextMeshProUGUI _hotkeyKeyLabel;

	private Button _deleteKeyButton;

	private TextMeshProUGUI _deleteKeyLabel;

	private int _listenHotkey;

	private bool _visible;

	private bool _built;

	private bool _builtWithPeakButtons;

	private int _pickingSlot = -1;

	private string _filter = string.Empty;

	private CursorLockMode _prevLock;

	private bool _prevCursorVisible;

	private Vector2 _frozenLookValues;

	private bool _hasFrozenLook;

	private static readonly string[] HotkeyModLabels = new string[7] { "None", "Left Ctrl", "Right Ctrl", "Left Alt", "Right Alt", "Left Shift", "Right Shift" };

	private static readonly int[] HotkeyModValues = new int[7] { 0, 306, 305, 308, 307, 304, 303 };

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

	public static bool IsListeningForHotkey => (Object)(object)_instance != (Object)null && _instance._listenHotkey != 0;

	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("CSK_StarterKitMenu");
			Object.DontDestroyOnLoad((Object)(object)val);
			_instance = val.AddComponent<StarterKitMenu>();
			val.SetActive(false);
		}
	}

	public static void Toggle()
	{
		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 OnCatalogReady()
	{
		if ((Object)(object)_instance != (Object)null && _instance._built)
		{
			_instance.RebuildItemRows();
		}
	}

	internal static void InjectPauseButton(PauseMenuMainPage page)
	{
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Expected O, but got Unknown
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)page == (Object)null)
		{
			return;
		}
		try
		{
			Transform val = null;
			Button val2 = GameAccess.GetPauseMenuButton(page, "m_settingsButton") ?? GameAccess.GetPauseMenuButton(page, "m_resumeButton");
			if ((Object)(object)val2 != (Object)null)
			{
				val = ((Component)val2).transform.parent;
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Transform val3 = val.Find("CSK_PauseStarterKit");
			GameObject val4 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).gameObject : null);
			if ((Object)(object)val4 == (Object)null)
			{
				val4 = Object.Instantiate<GameObject>(((Component)val2).gameObject, val, false);
				((Object)val4).name = "CSK_PauseStarterKit";
				LocalizedText[] componentsInChildren = val4.GetComponentsInChildren<LocalizedText>(true);
				foreach (LocalizedText val5 in componentsInChildren)
				{
					Object.Destroy((Object)(object)val5);
				}
				TextMeshProUGUI componentInChildren = val4.GetComponentInChildren<TextMeshProUGUI>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					((TMP_Text)componentInChildren).text = "Starter Kit";
				}
				RectTransform component = val4.GetComponent<RectTransform>();
				RectTransform component2 = ((Component)val2).GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
				{
					component.anchoredPosition = component2.anchoredPosition + new Vector2(0f, -56f);
				}
			}
			Button component3 = val4.GetComponent<Button>();
			if ((Object)(object)component3 != (Object)null)
			{
				((UnityEventBase)component3.onClick).RemoveAllListeners();
				((UnityEvent)component3.onClick).AddListener(new UnityAction(Toggle));
			}
			val4.SetActive(Plugin.GetShowPauseMenuButton());
		}
		catch (Exception ex)
		{
			Plugin.LogDebug("Pause button inject failed: " + ex.Message);
		}
	}

	internal static void RefreshPauseButton()
	{
		try
		{
			PauseMenuMainPage val = Object.FindFirstObjectByType<PauseMenuMainPage>((FindObjectsInactive)1);
			if ((Object)(object)val != (Object)null)
			{
				InjectPauseButton(val);
			}
		}
		catch
		{
		}
	}

	private void Open()
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (_built && !_builtWithPeakButtons && KitUi.HasPeakButtonDonor())
			{
				TearDownUi();
			}
			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();
			RefreshCatalogFromGame();
			ShowSlotPage();
			SyncTogglesFromConfig();
			RefreshSlotLabels();
			KitUi.ApplyAllFonts(((Component)this).transform);
			if (!ItemCatalog.IsReady && (Object)(object)_help != (Object)null)
			{
				((TMP_Text)_help).text = "Item list is still loading — open a slot again in a moment to pick items.";
			}
		}
		catch (Exception ex)
		{
			Plugin.LogError("Failed to open Starter Kit menu: " + ex);
		}
	}

	private void CloseInternal()
	{
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		if (_visible)
		{
			_visible = false;
			_listenHotkey = 0;
			_pickingSlot = -1;
			_hasFrozenLook = false;
			ChoiceDropdown.CloseOpen();
			if ((Object)(object)_search != (Object)null)
			{
				_search.DeactivateInputField(false);
			}
			KitUi.ReleaseUiFocus();
			ApplyMenuInputBlock(block: false);
			Cursor.lockState = _prevLock;
			Cursor.visible = _prevCursorVisible;
			((Component)this).gameObject.SetActive(false);
		}
	}

	private void TearDownUi()
	{
		for (int num = ((Component)this).transform.childCount - 1; num >= 0; num--)
		{
			Object.Destroy((Object)(object)((Component)((Component)this).transform.GetChild(num)).gameObject);
		}
		_itemRows.Clear();
		for (int i = 0; i < _slotValueLabels.Length; i++)
		{
			_slotValueLabels[i] = null;
		}
		_panel = null;
		_slotPage = null;
		_pickerPage = null;
		_pickerTitle = null;
		_help = null;
		_search = null;
		_itemContent = null;
		_givePackToggle = null;
		_fannyToggle = null;
		_randomToggle = null;
		_campfireToggle = null;
		_reviveToggle = null;
		_debugToggle = null;
		_pauseButtonToggle = null;
		_hotkeyModDropdown = null;
		_hotkeyKeyButton = null;
		_hotkeyKeyLabel = null;
		_deleteKeyButton = null;
		_deleteKeyLabel = null;
		_listenHotkey = 0;
		_canvas = null;
		_built = false;
		_builtWithPeakButtons = false;
		KitUi.InvalidateButtonDonor();
	}

	private void Build()
	{
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Expected O, but got Unknown
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Expected O, but got Unknown
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		if (!_built)
		{
			_built = true;
			_builtWithPeakButtons = KitUi.HasPeakButtonDonor();
			_canvas = KitUi.CreateOverlayCanvas(((Component)this).gameObject, 9300);
			_panel = KitUi.CreatePanel(((Component)this).transform, "Panel", new Vector2(720f, 900f), KitUi.PanelColor);
			KitUi.AddVerticalLayout(((Component)_panel).gameObject, 6f, new RectOffset(20, 20, 16, 16));
			GameObject val = new GameObject("TitleBar", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent((Transform)(object)_panel, false);
			KitUi.MakeNonCollapsing(val, 36f);
			TextMeshProUGUI val2 = KitUi.CreateLabel(val.transform, "Title", "Custom Starter Kit", 26f, (FontStyles)0, (TextAlignmentOptions)514);
			KitUi.Stretch(((TMP_Text)val2).rectTransform, 0f, 0f);
			KitUi.MakeDraggable(val, _panel);
			_help = KitUi.CreateLabel((Transform)(object)_panel, "Help", "This loadout is used when you host. Click a slot, then search and pick an item.", 15f, (FontStyles)0, (TextAlignmentOptions)514);
			((Graphic)_help).color = KitUi.CreamDim;
			KitUi.MakeNonCollapsing(((Component)_help).gameObject, 36f);
			((TMP_Text)_help).enableWordWrapping = true;
			BuildSlotPage();
			BuildPickerPage();
		}
	}

	private void BuildSlotPage()
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Expected O, but got Unknown
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Expected O, but got Unknown
		//IL_034a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0351: Expected O, but got Unknown
		//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bb: Expected O, but got Unknown
		//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_03de: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e8: Expected O, but got Unknown
		_slotPage = new GameObject("SlotPage", new Type[1] { typeof(RectTransform) });
		_slotPage.transform.SetParent((Transform)(object)_panel, false);
		LayoutElement val = _slotPage.AddComponent<LayoutElement>();
		val.flexibleHeight = 1f;
		val.minHeight = 520f;
		KitUi.AddVerticalLayout(_slotPage, 6f, new RectOffset(0, 0, 0, 0));
		RectTransform content;
		ScrollRect val2 = KitUi.CreateScrollView(_slotPage.transform, out content);
		((Component)val2).gameObject.AddComponent<LayoutElement>().flexibleHeight = 1f;
		KitUi.AddVerticalLayout(((Component)content).gameObject, 4f, new RectOffset(4, 4, 4, 4));
		ContentSizeFitter val3 = ((Component)content).gameObject.AddComponent<ContentSizeFitter>();
		val3.verticalFit = (FitMode)2;
		AddHeader((Transform)(object)content, "Controls");
		_debugToggle = KitUi.CreateToggle((Transform)(object)content, "Debug logs (writes extra lines to BepInEx/LogOutput.log)", Plugin.IsDebug, OnDebugToggled, 30f);
		KitUi.MakeNonCollapsing(((Component)_debugToggle).gameObject, 32f);
		_pauseButtonToggle = KitUi.CreateToggle((Transform)(object)content, "Show Starter Kit on the pause menu", Plugin.GetShowPauseMenuButton(), OnPauseButtonToggled, 30f);
		KitUi.MakeNonCollapsing(((Component)_pauseButtonToggle).gameObject, 32f);
		BuildHotkeyRow((Transform)(object)content);
		BuildDeleteKeyRow((Transform)(object)content);
		AddHeader((Transform)(object)content, "Loadout");
		_givePackToggle = KitUi.CreateToggle((Transform)(object)content, "Give pack", LoadoutStore.GivePack.Value, delegate(bool v)
		{
			LoadoutStore.GivePack.Value = v;
		});
		_fannyToggle = KitUi.CreateToggle((Transform)(object)content, "Use Fannypack", LoadoutStore.UseFannypack.Value, delegate(bool v)
		{
			LoadoutStore.UseFannypack.Value = v;
			if (v)
			{
				ClearRandomPackToggle();
			}
		});
		_randomToggle = KitUi.CreateToggle((Transform)(object)content, "Random pack (Backpack or Fannypack)", LoadoutStore.RandomPack.Value, delegate(bool v)
		{
			LoadoutStore.RandomPack.Value = v;
			if (v)
			{
				ClearFannyPackToggle();
			}
		});
		_campfireToggle = KitUi.CreateToggle((Transform)(object)content, "Re-kit when a campfire is lit", LoadoutStore.RepeatOnCampfire.Value, delegate(bool v)
		{
			LoadoutStore.RepeatOnCampfire.Value = v;
		});
		_reviveToggle = KitUi.CreateToggle((Transform)(object)content, "Re-kit on any revive", LoadoutStore.GivePackOnAnyRevive.Value, delegate(bool v)
		{
			LoadoutStore.GivePackOnAnyRevive.Value = v;
		});
		AddHeader((Transform)(object)content, "Pockets");
		for (int num = 0; num < 3; num++)
		{
			AddSlotRow((Transform)(object)content, num);
		}
		AddHeader((Transform)(object)content, "Re-kit");
		AddSlotRow((Transform)(object)content, 3);
		AddHeader((Transform)(object)content, "Backpack (4 slots)");
		for (int num2 = 4; num2 < 8; num2++)
		{
			AddSlotRow((Transform)(object)content, num2);
		}
		AddHeader((Transform)(object)content, "Fannypack (2 slots)");
		for (int num3 = 8; num3 < 10; num3++)
		{
			AddSlotRow((Transform)(object)content, num3);
		}
		GameObject val4 = new GameObject("Footer", new Type[1] { typeof(RectTransform) });
		val4.transform.SetParent(_slotPage.transform, false);
		KitUi.MakeNonCollapsing(val4, 44f);
		((LayoutGroup)KitUi.AddHorizontalLayout(val4, 10f)).childAlignment = (TextAnchor)4;
		KitUi.CreateButton(val4.transform, "Clear all slots", new UnityAction(ClearAllSlots), new Vector2(200f, 40f));
		KitUi.CreateButton(val4.transform, "Close", new UnityAction(CloseInternal), new Vector2(160f, 40f));
	}

	private void BuildPickerPage()
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Expected O, but got Unknown
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Expected O, but got Unknown
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Expected O, but got Unknown
		//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Expected O, but got Unknown
		_pickerPage = new GameObject("PickerPage", new Type[1] { typeof(RectTransform) });
		_pickerPage.transform.SetParent((Transform)(object)_panel, false);
		LayoutElement val = _pickerPage.AddComponent<LayoutElement>();
		val.flexibleHeight = 1f;
		val.minHeight = 480f;
		KitUi.AddVerticalLayout(_pickerPage, 8f, new RectOffset(0, 0, 0, 0));
		_pickerTitle = KitUi.CreateLabel(_pickerPage.transform, "PickerTitle", "Choose item", 22f, (FontStyles)0, (TextAlignmentOptions)514);
		KitUi.MakeNonCollapsing(((Component)_pickerTitle).gameObject, 32f);
		_search = KitUi.CreateSearchField(_pickerPage.transform, "Search items...", FilterItems);
		ScrollRect val2 = KitUi.CreateScrollView(_pickerPage.transform, out _itemContent);
		((Component)val2).gameObject.AddComponent<LayoutElement>().flexibleHeight = 1f;
		VerticalLayoutGroup val3 = ((Component)_itemContent).gameObject.AddComponent<VerticalLayoutGroup>();
		((HorizontalOrVerticalLayoutGroup)val3).spacing = 4f;
		((HorizontalOrVerticalLayoutGroup)val3).childForceExpandWidth = true;
		((HorizontalOrVerticalLayoutGroup)val3).childForceExpandHeight = false;
		((HorizontalOrVerticalLayoutGroup)val3).childControlWidth = true;
		((HorizontalOrVerticalLayoutGroup)val3).childControlHeight = true;
		((LayoutGroup)val3).padding = new RectOffset(4, 4, 4, 4);
		ContentSizeFitter val4 = ((Component)_itemContent).gameObject.AddComponent<ContentSizeFitter>();
		val4.verticalFit = (FitMode)2;
		GameObject val5 = new GameObject("PickerFooter", new Type[1] { typeof(RectTransform) });
		val5.transform.SetParent(_pickerPage.transform, false);
		KitUi.MakeNonCollapsing(val5, 44f);
		((LayoutGroup)KitUi.AddHorizontalLayout(val5, 10f)).childAlignment = (TextAnchor)4;
		KitUi.CreateButton(val5.transform, "Back", new UnityAction(ShowSlotPage), new Vector2(160f, 40f));
		_pickerPage.SetActive(false);
	}

	private void AddHeader(Transform parent, string text)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		TextMeshProUGUI val = KitUi.CreateLabel(parent, "Hdr_" + text, text, 18f, (FontStyles)0, (TextAlignmentOptions)513);
		((Graphic)val).color = KitUi.CreamDim;
		KitUi.MakeNonCollapsing(((Component)val).gameObject, 24f);
	}

	private void AddSlotRow(Transform parent, int slotIndex)
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Expected O, but got Unknown
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Expected O, but got Unknown
		GameObject val = new GameObject("Slot_" + slotIndex, new Type[1] { typeof(RectTransform) });
		val.transform.SetParent(parent, false);
		KitUi.MakeNonCollapsing(val, 40f);
		HorizontalLayoutGroup val2 = KitUi.AddHorizontalLayout(val, 10f);
		((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = true;
		((LayoutGroup)val2).childAlignment = (TextAnchor)3;
		TextMeshProUGUI val3 = KitUi.CreateLabel(val.transform, "Name", SlotLabels[slotIndex], 18f, (FontStyles)0, (TextAlignmentOptions)513);
		LayoutElement val4 = ((Component)val3).gameObject.AddComponent<LayoutElement>();
		val4.minWidth = 140f;
		val4.preferredWidth = 140f;
		val4.flexibleWidth = 0f;
		Button val5 = KitUi.CreatePlainButton(val.transform, "(empty)", (UnityAction)delegate
		{
			OpenPicker(slotIndex);
		}, new Vector2(400f, 36f));
		_slotValueLabels[slotIndex] = ((Component)val5).GetComponentInChildren<TextMeshProUGUI>(true);
		if ((Object)(object)_slotValueLabels[slotIndex] != (Object)null)
		{
			((TMP_Text)_slotValueLabels[slotIndex]).overflowMode = (TextOverflowModes)0;
		}
	}

	private void RefreshCatalogFromGame()
	{
		int count = ItemCatalog.Count;
		try
		{
			ItemCatalog.TryRefresh();
		}
		catch (Exception ex)
		{
			Plugin.LogDebug("Catalog refresh: " + ex.Message);
			return;
		}
		int num = ItemCatalog.Count - count;
		if (num > 0)
		{
			Plugin instance = Plugin.Instance;
			if (instance != null)
			{
				instance.Logger.LogInfo((object)("Found " + num + " more item(s) in the Starter Kit picker (" + ItemCatalog.Count + " total)."));
			}
			LoadoutStore.NormalizeSavedNames();
			if (_built)
			{
				RebuildItemRows();
			}
		}
	}

	private void RebuildItemRows()
	{
		for (int i = 0; i < _itemRows.Count; i++)
		{
			if ((Object)(object)_itemRows[i] != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_itemRows[i]).gameObject);
			}
		}
		_itemRows.Clear();
		string[] dropdownNames = ItemCatalog.DropdownNames;
		if (dropdownNames != null && !((Object)(object)_itemContent == (Object)null))
		{
			for (int j = 0; j < dropdownNames.Length; j++)
			{
				string label = dropdownNames[j];
				KitItemRow kitItemRow = KitUi.CreateItemRow((Transform)(object)_itemContent, label, Pick, 34f);
				((Object)((Component)kitItemRow).gameObject).name = "Item_" + j;
				_itemRows.Add(kitItemRow);
			}
			Canvas.ForceUpdateCanvases();
			KitUi.ApplyAllFonts((Transform)(object)_itemContent);
			FilterItems(_filter);
		}
	}

	private void OpenPicker(int slotIndex)
	{
		if (!ItemCatalog.IsReady)
		{
			Plugin instance = Plugin.Instance;
			if (instance != null)
			{
				instance.Logger.LogWarning((object)"Item database is still loading — try the slot again in a moment.");
			}
			if ((Object)(object)_help != (Object)null)
			{
				((TMP_Text)_help).text = "Item list is still loading — try again in a moment.";
			}
			return;
		}
		if (_itemRows.Count == 0)
		{
			RebuildItemRows();
		}
		_pickingSlot = slotIndex;
		((TMP_Text)_pickerTitle).text = "Choose " + SlotLabels[slotIndex];
		if ((Object)(object)_search != (Object)null)
		{
			_search.SetTextWithoutNotify(string.Empty);
			_filter = string.Empty;
		}
		FilterItems(string.Empty);
		_slotPage.SetActive(false);
		_pickerPage.SetActive(true);
		Canvas.ForceUpdateCanvases();
		KitUi.ApplyAllFonts(_pickerPage.transform);
		FocusSearch();
	}

	private void ShowSlotPage()
	{
		_pickingSlot = -1;
		if ((Object)(object)_search != (Object)null)
		{
			_search.DeactivateInputField(false);
		}
		KitUi.ReleaseUiFocus();
		if ((Object)(object)_pickerPage != (Object)null)
		{
			_pickerPage.SetActive(false);
		}
		if ((Object)(object)_slotPage != (Object)null)
		{
			_slotPage.SetActive(true);
		}
		RefreshSlotLabels();
		ChoiceDropdown.CloseOpen();
		KitUi.SetToggleVisual(_debugToggle, Plugin.IsDebug);
		KitUi.SetToggleVisual(_pauseButtonToggle, Plugin.GetShowPauseMenuButton());
		RefreshHotkeyRows();
		if ((Object)(object)_help != (Object)null && ItemCatalog.IsReady)
		{
			((TMP_Text)_help).text = "This loadout is used when you host. Click a slot, then search and pick an item.";
		}
	}

	private void Pick(string dropdownName)
	{
		if (_pickingSlot >= 0)
		{
			LoadoutStore.Set(_pickingSlot, dropdownName);
			ShowSlotPage();
		}
	}

	private void ClearAllSlots()
	{
		LoadoutStore.ClearAllSlots();
		RefreshSlotLabels();
		if ((Object)(object)_help != (Object)null)
		{
			((TMP_Text)_help).text = "All item slots cleared. Pack and campfire toggles are unchanged.";
		}
	}

	private void RefreshSlotLabels()
	{
		for (int i = 0; i < _slotValueLabels.Length; i++)
		{
			if ((Object)(object)_slotValueLabels[i] != (Object)null)
			{
				((TMP_Text)_slotValueLabels[i]).text = LoadoutStore.Get(i);
			}
		}
	}

	private void FocusSearch()
	{
		if ((Object)(object)_search == (Object)null)
		{
			return;
		}
		((Component)_search).gameObject.SetActive(true);
		_search.ActivateInputField();
		((Selectable)_search).Select();
		try
		{
			EventSystem current = EventSystem.current;
			if ((Object)(object)current != (Object)null)
			{
				current.SetSelectedGameObject(((Component)_search).gameObject);
			}
		}
		catch
		{
		}
	}

	private void SyncTogglesFromConfig()
	{
		LoadoutStore.EnforceExclusivePackToggles();
		KitUi.SetToggleVisual(_givePackToggle, LoadoutStore.GivePack.Value);
		KitUi.SetToggleVisual(_fannyToggle, LoadoutStore.UseFannypack.Value);
		KitUi.SetToggleVisual(_randomToggle, LoadoutStore.RandomPack.Value);
		KitUi.SetToggleVisual(_campfireToggle, LoadoutStore.RepeatOnCampfire.Value);
		KitUi.SetToggleVisual(_reviveToggle, LoadoutStore.GivePackOnAnyRevive.Value);
		KitUi.SetToggleVisual(_debugToggle, Plugin.IsDebug);
		KitUi.SetToggleVisual(_pauseButtonToggle, Plugin.GetShowPauseMenuButton());
		RefreshHotkeyRows();
	}

	private void OnDebugToggled(bool value)
	{
		Plugin.SetDebug(value);
		if ((Object)(object)_help != (Object)null)
		{
			((TMP_Text)_help).text = (value ? "Debug is ON. Open BepInEx/LogOutput.log and search for Custom Starter Kit." : "This loadout is used when you host. Click a slot, then search and pick an item.");
		}
	}

	private void OnPauseButtonToggled(bool value)
	{
		Plugin.SetShowPauseMenuButton(value);
		RefreshPauseButton();
		if ((Object)(object)_help != (Object)null)
		{
			((TMP_Text)_help).text = (value ? "Pause menu button is ON. The hotkey still works either way." : ("Pause menu button is OFF. Open with " + Plugin.FormatHotkey() + "."));
		}
	}

	private void BuildHotkeyRow(Transform parent)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Expected I4, but got Unknown
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Expected O, but got Unknown
		GameObject val = new GameObject("HotkeyRow", new Type[1] { typeof(RectTransform) });
		val.transform.SetParent(parent, false);
		KitUi.MakeNonCollapsing(val, 38f);
		HorizontalLayoutGroup val2 = KitUi.AddHorizontalLayout(val, 8f);
		((LayoutGroup)val2).childAlignment = (TextAnchor)3;
		TextMeshProUGUI val3 = KitUi.CreateLabel(val.transform, "HotkeyLbl", "Open menu", 16f, (FontStyles)0, (TextAlignmentOptions)513);
		LayoutElement val4 = ((Component)val3).gameObject.AddComponent<LayoutElement>();
		val4.minWidth = 90f;
		val4.preferredWidth = 90f;
		val4.flexibleWidth = 0f;
		_hotkeyModDropdown = KitUi.CreateChoiceDropdown(val.transform, HotkeyModLabels, HotkeyModValues, (int)Plugin.GetMenuModifier(), OnHotkeyModifierPicked);
		_hotkeyKeyButton = KitUi.CreateButton(val.transform, Plugin.PrettyKey(Plugin.GetMenuKey()), new UnityAction(BeginListenMenuKey), new Vector2(130f, 34f));
		_hotkeyKeyLabel = ((Component)_hotkeyKeyButton).GetComponentInChildren<TextMeshProUGUI>(true);
	}

	private void BuildDeleteKeyRow(Transform parent)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Expected O, but got Unknown
		GameObject val = new GameObject("DeleteKeyRow", new Type[1] { typeof(RectTransform) });
		val.transform.SetParent(parent, false);
		KitUi.MakeNonCollapsing(val, 38f);
		HorizontalLayoutGroup val2 = KitUi.AddHorizontalLayout(val, 8f);
		((LayoutGroup)val2).childAlignment = (TextAnchor)3;
		TextMeshProUGUI val3 = KitUi.CreateLabel(val.transform, "DeleteLbl", "Delete bag", 16f, (FontStyles)0, (TextAlignmentOptions)513);
		LayoutElement val4 = ((Component)val3).gameObject.AddComponent<LayoutElement>();
		val4.minWidth = 90f;
		val4.preferredWidth = 90f;
		val4.flexibleWidth = 0f;
		_deleteKeyButton = KitUi.CreateButton(val.transform, Plugin.PrettyKey(Plugin.GetDeleteRekitBagKey()), new UnityAction(BeginListenDeleteKey), new Vector2(278f, 34f));
		_deleteKeyLabel = ((Component)_deleteKeyButton).GetComponentInChildren<TextMeshProUGUI>(true);
	}

	private void RefreshHotkeyRows()
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected I4, but got Unknown
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		_listenHotkey = 0;
		if ((Object)(object)_hotkeyModDropdown != (Object)null)
		{
			_hotkeyModDropdown.SetValue((int)Plugin.GetMenuModifier());
		}
		if ((Object)(object)_hotkeyKeyLabel != (Object)null)
		{
			((TMP_Text)_hotkeyKeyLabel).text = Plugin.PrettyKey(Plugin.GetMenuKey());
		}
		if ((Object)(object)_deleteKeyLabel != (Object)null)
		{
			((TMP_Text)_deleteKeyLabel).text = Plugin.PrettyKey(Plugin.GetDeleteRekitBagKey());
		}
	}

	private void OnHotkeyModifierPicked(int value)
	{
		Plugin.SetMenuModifier((KeyCode)value);
		if ((Object)(object)_help != (Object)null)
		{
			((TMP_Text)_help).text = "Menu hotkey is now " + Plugin.FormatHotkey() + ". Also available from the pause menu.";
		}
	}

	private void BeginListenMenuKey()
	{
		ChoiceDropdown.CloseOpen();
		_listenHotkey = 1;
		if ((Object)(object)_hotkeyKeyLabel != (Object)null)
		{
			((TMP_Text)_hotkeyKeyLabel).text = "Press a key...";
		}
		if ((Object)(object)_help != (Object)null)
		{
			((TMP_Text)_help).text = "Press the key to open this menu. Esc cancels.";
		}
	}

	private void BeginListenDeleteKey()
	{
		ChoiceDropdown.CloseOpen();
		_listenHotkey = 2;
		if ((Object)(object)_deleteKeyLabel != (Object)null)
		{
			((TMP_Text)_deleteKeyLabel).text = "Press a key...";
		}
		if ((Object)(object)_help != (Object)null)
		{
			((TMP_Text)_help).text = "Press the key to delete a hovered re-kit bag. Esc cancels. None disables.";
		}
	}

	private void FinishListenHotkey(KeyCode key)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Invalid comparison between Unknown and I4
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Invalid comparison between Unknown and I4
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		int listenHotkey = _listenHotkey;
		_listenHotkey = 0;
		switch (listenHotkey)
		{
		case 1:
			if ((int)key > 0)
			{
				Plugin.SetMenuKey(key);
			}
			if ((Object)(object)_hotkeyKeyLabel != (Object)null)
			{
				((TMP_Text)_hotkeyKeyLabel).text = Plugin.PrettyKey(Plugin.GetMenuKey());
			}
			if ((Object)(object)_help != (Object)null)
			{
				((TMP_Text)_help).text = "Menu hotkey is now " + Plugin.FormatHotkey() + ". Also available from the pause menu.";
			}
			break;
		case 2:
			if ((int)key > 0)
			{
				Plugin.SetDeleteRekitBagKey(key);
			}
			if ((Object)(object)_deleteKeyLabel != (Object)null)
			{
				((TMP_Text)_deleteKeyLabel).text = Plugin.PrettyKey(Plugin.GetDeleteRekitBagKey());
			}
			if ((Object)(object)_help != (Object)null)
			{
				((TMP_Text)_help).text = "Delete bag key is now " + Plugin.PrettyKey(Plugin.GetDeleteRekitBagKey()) + ".";
			}
			break;
		}
	}

	private static KeyCode ReadPressedKey()
	{
		//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_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected I4, but got Unknown
		//IL_0028: 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_002e: Invalid comparison between Unknown and I4
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		foreach (KeyCode value in Enum.GetValues(typeof(KeyCode)))
		{
			int num = (int)value;
			if ((int)value == 0 || (int)value == 27 || (num >= 323 && num <= 329) || !Input.GetKeyDown(value))
			{
				continue;
			}
			return value;
		}
		return (KeyCode)0;
	}

	private void ClearRandomPackToggle()
	{
		if (LoadoutStore.RandomPack != null && LoadoutStore.RandomPack.Value)
		{
			LoadoutStore.RandomPack.Value = false;
		}
		KitUi.SetToggleVisual(_randomToggle, isOn: false);
	}

	private void ClearFannyPackToggle()
	{
		if (LoadoutStore.UseFannypack != null && LoadoutStore.UseFannypack.Value)
		{
			LoadoutStore.UseFannypack.Value = false;
		}
		KitUi.SetToggleVisual(_fannyToggle, isOn: false);
	}

	private void FilterItems(string filter)
	{
		_filter = filter ?? string.Empty;
		string text = _filter.Trim();
		for (int i = 0; i < _itemRows.Count; i++)
		{
			KitItemRow kitItemRow = _itemRows[i];
			if (!((Object)(object)kitItemRow == (Object)null))
			{
				bool flag = text.Length == 0 || (!string.IsNullOrEmpty(kitItemRow.ItemName) && kitItemRow.ItemName.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0);
				if (((Component)kitItemRow).gameObject.activeSelf != flag)
				{
					((Component)kitItemRow).gameObject.SetActive(flag);
				}
			}
		}
	}

	private void Update()
	{
		//IL_0034: 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_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Invalid comparison between Unknown and I4
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		if (!_visible)
		{
			return;
		}
		if (_listenHotkey != 0)
		{
			if (Input.GetKeyDown((KeyCode)27))
			{
				FinishListenHotkey((KeyCode)0);
				return;
			}
			KeyCode val = ReadPressedKey();
			if ((int)val > 0)
			{
				FinishListenHotkey(val);
			}
		}
		else if (Input.GetKeyDown((KeyCode)27))
		{
			if (_pickingSlot >= 0)
			{
				ShowSlotPage();
			}
			else
			{
				CloseInternal();
			}
		}
	}

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

	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 static class KitUi
{
	internal static readonly Color PanelColor = new Color(0.08f, 0.06f, 0.05f, 0.94f);

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

	internal static readonly Color ButtonHover = new Color(0.26f, 0.18f, 0.13f, 0.92f);

	internal static readonly Color Cream = new Color(0.95f, 0.93f, 0.88f, 1f);

	internal static readonly Color CreamDim = new Color(0.82f, 0.78f, 0.72f, 0.92f);

	internal static readonly Color AccentOn = new Color(0.55f, 0.42f, 0.22f, 0.95f);

	internal static readonly Color FieldWellColor = new Color(0.22f, 0.16f, 0.11f, 1f);

	private static readonly Color CheckboxWellColor = new Color(0.1f, 0.08f, 0.06f, 0.92f);

	private static Sprite _whiteSprite;

	private static GameObject _buttonDonor;

	private static TMP_FontAsset _cachedFont;

	private static int _cachedSceneHandle = -1;

	internal static Canvas CreateOverlayCanvas(GameObject root, int sortingOrder)
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		Canvas val = root.GetComponent<Canvas>() ?? root.AddComponent<Canvas>();
		val.renderMode = (RenderMode)0;
		val.sortingOrder = sortingOrder;
		val.additionalShaderChannels = (AdditionalCanvasShaderChannels)25;
		CanvasScaler val2 = root.GetComponent<CanvasScaler>() ?? root.AddComponent<CanvasScaler>();
		val2.uiScaleMode = (ScaleMode)1;
		val2.referenceResolution = new Vector2(1920f, 1080f);
		val2.matchWidthOrHeight = 1f;
		if ((Object)(object)root.GetComponent<GraphicRaycaster>() == (Object)null)
		{
			root.AddComponent<GraphicRaycaster>();
		}
		return val;
	}

	internal static RectTransform CreatePanel(Transform parent, string name, Vector2 size, Color color)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		//IL_005d: 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_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name, new Type[3]
		{
			typeof(RectTransform),
			typeof(CanvasRenderer),
			typeof(Image)
		});
		val.transform.SetParent(parent, false);
		RectTransform component = val.GetComponent<RectTransform>();
		Vector2 val2 = default(Vector2);
		((Vector2)(ref val2))..ctor(0.5f, 0.5f);
		component.anchorMax = val2;
		component.anchorMin = val2;
		component.pivot = new Vector2(0.5f, 0.5f);
		component.sizeDelta = size;
		Image component2 = val.GetComponent<Image>();
		component2.sprite = WhiteSprite();
		component2.type = (Type)1;
		((Graphic)component2).color = color;
		((Graphic)component2).raycastTarget = true;
		return component;
	}

	internal static TextMeshProUGUI CreateLabel(Transform parent, string name, string text, float fontSize, FontStyles style = (FontStyles)0, TextAlignmentOptions align = (TextAlignmentOptions)513)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected O, but got Unknown
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name, new Type[2]
		{
			typeof(RectTransform),
			typeof(C