Decompiled source of suitsTerminal v1.3.0

suitsTerminal.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using OpenBodyCams;
using OpenBodyCams.API;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("suitsTerminal")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+d68215a4bfa7c6129112ed0dbac67e24ba2c271d")]
[assembly: AssemblyProduct("suitsTerminal")]
[assembly: AssemblyTitle("suitsTerminal")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace suitsTerminal
{
	internal class ChatHandler
	{
		internal static string lastCommandRun;

		internal static void HandleChatMessage(string command)
		{
			if (lastCommandRun == command)
			{
				return;
			}
			if (command.StartsWith("!suits"))
			{
				string[] array = command.Split(' ');
				if (array.Length == 1)
				{
					AdvancedMenu.GetCurrentSuitID();
					string text = StringStuff.ChatListing(AllSuits.suitNames, 6, 1);
					HUDManager.Instance.AddTextToChatOnServer("[suitsTerminal]:\t " + text, -1);
					lastCommandRun = command;
				}
				else if (array.Length > 1)
				{
					string text2 = array[1];
					if (int.TryParse(text2, out var result))
					{
						string text3 = StringStuff.ChatListing(AllSuits.suitNames, 6, result);
						HUDManager.Instance.AddTextToChatOnServer("[suitsTerminal]:\t " + text3, -1);
						lastCommandRun = command;
					}
					else
					{
						HUDManager.Instance.AddTextToChatOnServer("[suitsTerminal]:\t Invalid page number format: " + text2, -1);
						suitsTerminal.X("Invalid page number format: " + text2);
						lastCommandRun = command;
					}
				}
			}
			else if (command.StartsWith("!wear"))
			{
				string[] array2 = command.Split(' ');
				if (array2.Length == 1)
				{
					HUDManager.Instance.AddTextToChatOnServer("[suitsTerminal]:\t No suit specified...", -1);
					lastCommandRun = command;
				}
				else
				{
					if (array2.Length <= 1)
					{
						return;
					}
					string text4 = array2[1];
					if (int.TryParse(text4, out var result2))
					{
						if (result2 >= 0 && result2 < AllSuits.suitNames.Count)
						{
							string selectedSuit = AllSuits.suitNames[result2];
							suitsTerminal.X("wear command");
							CommandHandler.AdvancedSuitPick(selectedSuit);
							AdvancedMenu.GetCurrentSuitID();
							lastCommandRun = command;
						}
						else
						{
							HUDManager.Instance.AddTextToChatOnServer("[suitsTerminal]:\t Invalid suit number: " + text4, -1);
							suitsTerminal.X("Invalid suit number: " + text4);
							lastCommandRun = command;
						}
					}
					else
					{
						HUDManager.Instance.AddTextToChatOnServer("[suitsTerminal]:\t Invalid suit number format: " + text4, -1);
						suitsTerminal.X("Invalid suit number format: " + text4);
						lastCommandRun = command;
					}
				}
			}
			else if (command.StartsWith("!clear"))
			{
				((TMP_Text)HUDManager.Instance.chatText).text.Remove(0, ((TMP_Text)HUDManager.Instance.chatText).text.Length);
				HUDManager.Instance.ChatMessageHistory.Clear();
				lastCommandRun = command;
			}
		}
	}
	[HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")]
	public class Chat_Patch : MonoBehaviour
	{
		internal static string lastMessage = "";

		private static void Postfix(HUDManager __instance)
		{
			if (SConfig.chatCommands.Value && !(lastMessage == __instance.lastChatMessage))
			{
				suitsTerminal.X("Testing message [" + __instance.lastChatMessage + "] for command.");
				string lastChatMessage = __instance.lastChatMessage;
				ChatHandler.HandleChatMessage(lastChatMessage);
			}
		}
	}
	public class Suits_Patch : MonoBehaviour
	{
		[HarmonyPatch(typeof(PlayerControllerB), "SpawnPlayerAnimation")]
		public class PlayerSpawnPatch : MonoBehaviour
		{
			private static void Postfix()
			{
				if (!Misc.rackSituated)
				{
					suitsTerminal.X("player loaded & rackSituated is false, fixing suits rack");
					AdvancedMenu.InitSettings();
					InitThisPlugin.InitSuitsTerm();
					PictureInPicture.InitPiP();
					Misc.hasLaunched = true;
				}
			}
		}

		[HarmonyPatch(typeof(Terminal), "Awake")]
		public class AwakeTermPatch : Terminal
		{
			private static void Postfix(Terminal __instance)
			{
				suitsTerminal.Terminal = __instance;
				suitsTerminal.X("Setting suitsTerminal.Terminal");
				ResetVars();
			}

			private static void ResetVars()
			{
				Misc.hasLaunched = false;
				Misc.normSuit = 0;
				Misc.showSuit = 0;
				Misc.hintOnce = false;
				Misc.rackSituated = false;
				AllSuits.favSuitsSet = false;
				PictureInPicture.PiPCreated = false;
				suitsTerminal.X("set initial suits values");
			}
		}

		[HarmonyPatch(typeof(Terminal), "LoadNewNodeIfAffordable")]
		public class AffordableNode : Terminal
		{
			private static void Postfix()
			{
				suitsTerminal.X("purchase detected");
				InitThisPlugin.InitSuitsTerm();
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "Start")]
		public class StartofRoundPatch : MonoBehaviour
		{
			private static void Postfix()
			{
			}
		}
	}
	public class SuitInfo : MonoBehaviour
	{
		public string suitTag;
	}
	[HarmonyPatch(typeof(StartOfRound), "PositionSuitsOnRack")]
	public class SuitBoughtByOthersPatch
	{
		private static void Postfix(StartOfRound __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && Misc.hasLaunched)
			{
				suitsTerminal.X("suits rack func called, calling InitSuitsTerm func");
				InitThisPlugin.InitSuitsTerm();
			}
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "Start")]
	public class GameStartPatch
	{
		public static void Postfix()
		{
			CompatibilityCheck();
		}

		private static void CompatibilityCheck()
		{
			if (Chainloader.PluginInfos.ContainsKey("Zaggy1024.OpenBodyCams"))
			{
				suitsTerminal.X("OpenBodyCams by Zaggy1024 detected!");
				suitsTerminal.OpenBodyCams = true;
				GetResolutionForOBC();
			}
			if (Chainloader.PluginInfos.ContainsKey("darmuh.TerminalStuff"))
			{
				suitsTerminal.X("darmuhsTerminalStuff detected!");
				suitsTerminal.TerminalStuff = true;
			}
		}

		private static void GetResolutionForOBC()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			List<string> listFromConfigItem = StringStuff.GetListFromConfigItem(SConfig.obcResolution.Value);
			List<int> numberListFromStringList = StringStuff.GetNumberListFromStringList(listFromConfigItem);
			if (numberListFromStringList.Count == 2)
			{
				OpenBodyCams.defaultRes = new Vector2Int(numberListFromStringList[0], numberListFromStringList[1]);
				suitsTerminal.Log.LogInfo((object)$"Resolution set to {numberListFromStringList[0]}x{numberListFromStringList[1]}");
			}
			else
			{
				OpenBodyCams.defaultRes = new Vector2Int(1000, 700);
				suitsTerminal.Log.LogInfo((object)("Unable to set resolution to values provided in config: " + SConfig.obcResolution.Value + "\nUsing default of 1000x700"));
			}
		}
	}
	[HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")]
	public class Terminal_ParsePlayerSentence_Patch
	{
		private static void Postfix(ref TerminalNode __result)
		{
			if (CommandStuff.GetNewDisplayText(ref __result))
			{
				suitsTerminal.X("command found in base funcstring listing...");
			}
		}
	}
	public class Page
	{
		public StringBuilder Content { get; set; }

		public int PageNumber { get; set; }
	}
	public class PageSplitter
	{
		public static List<Page> SplitTextIntoPages(string inputText, int maxLinesPerPage)
		{
			string[] array = inputText.Split(new string[1] { Environment.NewLine }, StringSplitOptions.None);
			List<Page> list = new List<Page>();
			int num = 0;
			int num2 = 1;
			while (num < array.Length)
			{
				Page page = new Page
				{
					Content = new StringBuilder(),
					PageNumber = num2
				};
				page.Content.AppendLine($"=== Choose your Suit! Page {num2} ===\r\n\r\n");
				for (int i = 0; i < maxLinesPerPage; i++)
				{
					if (num >= array.Length)
					{
						break;
					}
					page.Content.AppendLine(array[num]);
					num++;
				}
				if (num < array.Length)
				{
					page.Content.AppendLine($"> Use command 'suits {num2 + 1}' to see the next page of suits!\r\n");
				}
				list.Add(page);
				num2++;
			}
			return list;
		}
	}
	internal class CommandStuff
	{
		public static Dictionary<TerminalNode, Func<string>> sT = new Dictionary<TerminalNode, Func<string>>();

		internal static bool GetNewDisplayText(ref TerminalNode node)
		{
			if ((Object)(object)node == (Object)null)
			{
				return false;
			}
			if (sT.TryGetValue(node, out var value))
			{
				node.displayText = value();
				return true;
			}
			suitsTerminal.X("Not in special nodeListing dictionary");
			return false;
		}

		internal static TerminalNode GetFromAllNodes(string nodeName)
		{
			List<TerminalNode> list = new List<TerminalNode>(Object.FindObjectsOfType<TerminalNode>(true));
			foreach (TerminalNode item in list)
			{
				if (((Object)item).name == nodeName)
				{
					suitsTerminal.X(nodeName + " found!");
					return item;
				}
			}
			suitsTerminal.X(nodeName + " could not be found, result set to null.");
			return null;
		}
	}
	internal class TerminalHook
	{
		internal static List<UnlockableItem> suitsTermUnlockables = new List<UnlockableItem>();

		internal static void AddKeywordToExistingNode(string keyWord, TerminalNode existingNode)
		{
			//IL_0072: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			TerminalKeyword[] allKeywords = suitsTerminal.Terminal.terminalNodes.allKeywords;
			List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length);
			list.AddRange(allKeywords);
			List<TerminalKeyword> list2 = list;
			TerminalKeyword val = ScriptableObject.CreateInstance<TerminalKeyword>();
			((Object)val).name = keyWord + "_keyword";
			val.word = keyWord.ToLower();
			val.isVerb = false;
			val.specialKeywordResult = existingNode;
			CompatibleNoun[] terminalOptions = existingNode.terminalOptions;
			List<CompatibleNoun> list3 = new List<CompatibleNoun>(terminalOptions.Length);
			list3.AddRange(terminalOptions);
			List<CompatibleNoun> list4 = list3;
			CompatibleNoun item = new CompatibleNoun
			{
				noun = val,
				result = existingNode
			};
			list4.Add(item);
			existingNode.terminalOptions = list4.ToArray();
			list2.Add(val);
			suitsTerminal.Terminal.terminalNodes.allKeywords = list2.ToArray();
		}

		internal static void MakeDynamicCommand(string nodeName, string keyWord, string failtext, bool clearText, bool acceptAnything, Func<string> commandFunc, Dictionary<TerminalNode, string> specialNodeList, Dictionary<TerminalNode, Func<string>> nodeListing)
		{
			TerminalKeyword[] allKeywords = suitsTerminal.Terminal.terminalNodes.allKeywords;
			List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length);
			list.AddRange(allKeywords);
			List<TerminalKeyword> list2 = list;
			CheckForAndDeleteKeyWord(keyWord.ToLower());
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)val).name = nodeName;
			val.displayText = failtext;
			val.clearPreviousText = clearText;
			val.acceptAnything = acceptAnything;
			TerminalKeyword val2 = ScriptableObject.CreateInstance<TerminalKeyword>();
			((Object)val2).name = nodeName + "_keyword";
			val2.word = keyWord.ToLower();
			val2.isVerb = false;
			val2.specialKeywordResult = val;
			nodeListing.Add(val, commandFunc);
			specialNodeList.Add(val, keyWord.ToLower());
			list2.Add(val2);
			suitsTerminal.Terminal.terminalNodes.allKeywords = list2.ToArray();
		}

		internal static void MakeCommand(string nodeName, string keyWord, string displayText, bool isVerb, bool clearText)
		{
			//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)
			TerminalKeyword[] allKeywords = suitsTerminal.Terminal.terminalNodes.allKeywords;
			List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length);
			list.AddRange(allKeywords);
			List<TerminalKeyword> list2 = list;
			CheckForAndDeleteKeyWord(keyWord);
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)val).name = nodeName;
			val.displayText = displayText;
			val.clearPreviousText = clearText;
			TerminalKeyword val2 = ScriptableObject.CreateInstance<TerminalKeyword>();
			((Object)val2).name = nodeName + "_keyword";
			val2.word = keyWord.ToLower();
			val2.isVerb = isVerb;
			val2.specialKeywordResult = val;
			new CompatibleNoun
			{
				noun = val2,
				result = val
			};
			list2.Add(val2);
			suitsTerminal.Terminal.terminalNodes.allKeywords = list2.ToArray();
		}

		internal static void MakeCommand(string nodeName, string keyWord, string displayText, bool isVerb, bool clearText, Func<string> commandAction, Dictionary<TerminalNode, Func<string>> nodeListing, int specialNumber, Dictionary<TerminalNode, int> specialNodeList)
		{
			TerminalKeyword[] allKeywords = suitsTerminal.Terminal.terminalNodes.allKeywords;
			List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length);
			list.AddRange(allKeywords);
			List<TerminalKeyword> list2 = list;
			CheckForAndDeleteKeyWord(keyWord);
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)val).name = nodeName;
			val.displayText = displayText;
			val.clearPreviousText = clearText;
			TerminalKeyword val2 = ScriptableObject.CreateInstance<TerminalKeyword>();
			((Object)val2).name = nodeName + "_keyword";
			val2.word = keyWord.ToLower();
			val2.isVerb = isVerb;
			val2.specialKeywordResult = val;
			nodeListing.Add(val, commandAction);
			specialNodeList.Add(val, specialNumber);
			list2.Add(val2);
			suitsTerminal.Terminal.terminalNodes.allKeywords = list2.ToArray();
		}

		internal static void MakeCommand(string nodeName, string keyWord, string displayText, bool isVerb, bool clearText, Func<string> commandAction, Dictionary<TerminalNode, Func<string>> nodeListing, int specialNumber, string specialName, Dictionary<TerminalNode, int> specialNodeList, Dictionary<int, string> reverseNodeNumList)
		{
			TerminalKeyword[] allKeywords = suitsTerminal.Terminal.terminalNodes.allKeywords;
			List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length);
			list.AddRange(allKeywords);
			List<TerminalKeyword> list2 = list;
			CheckForAndDeleteKeyWord(keyWord);
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)val).name = nodeName;
			val.displayText = displayText;
			val.clearPreviousText = clearText;
			TerminalKeyword val2 = ScriptableObject.CreateInstance<TerminalKeyword>();
			((Object)val2).name = nodeName + "_keyword";
			val2.word = keyWord.ToLower();
			val2.isVerb = isVerb;
			val2.specialKeywordResult = val;
			nodeListing.Add(val, commandAction);
			specialNodeList.Add(val, specialNumber);
			if (!reverseNodeNumList.ContainsKey(specialNumber))
			{
				reverseNodeNumList.Add(specialNumber, specialName);
			}
			list2.Add(val2);
			suitsTerminal.Terminal.terminalNodes.allKeywords = list2.ToArray();
		}

		internal static void MakeCommand(string nodeName, string keyWord, string displayText, bool isVerb, bool clearText, Func<string> commandAction, Dictionary<TerminalNode, Func<string>> nodeListing)
		{
			TerminalKeyword[] allKeywords = suitsTerminal.Terminal.terminalNodes.allKeywords;
			List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length);
			list.AddRange(allKeywords);
			List<TerminalKeyword> list2 = list;
			CheckForAndDeleteKeyWord(keyWord);
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)val).name = nodeName;
			val.displayText = displayText;
			val.clearPreviousText = clearText;
			TerminalKeyword val2 = ScriptableObject.CreateInstance<TerminalKeyword>();
			((Object)val2).name = nodeName + "_keyword";
			val2.word = keyWord.ToLower();
			val2.isVerb = isVerb;
			val2.specialKeywordResult = val;
			nodeListing.Add(val, commandAction);
			list2.Add(val2);
			suitsTerminal.Terminal.terminalNodes.allKeywords = list2.ToArray();
		}

		internal static void MakeCommand(string nodeName, string keyWord, string displayText, bool isVerb, bool clearText, bool needsConfirm, bool acceptAnything, string confirmResultName, string denyResultName, string confirmDisplayText, string denyDisplayText, int price, Func<string> commandAction, Func<string> confirmAction, Func<string> denyAction, Dictionary<TerminalNode, Func<string>> nodeListing)
		{
			TerminalKeyword[] allKeywords = suitsTerminal.Terminal.terminalNodes.allKeywords;
			List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length);
			list.AddRange(allKeywords);
			List<TerminalKeyword> list2 = list;
			CheckForAndDeleteKeyWord(keyWord);
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)val).name = nodeName;
			val.displayText = displayText;
			val.clearPreviousText = clearText;
			val.itemCost = price;
			val.overrideOptions = true;
			val.acceptAnything = acceptAnything;
			TerminalKeyword val2 = ScriptableObject.CreateInstance<TerminalKeyword>();
			((Object)val2).name = nodeName + "_keyword";
			val2.word = keyWord.ToLower();
			val2.isVerb = isVerb;
			val2.specialKeywordResult = val;
			if (needsConfirm && confirmAction != null && denyAction != null)
			{
				MakeConfirmationNode(confirmResultName, denyResultName, confirmAction, denyAction, confirmDisplayText, denyDisplayText, price, nodeListing, out var confirm, out var deny);
				val.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { confirm, deny };
				list2.Add(val2);
				list2.Add(confirm.noun);
				list2.Add(deny.noun);
				nodeListing.Add(val, commandAction);
				suitsTerminal.X("Node/Keyword added with confirmation nodes for " + keyWord);
			}
			else
			{
				list2.Add(val2);
				nodeListing.Add(val, commandAction);
				suitsTerminal.X("Node/Keyword added without confirmation nodes for " + keyWord);
			}
			suitsTerminal.Terminal.terminalNodes.allKeywords = list2.ToArray();
		}

		internal static void MakeCommand(string nodeName, string keyWord, string displayText, bool isVerb, bool clearText, bool needsConfirm, bool acceptAnything, string confirmResultName, string denyResultName, string confirmDisplayText, string denyDisplayText, int price, Func<string> commandAction, Func<string> confirmAction, Func<string> denyAction, Dictionary<TerminalNode, string> specialNodeList, Dictionary<TerminalNode, Func<string>> nodeListing)
		{
			TerminalKeyword[] allKeywords = suitsTerminal.Terminal.terminalNodes.allKeywords;
			List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length);
			list.AddRange(allKeywords);
			List<TerminalKeyword> list2 = list;
			CheckForAndDeleteKeyWord(keyWord);
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)val).name = nodeName;
			val.displayText = displayText;
			val.clearPreviousText = clearText;
			val.itemCost = price;
			val.overrideOptions = true;
			val.acceptAnything = acceptAnything;
			TerminalKeyword val2 = ScriptableObject.CreateInstance<TerminalKeyword>();
			((Object)val2).name = nodeName + "_keyword";
			val2.word = keyWord.ToLower();
			val2.isVerb = isVerb;
			val2.specialKeywordResult = val;
			specialNodeList.Add(val, keyWord);
			if (needsConfirm && confirmAction != null && denyAction != null)
			{
				MakeConfirmationNode(confirmResultName, denyResultName, confirmAction, denyAction, confirmDisplayText, denyDisplayText, price, nodeListing, out var confirm, out var deny);
				val.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { confirm, deny };
				list2.Add(val2);
				list2.Add(confirm.noun);
				list2.Add(deny.noun);
				nodeListing.Add(val, commandAction);
				suitsTerminal.X("Node/Keyword added with confirmation nodes for " + keyWord);
			}
			else
			{
				list2.Add(val2);
				nodeListing.Add(val, commandAction);
				suitsTerminal.X("Node/Keyword added without confirmation nodes for " + keyWord);
			}
			suitsTerminal.Terminal.terminalNodes.allKeywords = list2.ToArray();
		}

		private static void AddToBuyWord(ref TerminalKeyword buyKeyword, ref TerminalKeyword terminalKeyword, UnlockableItem item)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			terminalKeyword.defaultVerb = buyKeyword;
			suitsTerminal.X($"Added buy verb to {buyKeyword}");
			CompatibleNoun item2 = new CompatibleNoun
			{
				noun = terminalKeyword,
				result = item.shopSelectionNode
			};
			CompatibleNoun[] compatibleNouns = buyKeyword.compatibleNouns;
			List<CompatibleNoun> list = new List<CompatibleNoun>(compatibleNouns.Length);
			list.AddRange(compatibleNouns);
			List<CompatibleNoun> list2 = list;
			list2.Add(item2);
			buyKeyword.compatibleNouns = list2.ToArray();
		}

		internal static void MakeStoreCommand(string nodeName, string keyWord, string storeName, bool isVerb, bool clearText, bool acceptAnything, string confirmResultName, string denyResultName, string confirmDisplayText, string denyDisplayText, int price, Func<string> commandAction, Func<string> confirmAction, Dictionary<TerminalNode, Func<string>> nodeListing)
		{
			TerminalKeyword[] allKeywords = suitsTerminal.Terminal.terminalNodes.allKeywords;
			List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length);
			list.AddRange(allKeywords);
			List<TerminalKeyword> list2 = list;
			CheckForAndDeleteKeyWord(keyWord);
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)val).name = nodeName;
			val.displayText = storeName;
			val.clearPreviousText = clearText;
			val.itemCost = price;
			val.overrideOptions = true;
			val.acceptAnything = acceptAnything;
			TerminalKeyword terminalKeyword = ScriptableObject.CreateInstance<TerminalKeyword>();
			((Object)terminalKeyword).name = nodeName + "_keyword";
			terminalKeyword.word = keyWord.ToLower();
			terminalKeyword.isVerb = isVerb;
			terminalKeyword.specialKeywordResult = val;
			if (confirmAction != null)
			{
				MakeConfirmationNode(confirmResultName, denyResultName, confirmAction, confirmDisplayText, denyDisplayText, price, nodeListing, out var confirm, out var deny);
				val.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { confirm, deny };
				UnlockableItem item = AddUnlockable(confirm.result, alwaysInStock: true, storeName ?? "");
				StartOfRound.Instance.unlockablesList.unlockables.Add(item);
				int shipUnlockableID = (val.shipUnlockableID = StartOfRound.Instance.unlockablesList.unlockables.IndexOf(item));
				confirm.result.shipUnlockableID = shipUnlockableID;
				confirm.result.buyUnlockable = true;
				confirm.result.itemCost = price;
				if (TryGetKeyword("buy", out var terminalKeyword2))
				{
					AddToBuyWord(ref terminalKeyword2, ref terminalKeyword, item);
				}
				list2.Add(terminalKeyword);
				list2.Add(confirm.noun);
				list2.Add(deny.noun);
				nodeListing.Add(val, commandAction);
				suitsTerminal.X("Node/Keyword added with confirmation nodes for " + keyWord);
			}
			else
			{
				suitsTerminal.Log.LogError((object)("Shop nodes NEED confirmation, but confirmAction is null for " + keyWord + "!"));
			}
			suitsTerminal.Terminal.terminalNodes.allKeywords = list2.ToArray();
		}

		internal static void MakeConfirmationNode(string confirmResultName, string denyResultName, Func<string> confirmAction, string confirmDisplayText, string denyDisplayText, int price, Dictionary<TerminalNode, Func<string>> nodeListing, out CompatibleNoun confirm, out CompatibleNoun deny)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			confirm = new CompatibleNoun
			{
				noun = ScriptableObject.CreateInstance<TerminalKeyword>()
			};
			confirm.noun.word = "confirm";
			confirm.noun.isVerb = true;
			confirm.result = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)confirm.result).name = confirmResultName;
			confirm.result.displayText = confirmDisplayText;
			confirm.result.clearPreviousText = true;
			confirm.result.itemCost = price;
			nodeListing.Add(confirm.result, confirmAction);
			deny = new CompatibleNoun
			{
				noun = ScriptableObject.CreateInstance<TerminalKeyword>()
			};
			deny.noun.word = "deny";
			deny.noun.isVerb = true;
			deny.result = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)deny.result).name = denyResultName;
			deny.result.clearPreviousText = true;
			deny.result.displayText = denyDisplayText;
		}

		internal static void MakeConfirmationNode(string confirmResultName, string denyResultName, Func<string> confirmAction, Func<string> denyAction, string confirmDisplayText, string denyDisplayText, int price, Dictionary<TerminalNode, Func<string>> nodeListing, out CompatibleNoun confirm, out CompatibleNoun deny)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			confirm = new CompatibleNoun
			{
				noun = ScriptableObject.CreateInstance<TerminalKeyword>()
			};
			confirm.noun.word = "confirm";
			confirm.noun.isVerb = true;
			confirm.result = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)confirm.result).name = confirmResultName;
			confirm.result.displayText = confirmDisplayText;
			confirm.result.clearPreviousText = true;
			confirm.result.itemCost = price;
			nodeListing.Add(confirm.result, confirmAction);
			deny = new CompatibleNoun
			{
				noun = ScriptableObject.CreateInstance<TerminalKeyword>()
			};
			deny.noun.word = "deny";
			deny.noun.isVerb = true;
			deny.result = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)deny.result).name = denyResultName;
			deny.result.displayText = denyDisplayText;
			deny.result.clearPreviousText = true;
			nodeListing.Add(deny.result, denyAction);
		}

		internal static void CheckForAndDeleteKeyWord(string keyWord)
		{
			TerminalKeyword[] allKeywords = suitsTerminal.Terminal.terminalNodes.allKeywords;
			List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length);
			list.AddRange(allKeywords);
			List<TerminalKeyword> list2 = list;
			for (int num = list2.Count - 1; num >= 0; num--)
			{
				if (list2[num].word.Equals(keyWord))
				{
					list2.RemoveAt(num);
					break;
				}
			}
			suitsTerminal.Terminal.terminalNodes.allKeywords = list2.ToArray();
		}

		internal static void AddLogicToCommand(TerminalNode terminalNode, Func<string> commandAction, Dictionary<TerminalNode, Func<string>> nodeListing)
		{
			nodeListing.Add(terminalNode, commandAction);
			suitsTerminal.X("associating " + ((Object)terminalNode).name + " to specified commandAction");
		}

		internal static bool TryGetKeyword(string keyWord)
		{
			TerminalKeyword[] allKeywords = suitsTerminal.Terminal.terminalNodes.allKeywords;
			List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length);
			list.AddRange(allKeywords);
			List<TerminalKeyword> list2 = list;
			foreach (TerminalKeyword item in list2)
			{
				if (item.word.Equals(keyWord))
				{
					return true;
				}
			}
			return false;
		}

		internal static bool TryGetKeyword(string keyWord, out TerminalKeyword terminalKeyword)
		{
			TerminalKeyword[] allKeywords = suitsTerminal.Terminal.terminalNodes.allKeywords;
			List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length);
			list.AddRange(allKeywords);
			List<TerminalKeyword> list2 = list;
			foreach (TerminalKeyword item in list2)
			{
				if (item.word.Equals(keyWord))
				{
					suitsTerminal.X("Keyword: [" + keyWord + "] found!");
					terminalKeyword = item;
					return true;
				}
			}
			terminalKeyword = null;
			return false;
		}

		internal static TerminalNode CreateDummyNode(string nodeName, bool clearPrevious, string displayText)
		{
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)val).name = nodeName;
			val.clearPreviousText = clearPrevious;
			val.displayText = displayText;
			return val;
		}

		internal static UnlockableItem AddUnlockable(TerminalNode shopNode, bool alwaysInStock, string unlockableName)
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			UnlockableItem val = new UnlockableItem
			{
				unlockableType = 1,
				unlockableName = unlockableName,
				shopSelectionNode = shopNode,
				alwaysInStock = alwaysInStock,
				IsPlaceable = false,
				spawnPrefab = false,
				maxNumber = 1
			};
			suitsTerminal.Terminal.ShipDecorSelection.Add(shopNode);
			suitsTermUnlockables.Add(val);
			return val;
		}

		internal static void SetTerminalInput(string terminalInput)
		{
			Terminal terminal = suitsTerminal.Terminal;
			string currentText = suitsTerminal.Terminal.currentText;
			int textAdded = suitsTerminal.Terminal.textAdded;
			terminal.TextChanged(currentText.Substring(0, currentText.Length - textAdded) + terminalInput);
			suitsTerminal.Terminal.screenText.text = suitsTerminal.Terminal.currentText;
			suitsTerminal.Terminal.textAdded = terminalInput.Length;
		}
	}
	internal class Bools
	{
		internal static bool ShouldShowSuit(UnlockableSuit suit, List<string> suitNames)
		{
			if (SConfig.hideRack.Value)
			{
				return false;
			}
			if (!SConfig.suitsOnRackCustom.Value && Misc.normSuit >= SConfig.suitsOnRack.Value && !Misc.rackSituated)
			{
				return false;
			}
			if (Misc.showSuit == SConfig.suitsOnRack.Value && !Misc.rackSituated)
			{
				return false;
			}
			if (Misc.rackSituated && !Misc.isHanging)
			{
				return false;
			}
			if (SConfig.suitsOnRackCustom.Value && !suitNames.Contains(AllSuits.UnlockableItems[suit.syncedSuitID.Value].unlockableName))
			{
				return false;
			}
			if (Misc.rackSituated && Misc.isHanging)
			{
				return true;
			}
			if (Misc.showSuit < SConfig.suitsOnRack.Value && !Misc.rackSituated)
			{
				return true;
			}
			return false;
		}
	}
	public static class SConfig
	{
		public static ConfigEntry<bool> extensiveLogging { get; internal set; }

		public static ConfigEntry<int> suitsOnRack { get; internal set; }

		public static ConfigEntry<bool> hideRack { get; internal set; }

		public static ConfigEntry<bool> hideBoots { get; internal set; }

		public static ConfigEntry<bool> keepSuitsWithNegativeIDs { get; internal set; }

		public static ConfigEntry<bool> randomSuitCommand { get; internal set; }

		public static ConfigEntry<bool> chatCommands { get; internal set; }

		public static ConfigEntry<bool> dontRemove { get; internal set; }

		public static ConfigEntry<bool> enforcePaidSuits { get; internal set; }

		public static ConfigEntry<bool> terminalCommands { get; internal set; }

		public static ConfigEntry<bool> advancedTerminalMenu { get; internal set; }

		public static ConfigEntry<bool> enablePiPCamera { get; internal set; }

		public static ConfigEntry<bool> chatHints { get; internal set; }

		public static ConfigEntry<bool> bannerHints { get; internal set; }

		public static ConfigEntry<bool> useOpenBodyCams { get; internal set; }

		public static ConfigEntry<string> obcResolution { get; internal set; }

		public static ConfigEntry<string> menuUp { get; internal set; }

		public static ConfigEntry<string> menuDown { get; internal set; }

		public static ConfigEntry<string> menuLeft { get; internal set; }

		public static ConfigEntry<string> menuRight { get; internal set; }

		public static ConfigEntry<string> leaveMenu { get; internal set; }

		public static ConfigEntry<string> selectMenu { get; internal set; }

		public static ConfigEntry<string> helpMenu { get; internal set; }

		public static ConfigEntry<string> favItemKey { get; internal set; }

		public static ConfigEntry<string> favMenuKey { get; internal set; }

		public static ConfigEntry<string> togglePiP { get; internal set; }

		public static ConfigEntry<string> togglePiPZoom { get; internal set; }

		public static ConfigEntry<string> togglePiPRotation { get; internal set; }

		public static ConfigEntry<string> togglePiPHeight { get; internal set; }

		public static ConfigEntry<string> suitsOnRackList { get; internal set; }

		public static ConfigEntry<bool> suitsOnRackCustom { get; internal set; }

		public static ConfigEntry<string> favoritesMenuList { get; internal set; }

		public static ConfigEntry<string> suitsSortingStyle { get; internal set; }

		public static ConfigEntry<float> menuKeyPressDelay { get; internal set; }

		public static ConfigEntry<float> menuPostSelectDelay { get; internal set; }

		public static void Settings()
		{
			suitsTerminal.Log.LogInfo((object)"Reading configuration settings");
			advancedTerminalMenu = MakeBool("General", "advancedTerminalMenu", defaultValue: true, "Enable this to utilize the advanced menu system and keybinds below");
			extensiveLogging = MakeBool("General", "extensiveLogging", defaultValue: false, "Enable or Disable extensive logging for this mod.");
			enforcePaidSuits = MakeBool("General", "enforcePaidSuits", defaultValue: true, "Enable or Disable enforcing paid suits being locked until they are paid for & unlocked.");
			keepSuitsWithNegativeIDs = MakeBool("General", "keepSuitsWithNegativeIDs", defaultValue: false, "Enable this to attempt to keep suits with negative suitIDs, this option could break the mod or others");
			randomSuitCommand = MakeBool("General", "randomSuitCommand", defaultValue: false, "Enable/Disable the randomsuit terminal command.");
			chatCommands = MakeBool("General", "chatCommands", defaultValue: false, "Enable/Disable suits commands via chat (!suits/!wear).");
			terminalCommands = MakeBool("General", "terminalCommands", defaultValue: true, "Enable/Disable the base suits commands via terminal (suits, wear).");
			dontRemove = MakeBool("General", "dontRemove", defaultValue: false, "Enable this to stop this mod from removing suits from the rack and make it compatible with other mods like TooManySuits.");
			suitsOnRack = MakeClampedInt("Rack Settings", "suitsOnRack", 13, "Number of suits to keep on the rack. (Up to 13)", 0, 13);
			suitsOnRackCustom = MakeBool("Rack Settings", "suitsOnRackCustom", defaultValue: false, "Enable this to set specific suits on the rack from the [suitsOnRackList] when [suitsOnRack] is above 0");
			suitsOnRackList = MakeString("Rack Settings", "suitsOnRackList", "YORU, Blue Sapphire, Arctic, OMEN, Elite, GlowRed, GreenImposter, HEVSuit, Medic, RedImposter, Shadow, Santa, Speedster", "when suitsOnRackCustom is enabled, list suits to display on the rack by name (separated by commas & case sensitive). NOTE: If no suits match these names, none will be displayed on the rack.");
			hideBoots = MakeBool("Rack Settings", "hideBoots", defaultValue: false, "Enable this to hide the boots by the rack.");
			hideRack = MakeBool("Rack Settings", "hideRack", defaultValue: false, "Enable this to hide the rack, (rack will not be hidden if dontRemove is enabled, suitsOnRack integer will be ignored if rack hidden).");
			suitsSortingStyle = MakeClampedString("Rack Settings", "suitsSortingStyle", "alphabetical (UnlockableName)", "How suits will be sorted in menus & on the rack", new AcceptableValueList<string>(new string[3] { "alphabetical", "numerical", "none" }));
			favoritesMenuList = MakeString("advancedTerminalMenu", "favoritesMenuList", "", "Favorited suit names will be stored here and displayed in the advancedTerminalMenu.");
			enablePiPCamera = MakeBool("advancedTerminalMenu", "enablePiPCamera", defaultValue: true, "Disable this to stop the PiP camera from being created");
			menuLeft = MakeString("advancedTerminalMenu", "menuLeft", "LeftArrow", "Set key to press to go to previous page in advanced menu system");
			menuRight = MakeString("advancedTerminalMenu", "menuRight", "RightArrow", "Set key to press to go to next page in advanced menu system");
			menuUp = MakeString("advancedTerminalMenu", "menuUp", "UpArrow", "Set key to press to go to previous item on page in advanced menu system");
			menuDown = MakeString("advancedTerminalMenu", "menuDown", "DownArrow", "Set key to press to go to next item on page in advanced menu system");
			leaveMenu = MakeString("advancedTerminalMenu", "leaveMenu", "Backspace", "Set key to press to leave advanced menu system");
			selectMenu = MakeString("advancedTerminalMenu", "selectMenu", "Enter", "Set key to press to select an item in advanced menu system");
			helpMenu = MakeString("advancedTerminalMenu", "helpMenu", "H", "Set key to press to toggle help & controls page in advanced menu system");
			favItemKey = MakeString("advancedTerminalMenu", "favItemKey", "F", "Set key to press to set an item as a favorite in advanced menu system");
			favMenuKey = MakeString("advancedTerminalMenu", "favMenuKey", "F1", "Set key to press to show favorites menu in advanced menu system");
			togglePiP = MakeString("advancedTerminalMenu", "togglePiP", "F12", "Set key to press to toggle PiP (mirror cam) on/off in advanced menu system");
			togglePiPZoom = MakeString("advancedTerminalMenu", "togglePiPZoom", "Minus", "Set key to press to toggle PiP (mirror cam) zoom in advanced menu system");
			togglePiPRotation = MakeString("advancedTerminalMenu", "togglePiPRotation", "Equals", "Set key to press to toggle PiP (mirror cam) rotation in advanced menu system");
			togglePiPHeight = MakeString("advancedTerminalMenu", "togglePiPHeight", "Backslash", "Set key to press to toggle PiP (mirror cam) height in advanced menu system");
			chatHints = MakeBool("Hints", "chatHints", defaultValue: true, "Disable this to remove the chat hints displayed at load in.");
			bannerHints = MakeBool("Hints", "bannerHints", defaultValue: true, "Disable this to remove the banner hints displayed at load in.");
			useOpenBodyCams = MakeBool("OpenBodyCams", "useOpenBodyCams", defaultValue: true, "Disable this to remove the banner hints displayed at load in.");
			obcResolution = MakeString("OpenBodyCams", "obcResolution", "1000; 700", "Set the resolution of the Mirror Camera created with OpenBodyCams");
			menuKeyPressDelay = MakeClampedFloat("advancedTerminalMenu", "menuKeyPressDelay", 0.15f, "Regular delay when checking for key presses in the advancedTerminalMenu. (This delay will be added ontop of menuPostSelectDelay)", 0.05f, 1f);
			menuPostSelectDelay = MakeClampedFloat("advancedTerminalMenu", "menuPostSelectDelay", 0.1f, "Delay used after a key press is registered in the advancedTerminalMenu.", 0.05f, 1f);
			PropertyInfo property = ((object)((BaseUnityPlugin)suitsTerminal.instance).Config).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
			Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(((BaseUnityPlugin)suitsTerminal.instance).Config, null);
			dictionary.Clear();
			((BaseUnityPlugin)suitsTerminal.instance).Config.Save();
		}

		private static ConfigEntry<bool> MakeBool(string section, string configItemName, bool defaultValue, string configDescription)
		{
			return ((BaseUnityPlugin)suitsTerminal.instance).Config.Bind<bool>(section, configItemName, defaultValue, configDescription);
		}

		private static ConfigEntry<int> MakeInt(string section, string configItemName, int defaultValue, string configDescription)
		{
			return ((BaseUnityPlugin)suitsTerminal.instance).Config.Bind<int>(section, configItemName, defaultValue, configDescription);
		}

		private static ConfigEntry<string> MakeClampedString(string section, string configItemName, string defaultValue, string configDescription, AcceptableValueList<string> acceptedValues)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			return ((BaseUnityPlugin)suitsTerminal.instance).Config.Bind<string>(section, configItemName, defaultValue, new ConfigDescription(configDescription, (AcceptableValueBase)(object)acceptedValues, Array.Empty<object>()));
		}

		private static ConfigEntry<int> MakeClampedInt(string section, string configItemName, int defaultValue, string configDescription, int minValue, int maxValue)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			return ((BaseUnityPlugin)suitsTerminal.instance).Config.Bind<int>(section, configItemName, defaultValue, new ConfigDescription(configDescription, (AcceptableValueBase)(object)new AcceptableValueRange<int>(minValue, maxValue), Array.Empty<object>()));
		}

		private static ConfigEntry<float> MakeClampedFloat(string section, string configItemName, float defaultValue, string configDescription, float minValue, float maxValue)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			return ((BaseUnityPlugin)suitsTerminal.instance).Config.Bind<float>(section, configItemName, defaultValue, new ConfigDescription(configDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(minValue, maxValue), Array.Empty<object>()));
		}

		private static ConfigEntry<string> MakeString(string section, string configItemName, string defaultValue, string configDescription)
		{
			return ((BaseUnityPlugin)suitsTerminal.instance).Config.Bind<string>(section, configItemName, defaultValue, configDescription);
		}
	}
	internal class Enums
	{
		internal static IEnumerator ChatHints()
		{
			if (SConfig.chatHints.Value)
			{
				yield return (object)new WaitForSeconds(5f);
				suitsTerminal.X("hint in chat.");
				if (SConfig.terminalCommands.Value)
				{
					HUDManager.Instance.AddTextToChatOnServer("[suitsTerminal]: Access more suits by typing 'suits' in the terminal.", -1);
				}
				if (SConfig.chatCommands.Value)
				{
					HUDManager.Instance.AddTextToChatOnServer("[suitsTerminal]: Access more suits by typing '!suits' in chat.", -1);
				}
			}
		}

		internal static IEnumerator HudHints()
		{
			if (SConfig.bannerHints.Value)
			{
				yield return (object)new WaitForSeconds(20f);
				suitsTerminal.X("hint on hud.");
				if (SConfig.suitsOnRack.Value > 0 && !SConfig.dontRemove.Value && SConfig.terminalCommands.Value && !SConfig.chatCommands.Value)
				{
					HUDManager.Instance.DisplayTip("Suits Access", "Excess suits have been moved to the terminal for storage. Use command 'suits' in the terminal to access them and change your suit!", false, false, "suitsTerminal-Hint");
				}
				else if (SConfig.suitsOnRack.Value == 0 && !SConfig.dontRemove.Value && SConfig.terminalCommands.Value && !SConfig.chatCommands.Value)
				{
					HUDManager.Instance.DisplayTip("Suits Access", "All suits have been moved to the terminal for storage. Use command 'suits' in the terminal to access them and change your suit!", false, false, "suitsTerminal-Hint");
				}
				else if (SConfig.suitsOnRack.Value == 0 && !SConfig.dontRemove.Value && SConfig.terminalCommands.Value && SConfig.chatCommands.Value)
				{
					HUDManager.Instance.DisplayTip("Suits Access", "All suits have been moved to the terminal for storage. Use command 'suits' in the terminal or !suits in the chat to access them and change your suit!", false, false, "suitsTerminal-Hint");
				}
				else if (SConfig.suitsOnRack.Value > 0 && !SConfig.dontRemove.Value && SConfig.terminalCommands.Value && SConfig.chatCommands.Value)
				{
					HUDManager.Instance.DisplayTip("Suits Access", "Excess suits have been moved to the terminal for storage. Use command 'suits' in the terminal or !suits in the chat to access them and change your suit!", false, false, "suitsTerminal-Hint");
				}
			}
		}
	}
	internal class InitThisPlugin
	{
		internal static bool initStarted;

		internal static void InitSuitsTerm()
		{
			if (initStarted)
			{
				suitsTerminal.X("init already started, ending func");
				return;
			}
			initStarted = true;
			suitsTerminal.X($"Suits patch, normSuit value: {Misc.normSuit} & showSuit value: {Misc.showSuit}");
			AllSuits.InitSuitsListing();
			if (!Misc.hintOnce)
			{
				((MonoBehaviour)suitsTerminal.Terminal).StartCoroutine(Enums.ChatHints());
				((MonoBehaviour)suitsTerminal.Terminal).StartCoroutine(Enums.HudHints());
				Misc.hintOnce = true;
			}
		}
	}
	internal class Misc
	{
		internal static bool keywordsCreated;

		internal static bool rackSituated;

		internal static int normSuit;

		internal static int showSuit;

		internal static int weirdSuitNum;

		internal static int reorderSuits;

		internal static bool hasLaunched;

		internal static bool hintOnce;

		internal static bool isHanging;

		internal static List<string> GetString()
		{
			if (AllSuits.favSuits.Count == 0)
			{
				suitsTerminal.Log.LogWarning((object)"Favorite suits empty, displaying regular menu");
				AdvancedMenu.inFavsMenu = false;
				return AllSuits.suitNames;
			}
			if (AdvancedMenu.inFavsMenu)
			{
				return AllSuits.favSuits;
			}
			return AllSuits.suitNames;
		}

		internal static string HelpMenuDisplay(bool inHelpMenu, List<string> currentMenu)
		{
			if (inHelpMenu)
			{
				suitsTerminal.X("Help Menu Enabled, showing help information");
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("========= AdvancedsuitsMenu Help Page  =========\r\n");
				stringBuilder.Append("\r\n\r\n");
				stringBuilder.Append("Highlight Next Item: [" + AdvancedMenu.downString + "]\r\nHighlight Last Item: [" + AdvancedMenu.upString + "]\r\nFavorite Item: [" + AdvancedMenu.favItemKeyString + "]\r\nShow Favorites Menu: [" + AdvancedMenu.favMenuKeyString + "]\r\n");
				if (SConfig.enablePiPCamera.Value)
				{
					stringBuilder.Append("Toggle Camera Preview: [" + AdvancedMenu.togglePiPstring + "]\r\nRotate Camera: [" + AdvancedMenu.pipRotateString + "]\r\nChange Camera Height: [" + AdvancedMenu.pipHeightString + "]\r\nChange Camera Zoom: [" + AdvancedMenu.pipZoomString + "]\r\n");
				}
				stringBuilder.Append("Leave Suits Menu: [" + AdvancedMenu.leaveString + "]\r\nSelect Suit: [" + AdvancedMenu.selectString + "]\r\n");
				stringBuilder.Append("\r\n>>>\tReturn to Suit Selection: [" + AdvancedMenu.helpMenuKeyString + "]\t<<\r\n");
				return stringBuilder.ToString();
			}
			suitsTerminal.X("Help Menu disabled, returning to menu selection...");
			return StringStuff.AdvancedMenuDisplay(currentMenu, AdvancedMenu.activeSelection, 10, AdvancedMenu.currentPage);
		}

		internal static void SaveToConfig(List<string> stringList, out string configItem)
		{
			configItem = string.Join(", ", stringList);
			suitsTerminal.X("Saving to config\n" + configItem);
		}

		internal static PlayerControllerB GetPlayerUsingTerminal()
		{
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (!val.isPlayerDead && (Object)(object)val.currentTriggerInAnimationWith == (Object)(object)suitsTerminal.Terminal.terminalTrigger)
				{
					suitsTerminal.X("Player: " + val.playerUsername + " detected using terminal.");
					return val;
				}
			}
			return null;
		}
	}
	internal class StringStuff
	{
		internal static string GetNumbers(string selectedSuit)
		{
			int num = selectedSuit.IndexOf("^");
			string text;
			if (num == -1)
			{
				text = string.Empty;
			}
			else
			{
				int num2 = num + 1;
				text = selectedSuit.Substring(num2, selectedSuit.Length - num2);
			}
			string text2 = text;
			return text2.Replace("^", "").Replace("(", "").Replace(")", "");
		}

		internal static string RemoveNumbers(string selectedSuit)
		{
			int num = selectedSuit.IndexOf("^");
			return (num != -1) ? selectedSuit.Substring(0, num) : selectedSuit;
		}

		internal static string TerminalFriendlyString(string s)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (char c in s)
			{
				if (!char.IsPunctuation(c))
				{
					stringBuilder.Append(c);
				}
			}
			if (stringBuilder.Length > 14)
			{
				int length = stringBuilder.Length - 14;
				stringBuilder.Remove(14, length);
			}
			return stringBuilder.ToString().ToLower();
		}

		internal static string ChatListing(List<string> menuItems, int pageSize, int currentPage)
		{
			currentPage = Mathf.Clamp(currentPage, 1, Mathf.CeilToInt((float)menuItems.Count / (float)pageSize));
			int num = (currentPage - 1) * pageSize;
			int num2 = Mathf.Min(num + pageSize, menuItems.Count);
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("\r\n");
			for (int i = num; i < num2; i++)
			{
				string text = ((i == AdvancedMenu.currentlyWearing) ? (menuItems[i] + " [EQUIPPED]") : menuItems[i]);
				stringBuilder.Append($"'!wear {i}' (" + text + ")\r\n");
			}
			stringBuilder.Append("\r\n");
			stringBuilder.Append($"Page {currentPage}/{Mathf.CeilToInt((float)menuItems.Count / (float)pageSize)}\r\n");
			return stringBuilder.ToString();
		}

		internal static string AdvancedMenuDisplay(List<string> menuItems, int activeIndex, int pageSize, int currentPage)
		{
			currentPage = Mathf.Clamp(currentPage, 1, Mathf.CeilToInt((float)menuItems.Count / (float)pageSize));
			int num = (currentPage - 1) * pageSize;
			int num2 = Mathf.Min(num + pageSize, menuItems.Count);
			int num3 = 0;
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("============= AdvancedsuitsMenu  =============\r\n");
			stringBuilder.Append("\r\n");
			activeIndex = Mathf.Clamp(activeIndex, num, num2 - 1);
			suitsTerminal.X($"activeSelection: {AdvancedMenu.activeSelection} activeIndex: {activeIndex}");
			suitsTerminal.X("matching values");
			AdvancedMenu.activeSelection = activeIndex;
			for (int i = num; i < num2; i++)
			{
				bool flag = AllSuits.favSuits.Contains(menuItems[i]);
				string text = ((i == activeIndex) ? ("> " + ((i == AdvancedMenu.currentlyWearing) ? (menuItems[i] + " [EQUIPPED]") : menuItems[i]) + (flag ? " (*)" : "")) : (((i == AdvancedMenu.currentlyWearing) ? (menuItems[i] + " [EQUIPPED]") : menuItems[i]) + (flag ? " (*)" : "")));
				stringBuilder.Append(text + "\r\n");
				num3++;
			}
			int num4 = pageSize - num3;
			for (int j = 0; j < num4; j++)
			{
				stringBuilder.Append("\r\n");
			}
			stringBuilder.Append("\r\n\r\n");
			stringBuilder.Append($"Page [{AdvancedMenu.leftString}] < {currentPage}/{Mathf.CeilToInt((float)menuItems.Count / (float)pageSize)} > [{AdvancedMenu.rightString}]\r\n");
			stringBuilder.Append("Leave Menu: [" + AdvancedMenu.leaveString + "]\tSelect Suit: [" + AdvancedMenu.selectString + "]\r\n");
			stringBuilder.Append("\r\n\r\n>>>\tDisplay Help Page: [" + AdvancedMenu.helpMenuKeyString + "]\t<<\r\n");
			return stringBuilder.ToString();
		}

		internal static string GetActiveMenuItem(List<string> menuItems, int activeIndex, int pageSize, int currentPage)
		{
			suitsTerminal.X("GetActiveMenuItem");
			int num = (currentPage - 1) * pageSize;
			int num2 = Mathf.Min(num + pageSize, menuItems.Count);
			if (activeIndex < num || activeIndex >= num2)
			{
				currentPage = activeIndex / pageSize + 1;
				num = (currentPage - 1) * pageSize;
				num2 = Mathf.Min(num + pageSize, menuItems.Count);
			}
			string text = menuItems[activeIndex];
			suitsTerminal.X("Selecting Active Menu Item: " + text);
			return text;
		}

		internal static List<string> GetListFromConfigItem(string configItem)
		{
			return (from item in configItem.Split(';')
				select item.TrimStart()).ToList();
		}

		internal static List<int> GetNumberListFromStringList(List<string> stringList)
		{
			List<int> list = new List<int>();
			foreach (string @string in stringList)
			{
				if (int.TryParse(@string, out var result))
				{
					list.Add(result);
				}
				else
				{
					suitsTerminal.Log.LogError((object)("Could not parse " + @string + " to integer"));
				}
			}
			return list;
		}
	}
	[BepInPlugin("darmuh.suitsTerminal", "suitsTerminal", "1.3.0")]
	public class suitsTerminal : BaseUnityPlugin
	{
		public static class PluginInfo
		{
			public const string PLUGIN_GUID = "darmuh.suitsTerminal";

			public const string PLUGIN_NAME = "suitsTerminal";

			public const string PLUGIN_VERSION = "1.3.0";
		}

		public static suitsTerminal instance;

		internal static bool TerminalStuff;

		internal static bool OpenBodyCams;

		public static Terminal Terminal;

		internal static ManualLogSource Log;

		private void Awake()
		{
			instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"suitsTerminal version 1.3.0 has been started!");
			Misc.keywordsCreated = false;
			SConfig.Settings();
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
		}

		public static void X(string message)
		{
			if (SConfig.extensiveLogging.Value)
			{
				Log.LogInfo((object)message);
			}
		}
	}
	internal class AllSuits
	{
		internal static List<UnlockableSuit> allSuits = new List<UnlockableSuit>();

		internal static List<UnlockableItem> UnlockableItems = new List<UnlockableItem>();

		internal static Dictionary<int, string> suitNameToID = new Dictionary<int, string>();

		internal static List<string> suitNames = new List<string>();

		internal static List<string> favSuits = new List<string>();

		internal static List<Page> suitsPages = new List<Page>();

		internal static bool favSuitsSet = false;

		internal static void GetList()
		{
			suitNameToID.Clear();
			suitNames.Clear();
			Misc.weirdSuitNum = 0;
			foreach (UnlockableSuit allSuit in allSuits)
			{
				if (allSuit.syncedSuitID.Value >= 0 && AddSuitToList(allSuit))
				{
					string text = UnlockableItems[allSuit.syncedSuitID.Value].unlockableName;
					if (!SConfig.advancedTerminalMenu.Value)
					{
						text = StringStuff.TerminalFriendlyString(text);
					}
					suitNameToID.Add(allSuit.syncedSuitID.Value, text);
				}
				else
				{
					Misc.weirdSuitNum++;
					suitsTerminal.X("Skipping suit, either weird or locked.");
				}
			}
			CheckForDuplicateSuitNames();
			FixRack();
			InitFavorites();
			OldCommands.MakeRandomSuitCommand();
		}

		private static void CheckForDuplicateSuitNames()
		{
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			foreach (KeyValuePair<int, string> kvp in suitNameToID)
			{
				if (!list.Any((string name) => string.Equals(name, kvp.Value, StringComparison.OrdinalIgnoreCase)))
				{
					list.Add(kvp.Value);
				}
				else
				{
					list2.Add(kvp.Value);
				}
			}
			CreateFinalSuitsList(list2);
		}

		private static void CreateFinalSuitsList(List<string> duplicateSuitNames)
		{
			foreach (KeyValuePair<int, string> kvp in suitNameToID)
			{
				if (!duplicateSuitNames.Any((string name) => string.Equals(name, kvp.Value, StringComparison.OrdinalIgnoreCase)))
				{
					suitNames.Add(kvp.Value);
					continue;
				}
				string item = $"{kvp.Value}^({kvp.Key})";
				suitNames.Add(item);
			}
		}

		private static bool AddSuitToList(UnlockableSuit suit)
		{
			if (!SConfig.enforcePaidSuits.Value)
			{
				return true;
			}
			if ((Object)(object)UnlockableItems[suit.syncedSuitID.Value].shopSelectionNode == (Object)null)
			{
				return true;
			}
			if (!UnlockableItems[suit.syncedSuitID.Value].spawnPrefab)
			{
				suitsTerminal.X("Locked suit [" + UnlockableItems[suit.syncedSuitID.Value].unlockableName + "] detected, not adding to list.");
				suitsTerminal.X($"hasBeenUnlockedByPlayer: {UnlockableItems[suit.syncedSuitID.Value].hasBeenUnlockedByPlayer} \nalreadyUnlocked: {UnlockableItems[suit.syncedSuitID.Value].alreadyUnlocked}");
				return false;
			}
			return true;
		}

		private static void RemoveBadSuitIDs()
		{
			if (!SConfig.keepSuitsWithNegativeIDs.Value)
			{
				allSuits.RemoveAll((UnlockableSuit suit) => suit.syncedSuitID.Value < 0);
				suitsTerminal.X("Removing suits with negative suitID values.");
			}
			else
			{
				suitsTerminal.X("Attempting to keep suits with negative suitID values.");
				allSuits.RemoveAll(delegate(UnlockableSuit suit)
				{
					if (suit.syncedSuitID.Value < 0)
					{
						int newRandomNumber;
						do
						{
							newRandomNumber = Random.Range(1, int.MaxValue);
						}
						while (allSuits.Any((UnlockableSuit otherSuit) => otherSuit.syncedSuitID.Value == newRandomNumber));
						suitsTerminal.X($"suit ID was {suit.syncedSuitID.Value}");
						suit.syncedSuitID.Value = newRandomNumber;
						suitsTerminal.X($"suit ID changed to {suit.syncedSuitID.Value}");
						return true;
					}
					return false;
				});
			}
			if (SConfig.suitsSortingStyle.Value == "alphabetical")
			{
				OrderSuitsByName();
			}
			else if (SConfig.suitsSortingStyle.Value == "numerical")
			{
				OrderSuitsByID();
			}
			else if (SConfig.suitsSortingStyle.Value == "none")
			{
				suitsTerminal.Log.LogInfo((object)"No sorting requested, host/client may be desynced.");
			}
			else
			{
				suitsTerminal.Log.LogError((object)"Config failure, no sorting");
			}
		}

		private static void GetAllSuits()
		{
			allSuits.Clear();
			UnlockableSuit[] array = Resources.FindObjectsOfTypeAll<UnlockableSuit>();
			List<UnlockableSuit> list = new List<UnlockableSuit>(array.Length);
			list.AddRange(array);
			allSuits = list;
			List<UnlockableSuit> list2 = new List<UnlockableSuit>();
			list2.AddRange(allSuits.OrderBy((UnlockableSuit suit) => suit.suitID));
			allSuits = list2;
			UnlockableItems = StartOfRound.Instance.unlockablesList.unlockables;
			RemoveBadSuitIDs();
		}

		private static void OrderSuitsByName()
		{
			List<UnlockableSuit> list = new List<UnlockableSuit>();
			list.AddRange(allSuits.OrderBy((UnlockableSuit suit) => UnlockableItems[suit.syncedSuitID.Value].unlockableName));
			allSuits = list;
		}

		private static void OrderSuitsByID()
		{
			List<UnlockableSuit> list = new List<UnlockableSuit>();
			list.AddRange(allSuits.OrderBy((UnlockableSuit suit) => suit.syncedSuitID.Value));
			allSuits = list;
		}

		internal static void InitSuitsListing()
		{
			GetAllSuits();
			GetList();
		}

		private static void InitFavorites()
		{
			List<string> list = (from item in SConfig.favoritesMenuList.Value.Split(',')
				select item.TrimStart()).ToList();
			favSuits.Clear();
			foreach (string item in list)
			{
				if (suitNames.Contains(item) && !favSuits.Contains(item))
				{
					favSuits.Add(item);
					suitsTerminal.X("Added [" + item + "] to favorites list.");
				}
				else
				{
					suitsTerminal.Log.LogWarning((object)("[" + item + "] not loaded to favorites. Suit is locked, already added, or not found."));
				}
			}
		}

		private static void HideBootsAndRack()
		{
			if (!Misc.rackSituated)
			{
				if (SConfig.hideBoots.Value)
				{
					GameObject val = GameObject.Find("Environment/HangarShip/ScavengerModelSuitParts/Circle.004");
					Object.Destroy((Object)(object)val);
				}
				if (!SConfig.dontRemove.Value && SConfig.hideRack.Value)
				{
					GameObject val2 = GameObject.Find("Environment/HangarShip/NurbsPath.002");
					Object.Destroy((Object)(object)val2);
				}
			}
		}

		private static void FixRack()
		{
			suitsTerminal.X($"Suit Count: {allSuits.Count}");
			suitsTerminal.X($"Unlockables Count: {UnlockableItems.Count}");
			Misc.weirdSuitNum = 0;
			Misc.reorderSuits = 0;
			Misc.normSuit = 0;
			List<string> list = (from item in SConfig.suitsOnRackList.Value.Split(',')
				select item.TrimStart()).ToList();
			HideBootsAndRack();
			foreach (UnlockableSuit allSuit in allSuits)
			{
				AutoParentToShip component = ((Component)allSuit).gameObject.GetComponent<AutoParentToShip>();
				SuitInfo component2 = ((Component)component).gameObject.GetComponent<SuitInfo>();
				OldCommands.CreateOldWearCommands(allSuit);
				if (SConfig.dontRemove.Value)
				{
					continue;
				}
				Misc.isHanging = false;
				if ((Object)(object)component2 != (Object)null)
				{
					string suitTag = component2.suitTag;
					if (suitTag == "hanging")
					{
						Misc.isHanging = true;
						suitsTerminal.X("Hanging suit detected - " + suitTag);
					}
					else if (suitTag == "hidden")
					{
						Misc.isHanging = false;
						suitsTerminal.X("Hidden suit detected - " + suitTag);
					}
					else
					{
						component2.suitTag = "hidden";
					}
				}
				if (!Bools.ShouldShowSuit(allSuit, list))
				{
					ProcessRack.ProcessHiddenSuit(component);
					Misc.normSuit++;
				}
				else if (Misc.rackSituated && Bools.ShouldShowSuit(allSuit, list))
				{
					ProcessRack.ProcessHangingSuit(component);
				}
				else if (!Misc.rackSituated && Bools.ShouldShowSuit(allSuit, list))
				{
					ProcessRack.ProcessVisibleSuit(component, Misc.showSuit);
					Misc.normSuit++;
				}
				else
				{
					ProcessRack.ProcessHiddenSuit(component);
				}
				if (Misc.showSuit == SConfig.suitsOnRack.Value && !Misc.rackSituated)
				{
					Misc.rackSituated = true;
					suitsTerminal.X("Max suits are on the rack now. rack is situated, yippeee!!!");
				}
			}
			InitThisPlugin.initStarted = false;
		}
	}
	internal class ProcessRack
	{
		internal static void ProcessHiddenSuit(AutoParentToShip component)
		{
			if (((Component)component).gameObject.GetComponent<SuitInfo>() == null)
			{
				((Component)component).gameObject.AddComponent<SuitInfo>();
			}
			((Component)component).GetComponent<SuitInfo>().suitTag = "hidden";
			component.disableObject = true;
			((Renderer)((Component)component).gameObject.GetComponentInChildren<SkinnedMeshRenderer>()).enabled = false;
			((Renderer)((Component)component).gameObject.GetComponentInChildren<MeshRenderer>()).enabled = false;
		}

		internal static void ProcessHangingSuit(AutoParentToShip component)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			component.disableObject = false;
			component.overrideOffset = true;
			float num = 0.18f;
			component.positionOffset = new Vector3(-2.45f, 2.75f, -8.41f) + StartOfRound.Instance.rightmostSuitPosition.forward * num * (float)Misc.reorderSuits;
			component.rotationOffset = new Vector3(0f, 90f, 0f);
			Misc.reorderSuits++;
		}

		internal static void ProcessVisibleSuit(AutoParentToShip component, int normSuit)
		{
			//IL_0047: 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_005c: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			if (((Component)component).gameObject.GetComponent<SuitInfo>() == null)
			{
				((Component)component).gameObject.AddComponent<SuitInfo>();
			}
			((Component)component).GetComponent<SuitInfo>().suitTag = "hanging";
			component.overrideOffset = true;
			float num = 0.18f;
			component.positionOffset = new Vector3(-2.45f, 2.75f, -8.41f) + StartOfRound.Instance.rightmostSuitPosition.forward * num * (float)normSuit;
			component.rotationOffset = new Vector3(0f, 90f, 0f);
			Misc.showSuit++;
		}
	}
	public class AdvancedMenu
	{
		internal static Dictionary<Key, string> keyActions = new Dictionary<Key, string>();

		internal static Key keyBeingPressed;

		internal static Key leaveMenu;

		internal static Key selectMenu;

		internal static Key togglePiP;

		internal static string upString;

		internal static string downString;

		internal static string leftString;

		internal static string rightString;

		internal static string leaveString;

		internal static string selectString;

		internal static string favItemKeyString;

		internal static string favMenuKeyString;

		internal static string helpMenuKeyString;

		internal static string togglePiPstring;

		internal static string pipHeightString;

		internal static string pipRotateString;

		internal static string pipZoomString;

		internal static bool inFavsMenu = false;

		internal static bool inHelpMenu = false;

		internal static int currentPage;

		internal static int activeSelection;

		internal static int currentlyWearing;

		internal static bool exitSpecialMenu = false;

		public static bool specialMenusActive = false;

		internal static TerminalNode menuDisplay = null;

		internal static bool initKeySettings = false;

		internal static void InitSettings()
		{
			if (!initKeySettings)
			{
				initKeySettings = true;
				keyActions.Clear();
				suitsTerminal.X("Loading keybinds from config");
				CollectionOfKeys();
				TogglePiPKey();
				CreateMenuCommand();
				if ((Object)(object)menuDisplay == (Object)null)
				{
					menuDisplay = TerminalHook.CreateDummyNode("suitsTerminal AdvancedMenu", clearPrevious: true, "");
				}
				initKeySettings = false;
			}
		}

		private static void GetCurrentSuitNum()
		{
			if (StartOfRound.Instance.localPlayerController.currentSuitID >= 0)
			{
				GetCurrentSuitID();
				suitsTerminal.X($"Currently Wearing: {currentlyWearing}\ncurrentSuitID: {StartOfRound.Instance.localPlayerController.currentSuitID}\n UnlockableItems: {AllSuits.UnlockableItems.Count}");
			}
		}

		internal static void CreateMenuCommand()
		{
			if (SConfig.advancedTerminalMenu.Value)
			{
				CommandHandler.AddCommand("Advanced Menus Corotuine", clearText: true, "suits", isVerb: false, "advanced_suitsTerm", CommandHandler.AdvancedSuitsTerm, CommandStuff.sT);
			}
		}

		private static void CollectionOfKeys()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			CheckKeys(SConfig.menuUp.Value, out var usingKey, out upString);
			BindKeys("previous_item", usingKey, ref upString, "UpArrow", (Key)63);
			CheckKeys(SConfig.menuDown.Value, out var usingKey2, out downString);
			BindKeys("next_item", usingKey2, ref downString, "DownArrow", (Key)64);
			CheckKeys(SConfig.menuLeft.Value, out var usingKey3, out leftString);
			BindKeys("previous_page", usingKey3, ref leftString, "LeftArrow", (Key)61);
			CheckKeys(SConfig.menuRight.Value, out var usingKey4, out rightString);
			BindKeys("next_page", usingKey4, ref rightString, "RightArrow", (Key)62);
			CheckKeys(SConfig.leaveMenu.Value, out var usingKey5, out leaveString);
			BindKeys("leave_menu", usingKey5, ref leaveString, "Backspace", (Key)65);
			CheckKeys(SConfig.selectMenu.Value, out var usingKey6, out selectString);
			BindKeys("menu_select", usingKey6, ref selectString, "Enter", (Key)2);
			CheckKeys(SConfig.favItemKey.Value, out var usingKey7, out favItemKeyString);
			BindKeys("favorite_item", usingKey7, ref favItemKeyString, "F", (Key)20);
			CheckKeys(SConfig.favMenuKey.Value, out var usingKey8, out favMenuKeyString);
			BindKeys("favorites_menu", usingKey8, ref favMenuKeyString, "F1", (Key)94);
			CheckKeys(SConfig.helpMenu.Value, out var usingKey9, out helpMenuKeyString);
			BindKeys("help_menu", usingKey9, ref helpMenuKeyString, "H", (Key)22);
		}

		private static void BindKeys(string menuAction, Key givenKey, ref string givenKeyString, string defaultKeyString, Key defaultKey)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			suitsTerminal.X("Binding " + menuAction);
			if ((int)givenKey > 0)
			{
				keyActions.Add(givenKey, menuAction);
				suitsTerminal.X(givenKeyString + " bound to " + menuAction);
			}
			else
			{
				keyActions.Add(defaultKey, menuAction);
				givenKeyString = defaultKeyString;
				suitsTerminal.X(givenKeyString + " bound to " + menuAction);
			}
		}

		private static void CheckKeys(string configString, out Key usingKey, out string keyString)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected I4, but got Unknown
			if (IsValidKey(configString, out var validKey))
			{
				usingKey = (Key)(int)validKey;
				keyString = configString;
			}
			else
			{
				usingKey = (Key)0;
				keyString = "FAIL";
			}
		}

		private static void TogglePiPKey()
		{
			//IL_0035: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			if (SConfig.enablePiPCamera.Value)
			{
				CheckKeys(SConfig.togglePiPHeight.Value, out var usingKey, out pipHeightString);
				BindKeys("pip_height", usingKey, ref pipHeightString, "Backslash", (Key)10);
				CheckKeys(SConfig.togglePiPRotation.Value, out var usingKey2, out pipRotateString);
				BindKeys("pip_rotate", usingKey2, ref pipRotateString, "Equals", (Key)14);
				CheckKeys(SConfig.togglePiPZoom.Value, out var usingKey3, out pipZoomString);
				BindKeys("pip_zoom", usingKey3, ref pipZoomString, "Minus", (Key)13);
				if (IsValidKey(SConfig.togglePiP.Value, out var validKey))
				{
					togglePiP = validKey;
					keyActions.Add(togglePiP, "toggle_pip");
					togglePiPstring = SConfig.togglePiP.Value;
				}
				else
				{
					keyActions.Add((Key)105, "toggle_pip");
					togglePiPstring = "F12";
				}
			}
		}

		private static bool IsValidKey(string key, out Key validKey)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected I4, but got Unknown
			List<Key> list = new List<Key>(1) { (Key)3 };
			if (Enum.TryParse<Key>(key, ignoreCase: true, out Key result))
			{
				if (list.Contains(result))
				{
					suitsTerminal.X("Tab Key detected, rejecting bind.");
					validKey = (Key)0;
					return false;
				}
				if (keyActions.ContainsKey(result))
				{
					suitsTerminal.X("Key was already bound to something, returning false");
					string text = string.Join(", ", keyActions.Keys);
					suitsTerminal.X("Key list: " + text);
					validKey = (Key)0;
					return false;
				}
				suitsTerminal.X("Valid Key Detected and being assigned to bind");
				validKey = (Key)(int)result;
				return true;
			}
			validKey = (Key)0;
			return false;
		}

		internal static void TerminalInputEnabled(bool state)
		{
			if (!state)
			{
				((Selectable)suitsTerminal.Terminal.screenText).interactable = false;
			}
			else
			{
				((Selectable)suitsTerminal.Terminal.screenText).interactable = true;
			}
		}

		public static bool AnyKeyIsPressed()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			TerminalInputEnabled(state: false);
			foreach (KeyValuePair<Key, string> keyAction in keyActions)
			{
				if (((ButtonControl)Keyboard.current[keyAction.Key]).isPressed)
				{
					keyBeingPressed = keyAction.Key;
					suitsTerminal.X($"Key detected in use: {keyAction.Key}");
					return true;
				}
			}
			return false;
		}

		private static void HandleKeyPress(Key key)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (keyActions.ContainsKey(key))
			{
				keyActions.TryGetValue(key, out var value);
				suitsTerminal.X("Attempting to match given key to action: " + value);
				HandleKeyAction(value);
			}
			else
			{
				suitsTerminal.Log.LogError((object)"Shortcut KeyActions list not updating properly");
			}
		}

		private static Camera GetCam()
		{
			if (suitsTerminal.OpenBodyCams && SConfig.useOpenBodyCams.Value)
			{
				return OpenBodyCams.GetMirrorCam();
			}
			return PictureInPicture.playerCam;
		}

		private static void HandleKeyAction(string value)
		{
			List<string> @string = Misc.GetString();
			Camera cam = GetCam();
			if (value == "previous_page" && !inHelpMenu)
			{
				if (currentPage > 0)
				{
					currentPage--;
				}
				menuDisplay.displayText = StringStuff.AdvancedMenuDisplay(@string, activeSelection, 10, currentPage);
				suitsTerminal.Terminal.LoadNewNode(menuDisplay);
				TerminalInputEnabled(state: false);
				suitsTerminal.X($"Current Page: {currentPage}\n Current Item: {activeSelection}");
			}
			else if (value == "next_page" && !inHelpMenu)
			{
				currentPage++;
				menuDisplay.displayText = StringStuff.AdvancedMenuDisplay(@string, activeSelection, 10, currentPage);
				suitsTerminal.Terminal.LoadNewNode(menuDisplay);
				TerminalInputEnabled(state: false);
				suitsTerminal.X($"Current Page: {currentPage}\n Current Item: {activeSelection}");
			}
			else if (value == "previous_item" && !inHelpMenu)
			{
				if (activeSelection > 0)
				{
					activeSelection--;
				}
				menuDisplay.displayText = StringStuff.AdvancedMenuDisplay(@string, activeSelection, 10, currentPage);
				suitsTerminal.Terminal.LoadNewNode(menuDisplay);
				TerminalInputEnabled(state: false);
				suitsTerminal.X($"Current Page: {currentPage}\n Current Item: {activeSelection}");
			}
			else if (value == "next_item" && !inHelpMenu)
			{
				activeSelection++;
				menuDisplay.displayText = StringStuff.AdvancedMenuDisplay(@string, activeSelection, 10, currentPage);
				suitsTerminal.Terminal.LoadNewNode(menuDisplay);
				TerminalInputEnabled(state: false);
				suitsTerminal.X($"Current Page: {currentPage}\n Current Item: {activeSelection}");
			}
			else if (value == "leave_menu")
			{
				exitSpecialMenu = true;
				TerminalInputEnabled(state: true);
			}
			else if (value == "menu_select" && !inHelpMenu)
			{
				string activeMenuItem = StringStuff.GetActiveMenuItem(@string, activeSelection, 10, currentPage);
				CommandHandler.AdvancedSuitPick(activeMenuItem);
				suitsTerminal.X($"Current Page: {currentPage}\n Current Item: {activeSelection}");
				GetCurrentSuitNum();
				menuDisplay.displayText = StringStuff.AdvancedMenuDisplay(@string, activeSelection, 10, currentPage);
				suitsTerminal.Terminal.LoadNewNode(menuDisplay);
				((MonoBehaviour)suitsTerminal.Terminal).StartCoroutine(TransformHotfix(cam));
				TerminalInputEnabled(state: false);
			}
			else if (value == "toggle_pip" && !inHelpMenu)
			{
				PictureInPicture.TogglePiP(!PictureInPicture.pipActive);
				suitsTerminal.X($"Toggling PiP to state {!PictureInPicture.pipActive}");
			}
			else if (value == "pip_height" && !inHelpMenu)
			{
				PictureInPicture.MoveCamera(((Component)cam).transform, ref PictureInPicture.heightStep);
				suitsTerminal.X($"Changing PiP height to {PictureInPicture.heightStep}");
			}
			else if (value == "pip_rotate" && !inHelpMenu)
			{
				PictureInPicture.RotateCameraAroundPlayer(((Component)StartOfRound.Instance.localPlayerController).transform, ((Component)cam).transform);
				suitsTerminal.X("Rotating PiP around player");
			}
			else if (value == "pip_zoom" && !inHelpMenu)
			{
				PictureInPicture.ChangeCamZoom(cam, ref PictureInPicture.zoomStep);
				suitsTerminal.X($"Changing PiP zoom to zoomStep: [{PictureInPicture.zoomStep}]");
			}
			else if (value == "favorite_item" && !inHelpMenu)
			{
				string activeMenuItem2 = StringStuff.GetActiveMenuItem(AllSuits.suitNames, activeSelection, 10, currentPage);
				if (AllSuits.favSuits.Contains(activeMenuItem2))
				{
					AllSuits.favSuits.Remove(activeMenuItem2);
				}
				else
				{
					AllSuits.favSuits.Add(activeMenuItem2);
				}
				Misc.SaveToConfig(AllSuits.favSuits, out var configItem);
				SConfig.favoritesMenuList.Value = configItem;
				suitsTerminal.X($"Current Page: {currentPage}\n Current Item: {activeSelection}");
				menuDisplay.displayText = StringStuff.AdvancedMenuDisplay(AllSuits.suitNames, activeSelection, 10, currentPage);
				suitsTerminal.Terminal.LoadNewNode(menuDisplay);
				TerminalInputEnabled(state: false);
			}
			else if (value == "favorites_menu" && !inHelpMenu)
			{
				inFavsMenu = !inFavsMenu;
				List<string> string2 = Misc.GetString();
				currentPage = 1;
				activeSelection = 0;
				GetCurrentSuitNum();
				menuDisplay.displayText = StringStuff.AdvancedMenuDisplay(string2, activeSelection, 10, currentPage);
				suitsTerminal.Terminal.LoadNewNode(menuDisplay);
				TerminalInputEnabled(state: false);
				DisplayAllMenuItemsLog(string2);
			}
			else if (value == "help_menu")
			{
				inHelpMenu = !inHelpMenu;
				currentPage = 1;
				activeSelection = 0;
				GetCurrentSuitNum();
				menuDisplay.displayText = Misc.HelpMenuDisplay(inHelpMenu, @string);
				PictureInPicture.TogglePiP(!inHelpMenu);
				suitsTerminal.Terminal.LoadNewNode(menuDisplay);
				TerminalInputEnabled(state: false);
			}
		}

		internal static IEnumerator TransformHotfix(Camera currentCam)
		{
			if (suitsTerminal.OpenBodyCams && SConfig.useOpenBodyCams.Value)
			{
				yield return (object)new WaitForEndOfFrame();
				PictureInPicture.CamInit(currentCam);
			}
		}

		private static void DisplayAllMenuItemsLog(List<string> menuListing)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (string item in menuListing)
			{
				stringBuilder.Append(item + "\n");
			}
			suitsTerminal.X($"{stringBuilder}");
		}

		internal static void GetCurrentSuitID()
		{
			foreach (UnlockableSuit allSuit in AllSuits.allSuits)
			{
				if (allSuit.suitID != StartOfRound.Instance.localPlayerController.currentSuitID && allSuit.syncedSuitID.Value != StartOfRound.Instance.localPlayerController.currentSuitID)
				{
					continue;
				}
				if (!inFavsMenu)
				{
					currentlyWearing = AllSuits.allSuits.IndexOf(allSuit);
					break;
				}
				string unlockableName = AllSuits.UnlockableItems[allSuit.syncedSuitID.Value].unlockableName;
				int num = AllSuits.favSuits.IndexOf(unlockableName);
				if (num == -1)
				{
					currentlyWearing = AllSuits.favSuits.IndexOf(unlockableName + $"^({allSuit.syncedSuitID.Value})");
				}
				else
				{
					currentlyWearing = num;
				}
				break;
			}
		}

		private static void PiPSetParent()
		{
			if (SConfig.enablePiPCamera.Value)
			{
				((Component)PictureInPicture.pipRawImage).transform.SetParent(((Component)((Selectable)suitsTerminal.Terminal.screenText).image).transform);
			}
		}

		internal static IEnumerator ActiveMenu()
		{
			if (specialMenusActive)
			{
				yield break;
			}
			specialMenusActive = true;
			inFavsMenu = false;
			PictureInPicture.rotateStep = 0;
			PictureInPicture.heightStep = 0;
			PictureInPicture.zoomStep = 1;
			GetCurrentSuitNum();
			PictureInPicture.TogglePiP(state: true);
			suitsTerminal.Terminal.screenText.DeactivateInputField(false);
			((Selectable)suitsTerminal.Terminal.screenText).interactable = false;
			yield return (object)new WaitForSeconds(0.2f);
			suitsTerminal.X("ActiveMenu Coroutine");
			currentPage = 1;
			activeSelection = 0;
			PiPSetParent();
			while (suitsTerminal.Terminal.terminalInUse && SConfig.advancedTerminalMenu.Value && !exitSpecialMenu)
			{
				if (AnyKeyIsPressed())
				{
					HandleKeyPress(keyBeingPressed);
					yield return (object)new WaitForSeconds(SConfig.menuKeyPressDelay.Value);
				}
				else
				{
					yield return (object)new WaitForSeconds(SConfig.menuPostSelectDelay.Value);
				}
			}
			if (!suitsTerminal.Terminal.terminalInUse)
			{
				suitsTerminal.X("Terminal no longer in use");
			}
			if (exitSpecialMenu)
			{
				exitSpecialMenu = false;
			}
			specialMenusActive = false;
			PictureInPicture.TogglePiP(state: false);
			yield return (object)new WaitForSeconds(0.1f);
			suitsTerminal.Terminal.screenText.ActivateInputField();
			((Selectable)suitsTerminal.Terminal.screenText).interactable = true;
			suitsTerminal.Terminal.LoadNewNode(suitsTerminal.Terminal.terminalNodes.specialNodes[13]);
		}
	}
	internal class CommandHandler
	{
		public delegate void CommandDelegate(out string displayText);

		internal static string RandomSuit()
		{
			suitsTerminal.X($"Suit Count: {AllSuits.allSuits.Count}");
			suitsTerminal.X($"Unlockables Count: {AllSuits.UnlockableItems.Count}");
			if (AllSuits.UnlockableItems != null)
			{
				for (int i = 0; i < AllSuits.UnlockableItems.Count; i++)
				{
					int index = Random.Range(0, AllSuits.allSuits.Count);
					UnlockableSuit val = AllSuits.allSuits[index];
					if ((Object)(object)val != (Object)null && AllSuits.UnlockableItems[val.syncedSuitID.Value] != null)
					{
						string unlockableName = AllSuits.UnlockableItems[val.syncedSuitID.Value].unlockableName;
						val.SwitchSuitToThis(StartOfRound.Instance.localPlayerController);
						return "Changing suit to " + unlockableName + "!\r\n";
					}
					suitsTerminal.X("Random suit ID was invalid or null");
				}
			}
			return "Unable to set suit random suit.\r\n";
		}

		internal static string SuitPickCommand()
		{
			return PickSuit();
		}

		internal static string RandomSuitCommand()
		{
			return RandomSuit();
		}

		internal static string AdvancedSuitsTerm()
		{
			((MonoBehaviour)suitsTerminal.Terminal).StartCoroutine(AdvancedMenu.ActiveMenu());
			return StringStuff.AdvancedMenuDisplay(AllSuits.suitNames, 0, 10, 1);
		}

		private static void PickSuitBasedOnID(int suitID, out UnlockableSuit suitToUse)
		{
			foreach (UnlockableSuit allSuit in AllSuits.allSuits)
			{
				if (allSuit.syncedSuitID.Value == suitID)
				{
					suitToUse = allSuit;
					return;
				}
			}
			suitToUse = null;
		}

		private static void PickUnlockableBasedOnID(int suitID, out UnlockableItem itemToUse)
		{
			foreach (UnlockableSuit allSuit in AllSuits.allSuits)
			{
				if (allSuit.syncedSuitID.Value == suitID)
				{
					itemToUse = AllSuits.UnlockableItems[allSuit.syncedSuitID.Value];
					return;
				}
			}
			itemToUse = null;
		}

		private static void PickSuitBasedOnItem(UnlockableItem itemGiven, out UnlockableSuit suitToWear)
		{
			foreach (UnlockableSuit allSuit in AllSuits.allSuits)
			{
				if (AllSuits.UnlockableItems[allSuit.syncedSuitID.Value] == itemGiven)
				{
					suitToWear = allSuit;
					suitsTerminal.X("Found suit to wear");
					return;
				}
			}
			suitToWear = null;
		}

		private static void FindSuitWithoutID(string suitName, List<int> dontUse)
		{
			List<UnlockableItem> list = new List<UnlockableItem>();
			suitsTerminal.X("grabbing duplicate suits items to not use");
			foreach (int item in dontUse)
			{
				PickUnlockableBasedOnID(item, out var itemToUse);
				if (itemToUse != null)
				{
					list.Add(itemToUse);
				}
			}
			suitsTerminal.X("iterating through item to grab the remaining suitID");
			foreach (UnlockableItem unlockableItem in AllSuits.UnlockableItems)
			{
				if (unlockableItem.unlockableName == suitName && !list.Contains(unlockableItem))
				{
					suitsTerminal.X("Found unique suit, assigning.");
					PickSuitBasedOnItem(unlockableItem, out var suitToWear);
					if ((Object)(object)suitToWear != (Object)null)
					{
						suitToWear.SwitchSuitToThis(StartOfRound.Instance.localPlayerController);
						suitsTerminal.X("Wearing: " + AllSuits.UnlockableItems[suitToWear.syncedSuitID.Value].unlockableName);
					}
					else
					{
						suitsTerminal.Log.LogError((object)"failed to get suit from item!");
					}
				}
			}
		}

		private static void DuplicateSuitHandling(string selectedSuit)
		{
			string numbers = StringStuff.GetNumbers(selectedSuit);
			if (int.TryParse(numbers, out var result))
			{
				if (result != -1)
				{
					PickSuitBasedOnID(result, out var suitToUse);
					if ((Object)(object)suitToUse != (Object)null)
					{
						suitToUse.SwitchSuitToThis(StartOfRound.Instance.localPlayerController);
						suitsTerminal.X("Wearing: " + AllSuits.UnlockableItems[suitToUse.syncedSuitID.Value].unlockableName);
					}
					else
					{
						suitsTerminal.Log.LogError((object)$"failed to resolve suit name from {result}");
					}
				}
				else
				{
					suitsTerminal.Log.LogError((object)("failed to resolve suit name from " + selectedSuit));
				}
			}
			else
			{
				suitsTerminal.Log.LogError((object)("failed to resolve suit ID from " + numbers));
			}
		}

		internal static void AdvancedSuitPick(string selectedSuit)
		{
			if (selectedSuit.Contains("^("))
			{
				DuplicateSuitHandling(selectedSuit);
				return;
			}
			string message;
			if (AllSuits.UnlockableItems != null && selectedSuit != string.Empty)
			{
				foreach (UnlockableSuit allSuit in AllSuits.allSuits)
				{
					if (allSuit.syncedSuitID != null && allSuit.syncedSuitID.Value >= 0)
					{
						suitsTerminal.X("3.");
						if (AllSuits.UnlockableItems.Count < allSuit.syncedSuitID.Value)
						{
							suitsTerminal.Log.LogError((object)"suit change encountered error with suitID");
							return;
						}
						string unlockableName = AllSuits.UnlockableItems[allSuit.syncedSuitID.Value].unlockableName;
						if (unlockableName.Equals(selectedSuit))
						{
							suitsTerminal.X("4.");
							allSuit.SwitchSuitToThis(StartOfRound.Instance.localPlayerController);
							message = "Changing suit to " + AllSuits.UnlockableItems[allSuit.syncedSuitID.Value].unlockableName + "\r\n";
							suitsTerminal.X(message);
							return;
						}
					}
				}
			}
			message = "Unable to set suit to match command: " + selectedSuit;
			suitsTerminal.X(message);
		}

		internal static string PickSuit()
		{
			suitsTerminal.X($"Suit Count: {AllSuits.allSuits.Count}");
			suitsTerminal.X($"Unlockables Count: {AllSuits.UnlockableItems.Count}");
			string screenCleanedText = GetScreenCleanedText(suitsTerminal.Terminal);
			if (AllSuits.UnlockableItems != null)
			{
				foreach (UnlockableSuit allSuit in AllSuits.allSuits)
				{
					if (allSuit.syncedSuitID.Value >= 0)
					{
						string s = AllSuits.UnlockableItems[allSuit.syncedSuitID.Value].unlockableName.ToLower();
						s = StringStuff.TerminalFriendlyString(s);
						if (screenCleanedText.Equals("wear " + s))
						{
							allSuit.SwitchSuitToThis(StartOfRound.Instance.localPlayerController);
							return "Changing suit to " + AllSuits.UnlockableItems[allSuit.syncedSuitID.Value].unlockableName + "\r\n";
						}
						suitsTerminal.X("SuitName: " + s + " doesn't match Cleaned Text: " + screenCleanedText);
					}
					else
					{
						suitsTerminal.X($"suit ID was {allSuit.syncedSuitID.Value}");
					}
				}
			}
			return "Unable to set suit to match command: " + screenCleanedText;
		}

		private static string GetScreenCleanedText(Terminal __instance)
		{
			string s = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded);
			return RemovePunctuation(s);
		}

		private static string RemovePunctuation(string s)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (char c in s)
			{
				if (!char.IsPunctuation(c))
				{
					stringBuilder.Append(c);
				}
			}
			return stringBuilder.ToString().ToLower();
		}

		internal static void AddCommand(string textFail, bool clearText, string keyWord, bool isVerb, string nodeName, Func<string> methodName, Dictionary<TerminalNode, Func<string>> nodeListing)
		{
			TerminalHook.MakeCommand(nodeName, keyWord, textFail, isVerb, clearText, methodName, nodeListing);
		}
	}
	internal class OldCommands
	{
		internal static void CreateOldWearCommands(UnlockableSuit item)
		{
			if (!SConfig.terminalCommands.Value || SConfig.advancedTerminalMenu.Value)
			{
				return;
			}
			string text = "";
			if (item.syncedSuitID.Value >= 0 && !Misc.keywordsCreated)
			{
				text = AllSuits.UnlockableItems[item.syncedSuitID.Value].unlockableName;
				text = StringStuff.TerminalFriendlyString(text);
				if (AllSuits.suitNames.Contains(text.ToLower()))
				{
					text += "z";
					suitsTerminal.X("Duplicate found. Updated SuitName: " + text);
				}
				AllSuits.suitNames.Add(text.ToLower());
				CommandHandler.AddCommand(text, clearText: true, "wear " + text, isVerb: false, text, CommandHandler.SuitPickCommand, CommandStuff.sT);
				suitsTerminal.X("Keyword for " + text + " added");
			}
			else if (item.syncedSuitID.Value >= 0 && Misc.keywordsCreated)
			{
				text = AllSuits.UnlockableItems[item.syncedSuitID.Value].unlockableName;
				text = StringStuff.TerminalFriendlyString(text);
				if (TerminalHook.TryGetKeyword("wear " + text))
				{
					CommandHandler.AddCommand(text, clearText: true, "wear " + text, isVerb: false, text, CommandHandler.SuitPickCommand, CommandStuff.sT);
					suitsTerminal.X("Keyword for " + text + " updated");
				}
				else
				{
					CommandHandler.AddCommand(text, clearText: true, "wear " + text, isVerb: false, text, CommandHandler.SuitPickCommand, CommandStuff.sT);
					suitsTerminal.X("Keyword for " + text + " added, keyword appears to have been removed.");
				}
			}
			else if (item.syncedSuitID.Value < 0)
			{
				Misc.weirdSuitNum++;
				suitsTerminal.X($"Skipping suit with invalid ID number: {item.syncedSuitID.Value}");
			}
			else
			{
				suitsTerminal.X("leaving this here but it should never happen");
			}
			CreateOldPageCommands();
		}

		internal static void CreateOldPageCommands()
		{
			if ((Object)(object)suitsTerminal.Terminal != (Object)null && !Misc.keywordsCreated)
			{
				StringBuilder suitsList = BuildSuitsList();
				CreateSuitPages(suitsList);
				Misc.keywordsCreated = true;
			}
			else if (Misc.keywordsCreated)
			{
				StringBuilder suitsList2 = BuildSuitsList();
				UpdateOrRecreateSuitKeywords(suitsList2);
			}
		}

		private static StringBuilder BuildSuitsList()
		{
			StringBuilder stringBuilder = new StringBuilder();
			Misc.weirdSuitNum = 0;
			foreach (UnlockableSuit allSuit in AllSuits.allSuits)
			{
				if (allSuit.syncedSuitID.Value >= 0)
				{
					string unlockableName = AllSuits.UnlockableItems[allSuit.syncedSuitID.Value].unlockableName;
					unlockableName = StringStuff.TerminalFriendlyString(unlockableName);
					stringBuilder.AppendLine("> wear " + unlockableName + "\n");
				}
				else
				{
					Misc.weirdSuitNum++;
					suitsTerminal.X("Skipping suit.");
				}
			}
			return stringBuilder;
		}

		private static void CreateSuitPages(StringBuilder suitsList)
		{
			List<Page> list = PageSplitter.SplitTextIntoPages(suitsList.ToString(), 6);
			if (!SConfig.terminalCommands.Value)
			{
				return;
			}
			foreach (Page item in list)
			{
				if (item.PageNumber == 1)
				{
					CreateOrUpdateMainSuitCommand(item);
				}
				else
				{
					CreateOrUpdateSuitPage(item);
				}
			}
		}

		private static void UpdateOrRecreateSuitKeywords(StringBuilder suitsList)
		{
			List<Page> list = PageSplitter.SplitTextIntoPages(suitsList.ToString(), 6);
			if (!SConfig.terminalCommands.Value)
			{
				return;
			}
			foreach (Page item in list)
			{
				if (item.PageNumber == 1)
				{
					CreateOrUpdateMainSuitCommand(item);
				}
				else
				{
					CreateOrUpdateSuitPage(item);
				}
			}
		}

		private static void CreateOrUpdateMainSuitCommand(Page page)
		{
			if (TerminalHook.TryGetKeyword("suits"))
			{
				TerminalHook.MakeCommand("suits (main)", "suits", $"{page.Content}", isVerb: false, clearText: true);
				suitsTerminal.X("Updating main suits command");
			}
			else
			{
				TerminalHook.MakeCommand("suits (main)", "suits", $"{page.Content}", isVerb: false, clearText: true);
				suitsTerminal.X("main suits command was deleted, creating again");
			}
		}

		private static void CreateOrUpdateSuitPage(Page page)
		{
			if (TerminalHook.TryGetKeyword($"suits {page.PageNumber}"))
			{
				suitsTerminal.X($"page {page.PageNumber} has already been creating, updating keyword");
				TerminalHook.MakeCommand($"suits (pg.{page.PageNumber})", $"suits {page.PageNumber}", $"{page.Content}", isVerb: false, clearText: true);
			}
			else
			{
				suitsTerminal.X($"page {page.PageNumber} has been deleted, creating keyword again");
				TerminalHook.MakeCommand($"suits (pg.{page.PageNumber})", $"suits {page.PageNumber}", $"{page.Content}", isVerb: false, clearText: true);
			}
		}

		internal static void MakeRandomSuitCommand()
		{
			if (SConfig.randomSuitCommand.Value)
			{
				CommandHandler.AddCommand("random suit command", clearText: true, "randomsuit", isVerb: false, "sT_random_suit", CommandHandler.RandomSuitCommand, CommandStuff.sT);
			}
		}
	}
	internal class OpenBodyCams
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static GetRenderersToHide <>9__8_0;

			internal Renderer[] <GetRenderersForOBC>b__8_0(Renderer[] original)
			{
				return new Span<Renderer>(((Component)suitsTerminal.Terminal).GetComponentsInChildren<Renderer>()).ToArray();
			}
		}

		internal static MonoBehaviour TerminalMirrorCam;

		internal static Vector2Int defaultRes;

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void CreateOpenBodyCamsMirror()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			suitsTerminal.X("Getting ZaggyCam texture");
			if ((Object)(object)TerminalMirrorCam == (Object)null || (Object)(object)((Component)TerminalMirrorCam).gameObject == (Object)null || (Object)(BodyCamComponent)TerminalMirrorCam == (Object)null)
			{
				CreateTerminalMirror();
			}
			suitsTerminal.X("Attempting to grab targetTexture");
			SetBodyCamTexture(((BodyCamComponent)TerminalMirrorCam).GetCamera().targetTexture);
			((BodyCamComponent)TerminalMirrorCam).ForceEnableCamera = true;
			Camera mirrorCam = GetMirrorCam();
			mirrorCam.orthographic = true;
			mirrorCam.orthographicSize = 0.55f;
			mirrorCam.usePhysicalProperties = false;
			mirrorCam.farClipPlane = 30f;
			mirrorCam.nearClipPlane = 0.05f;
			mirrorCam.fieldOfView = 130f;
			PictureInPicture.CamInit(mirrorCam);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void OpenBodyCamsMirror(bool state)
		{
			if (state)
			{
				CreateOpenBodyCamsMirror();
			}
			else
			{
				DestroyBodyCamsMirror();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static Camera GetMirrorCam()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return ((BodyCamComponent)TerminalMirrorCam).GetCamera();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void DestroyBodyCamsMirror()
		{
			if ((Object)(object)TerminalMirrorCam != (Object)null && (Object)(object)((Component)TerminalMirrorCam).gameObject != (Object)null)
			{
				Camera mirrorCam = GetMirrorCam();
				Object.Destroy((Object)(object)mirrorCam);
			}
		}

		private static void SetBodyCamTexture(RenderTexture texture)
		{
			suitsTerminal.X("Setting mirror texture stuff");
			PictureInPicture.pipRawImage.texture = (Texture)(object)texture;
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void CreateTerminalMirror()
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			if (suitsTerminal.OpenBodyCams)
			{
				if ((Object)(object)TerminalMirrorCam != (Object)null && (Object)(object)((Component)TerminalMirrorCam).gameObject != (Object)null)
				{
					DestroyBodyCamsMirror();
				}
				suitsTerminal.X("CreateTerminalMirror called");
				BodyCamComponent val = (BodyCamComponent)(object)(TerminalMirrorCam = (MonoBehaviour)(object)BodyCam.CreateBodyCam(((Component)suitsTerminal.Terminal).gameObject, (Material)null, (ManualCameraRenderer)null));
				val.OnRenderTextureCreated += SetBodyCamTexture;
				val.OnRenderersToHideChanged += GetRenderersForOBC(((Component)(BodyCamComponent)TerminalMirrorCam).GetComponent<Renderer>());
				val.OnCameraCreated += ResetTransform;
				val.OnBlankedSet += CamIsBlanked;
				Camera camera = val.GetCamera();
				((Object)((Component)camera).gameObject).name = "suitsTerminal mirrorcam";
				val.Resolution = defaultRes;
				val.SetTargetToTransform(((Component)suitsTerminal.Terminal).transform);
				suitsTerminal.X("suitsTerminal mirrorcam created!");
			}
		}

		private static GetRenderersToHide GetRenderersForOBC(Renderer original)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			object obj = <>c.<>9__8_0;
			if (obj == null)
			{
				GetRenderersToHide val = (Renderer[] original) => new Span<Renderer>(((Component)suitsTerminal.Terminal).GetComponentsInChildren<Renderer>()).ToArray();
				<>c.<>9__8_0 = val;
				obj = (object)val;
			}
			return (GetRenderersToHide)obj;
		}

		private static void CamIsBlanked(bool isBlanked)
		{
			suitsTerminal.X($"CamIsBlanked: {isBlanked}");
		}

		private static void ResetTransform(Camera cam)
		{
			suitsTerminal.X("ResetTransform Called!");
			PictureInPicture.CamInit(cam);
		}
	}
	internal class PictureInPicture
	{
		internal static bool PiPCreated;

		internal static GameObject pipGameObject;

		internal static GameObject camGameObject;

		internal static int cullingMaskInt;

		internal static Camera playerCam;

		internal static RawImage pipRawImage;

		internal static Canvas terminalCanvas;

		internal static bool pipActive;

		internal