Decompiled source of ChatCommands v2.0.0

ChatCommands.dll

Decompiled 4 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ChatCommands;
using ChatCommands.Commands;
using ChatCommands.Patches;
using GameNetcodeStuff;
using HarmonyLib;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.EventSystems;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ChatCommands")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ChatCommands")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("d9d7c116-3da7-4a2a-8b87-f83dac82c4cb")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Networking
{
	public class CCMDNetworking : NetworkBehaviour
	{
		[SerializeField]
		private string netHostCommandPrefix = "[COMMAND]";

		[SerializeField]
		private string netCommandPostfix = "[/COMMAND]";

		public static CCMDNetworking instance;

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			}
			else
			{
				Debug.LogWarning((object)"Multiple instances of CustomNetworkManager found!");
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		internal static void SendHostCommand(string commandInput)
		{
			if ((Object)(object)instance == (Object)null)
			{
				Debug.LogError((object)"CCMDNetworking instance is not initialized!");
				return;
			}
			string command = instance.netHostCommandPrefix + commandInput + instance.netCommandPostfix;
			Utils.DisplayChatMessage("Host Command: " + commandInput + "\nsending to clients via RPC");
			instance.RpcExecuteCommandOnClients(command);
		}

		[ClientRpc]
		private void RpcExecuteCommandOnClients(string command)
		{
			Utils.DisplayChatMessage("Client Command: " + command);
		}
	}
}
namespace ChatCommands
{
	public static class Utils
	{
		private static bool logToChat = ChatCommands.LogToChatSetting.Value;

		private static string NetCommandPrefix = "<size=0>CCMD:";

		private static string NetHostCommandPrefix = "<size=0>CHCMD:";

		private static string NetCommandPostfix = ":CCMD</size>";

		internal static bool DisplayAsTooltip = ChatCommands.DisplayChatMessagesAsPopupSetting.Value;

		public static Vector3 CalculateSpawnPosition(string sposition)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			Vector3 result = Vector3.zero;
			if (sposition == "random")
			{
				return result;
			}
			if (sposition.StartsWith("@"))
			{
				PlayerControllerB[] allPlayerScripts;
				try
				{
					allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
				}
				catch (Exception ex)
				{
					LogWarning("Error getting allPlayerScripts: " + ex);
					return result;
				}
				if (sposition == "@me")
				{
					PlayerControllerB[] array = allPlayerScripts;
					foreach (PlayerControllerB val in array)
					{
						ChatCommands.mls.LogInfo((object)("Checking Playername " + val.playerUsername));
						if (val.playerUsername.Replace(" ", "").ToLower().Contains(ChatCommands.playerwhocalled.ToLower()))
						{
							ChatCommands.mls.LogInfo((object)("Found player " + val.playerUsername));
							result = ((Component)val).transform.position;
							break;
						}
					}
				}
				else
				{
					string text = sposition.Substring(1);
					string text2 = ConvertPlayername(text);
					bool flag = false;
					ChatCommands.mls.LogInfo((object)("Looking for Playername " + text2 + " or Playername " + text + "..."));
					PlayerControllerB[] array2 = allPlayerScripts;
					foreach (PlayerControllerB val2 in array2)
					{
						ChatCommands.mls.LogInfo((object)("Checking Playername " + val2.playerUsername.Replace(" ", "")));
						if (val2.playerUsername.Replace(" ", "").ToLower().Contains(text2.ToLower()) || val2.playerUsername.Replace(" ", "").ToLower().Contains(text.ToLower()))
						{
							result = ((Component)val2).transform.position;
							flag = true;
							ChatCommands.mls.LogInfo((object)("Found player " + val2.playerUsername));
							break;
						}
					}
					if (!flag)
					{
						ChatCommands.mls.LogWarning((object)"Player not found");
						DisplayChatMessage("Player not found, spawning in random position");
					}
				}
			}
			else
			{
				string[] array3 = sposition.Split(new char[1] { ',' });
				if (array3.Length == 3)
				{
					((Vector3)(ref result))..ctor(float.Parse(array3[0]), float.Parse(array3[1]), float.Parse(array3[2]));
				}
				else
				{
					ChatCommands.mls.LogWarning((object)"Position Invalid, Using Default 'random'");
				}
			}
			return result;
		}

		public static void LogInfo(string message)
		{
			ChatCommands.mls.LogInfo((object)message);
			if (logToChat)
			{
				DisplayChatMessage(message);
			}
		}

		public static void LogWarning(string message)
		{
			ChatCommands.mls.LogWarning((object)message);
			if (logToChat)
			{
				DisplayChatError(message);
			}
		}

		public static void LogError(string message)
		{
			ChatCommands.mls.LogError((object)message);
			if (logToChat)
			{
				DisplayChatError(message);
			}
		}

		public static void DisplayChatMessage(string chatMessage)
		{
			try
			{
				string item = "<color=#FF00FF>ChatCommands</color>: <color=#FFFF00>" + chatMessage + "</color>";
				HUDManager.Instance.ChatMessageHistory.Add(item);
				UpdateChatText();
			}
			catch (Exception ex)
			{
				ChatCommands.mls.LogError((object)("Error displaying chat message: " + ex));
			}
			if (DisplayAsTooltip)
			{
				HUDManager.Instance.DisplayTip("ChatCommands", chatMessage, false, false, "LC_Tip1");
			}
		}

		public static void DisplayChatError(string errorMessage)
		{
			try
			{
				string item = "<color=#FF0000>CCMD: ERROR</color>: <color=#FF0000>" + errorMessage + "</color>";
				HUDManager.Instance.ChatMessageHistory.Add(item);
				UpdateChatText();
			}
			catch (Exception ex)
			{
				ChatCommands.mls.LogError((object)("Error displaying chat error: " + ex));
			}
			if (DisplayAsTooltip)
			{
				HUDManager.Instance.DisplayTip("ChatCommands", errorMessage, true, false, "LC_Tip1");
			}
		}

		private static void UpdateChatText()
		{
			((TMP_Text)HUDManager.Instance.chatText).text = string.Join("\n", HUDManager.Instance.ChatMessageHistory);
		}

		internal static string ConvertPlayername(string name)
		{
			ChatCommands.mls.LogInfo((object)("Converting name: " + name));
			string input = new string(name.Where((char c) => char.IsLetter(c)).ToArray());
			input = Regex.Replace(input, "[^\\w\\._]", "");
			ChatCommands.mls.LogInfo((object)("Converted name: " + input));
			return input;
		}

		internal static bool IsNetCommand(string message)
		{
			return message.StartsWith(NetCommandPrefix) && message.EndsWith(NetCommandPostfix);
		}

		internal static bool IsNetHostCommand(string message)
		{
			return message.StartsWith(NetHostCommandPrefix) && message.EndsWith(NetCommandPostfix);
		}

		internal static string ConvertFromNetCommand(string command)
		{
			LogInfo("Converting command: " + command);
			string text = command;
			if (!IsNetCommand(text))
			{
				throw new Exception("Not a valid NetCommand");
			}
			text = text.Substring(NetCommandPrefix.Length);
			text = text.Substring(0, text.Length - NetCommandPostfix.Length);
			text = ChatCommands.PrefixSetting.Value + text;
			LogInfo("Converted command: " + text);
			return text;
		}

		internal static string ConvertFromNetHostCommand(string command)
		{
			LogInfo("Converting command: " + command);
			string text = command;
			if (!IsNetHostCommand(text))
			{
				throw new Exception("Not a valid NetHostCommand");
			}
			text = text.Substring(NetHostCommandPrefix.Length);
			text = text.Substring(0, text.Length - NetCommandPostfix.Length);
			text = ChatCommands.PrefixSetting.Value + text;
			LogInfo("Converted command: " + text);
			return text;
		}

		internal static string ConvertToNetCommand(string command)
		{
			if (command.StartsWith(ChatCommands.PrefixSetting.Value))
			{
				command = command.Substring(ChatCommands.PrefixSetting.Value.Length);
			}
			LogInfo("Converting to NetCommand: " + command);
			LogInfo("Converted to NetCommand: " + NetCommandPrefix + command + NetCommandPostfix);
			return NetCommandPrefix + command + NetCommandPostfix;
		}

		internal static string ConvertToNetHostCommand(string command)
		{
			if (command.StartsWith(ChatCommands.PrefixSetting.Value))
			{
				command = command.Substring(ChatCommands.PrefixSetting.Value.Length);
			}
			LogInfo("Converting to NetHostCommand: " + command);
			LogInfo("Converted to NetHostCommand: " + NetHostCommandPrefix + command + NetCommandPostfix);
			return NetHostCommandPrefix + command + NetCommandPostfix;
		}

		internal static void SendHostCommand(string commandInput)
		{
			if (ChatCommands.isHost && ChatCommands.SendHostCommandsSetting.Value)
			{
				string text = ConvertToNetHostCommand(commandInput);
				LogInfo("Sending command to clients: " + text);
				HUDManager.Instance.AddTextToChatOnServer(text, -1);
			}
		}

		internal static void SendCommandToServer(string commandInput)
		{
			string text = ConvertToNetCommand(commandInput);
			LogInfo("Sending command to server: " + text);
			HUDManager.Instance.AddTextToChatOnServer(text, -1);
		}

		internal static SelectableLevel GetCurrentLevel()
		{
			return RoundManager.Instance.currentLevel;
		}

		internal static RoundManager GetCurrentRound()
		{
			return RoundManager.Instance;
		}
	}
	[BepInPlugin("toemmsen.ChatCommands", "ChatCommands", "2.0.0")]
	public class ChatCommands : BaseUnityPlugin
	{
		private const string modGUID = "toemmsen.ChatCommands";

		private const string modName = "ChatCommands";

		private const string modVersion = "2.0.0";

		private readonly Harmony harmony = new Harmony("toemmsen.ChatCommands");

		private static ChatCommands instance;

		internal static ManualLogSource mls = Logger.CreateLogSource("toemmsen.ChatCommands");

		public static Dictionary<SelectableLevel, List<SpawnableEnemyWithRarity>> levelEnemySpawns;

		public static Dictionary<SpawnableEnemyWithRarity, int> enemyRaritys;

		public static Dictionary<SpawnableEnemyWithRarity, AnimationCurve> enemyPropCurves;

		internal static ConfigEntry<string> PrefixSetting;

		internal static ConfigEntry<bool> HostSetting;

		internal static ConfigEntry<bool> LogToChatSetting;

		internal static ConfigEntry<bool> SendHostCommandsSetting;

		internal static ConfigEntry<bool> OverrideSpawnsSetting;

		internal static ConfigEntry<bool> EnableDebugModeSetting;

		internal static ConfigEntry<bool> DisplayChatMessagesAsPopupSetting;

		internal static bool OverrideSpawns = false;

		internal static bool AllowHostCommands = false;

		internal static bool isHost;

		internal static string playerwhocalled;

		internal static List<AllowedHostPlayer> AllowedHostPlayers = new List<AllowedHostPlayer>();

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			DisplayChatMessagesAsPopupSetting = ((BaseUnityPlugin)instance).Config.Bind<bool>("Command Settings", "Display Chat Messages As Popup", false, "Determines if chat messages are displayed as popup messages");
			PrefixSetting = ((BaseUnityPlugin)instance).Config.Bind<string>("Command Settings", "Command Prefix", "/", "An optional prefix for chat commands");
			HostSetting = ((BaseUnityPlugin)instance).Config.Bind<bool>("Command Settings", "Has to be Host", true, "(for server host only): determines if clients can also use the host commands");
			SendHostCommandsSetting = ((BaseUnityPlugin)instance).Config.Bind<bool>("Command Settings", "Send Host Commands", true, "(for server host only): determines if commands get sent to the clients, so for example god mode is enabled for them too");
			OverrideSpawnsSetting = ((BaseUnityPlugin)instance).Config.Bind<bool>("Command Settings", "Override Spawns", false, "(for server host only): determines if the spawn command overrides the default spawns. If enabled there can be spawned more than one girl etc. Can be toggled ingame by using /override command.");
			EnableDebugModeSetting = ((BaseUnityPlugin)instance).Config.Bind<bool>("Command Settings", "Enable Debug Mode", true, "Enables Unity Debug mode");
			LogToChatSetting = ((BaseUnityPlugin)instance).Config.Bind<bool>("Command Settings", "Log To Chat", false, "Enables logging to (local) chat");
			OverrideSpawns = OverrideSpawnsSetting.Value;
			AllowHostCommands = HostSetting.Value;
			enemyRaritys = new Dictionary<SpawnableEnemyWithRarity, int>();
			levelEnemySpawns = new Dictionary<SelectableLevel, List<SpawnableEnemyWithRarity>>();
			enemyPropCurves = new Dictionary<SpawnableEnemyWithRarity, AnimationCurve>();
			harmony.PatchAll(typeof(ChatCommands));
			harmony.PatchAll(typeof(global::ChatCommands.Patches.Patches));
			harmony.PatchAll(typeof(CommandController));
			harmony.PatchAll(typeof(SetCustomDeadline));
			harmony.PatchAll(typeof(SpeedHack));
			harmony.PatchAll(typeof(SpawnTruck));
			harmony.PatchAll(typeof(InfiniteAmmo));
			harmony.PatchAll(typeof(GodMode));
			harmony.PatchAll(typeof(SetMoney));
			harmony.PatchAll(typeof(SpawnMapObject));
			harmony.PatchAll(typeof(ToggleOverrideSpawns));
			mls.LogWarning((object)("\n" + "  ______                                                                                                       \n /_  __/  ____   ___    ____ ___    ____ ___    _____  ___    ____    _____                                    \n  / /    / __ \\ / _ \\  / __ `__ \\  / __ `__ \\  / ___/ / _ \\  / __ \\  / ___/                                    \n / /    / /_/ //  __/ / / / / / / / / / / / / (__  ) /  __/ / / / / (__  )                                     \n/_/_____\\____/_\\___/ /_/ /_/_/_/ /_/ /_/ /_/_/____/  \\___/ /_/ /_/ /____/                            __        \n  / ____/   / /_   ____ _  / /_         / ____/  ____    ____ ___    ____ ___   ____ _   ____   ____/ /   _____\n / /       / __ \\ / __ `/ / __/        / /      / __ \\  / __ `__ \\  / __ `__ \\ / __ `/  / __ \\ / __  /   / ___/\n/ /___    / / / // /_/ / / /_         / /___   / /_/ / / / / / / / / / / / / // /_/ /  / / / // /_/ /   (__  ) \n\\____/   /_/ /_/ \\__,_/  \\__/         \\____/   \\____/ /_/ /_/ /_/ /_/ /_/ /_/ \\__,_/  /_/ /_/ \\__,_/   /____/  \n"));
			mls.LogInfo((object)"ChatCommands loaded");
		}

		internal static void SpawnItems(Vector3 location, string itemToSpawn, int value, int amount)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			Utils.DisplayChatMessage("Trying to spawn: " + itemToSpawn);
			foreach (Item items in StartOfRound.Instance.allItemsList.itemsList)
			{
				if (((Object)items).name.ToLower().StartsWith(itemToSpawn))
				{
					for (int i = 0; i < amount; i++)
					{
						GameObject val = Object.Instantiate<GameObject>(items.spawnPrefab, location, Quaternion.identity, StartOfRound.Instance.propsContainer);
						val.GetComponent<GrabbableObject>().fallTime = 0f;
						val.GetComponent<GrabbableObject>().SetScrapValue(value);
						val.GetComponent<NetworkObject>().Spawn(false);
					}
					string[] obj = new string[9]
					{
						"Spawned ",
						amount.ToString(),
						" ",
						itemToSpawn,
						(amount > 1) ? "s" : "",
						" with value of:",
						value.ToString(),
						"\n at position: ",
						null
					};
					Vector3 val2 = location;
					obj[8] = ((object)(Vector3)(ref val2)).ToString();
					Utils.DisplayChatMessage(string.Concat(obj));
					return;
				}
			}
			Utils.DisplayChatError("Could not spawn: " + itemToSpawn);
		}
	}
	internal class AllowedHostPlayer
	{
		public string Name { get; set; }

		public bool AllowHostCMD { get; set; }

		public AllowedHostPlayer(string name, bool isActive)
		{
			Name = name;
			AllowHostCMD = isActive;
		}
	}
}
namespace ChatCommands.Patches
{
	internal class Patches
	{
		internal static float defaultJumpForce;

		[HarmonyPatch(typeof(RoundManager), "SpawnEnemyFromVent")]
		[HarmonyPrefix]
		private static void LogSpawnEnemyFromVent()
		{
			Utils.LogInfo("Attempting to spawn an enemy");
		}

		[HarmonyPatch(typeof(RoundManager), "LoadNewLevel")]
		[HarmonyPostfix]
		private static void UpdateNewInfo(ref EnemyVent[] ___allEnemyVents, ref SelectableLevel ___currentLevel)
		{
			HUDManager.Instance.chatTextField.characterLimit = 999;
		}

		[HarmonyPatch(typeof(RoundManager), "LoadNewLevel")]
		[HarmonyPrefix]
		private static bool ModifyLevel(ref SelectableLevel newLevel)
		{
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Expected O, but got Unknown
			if (!ChatCommands.levelEnemySpawns.ContainsKey(newLevel))
			{
				List<SpawnableEnemyWithRarity> list = new List<SpawnableEnemyWithRarity>();
				foreach (SpawnableEnemyWithRarity enemy in newLevel.Enemies)
				{
					list.Add(enemy);
				}
				ChatCommands.levelEnemySpawns.Add(newLevel, list);
			}
			ChatCommands.levelEnemySpawns.TryGetValue(newLevel, out var value);
			newLevel.Enemies = value;
			foreach (SpawnableEnemyWithRarity enemy2 in newLevel.Enemies)
			{
				Utils.LogInfo("Inside: " + enemy2.enemyType.enemyName);
				if (!ChatCommands.enemyRaritys.ContainsKey(enemy2))
				{
					ChatCommands.enemyRaritys.Add(enemy2, enemy2.rarity);
				}
				ChatCommands.enemyRaritys.TryGetValue(enemy2, out var value2);
				enemy2.rarity = value2;
			}
			foreach (SpawnableEnemyWithRarity outsideEnemy in newLevel.OutsideEnemies)
			{
				Utils.LogInfo("Outside: " + outsideEnemy.enemyType.enemyName);
				if (!ChatCommands.enemyRaritys.ContainsKey(outsideEnemy))
				{
					ChatCommands.enemyRaritys.Add(outsideEnemy, outsideEnemy.rarity);
				}
				ChatCommands.enemyRaritys.TryGetValue(outsideEnemy, out var value3);
				outsideEnemy.rarity = value3;
			}
			foreach (SpawnableEnemyWithRarity enemy3 in newLevel.Enemies)
			{
				if (!ChatCommands.enemyPropCurves.ContainsKey(enemy3))
				{
					ChatCommands.enemyPropCurves.Add(enemy3, enemy3.enemyType.probabilityCurve);
				}
				AnimationCurve value4 = new AnimationCurve();
				ChatCommands.enemyPropCurves.TryGetValue(enemy3, out value4);
				enemy3.enemyType.probabilityCurve = value4;
			}
			return true;
		}

		[HarmonyPatch(typeof(RoundManager), "Start")]
		[HarmonyPrefix]
		private static void SetIsHost()
		{
			Utils.LogInfo("Host Status: " + ((NetworkBehaviour)RoundManager.Instance).NetworkManager.IsHost);
			ChatCommands.isHost = ((NetworkBehaviour)RoundManager.Instance).NetworkManager.IsHost;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Start")]
		[HarmonyPrefix]
		private static void SetDefaultJumpForce(ref PlayerControllerB __instance)
		{
			defaultJumpForce = __instance.jumpForce;
			Utils.LogInfo("Default Jump Force: " + defaultJumpForce);
		}

		[HarmonyPatch(typeof(Application), "get_isEditor")]
		[HarmonyPostfix]
		private static void IsEditorPatch(ref bool __result)
		{
			__result = ChatCommands.EnableDebugModeSetting.Value;
		}
	}
}
namespace ChatCommands.Commands
{
	internal class CommandController
	{
		private static string nullChatMessage = "";

		public static List<CustomChatCommand> Commands { get; } = new List<CustomChatCommand>
		{
			new SpawnEnemyCommand(),
			new SetCustomDeadline(),
			new SpawnScrapCommand(),
			new TeleportCommand(),
			new HelpCommand(),
			new ToggleLights(),
			new GetEnemies(),
			new BuyStuff(),
			new ChangeWeather(),
			new SpawnItem(),
			new GetEnemies(),
			new GetScrap(),
			new CoHost(),
			new GodMode(),
			new GetAlivePlayers(),
			new RevivePlayers(),
			new SpeedHack(),
			new SpawnTruck(),
			new GetItems(),
			new InfiniteAmmo(),
			new GetPosition(),
			new SetMoney(),
			new SpawnMapObject(),
			new TerminalCommand(),
			new ToggleHostCmd(),
			new ToggleOverrideSpawns(),
			new GetCredits()
		};


		[HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")]
		[HarmonyPrefix]
		private static bool ChatCommandsSubmitted(HUDManager __instance)
		{
			string text = __instance.chatTextField.text;
			if (Utility.IsNullOrWhiteSpace(text))
			{
				return true;
			}
			string username = GameNetworkManager.Instance.username;
			ChatCommands.playerwhocalled = Utils.ConvertPlayername(username);
			Utils.LogInfo("Received chat input: " + text);
			if (CheckForCommand(text))
			{
				__instance.chatTextField.text = nullChatMessage;
				GameNetworkManager.Instance.localPlayerController.isTypingChat = false;
				EventSystem.current.SetSelectedGameObject((GameObject)null);
				HUDManager.Instance.PingHUDElement(HUDManager.Instance.Chat, 2f, 1f, 0.2f);
				HUDManager.Instance.chatTextField.text = "";
				((Behaviour)HUDManager.Instance.typingIndicator).enabled = false;
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(HUDManager), "AddPlayerChatMessageClientRpc")]
		[HarmonyPrefix]
		private static bool ReadChatMessage(HUDManager __instance, ref string chatMessage, ref int playerId)
		{
			string playerUsername = __instance.playersManager.allPlayerScripts[playerId].playerUsername;
			Utils.LogInfo("Chat Message: " + chatMessage + " sent by: " + playerUsername);
			bool flag = true;
			if (Utils.IsNetCommand(chatMessage) && ChatCommands.isHost)
			{
				if (!ChatCommands.AllowHostCommands)
				{
					flag = false;
					Utils.LogWarning("Host, but not allowing commands, checking player for allowance");
					foreach (AllowedHostPlayer allowedHostPlayer in ChatCommands.AllowedHostPlayers)
					{
						if (allowedHostPlayer.Name.ToLower().Contains(playerUsername.ToLower()))
						{
							Utils.LogInfo("Player is allowed to send commands");
							flag = true;
							break;
						}
					}
				}
				if (flag)
				{
					string text = Utils.ConvertFromNetCommand(chatMessage);
					if (text.ToLower().Contains("p=@me"))
					{
						ChatCommands.playerwhocalled = Utils.ConvertPlayername(playerUsername);
					}
					Utils.LogInfo("Host, trying to handle command: " + text);
					Utils.DisplayChatMessage(playerUsername + " sent command: " + ChatCommands.PrefixSetting.Value + text);
					if (CheckForCommand(Utils.ConvertFromNetCommand(text)))
					{
						chatMessage = nullChatMessage;
						return false;
					}
					return true;
				}
				Utils.LogWarning("Player not allowed to send commands");
				chatMessage = nullChatMessage;
				return false;
			}
			if (Utils.IsNetHostCommand(chatMessage) && !ChatCommands.isHost)
			{
				string text2 = Utils.ConvertFromNetHostCommand(chatMessage);
				Utils.LogInfo("Recieved command from Host, trying to handle command: " + text2);
				ProcessNetHostCommand(text2);
				if (CheckForCommand(Utils.ConvertFromNetHostCommand(text2)))
				{
					chatMessage = nullChatMessage;
					return false;
				}
			}
			return true;
		}

		private static bool CheckForCommand(string message)
		{
			if (Utility.IsNullOrWhiteSpace(message))
			{
				return false;
			}
			foreach (CustomChatCommand command in Commands)
			{
				if (command.Handle(message))
				{
					return true;
				}
			}
			if (ChatCommands.isHost)
			{
				Utils.LogWarning("Command " + message + " not found.");
			}
			else
			{
				Utils.LogWarning("Command " + message + " not found. Sending to host.");
				Utils.SendCommandToServer(message);
			}
			return false;
		}

		private static void ProcessNetHostCommand(string commandInput)
		{
		}
	}
	internal class CommandInput
	{
		public string Command { get; private set; }

		public List<string> Args { get; private set; } = new List<string>();


		public static CommandInput Parse(string input)
		{
			Regex regex = new Regex(ChatCommands.PrefixSetting.Value + "(\\S+)(?:\\s+(\"([^\"]+)\"|\\S+))*");
			Match match = regex.Match(input);
			if (!match.Success)
			{
				return null;
			}
			CommandInput commandInput = new CommandInput();
			commandInput.Command = match.Groups[1].Value;
			GroupCollection groups = match.Groups;
			CaptureCollection captures = groups[2].Captures;
			for (int i = 0; i < captures.Count; i++)
			{
				commandInput.Args.Add(captures[i].Value.Trim(new char[1] { '"' }));
			}
			return commandInput;
		}
	}
	internal abstract class CustomChatCommand
	{
		public abstract string Name { get; }

		public abstract string Description { get; }

		public abstract string Format { get; }

		public abstract string AltFormat { get; }

		public abstract bool IsHostCommand { get; }

		public bool Handle(string message)
		{
			CommandInput commandInput = CommandInput.Parse(message);
			if (commandInput == null)
			{
				return false;
			}
			if (commandInput.Command != Format.Split(new char[1] { ' ' })[0].Trim(new char[1] { '/' }) && commandInput.Command != AltFormat.Split(new char[1] { ' ' })[0].Trim(new char[1] { '/' }))
			{
				return false;
			}
			if (IsHostCommand && !ChatCommands.isHost)
			{
				Utils.DisplayChatError("You must be the host to use this command. Trying to send this command to the host.");
				Utils.SendCommandToServer(message);
				return true;
			}
			Execute(commandInput);
			return true;
		}

		public abstract void Execute(CommandInput message);
	}
	internal class BuyStuff : CustomChatCommand
	{
		public override string Name => "Buy Stuff";

		public override string Description => "Buy stuff from the shop. Gets delivered via DropShip. (old function, you better use /term buy [itemname] instead)";

		public override string Format => "/buy [itemname]";

		public override string AltFormat => "/buyitem [itemname]";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			string text = "Item Buying";
			string text2 = "";
			Terminal val = Object.FindObjectOfType<Terminal>();
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			List<string> list = new List<string>
			{
				"Walkie-Talkie", "Pro Flashlight", "Normal Flashlight", "Shovel", "Lockpicker", "Stun Grenade", "Boom Box", "Inhaler", "Stun Gun", "Jet Pack",
				"Extension Ladder", "Radar Booster"
			};
			Dictionary<string, int> dictionary = new Dictionary<string, int>
			{
				{ "Walkie-Talkie", 0 },
				{ "Pro Flashlight", 4 },
				{ "Normal Flashlight", 1 },
				{ "Shovel", 2 },
				{ "Lockpicker", 3 },
				{ "Stun Grenade", 5 },
				{ "Boom Box", 6 },
				{ "Inhaler", 7 },
				{ "Stun Gun", 8 },
				{ "Jet Pack", 9 },
				{ "Extension Ladder", 10 },
				{ "Radar Booster", 11 }
			};
			if (message.Args.Count > 0)
			{
				bool flag = false;
				if (message.Args.Count > 1)
				{
					if (!int.TryParse(message.Args[1], out var result))
					{
						ChatCommands.mls.LogInfo((object)("Couldn't parse command [ " + message.Args[1] + " ]"));
						Utils.DisplayChatError("Couldn't parse command [ " + message.Args[1] + " ]");
						return;
					}
					foreach (string item in list)
					{
						if (item.ToLower().Contains(message.Args[0]))
						{
							flag = true;
							List<int> list2 = new List<int>();
							for (int i = 0; i < result; i++)
							{
								list2.Add(dictionary[item]);
							}
							val.BuyItemsServerRpc(list2.ToArray(), val.groupCredits, 0);
							text2 = "Bought " + result + " " + item + "s";
							break;
						}
					}
					if (!flag)
					{
						Utils.DisplayChatError("Couldn't figure out what [ " + message.Args[0] + " ] was.");
						return;
					}
				}
				if (!flag)
				{
					bool flag2 = false;
					foreach (string item2 in list)
					{
						if (item2.ToLower().Contains(message.Args[0]))
						{
							flag2 = true;
							int[] array = new int[1] { dictionary[item2] };
							val.BuyItemsServerRpc(array, val.groupCredits, 0);
							text2 = "Bought " + 1 + " " + item2;
						}
					}
					if (!flag2)
					{
						ChatCommands.mls.LogInfo((object)("Couldn't figure out what [ " + message.Args[0] + " ] was. Trying via int parser."));
					}
					if (!int.TryParse(message.Args[0], out var result2))
					{
						ChatCommands.mls.LogInfo((object)("Couldn't figure out what [ " + message.Args[0] + " ] was. Int parser failed, please try again."));
						Utils.DisplayChatError("Couldn't figure out what [ " + message.Args[0] + " ] was. Int parser failed, please try again.");
						return;
					}
					int[] array2 = new int[1] { result2 };
					val.BuyItemsServerRpc(array2, val.groupCredits, 0);
					text2 = "Bought item with ID [" + result2 + "]";
				}
			}
			Utils.DisplayChatMessage(text + "\n" + text2);
		}
	}
	internal class ChangeWeather : CustomChatCommand
	{
		public override string Name => "Change Weather";

		public override string Description => "Change Weather to a specific type.";

		public override string Format => "/changeweather [weathername]";

		public override string AltFormat => "/chwe [weathername]";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			string text = "Weather Change";
			string text2 = "";
			if (message.Args.Count > 0)
			{
				switch (message.Args[0].ToLower())
				{
				case "rain":
					Utils.GetCurrentRound().timeScript.currentLevelWeather = (LevelWeatherType)1;
					break;
				case "eclipse":
					Utils.GetCurrentRound().timeScript.currentLevelWeather = (LevelWeatherType)5;
					break;
				case "flood":
					Utils.GetCurrentRound().timeScript.currentLevelWeather = (LevelWeatherType)4;
					break;
				case "dust":
				case "fog":
				case "mist":
					Utils.GetCurrentRound().timeScript.currentLevelWeather = (LevelWeatherType)0;
					break;
				case "storm":
					Utils.GetCurrentRound().timeScript.currentLevelWeather = (LevelWeatherType)2;
					break;
				case "none":
					Utils.GetCurrentRound().timeScript.currentLevelWeather = (LevelWeatherType)(-1);
					break;
				default:
					Utils.LogInfo("Couldn't figure out what [ " + message.Args[1] + " ] was.");
					text2 = "Couldn't figure out what [ " + message.Args[1] + " ] was.";
					break;
				}
				text2 = "tried to change the weather to " + message.Args[0];
			}
			Utils.DisplayChatMessage(text + "\n" + text2);
		}
	}
	internal class CoHost : CustomChatCommand
	{
		public override string Name => "Give Co-Host to a player";

		public override string Description => "Gives co-host to a player, which allows them to use host commands, when you turned them off for everyone else.";

		public override string Format => "/cohost [playername]";

		public override string AltFormat => "/hostcmd [playername]";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			string name = message.Args[0];
			name = Utils.ConvertPlayername(name);
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			bool flag = false;
			PlayerControllerB[] array = allPlayerScripts;
			foreach (PlayerControllerB val in array)
			{
				if (Utils.ConvertPlayername(val.playerUsername).ToLower().Contains(name.ToLower()))
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				ChatCommands.mls.LogWarning((object)"Player not found");
				Utils.DisplayChatError("Player " + name + " not found!!!");
				return;
			}
			bool flag2 = false;
			foreach (AllowedHostPlayer allowedHostPlayer in ChatCommands.AllowedHostPlayers)
			{
				if (Utils.ConvertPlayername(allowedHostPlayer.Name).ToLower().Contains(name.ToLower()))
				{
					allowedHostPlayer.AllowHostCMD = !allowedHostPlayer.AllowHostCMD;
					Utils.DisplayChatMessage("Host Commands for " + name + " set to" + allowedHostPlayer.AllowHostCMD);
					flag2 = true;
					break;
				}
			}
			if (!flag2)
			{
				ChatCommands.AllowedHostPlayers.Add(new AllowedHostPlayer(name, isActive: true));
				Utils.DisplayChatMessage("Host Commands for " + name + " set to true");
			}
		}
	}
	internal class GetAlivePlayers : CustomChatCommand
	{
		public override string Name => "Get Alive Players";

		public override string Description => "Returns a list of all players and if they are alive or dead.";

		public override string Format => "/getalive";

		public override string AltFormat => "/getap";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			string text = "";
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				text = text + val.playerUsername + " is " + (val.isPlayerDead ? "Dead" : "Alive") + "\n";
			}
			Utils.DisplayChatMessage(text);
		}
	}
	internal class GetCredits : CustomChatCommand
	{
		public override string Name => "View Credits";

		public override string Description => "Shows the credits for the ChatCommands mod.";

		public override string Format => "/getcredits";

		public override string AltFormat => "/credits";

		public override bool IsHostCommand => false;

		public override void Execute(CommandInput message)
		{
			Utils.DisplayChatMessage("<color=#FF00FF>Credits:</color>\nChatCommands by Toemmsen96 and Chrigi. Visit the GitHub page for more information and to report issues:\n<color=#0000FF>github.com/Toemmsen96/ChatCommands/</color>");
		}
	}
	internal class GetEnemies : CustomChatCommand
	{
		public override string Name => "Get Spawnable Enemies";

		public override string Description => "Gets the spawnable enemies for the current level.";

		public override string Format => "/getenemies";

		public override string AltFormat => "/enemies";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			string text = "";
			SelectableLevel currentLevel = Utils.GetCurrentLevel();
			string text2 = "Enemies:";
			string text3 = "";
			if ((Object)(object)currentLevel == (Object)null)
			{
				Utils.DisplayChatError("Level is null.");
			}
			if (ChatCommands.levelEnemySpawns == null)
			{
				Utils.DisplayChatError("levelEnemySpawns is null.");
			}
			if (ChatCommands.levelEnemySpawns.TryGetValue(currentLevel, out var value))
			{
				currentLevel.Enemies = value;
				text += "<color=#FF00FF>Inside: </color><color=#FFFF00>";
				text3 = "<color=#FF00FF>Inside: </color><color=#FFFF00>";
				if (currentLevel.Enemies.Count == 0)
				{
					text += "None";
					text3 += "None";
				}
				else
				{
					foreach (SpawnableEnemyWithRarity enemy in currentLevel.Enemies)
					{
						Utils.LogInfo("Inside: " + enemy.enemyType.enemyName);
						text = text + enemy.enemyType.enemyName + ", ";
						text3 = text3 + enemy.enemyType.enemyName + ", ";
					}
				}
				text += "\n</color><color=#FF00FF>Outside: </color>";
				text3 += "\n</color><color=#FF00FF>Outside: </color>";
				if (currentLevel.OutsideEnemies.Count == 0)
				{
					text += "None";
					text3 += "None";
				}
				else
				{
					foreach (SpawnableEnemyWithRarity outsideEnemy in currentLevel.OutsideEnemies)
					{
						Utils.LogInfo("Outside: " + outsideEnemy.enemyType.enemyName);
						text = text + outsideEnemy.enemyType.enemyName + ", ";
						text3 = text3 + outsideEnemy.enemyType.enemyName + ", ";
					}
				}
				Utils.DisplayChatMessage(text);
			}
			Utils.DisplayChatMessage(text2 + "\n" + text3);
		}
	}
	internal class GetItems : CustomChatCommand
	{
		public override string Name => "Get ALL Spawnable Items";

		public override string Description => "Gets the spawnable items you can spawn with /spawnitem or /spwitm.";

		public override string Format => "/getitems";

		public override string AltFormat => "/items";

		public override bool IsHostCommand => false;

		public override void Execute(CommandInput message)
		{
			string text = "<color=yellow>Spawnable Items:</color>\n";
			foreach (Item items in StartOfRound.Instance.allItemsList.itemsList)
			{
				text = text + ((Object)items).name + "\n";
			}
			Utils.DisplayChatMessage(text);
		}
	}
	internal class GetPosition : CustomChatCommand
	{
		public override string Name => "Get your current Position";

		public override string Description => "Returns your current position.";

		public override string Format => "/getposition";

		public override string AltFormat => "/getpos";

		public override bool IsHostCommand => false;

		public override void Execute(CommandInput message)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			string text = "<color=yellow>Current Position:</color>\n";
			Vector3 position = ((Component)StartOfRound.Instance.localPlayerController).transform.position;
			text = text + "X: " + position.x + "\n";
			text = text + "Y: " + position.y + "\n";
			text = text + "Z: " + position.z + "\n";
			Utils.DisplayChatMessage(text);
		}
	}
	internal class GetScrap : CustomChatCommand
	{
		public override string Name => "Get Spawnable Scrap Items";

		public override string Description => "Gets the spawnable scrap items for the current level.";

		public override string Format => "/getscrap";

		public override string AltFormat => "/scrap";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			SelectableLevel currentLevel = Utils.GetCurrentLevel();
			if ((Object)(object)currentLevel == (Object)null)
			{
				Utils.DisplayChatError("Level is null.");
				return;
			}
			int count = Utils.GetCurrentLevel().spawnableScrap.Count;
			string text = ((Object)Utils.GetCurrentLevel().spawnableScrap[0].spawnableItem.spawnPrefab).name;
			for (int i = 1; i < count; i++)
			{
				text += ", ";
				text += ((Object)Utils.GetCurrentLevel().spawnableScrap[i].spawnableItem.spawnPrefab).name;
			}
			HUDManager.Instance.DisplayTip("Spawnable Scrap", text, false, false, "LC_Tip1");
			Utils.DisplayChatMessage("Spawnable Scrap: " + text);
		}
	}
	internal class GodMode : CustomChatCommand
	{
		private static bool isGod;

		public override string Name => "Toggle God Mode";

		public override string Description => "Toggles if invincibility is enabled.";

		public override string Format => "/godmode";

		public override string AltFormat => "/god";

		public override bool IsHostCommand => false;

		public override void Execute(CommandInput message)
		{
			if (ChatCommands.isHost)
			{
				isGod = !isGod;
				Utils.SendHostCommand(message.Command);
			}
			else
			{
				isGod = !isGod;
			}
			Utils.DisplayChatMessage("God Mode: " + (isGod ? "Enabled" : "Disabled"));
		}

		[HarmonyPatch(typeof(PlayerControllerB), "AllowPlayerDeath")]
		[HarmonyPrefix]
		private static bool OverrideDeath()
		{
			return !isGod;
		}

		[HarmonyPatch(typeof(MouthDogAI), "OnCollideWithPlayer")]
		[HarmonyPrefix]
		private static bool OverrideDeath2()
		{
			return !isGod;
		}

		[HarmonyPatch(typeof(ForestGiantAI), "GrabPlayerServerRpc")]
		[HarmonyPrefix]
		private static bool OverrideDeath3()
		{
			return !isGod;
		}
	}
	internal class HelpCommand : CustomChatCommand
	{
		public override string Name => "View Help";

		public override string Description => "Displays a list of available commands with their format. Use <color=#00FFFF>/help [command]</color> to get more information about a specific command.";

		public override string Format => "/help ([command])";

		public override string AltFormat => "/h ([command])";

		public override bool IsHostCommand => false;

		public override void Execute(CommandInput message)
		{
			if (message.Args.Count == 0)
			{
				string text = "";
				string text2 = "";
				foreach (CustomChatCommand command in CommandController.Commands)
				{
					text = text + "<color=#00FFFF>" + command.Format + "</color> - Alt: " + command.AltFormat + "\n";
					text2 = text2 + command.Name + ": Format: " + command.Format + " - Alt: " + command.AltFormat + "\nDescription: " + command.Description + ", " + (command.IsHostCommand ? "For Host only" : "Host and Client") + "\n";
				}
				Utils.LogInfo(text2);
				Utils.DisplayChatMessage(text);
				return;
			}
			string value = message.Args[0].ToLower();
			CustomChatCommand customChatCommand = null;
			foreach (CustomChatCommand command2 in CommandController.Commands)
			{
				if (command2.Format.ToLower().Contains(value) || command2.AltFormat.ToLower().Contains(value) || command2.Name.ToLower().Contains(value))
				{
					customChatCommand = command2;
					break;
				}
			}
			if (customChatCommand != null)
			{
				Utils.DisplayChatMessage($"<color=#771615>Command</color>: <color=#00FFFF>{customChatCommand.Name}</color>\n<color=#771615>Description</color>: {customChatCommand.Description}\n<color=#771615>Format</color>: {customChatCommand.Format}\n<color=#771615>Alternative Format</color>: {customChatCommand.AltFormat}\nHost only Command: {customChatCommand.IsHostCommand}");
			}
			else
			{
				Utils.DisplayChatError("Command not found.");
			}
		}
	}
	internal class InfiniteAmmo : CustomChatCommand
	{
		private static bool EnableInfiniteAmmo;

		public override string Name => "Infinite Ammo";

		public override string Description => "Toggle Infinite Ammo.";

		public override string Format => "/infammo";

		public override string AltFormat => "/ammo";

		public override bool IsHostCommand => false;

		public override void Execute(CommandInput message)
		{
			EnableInfiniteAmmo = !EnableInfiniteAmmo;
			Utils.DisplayChatMessage("Infinite Ammo: " + (EnableInfiniteAmmo ? "Enabled" : "Disabled"));
			if (ChatCommands.isHost)
			{
				Utils.SendHostCommand(message.Command);
			}
		}

		[HarmonyPatch(typeof(ShotgunItem), "ItemActivate")]
		[HarmonyPrefix]
		private static void ItemActivateGunPatch(ref ShotgunItem __instance)
		{
			if (EnableInfiniteAmmo)
			{
				__instance.shellsLoaded = 2;
			}
		}
	}
	internal class RevivePlayers : CustomChatCommand
	{
		public override string Name => "Revive all players";

		public override string Description => "Revives everyone.";

		public override string Format => "/revive";

		public override string AltFormat => "/rev";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			if (message.Args.Count == 0)
			{
				StartOfRound.Instance.ReviveDeadPlayers();
			}
		}
	}
	internal class SetCustomDeadline : CustomChatCommand
	{
		private static bool EnableCustomDeadline = false;

		private static int CustomDeadline = 6;

		private static bool SetNewCustomDeadline = false;

		public override string Name => "Set Custom Deadline";

		public override string Description => "Sets a custom deadline for the game. If no argument is provided, the custom deadline will be toggled.";

		public override string Format => "/deadline [days]";

		public override string AltFormat => "/dl [days]";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			if (message.Args.Count > 0)
			{
				if (int.TryParse(message.Args[0], out var result))
				{
					CustomDeadline = result;
					Utils.DisplayChatMessage("Deadline set to " + CustomDeadline + " days");
					EnableCustomDeadline = true;
					SetNewCustomDeadline = true;
				}
				else
				{
					CustomDeadline = int.MinValue;
					Utils.DisplayChatMessage("Deadline set to default");
					EnableCustomDeadline = false;
					SetNewCustomDeadline = false;
				}
			}
			else
			{
				EnableCustomDeadline = !EnableCustomDeadline;
				Utils.DisplayChatMessage("Deadline set to" + (EnableCustomDeadline ? "custom" : "default"));
			}
		}

		[HarmonyPatch(typeof(TimeOfDay), "SetBuyingRateForDay")]
		[HarmonyPrefix]
		private static void PatchDeadline(TimeOfDay __instance)
		{
			if (ChatCommands.isHost && EnableCustomDeadline && SetNewCustomDeadline)
			{
				__instance.quotaVariables.deadlineDaysAmount = CustomDeadline;
				__instance.timeUntilDeadline = (float)(__instance.quotaVariables.deadlineDaysAmount + CustomDeadline) * __instance.totalTime;
				TimeOfDay.Instance.timeUntilDeadline = (int)(TimeOfDay.Instance.totalTime * (float)TimeOfDay.Instance.quotaVariables.deadlineDaysAmount);
				TimeOfDay.Instance.SyncTimeClientRpc(__instance.globalTime, (int)__instance.timeUntilDeadline);
				((TMP_Text)StartOfRound.Instance.deadlineMonitorText).text = "DEADLINE:\n " + TimeOfDay.Instance.daysUntilDeadline;
				SetNewCustomDeadline = false;
			}
			else if (ChatCommands.isHost && EnableCustomDeadline)
			{
				StartOfRound.Instance.companyBuyingRate = 1f - (float)(TimeOfDay.Instance.daysUntilDeadline / CustomDeadline);
				if (TimeOfDay.Instance.daysUntilDeadline == 0)
				{
					StartOfRound.Instance.companyBuyingRate = 1f;
				}
			}
		}

		[HarmonyPatch(typeof(TimeOfDay), "SetNewProfitQuota")]
		[HarmonyPostfix]
		private static void ResetDeadline(TimeOfDay __instance)
		{
			if (ChatCommands.isHost && EnableCustomDeadline && !SetNewCustomDeadline)
			{
				SetNewCustomDeadline = true;
			}
		}
	}
	internal class SetMoney : CustomChatCommand
	{
		private static int customMoney;

		private static bool infMoney;

		public override string Name => "Set Money";

		public override string Description => "Set Terminal Money to defined value, or without value to toggle infinite money.";

		public override string Format => "/setmoney ([value])";

		public override string AltFormat => "/money ([value])";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			if (message.Args.Count == 1)
			{
				if (int.TryParse(message.Args[0], out var result))
				{
					customMoney = result;
					Terminal val = Object.FindObjectOfType<Terminal>();
					val.groupCredits = customMoney;
					Utils.DisplayChatMessage("Money set to: " + customMoney);
				}
				else
				{
					Utils.DisplayChatError("Invalid money value");
				}
			}
			else
			{
				infMoney = !infMoney;
				Utils.DisplayChatMessage("Infinite Money: " + (infMoney ? "Enabled" : "Disabled"));
			}
		}

		[HarmonyPatch(typeof(Terminal), "RunTerminalEvents")]
		[HarmonyPostfix]
		private static void InfiniteCredits(ref int ___groupCredits)
		{
			if (ChatCommands.isHost && infMoney)
			{
				___groupCredits = 99999;
			}
		}
	}
	internal class SpawnEnemyCommand : CustomChatCommand
	{
		public override string Name => "Spawn Enemy";

		public override string Description => "Spawns an enemy at the specified location. Either use the player's position or specify a position. Position, state and amount are optional. Use them with the following format: position=@(playername/me) amount=(number) state=(alive/dead)";

		public override string Format => "/spawnenemy [enemyname] ([p=position]) ([a=amount]) ([s=state])";

		public override string AltFormat => "/spweny [enemyname] ([a=amount]) ([s=state]) ([p=position])";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			string text = "Spawned Enemies";
			string text2 = "";
			if ((Object)(object)Utils.GetCurrentLevel() == (Object)null || ChatCommands.levelEnemySpawns == null || Utils.GetCurrentLevel().Enemies == null)
			{
				text = "Command";
				text2 = (((Object)(object)Utils.GetCurrentLevel() == (Object)null) ? "Unable to send command since currentLevel is null." : "Unable to send command since levelEnemySpawns is null.");
				Utils.DisplayChatError(text + "\n" + text2);
			}
			if (message.Args.Count < 1)
			{
				text = "Command Error";
				text2 = "Missing Arguments For Spawn\n'/spawnenemy <name> (amount=<amount>) (state=<state>) (position={random, @me, @<playername>})";
				Utils.DisplayChatError(text + "\n" + text2);
			}
			int num = 1;
			string text3 = "alive";
			Vector3 val = Vector3.zero;
			string text4 = "random";
			string[] array = message.Args.Skip(1).ToArray();
			string text5 = message.Args[0];
			string[] array2 = array;
			foreach (string text6 in array2)
			{
				string[] array3 = text6.Split(new char[1] { '=' });
				switch (array3[0])
				{
				case "a":
				case "amount":
					num = int.Parse(array3[1]);
					Utils.LogInfo($"{num}");
					break;
				case "s":
				case "state":
					text3 = array3[1];
					Utils.LogInfo(text3);
					break;
				case "p":
				case "position":
					text4 = array3[1];
					Utils.LogInfo(text4);
					break;
				}
			}
			if (text4 != "random")
			{
				val = Utils.CalculateSpawnPosition(text4);
				if (val == Vector3.zero && text4 != "random")
				{
					ChatCommands.mls.LogWarning((object)"Position Invalid, Using Default 'random'");
					text4 = "random";
				}
			}
			if (text5.Length <= 1)
			{
				return;
			}
			bool flag = false;
			string text7 = "";
			foreach (SpawnableEnemyWithRarity enemy in Utils.GetCurrentLevel().Enemies)
			{
				if (!enemy.enemyType.enemyName.ToLower().Contains(text5.ToLower()))
				{
					continue;
				}
				try
				{
					flag = true;
					text7 = enemy.enemyType.enemyName;
					if (text4 == "random")
					{
						SpawnEnemy(enemy, num, inside: true, new Vector3(0f, 0f, 0f));
					}
					else
					{
						SpawnEnemy(enemy, num, inside: true, val);
					}
					Utils.LogInfo("Spawned " + enemy.enemyType.enemyName);
				}
				catch
				{
					Utils.LogInfo("Could not spawn enemy");
				}
				text2 = "Spawned: " + text7;
				break;
			}
			if (flag)
			{
				return;
			}
			foreach (SpawnableEnemyWithRarity outsideEnemy in Utils.GetCurrentLevel().OutsideEnemies)
			{
				if (!outsideEnemy.enemyType.enemyName.ToLower().Contains(text5.ToLower()))
				{
					continue;
				}
				try
				{
					flag = true;
					text7 = outsideEnemy.enemyType.enemyName;
					Utils.LogInfo(outsideEnemy.enemyType.enemyName);
					Utils.LogInfo("The index of " + outsideEnemy.enemyType.enemyName + " is " + Utils.GetCurrentLevel().OutsideEnemies.IndexOf(outsideEnemy));
					if (text4 == "random")
					{
						SpawnEnemy(outsideEnemy, num, inside: false, new Vector3(0f, 0f, 0f));
					}
					else
					{
						SpawnEnemy(outsideEnemy, num, inside: false, val);
					}
					Utils.LogInfo("Spawned " + outsideEnemy.enemyType.enemyName);
				}
				catch (Exception ex)
				{
					Utils.LogInfo("Could not spawn enemy");
					Utils.LogInfo("The game tossed an error: " + ex.Message);
				}
				text2 = "Spawned " + num + " " + text7 + ((num > 1) ? "s" : "");
				break;
			}
		}

		internal static void SpawnEnemy(SpawnableEnemyWithRarity enemy, int amount, bool inside, Vector3 location)
		{
			//IL_0013: 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)
			//IL_002d: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			if (!ChatCommands.isHost)
			{
				return;
			}
			if (location.x != 0f && location.y != 0f && location.z != 0f && inside)
			{
				try
				{
					for (int i = 0; i < amount; i++)
					{
						Utils.GetCurrentRound().SpawnEnemyOnServer(location, 0f, Utils.GetCurrentLevel().Enemies.IndexOf(enemy));
					}
					return;
				}
				catch
				{
					Utils.LogWarning("Failed to spawn enemies, check your command.");
					return;
				}
			}
			if (location.x != 0f && location.y != 0f && location.z != 0f && !inside)
			{
				try
				{
					int j;
					for (j = 0; j < amount; j++)
					{
						Object.Instantiate<GameObject>(Utils.GetCurrentLevel().OutsideEnemies[Utils.GetCurrentLevel().OutsideEnemies.IndexOf(enemy)].enemyType.enemyPrefab, location, Quaternion.Euler(Vector3.zero)).gameObject.GetComponentInChildren<NetworkObject>().Spawn(true);
					}
					Utils.LogInfo($"You wanted to spawn: {amount} enemies");
					string text = j.ToString();
					Vector3 val = location;
					Utils.LogInfo("Spawned an enemy. Total Spawned: " + text + "at position:" + ((object)(Vector3)(ref val)).ToString());
					return;
				}
				catch
				{
					Utils.LogInfo("Failed to spawn enemies, check your command.");
					return;
				}
			}
			if (inside)
			{
				try
				{
					int k;
					for (k = 0; k < amount; k++)
					{
						Utils.GetCurrentRound().SpawnEnemyOnServer(Utils.GetCurrentRound().allEnemyVents[Random.Range(0, Utils.GetCurrentRound().allEnemyVents.Length)].floorNode.position, Utils.GetCurrentRound().allEnemyVents[k].floorNode.eulerAngles.y, Utils.GetCurrentLevel().Enemies.IndexOf(enemy));
					}
					Utils.LogInfo($"You wanted to spawn: {amount} enemies");
					Utils.LogInfo("Total Spawned: " + k);
					return;
				}
				catch
				{
					Utils.LogInfo("Failed to spawn enemies, check your command.");
					return;
				}
			}
			int l;
			for (l = 0; l < amount; l++)
			{
				Object.Instantiate<GameObject>(Utils.GetCurrentLevel().OutsideEnemies[Utils.GetCurrentLevel().OutsideEnemies.IndexOf(enemy)].enemyType.enemyPrefab, GameObject.FindGameObjectsWithTag("OutsideAINode")[Random.Range(0, GameObject.FindGameObjectsWithTag("OutsideAINode").Length - 1)].transform.position, Quaternion.Euler(Vector3.zero)).gameObject.GetComponentInChildren<NetworkObject>().Spawn(true);
			}
			Utils.LogInfo($"You wanted to spawn: {amount} enemies");
			Utils.LogInfo("Total Spawned: " + l);
		}
	}
	internal class SpawnItem : CustomChatCommand
	{
		public override string Name => "Spawn Item";

		public override string Description => "Spawns Items at a specified position or at a random position. Args are optional, use them like this: p=@me a=5 v=1234.\n Note: Value doesnt work for everything.";

		public override string Format => "/spawnitem [itemname] ([p=position]) ([a=amount]) ([v=value])";

		public override string AltFormat => "/spwitm [itemname] ([a=amount]) ([p=position]) ([v=value])";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			//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_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			string itemToSpawn = message.Args[0].ToLower();
			int num = 1;
			Vector3 val = Vector3.zero;
			string text = "random";
			int num2 = 1000;
			IEnumerable<string> enumerable = message.Args.Skip(1);
			foreach (string item in enumerable)
			{
				string[] array = item.Split(new char[1] { '=' });
				switch (array[0])
				{
				case "a":
				case "amount":
					num = int.Parse(array[1]);
					ChatCommands.mls.LogInfo((object)$"Amount {num}");
					break;
				case "p":
				case "position":
					text = array[1];
					ChatCommands.mls.LogInfo((object)text);
					break;
				case "v":
				case "value":
					num2 = int.Parse(array[1]);
					ChatCommands.mls.LogInfo((object)$"Value {num2}");
					break;
				}
			}
			if (text != "random")
			{
				val = Utils.CalculateSpawnPosition(text);
				if (val == Vector3.zero && text != "random")
				{
					ChatCommands.mls.LogWarning((object)"Position Invalid, Using Default 'random'");
					text = "random";
				}
			}
			ChatCommands.SpawnItems(val, itemToSpawn, num2, num);
		}
	}
	internal class SpawnMapObject : CustomChatCommand
	{
		private static GameObject minePrefab;

		private static GameObject turretPrefab;

		private static GameObject spikeRoofPrefab;

		public override string Name => "Spawn Map Object";

		public override string Description => "Spawns Map Object at the specified location. Either use the player's position or specify a position. Position and amount are optional. Use them with the following format: position=@(playername/me) amount=(number)";

		public override string Format => "/spawnobject [objectname] ([p=position]) ([a=amount])";

		public override string AltFormat => "/spwobj [objectname] ([a=amount]) ([p=position])";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0410: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_0523: Unknown result type (might be due to invalid IL or missing references)
			//IL_0542: Unknown result type (might be due to invalid IL or missing references)
			//IL_0543: Unknown result type (might be due to invalid IL or missing references)
			//IL_0571: Unknown result type (might be due to invalid IL or missing references)
			//IL_0572: Unknown result type (might be due to invalid IL or missing references)
			//IL_0515: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ee: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Utils.GetCurrentLevel() == (Object)null || Utils.GetCurrentLevel().spawnableMapObjects == null)
			{
				Utils.LogError("Unable to send command since currentLevel or spawnableMapObjects is null.");
				Utils.DisplayChatError("Unable to send command since currentLevel or spawnableMapObjects is null.");
				return;
			}
			if (message.Args.Count < 1)
			{
				Utils.LogError("Missing Arguments For Spawn\n'/spawnmapobj <name> (amount=<amount>) (position={random, @me, @<playername>})");
				Utils.DisplayChatError("Missing Arguments For Spawn\n'/spawnmapobj <name> (amount=<amount>) (position={random, @me, @<playername>})");
				return;
			}
			string text = message.Args[0].ToLower();
			int num = 1;
			Vector3 val = Vector3.zero;
			string text2 = "random";
			IEnumerable<string> enumerable = message.Args.Skip(1);
			foreach (string item in enumerable)
			{
				string[] array = item.Split(new char[1] { '=' });
				switch (array[0])
				{
				case "a":
				case "amount":
					num = int.Parse(array[1]);
					Utils.LogInfo($"Amount {num}");
					break;
				case "p":
				case "position":
					text2 = array[1];
					Utils.LogInfo(text2);
					break;
				}
			}
			if (text2 != "random")
			{
				val = Utils.CalculateSpawnPosition(text2);
				if (val == Vector3.zero && text2 != "random")
				{
					Utils.LogWarning("Position Invalid, Using Default 'random'");
					text2 = "random";
				}
			}
			Vector3 val2;
			if (text == "mine" || text == "landmine")
			{
				if ((Object)(object)minePrefab == (Object)null)
				{
					Utils.LogWarning("Mine not found");
					return;
				}
				for (int i = 0; i < num; i++)
				{
					if (text2 == "random")
					{
						val = ((!(Random.value > 0.5f)) ? GameObject.FindGameObjectsWithTag("OutsideAINode")[Random.Range(0, GameObject.FindGameObjectsWithTag("OutsideAINode").Length)].transform.position : Utils.GetCurrentRound().allEnemyVents[Random.Range(0, Utils.GetCurrentRound().allEnemyVents.Length)].floorNode.position);
					}
					val2 = val;
					Utils.LogInfo("Spawning mine at position:" + ((object)(Vector3)(ref val2)).ToString());
					GameObject val3 = Object.Instantiate<GameObject>(minePrefab, val, Quaternion.identity, Utils.GetCurrentRound().mapPropsContainer.transform);
					val3.GetComponent<NetworkObject>().Spawn(true);
					val2 = val;
					Utils.DisplayChatMessage("Spawned mine at position:" + ((object)(Vector3)(ref val2)).ToString());
				}
				return;
			}
			switch (text)
			{
			case "turret":
			{
				if ((Object)(object)turretPrefab == (Object)null)
				{
					Utils.LogWarning("Turret not found");
					break;
				}
				for (int k = 0; k < num; k++)
				{
					if (text2 == "random")
					{
						val = ((!(Random.value > 0.5f)) ? GameObject.FindGameObjectsWithTag("OutsideAINode")[Random.Range(0, GameObject.FindGameObjectsWithTag("OutsideAINode").Length)].transform.position : Utils.GetCurrentRound().allEnemyVents[Random.Range(0, Utils.GetCurrentRound().allEnemyVents.Length)].floorNode.position);
					}
					val2 = val;
					Utils.LogInfo("Spawning turret at position:" + ((object)(Vector3)(ref val2)).ToString());
					GameObject val5 = Object.Instantiate<GameObject>(turretPrefab, val, Quaternion.identity, Utils.GetCurrentRound().mapPropsContainer.transform);
					val5.GetComponent<NetworkObject>().Spawn(true);
					val2 = val;
					Utils.DisplayChatMessage("Spawned turret at position:" + ((object)(Vector3)(ref val2)).ToString());
				}
				break;
			}
			default:
				if (!(text == "trap"))
				{
					Utils.LogWarning("Object not found");
					Utils.DisplayChatError("Object not found");
					break;
				}
				goto case "spikeroof";
			case "spikeroof":
			case "spike":
			{
				if ((Object)(object)spikeRoofPrefab == (Object)null)
				{
					Utils.LogWarning("Spike Roof not found");
					break;
				}
				for (int j = 0; j < num; j++)
				{
					if (text2 == "random")
					{
						val = ((!(Random.value > 0.5f)) ? GameObject.FindGameObjectsWithTag("OutsideAINode")[Random.Range(0, GameObject.FindGameObjectsWithTag("OutsideAINode").Length)].transform.position : Utils.GetCurrentRound().allEnemyVents[Random.Range(0, Utils.GetCurrentRound().allEnemyVents.Length)].floorNode.position);
					}
					val2 = val;
					Utils.LogInfo("Spawning spike roof at position:" + ((object)(Vector3)(ref val2)).ToString());
					GameObject val4 = Object.Instantiate<GameObject>(spikeRoofPrefab, val, Quaternion.identity, Utils.GetCurrentRound().mapPropsContainer.transform);
					val4.GetComponent<NetworkObject>().Spawn(true);
					val2 = val;
					Utils.DisplayChatMessage("Spawned spike roof at position:" + ((object)(Vector3)(ref val2)).ToString());
				}
				break;
			}
			}
		}

		public void AddToSpawnableMapObjects(SpawnableMapObject newObject)
		{
			SpawnableMapObject[] array = (SpawnableMapObject[])(object)new SpawnableMapObject[RoundManager.Instance.currentLevel.spawnableMapObjects.Length + 1];
			for (int i = 0; i < RoundManager.Instance.currentLevel.spawnableMapObjects.Length; i++)
			{
				array[i] = RoundManager.Instance.currentLevel.spawnableMapObjects[i];
			}
			array[RoundManager.Instance.currentLevel.spawnableMapObjects.Length] = newObject;
			RoundManager.Instance.currentLevel.spawnableMapObjects = array;
		}

		[HarmonyPatch(typeof(RoundManager), "FinishGeneratingNewLevelClientRpc")]
		[HarmonyPrefix]
		private static void GetRoundManagerRef(ref RoundManager __instance)
		{
			if (!ChatCommands.isHost)
			{
				return;
			}
			Utils.LogInfo("Host, getting mine ref...");
			Landmine[] source = Object.FindObjectsOfType<Landmine>();
			Utils.LogInfo("Found: " + source.Count() + " Mines on this level");
			Turret[] source2 = Object.FindObjectsOfType<Turret>();
			Utils.LogInfo("Found: " + source2.Count() + " Turrets on this level");
			SpawnableMapObject[] spawnableMapObjects = __instance.currentLevel.spawnableMapObjects;
			foreach (SpawnableMapObject val in spawnableMapObjects)
			{
				Utils.LogInfo("Found: " + ((object)val.prefabToSpawn).ToString());
				if (((Object)val.prefabToSpawn).name.ToLower().Contains("turret"))
				{
					turretPrefab = val.prefabToSpawn;
					Utils.LogInfo("Found Turret");
				}
				if (((Object)val.prefabToSpawn).name.ToLower().Contains("mine"))
				{
					minePrefab = val.prefabToSpawn;
					Utils.LogInfo("Found Mine");
				}
				if (((Object)val.prefabToSpawn).name.ToLower().Contains("spikeroof"))
				{
					spikeRoofPrefab = val.prefabToSpawn;
					Utils.LogInfo("Found Spike Roof");
				}
			}
		}
	}
	internal class SpawnScrapCommand : CustomChatCommand
	{
		public override string Name => "Spawn Scrap";

		public override string Description => "Spawns Scrap at the specified location. Either use the player's position or specify a position. Position, value and amount are optional. Use them with the following format: position=@(playername/me) amount=(number) value=(number)";

		public override string Format => "/spawnscrap [scrapname] ([p=position]) ([a=amount]) ([v=value])";

		public override string AltFormat => "/spwscr [scrapname] ([a=amount]) ([v=value]) ([p=position])";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			//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_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_055c: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			//IL_057f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0581: Unknown result type (might be due to invalid IL or missing references)
			//IL_058a: Unknown result type (might be due to invalid IL or missing references)
			//IL_058c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0591: Unknown result type (might be due to invalid IL or missing references)
			//IL_0521: Unknown result type (might be due to invalid IL or missing references)
			//IL_0532: Unknown result type (might be due to invalid IL or missing references)
			//IL_0537: Unknown result type (might be due to invalid IL or missing references)
			//IL_053c: Unknown result type (might be due to invalid IL or missing references)
			//IL_054d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0552: Unknown result type (might be due to invalid IL or missing references)
			//IL_0557: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_061a: Unknown result type (might be due to invalid IL or missing references)
			//IL_061c: Unknown result type (might be due to invalid IL or missing references)
			string text = "";
			string text2 = "";
			if ((Object)(object)Utils.GetCurrentLevel() == (Object)null)
			{
				Utils.DisplayChatError("Unable to send command since currentLevel is null.");
				return;
			}
			if (message.Args.Count < 1)
			{
				text = "Command Error";
				text2 = "Missing Arguments For Spawn\n'/spawnscrap <name> (amount=<amount>) (position={random, @me, @<playername>})";
				Utils.DisplayChatError(text + "\n" + text2);
				HUDManager.Instance.DisplayTip(text, text2, true, false, "LC_Tip1");
				return;
			}
			string text3 = message.Args[0].ToLower();
			int num = 1;
			Vector3 val = Vector3.zero;
			string text4 = "random";
			int num2 = 1000;
			string[] array = message.Args.Skip(1).ToArray();
			string[] array2 = array;
			foreach (string text5 in array2)
			{
				string[] array3 = text5.Split(new char[1] { '=' });
				switch (array3[0])
				{
				case "v":
				case "value":
					num2 = int.Parse(array3[1]);
					Utils.LogInfo($"Value {num2}");
					break;
				case "a":
				case "amount":
					num = int.Parse(array3[1]);
					Utils.LogInfo($"Amount {num}");
					break;
				case "p":
				case "position":
					text4 = array3[1];
					Utils.LogInfo(text4);
					break;
				}
			}
			if (text4 != "random")
			{
				val = Utils.CalculateSpawnPosition(text4);
				if (val == Vector3.zero && text4 != "random")
				{
					Utils.LogWarning("Position Invalid, Using Default 'random'");
					text4 = "random";
				}
			}
			Vector3 val4;
			if (text3 == "gun")
			{
				for (int j = 0; j < Utils.GetCurrentLevel().Enemies.Count(); j++)
				{
					if (((Object)Utils.GetCurrentLevel().Enemies[j].enemyType).name == "Nutcracker")
					{
						GameObject val2 = Object.Instantiate<GameObject>(Utils.GetCurrentLevel().Enemies[j].enemyType.enemyPrefab, new Vector3(float.MinValue, float.MinValue, float.MinValue), Quaternion.identity);
						NutcrackerEnemyAI component = val2.GetComponent<NutcrackerEnemyAI>();
						Utils.LogInfo("Spawning " + num + " gun" + ((num > 1) ? "s" : ""));
						for (int k = 0; k < num; k++)
						{
							GameObject val3 = Object.Instantiate<GameObject>(component.gunPrefab, val, Quaternion.identity, Utils.GetCurrentRound().spawnedScrapContainer);
							GrabbableObject component2 = val3.GetComponent<GrabbableObject>();
							component2.startFallingPosition = val;
							component2.targetFloorPosition = component2.GetItemFloorPosition(val);
							component2.SetScrapValue(num2);
							((NetworkBehaviour)component2).NetworkObject.Spawn(false);
						}
						text = "Spawned gun";
						string[] obj = new string[8]
						{
							"Spawned ",
							num.ToString(),
							" gun",
							(num > 1) ? "s" : "",
							"with value of:",
							num2.ToString(),
							"\n at position: ",
							null
						};
						val4 = val;
						obj[7] = ((object)(Vector3)(ref val4)).ToString();
						text2 = string.Concat(obj);
						break;
					}
				}
			}
			int num3 = Utils.GetCurrentLevel().spawnableScrap.Count();
			bool flag = false;
			for (int l = 0; l < num3; l++)
			{
				Item scrap = Utils.GetCurrentLevel().spawnableScrap[l].spawnableItem;
				if (!(((Object)scrap.spawnPrefab).name.ToLower() == text3))
				{
					continue;
				}
				GameObject spawnPrefab = scrap.spawnPrefab;
				bool flag2 = text4 == "random";
				List<RandomScrapSpawn> list = null;
				if (flag2)
				{
					RandomScrapSpawn[] source = Object.FindObjectsOfType<RandomScrapSpawn>();
					list = ((scrap.spawnPositionTypes != null && scrap.spawnPositionTypes.Count != 0) ? source.Where((RandomScrapSpawn x) => scrap.spawnPositionTypes.Contains(x.spawnableItems) && !x.spawnUsed).ToList() : source.ToList());
				}
				Utils.LogInfo("Spawning " + num + " " + ((Object)spawnPrefab).name + ((num > 1) ? "s" : ""));
				for (int m = 0; m < num; m++)
				{
					if (flag2)
					{
						RandomScrapSpawn val5 = list[Utils.GetCurrentRound().AnomalyRandom.Next(0, list.Count)];
						val = Utils.GetCurrentRound().GetRandomNavMeshPositionInRadiusSpherical(((Component)val5).transform.position, val5.itemSpawnRange, Utils.GetCurrentRound().navHit) + Vector3.up * scrap.verticalOffset;
					}
					GameObject val6 = Object.Instantiate<GameObject>(spawnPrefab, val, Quaternion.identity, Utils.GetCurrentRound().spawnedScrapContainer);
					GrabbableObject component3 = val6.GetComponent<GrabbableObject>();
					component3.startFallingPosition = val;
					component3.targetFloorPosition = component3.GetItemFloorPosition(val);
					component3.SetScrapValue(num2);
					((NetworkBehaviour)component3).NetworkObject.Spawn(false);
					text = "Spawned " + ((Object)spawnPrefab).name;
					string[] obj2 = new string[9]
					{
						"Spawned ",
						num.ToString(),
						" ",
						((Object)spawnPrefab).name,
						(num > 1) ? "s" : "",
						" with value of:",
						num2.ToString(),
						"\n at position: ",
						null
					};
					val4 = val;
					obj2[8] = ((object)(Vector3)(ref val4)).ToString();
					text2 = string.Concat(obj2);
				}
				flag = true;
				break;
			}
			if (!flag)
			{
				Utils.LogWarning("Could not spawn " + text3);
				text = "Command Error";
				text2 = "Could not spawn " + text3 + ".\nHave you checked using /getscrap if the scrap you are trying to spawn\n is even spawnable?";
			}
			Utils.DisplayChatMessage(text + "\n" + text2);
		}
	}
	internal class SpawnTruck : CustomChatCommand
	{
		public static GameObject truckPrefab;

		public override string Name => "Spawn Truck";

		public override string Description => "Spawns the Truck, either at the default position or at a specified position.";

		public override string Format => "/spawntruck ([p=position])";

		public override string AltFormat => "/spwtrk ([p=position])";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//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 (message.Args.Count < 1)
			{
				Object.Instantiate<GameObject>(truckPrefab, StartOfRound.Instance.groundOutsideShipSpawnPosition.position, Quaternion.identity, RoundManager.Instance.VehiclesContainer).gameObject.GetComponent<NetworkObject>().Spawn(false);
				return;
			}
			Vector3 zero = Vector3.zero;
			zero = Utils.CalculateSpawnPosition(message.Args[0]);
			if (zero == Vector3.zero)
			{
				zero = StartOfRound.Instance.groundOutsideShipSpawnPosition.position;
			}
			Object.Instantiate<GameObject>(truckPrefab, zero, Quaternion.identity, RoundManager.Instance.VehiclesContainer).gameObject.GetComponent<NetworkObject>().Spawn(false);
		}

		[HarmonyPatch(typeof(QuickMenuManager), "Start")]
		[HarmonyPostfix]
		private static void GetTruckPrefab(QuickMenuManager __instance)
		{
			truckPrefab = __instance.truckPrefab;
		}
	}
	internal class SpeedHack : CustomChatCommand
	{
		private static float defaultJumpForce = 13f;

		private static float moddedJumpForce = 25f;

		private static float moddedSprintSpeed = 5f;

		private static bool speedHack = false;

		public override string Name => "Speed Hack";

		public override string Description => "Toggles Speed Hack, if speed is provided it will set the speed to that value.\n If jump force is provided it will set the jump force to that value.";

		public override string Format => "/speed ([speed]) ([jumpforce])";

		public override string AltFormat => "/speedhack ([speed]) ([jumpforce])";

		public override bool IsHostCommand => false;

		public override void Execute(CommandInput message)
		{
			if (message.Args.Count == 1)
			{
				if (float.TryParse(message.Args[0], out var result))
				{
					moddedSprintSpeed = result;
					speedHack = true;
					Utils.DisplayChatMessage("Speed Hack enabled with speed: " + moddedSprintSpeed);
					if (ChatCommands.SendHostCommandsSetting.Value && ChatCommands.isHost)
					{
						Utils.SendHostCommand(message.Command + moddedSprintSpeed);
					}
				}
				else
				{
					Utils.DisplayChatError("Invalid speed value");
				}
			}
			else if (message.Args.Count == 2)
			{
				if (float.TryParse(message.Args[0], out var result2))
				{
					moddedSprintSpeed = result2;
					if (float.TryParse(message.Args[1], out var result3))
					{
						moddedJumpForce = result3;
						speedHack = true;
						Utils.DisplayChatMessage("Speed Hack enabled with speed: " + moddedSprintSpeed + " and jump force: " + moddedJumpForce);
						if (ChatCommands.SendHostCommandsSetting.Value && ChatCommands.isHost)
						{
							Utils.SendHostCommand(message.Command + " " + moddedSprintSpeed + " " + moddedJumpForce);
						}
					}
					else
					{
						Utils.DisplayChatError("Invalid jump force value");
					}
				}
				else
				{
					Utils.DisplayChatError("Invalid speed value");
				}
			}
			else if (message.Args.Count > 2)
			{
				Utils.DisplayChatError("Too many arguments");
			}
			else
			{
				speedHack = !speedHack;
				if (!speedHack)
				{
					moddedSprintSpeed = 0f;
					moddedJumpForce = defaultJumpForce;
				}
				Utils.DisplayChatMessage("Speed Hack: " + (speedHack ? "Enabled" : "Disabled"));
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPrefix]
		private static void SpeedHackFunc(ref float ___jumpForce, ref float ___sprintMeter, ref float ___sprintMultiplier, ref bool ___isSprinting, ref float ___targetFOV)
		{
			defaultJumpForce = global::ChatCommands.Patches.Patches.defaultJumpForce;
			if (speedHack)
			{
				___jumpForce = moddedJumpForce;
				___sprintMeter = 1f;
				if (___isSprinting)
				{
					___sprintMultiplier = moddedSprintSpeed;
					___targetFOV *= moddedSprintSpeed;
				}
				else
				{
					___sprintMultiplier = 1f;
				}
			}
			else
			{
				___jumpForce = defaultJumpForce;
			}
		}
	}
	internal class TeleportCommand : CustomChatCommand
	{
		public override string Name => "Teleport";

		public override string Description => "Teleport to where you want. Use the following format: position=@(playername/me) or position=(random) or without arguments to teleport to the terminal.";

		public override string Format => "/teleport [position=(random/@<playername>/@me)]";

		public override string AltFormat => "/tp [position=(random/@<playername>/@me)]";

		public override bool IsHostCommand => false;

		public override void Execute(CommandInput message)
		{
			//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_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.zero;
			string text = ((message.Args.Count > 0) ? message.Args[0] : "");
			string text2 = "random";
			if (!Utility.IsNullOrWhiteSpace(text))
			{
				if (text.ToLower().StartsWith("p="))
				{
					text2 = text.ToLower().Substring(2);
					if (text2 != "random")
					{
						val = Utils.CalculateSpawnPosition(text2);
						if (val == Vector3.zero && text2 != "random")
						{
							ChatCommands.mls.LogWarning((object)"Position Invalid, Using Default 'random'");
							text2 = "random";
						}
					}
					if (text2 == "random" && (Object)(object)Utils.GetCurrentRound() != (Object)null && (Object)(object)Utils.GetCurrentLevel() != (Object)null)
					{
						Random random = new Random(StartOfRound.Instance.randomMapSeed + 17 + (int)GameNetworkManager.Instance.localPlayerController.playerClientId);
						Vector3 position = RoundManager.Instance.insideAINodes[random.Next(0, RoundManager.Instance.insideAINodes.Length)].transform.position;
						Debug.DrawRay(position, Vector3.up * 1f, Color.red);
						position = RoundManager.Instance.GetRandomNavMeshPositionInBoxPredictable(position, 10f, default(NavMeshHit), random, -1);
						Debug.DrawRay(position + Vector3.right * 0.01f, Vector3.up * 3f, Color.green);
						val = position;
					}
					GameNetworkManager.Instance.localPlayerController.beamUpParticle.Play();
					GameNetworkManager.Instance.localPlayerController.beamOutBuildupParticle.Play();
					GameNetworkManager.Instance.localPlayerController.TeleportPlayer(val, false, 0f, false, true);
					Utils.DisplayChatMessage("Teleported to " + text2);
					return;
				}
				string name = text.ToLower();
				name = Utils.ConvertPlayername(name);
				PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
				PlayerControllerB[] array = allPlayerScripts;
				foreach (PlayerControllerB val2 in array)
				{
					if (val2.playerUsername.ToLower().Contains(name))
					{
						GameNetworkManager.Instance.localPlayerController.beamUpParticle.Play();
						GameNetworkManager.Instance.localPlayerController.beamOutBuildupParticle.Play();
						GameNetworkManager.Instance.localPlayerController.TeleportPlayer(((Component)val2).transform.position, false, 0f, false, true);
						Utils.DisplayChatMessage("Teleported to " + val2.playerUsername);
						break;
					}
				}
			}
			else
			{
				Terminal val3 = Object.FindObjectOfType<Terminal>();
				if ((Object)(object)val3 != (Object)null)
				{
					GameNetworkManager.Instance.localPlayerController.beamUpParticle.Play();
					GameNetworkManager.Instance.localPlayerController.beamOutBuildupParticle.Play();
					GameNetworkManager.Instance.localPlayerController.TeleportPlayer(((Component)val3).transform.position, false, 0f, false, true);
					Utils.DisplayChatMessage("Teleported to Terminal");
				}
			}
		}
	}
	internal class TerminalCommand : CustomChatCommand
	{
		public override string Name => "Send Terminal Command";

		public override string Description => "Send a terminal commmand to the terminal and receive a response.";

		public override string Format => "/term [terminalcommand]";

		public override string AltFormat => "/terminal [terminalcommand]";

		public override bool IsHostCommand => false;

		public override void Execute(CommandInput message)
		{
			if (message.Args.Count == 0)
			{
				Utils.DisplayChatError("No command entered.");
				return;
			}
			Terminal val = Object.FindObjectOfType<Terminal>();
			string text = string.Join(" ", message.Args);
			if ((Object)(object)val == (Object)null)
			{
				Utils.DisplayChatError("Terminal not found.");
				return;
			}
			val.BeginUsingTerminal();
			val.currentText = "";
			val.screenText.text = text;
			val.OnSubmit();
			Utils.DisplayChatMessage("Command sent: " + text);
			delayedTerminalCommand(val, text);
		}

		private static async void delayedTerminalCommand(Terminal term, string command)
		{
			SelectableLevel[] moonsCatalogueList = term.moonsCatalogueList;
			foreach (SelectableLevel level in moonsCatalogueList)
			{
				if (level.PlanetName.ToLower().Contains(command.ToLower()))
				{
					Utils.LogInfo("Found Moon: " + command);
					await Task.Delay(300);
					term.currentText = "";
					term.screenText.text = "confirm";
					term.OnSubmit();
					break;
				}
			}
			if (command.ToLower().Contains("buy"))
			{
				Utils.LogInfo("Trying to buy");
				await Task.Delay(300);
				term.currentText = "";
				term.screenText.text = "confirm";
				term.OnSubmit();
			}
			await Task.Delay(300);
			term.QuitTerminal(true);
		}
	}
	internal class ToggleHostCmd : CustomChatCommand
	{
		public override string Name => "Toggle Host Commands";

		public override string Description => "Toggle if connecting clients can use host commands.";

		public override string Format => "/togglehostcmd";

		public override string AltFormat => "/thcmd";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			ChatCommands.AllowHostCommands = !ChatCommands.AllowHostCommands;
			Utils.DisplayChatMessage("Host Commands: " + (ChatCommands.AllowHostCommands ? "Enabled" : "Disabled"));
		}
	}
	internal class ToggleLights : CustomChatCommand
	{
		public override string Name => "Toggle Lights";

		public override string Description => "Toggles the lights on and off.";

		public override string Format => "/togglelights";

		public override string AltFormat => "/toglig";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			BreakerBox val = Object.FindObjectOfType<BreakerBox>();
			if ((Object)(object)val != (Object)null)
			{
				if (val.isPowerOn)
				{
					Utils.GetCurrentRound().TurnBreakerSwitchesOff();
					Utils.GetCurrentRound().TurnOnAllLights(false);
					val.isPowerOn = false;
					Utils.DisplayChatMessage("Turned the lights off");
				}
				else
				{
					Utils.GetCurrentRound().PowerSwitchOnClientRpc();
					Utils.DisplayChatMessage("Turned the lights on");
				}
			}
			else
			{
				Utils.DisplayChatError("Unable to find BreakerBox, need to be in a level with lights to use this command.");
			}
		}
	}
	internal class ToggleOverrideSpawns : CustomChatCommand
	{
		private static bool OverrideSpawns;

		public override string Name => "Toggle Overrride Spawns";

		public override string Description => "Toggles if Monster Spawns are overriden or not. This affects how many monsters spawn with the spawn command and natural spawns.";

		public override string Format => "/override";

		public override string AltFormat => "/ovr";

		public override bool IsHostCommand => true;

		public override void Execute(CommandInput message)
		{
			OverrideSpawns = !OverrideSpawns;
			Utils.DisplayChatMessage("Override Spawns: " + (OverrideSpawns ? "Enabled" : "Disabled"));
		}

		[HarmonyPatch(typeof(RoundManager), "EnemyCannotBeSpawned")]
		[HarmonyPrefix]
		private static bool OverrideCannotSpawn()
		{
			if (OverrideSpawns)
			{
				return false;
			}
			return true;
		}
	}
}