Decompiled source of ChatCommandAPI v1.1.2

baer1.ChatCommandAPI.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ChatCommandAPI.Commands;
using ChatCommandAPI.ServerCommands;
using ChatCommandAPI.Utils;
using GameNetcodeStuff;
using HarmonyLib;
using LethalModUtils;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("DunGen")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")]
[assembly: IgnoresAccessChecksTo("Unity.XR.Management")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("baer1")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) baer1 2026")]
[assembly: AssemblyDescription("A Lethal Company modding API for easy creation of Minecraft-style Chat Commands")]
[assembly: AssemblyFileVersion("1.1.2.0")]
[assembly: AssemblyInformationalVersion("1.1.2+5d04878647c5d1ace2335b8890355c8eb6c21999")]
[assembly: AssemblyProduct("ChatCommandAPI")]
[assembly: AssemblyTitle("baer1.ChatCommandAPI")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/baerchen201/LethalChatCommands.git")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
	{
		object IEnumerator.Current => _item;

		T IEnumerator<T>.Current => _item;

		public Enumerator(T item)
		{
			_item = item;
		}

		bool IEnumerator.MoveNext()
		{
			if (!_moveNextCalled)
			{
				return _moveNextCalled = true;
			}
			return false;
		}

		void IEnumerator.Reset()
		{
			_moveNextCalled = false;
		}

		void IDisposable.Dispose()
		{
		}
	}

	int ICollection.Count => 1;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => 1;

	T IReadOnlyList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
	}

	int ICollection<T>.Count => 1;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlySingleElementList(T item)
	{
		_item = item;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection.CopyTo(Array array, int index)
	{
		array.SetValue(_item, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return EqualityComparer<T>.Default.Equals(_item, (T)value);
	}

	int IList.IndexOf(object value)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
		{
			return -1;
		}
		return 0;
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return EqualityComparer<T>.Default.Equals(_item, item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		array[arrayIndex] = _item;
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, item))
		{
			return -1;
		}
		return 0;
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ChatCommandAPI
{
	public abstract class BaseCommand
	{
		public virtual string Name => GetType().Name;

		public virtual string Description => string.Empty;

		public virtual string Command => Name.ToLowerInvariant();

		public virtual string[] Aliases => new string[1] { GetType().Name.ToLowerInvariant() };

		public virtual string[] Syntax => Array.Empty<string>();

		public virtual bool Hidden => false;

		public string FullName => GetType().FullName;

		public sealed override string ToString()
		{
			return GetType().AssemblyQualifiedName ?? "";
		}
	}
	[BepInPlugin("baer1.ChatCommandAPI", "ChatCommandAPI", "1.1.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ChatCommandAPI : BaseUnityPlugin
	{
		internal const string COMMAND_NAME_REGEX = "\\S+";

		internal readonly Dictionary<string, Command> commands = new Dictionary<string, Command>();

		internal readonly Dictionary<string, ServerCommand> serverCommands = new Dictionary<string, ServerCommand>();

		private ConfigEntry<string> commandPrefix;

		private ConfigEntry<bool> compatibilityModeEnabled;

		private ConfigEntry<Color> defaultMessageColor;

		private ConfigEntry<string> serverCommandPrefix;

		private ConfigEntry<bool> serverCommandsEnabled;

		private ConfigEntry<string> serverWelcomeMessage;

		public static ChatCommandAPI Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		public System.Drawing.Color DefaultMessageColor => defaultMessageColor.Value.ToSystem();

		public char CommandPrefix => commandPrefix.Value[0];

		public bool CompatibilityModeEnabled => compatibilityModeEnabled.Value;

		public bool ServerCommandsEnabled => serverCommandsEnabled.Value;

		public char ServerCommandPrefix => serverCommandPrefix.Value[0];

		public string ServerWelcomeMessage => string.Format(serverWelcomeMessage.Value.Trim(), ServerCommandPrefix);

		public IReadOnlyDictionary<string, Command> Commands => commands;

		public IReadOnlyDictionary<string, ServerCommand> ServerCommands => serverCommands;

		private void Awake()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			defaultMessageColor = ((BaseUnityPlugin)this).Config.Bind<Color>("General", "DefaultMessageColor", System.Drawing.Color.Aqua.ToUnity(), "The default color to use for chat responses");
			commandPrefix = ((BaseUnityPlugin)this).Config.Bind<string>("Client", "CommandPrefix", '/'.ToString(), "The prefix to use for client-side commands");
			compatibilityModeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Client", "CompatibilityModeEnabled", false, "Allows non-API chat commands to run (may cause the command you run to be sent in chat)");
			serverCommandsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Server", "ServerCommandsEnabled", false, "Enables or disables server commands");
			serverCommandPrefix = ((BaseUnityPlugin)this).Config.Bind<string>("Server", "ServerCommandPrefix", '!'.ToString(), "The prefix to use for server-side commands");
			serverWelcomeMessage = ((BaseUnityPlugin)this).Config.Bind<string>("Server", "ServerWelcomeMessage", "This server supports chat commands.\nType {0}help for more information", "A welcome message that is displayed to any player that joins (clear to disable). {0} is replaced with ServerCommandPrefix");
			((BaseUnityPlugin)this).Config.SettingChanged += verifyConfigValues;
			verifyConfigValues(null, null);
			new global::ChatCommandAPI.Commands.Help();
			new global::ChatCommandAPI.ServerCommands.Help();
			Patch();
			Logger.LogInfo((object)"baer1.ChatCommandAPI v1.1.2 has loaded!");
			static void Patch()
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Expected O, but got Unknown
				if (Harmony == null)
				{
					Harmony = new Harmony("baer1.ChatCommandAPI");
				}
				Logger.LogDebug((object)"Patching...");
				Harmony.PatchAll();
				Logger.LogDebug((object)"Finished patching!");
			}
			void verifyConfigValues(object args, object sender)
			{
				int length = commandPrefix.Value.Length;
				if (length > 0)
				{
					if (length != 1)
					{
						Logger.LogWarning((object)("CommandPrefix '" + commandPrefix.Value + "' contains more than one character, only the first one will be used"));
					}
					if (!char.IsSymbol(CommandPrefix) && !char.IsPunctuation(CommandPrefix))
					{
						Logger.LogWarning((object)string.Format("Invalid {0} value '{1}', symbol expected...", "CommandPrefix", CommandPrefix));
						commandPrefix.Value = (string)((ConfigEntryBase)commandPrefix).DefaultValue;
					}
				}
				else
				{
					Logger.LogWarning((object)string.Format("Invalid {0} value '{1}', value expected...", "CommandPrefix", CommandPrefix));
					commandPrefix.Value = (string)((ConfigEntryBase)commandPrefix).DefaultValue;
				}
				int length2 = serverCommandPrefix.Value.Length;
				if (length2 > 0)
				{
					if (length2 != 1)
					{
						Logger.LogWarning((object)("ServerCommandPrefix '" + serverCommandPrefix.Value + "' contains more than one character, only the first one will be used"));
					}
					if (!char.IsSymbol(ServerCommandPrefix) && !char.IsPunctuation(ServerCommandPrefix))
					{
						Logger.LogWarning((object)string.Format("Invalid {0} value '{1}', symbol expected...", "ServerCommandPrefix", ServerCommandPrefix));
						serverCommandPrefix.Value = (string)((ConfigEntryBase)serverCommandPrefix).DefaultValue;
					}
				}
				else
				{
					Logger.LogWarning((object)string.Format("Invalid {0} value '{1}', symbol expected...", "ServerCommandPrefix", ServerCommandPrefix));
					serverCommandPrefix.Value = (string)((ConfigEntryBase)serverCommandPrefix).DefaultValue;
				}
				if (ServerCommandPrefix == CommandPrefix)
				{
					Logger.LogWarning((object)"ServerCommandPrefix is the same as CommandPrefix, this configuration will prioritize client commands and is not supported");
				}
			}
		}

		public static bool TryParseCommand(char prefix, string cmdline, out string name, out string args)
		{
			name = null;
			args = null;
			Match match = Regex.Match(cmdline, "^" + Regex.Escape(prefix.ToString()) + "(\\S+)(?: (.*))?$");
			if (!match.Success)
			{
				return false;
			}
			Group obj = match.Groups[2];
			name = match.Groups[1].Value;
			args = (obj.Success ? obj.Value : string.Empty);
			return true;
		}

		public bool TryParseCommand(string cmdline, out string name, out string args)
		{
			return TryParseCommand(CommandPrefix, cmdline, out name, out args);
		}

		public bool TryParseServerCommand(string cmdline, out string name, out string args)
		{
			return TryParseCommand(ServerCommandPrefix, cmdline, out name, out args);
		}

		public bool TryGetCommand(string name, out Command command, out string primaryName)
		{
			primaryName = (name = name.ToLowerInvariant());
			IReadOnlyDictionary<string, Command> readOnlyDictionary = Commands;
			if (readOnlyDictionary.TryGetValue(name, out command))
			{
				return true;
			}
			foreach (KeyValuePair<string, Command> item in readOnlyDictionary)
			{
				if (string.Equals(item.Value.FullName, name, StringComparison.InvariantCultureIgnoreCase))
				{
					primaryName = item.Key;
					command = item.Value;
					return true;
				}
			}
			foreach (KeyValuePair<string, Command> item2 in readOnlyDictionary)
			{
				if (string.Equals(item2.Value.Command, name, StringComparison.InvariantCultureIgnoreCase))
				{
					primaryName = item2.Key;
					command = item2.Value;
					return true;
				}
			}
			foreach (KeyValuePair<string, Command> item3 in readOnlyDictionary)
			{
				if (item3.Value.Aliases.Contains<string>(name, StringComparer.InvariantCultureIgnoreCase))
				{
					primaryName = item3.Key;
					command = item3.Value;
					return true;
				}
			}
			return false;
		}

		public bool TryGetServerCommand(string name, out ServerCommand command, out string primaryName)
		{
			primaryName = (name = name.ToLowerInvariant());
			IReadOnlyDictionary<string, ServerCommand> readOnlyDictionary = ServerCommands;
			if (readOnlyDictionary.TryGetValue(name, out command))
			{
				return true;
			}
			foreach (KeyValuePair<string, ServerCommand> item in readOnlyDictionary)
			{
				if (string.Equals(item.Value.FullName, name, StringComparison.InvariantCultureIgnoreCase))
				{
					primaryName = item.Key;
					command = item.Value;
					return true;
				}
			}
			foreach (KeyValuePair<string, ServerCommand> item2 in readOnlyDictionary)
			{
				if (string.Equals(item2.Value.Command, name, StringComparison.InvariantCultureIgnoreCase))
				{
					primaryName = item2.Key;
					command = item2.Value;
					return true;
				}
			}
			foreach (KeyValuePair<string, ServerCommand> item3 in readOnlyDictionary)
			{
				if (item3.Value.Aliases.Contains<string>(name, StringComparer.InvariantCultureIgnoreCase))
				{
					primaryName = item3.Key;
					command = item3.Value;
					return true;
				}
			}
			return false;
		}
	}
	public abstract class Command : BaseCommand
	{
		protected Command()
		{
			ChatCommandAPI.Logger.LogInfo((object)("Registering command " + base.FullName + "..."));
			string name = Name;
			if (string.IsNullOrWhiteSpace(name))
			{
				throw new InvalidCommandException("Name", name, this);
			}
			string text = Command.ToLowerInvariant();
			if (string.IsNullOrWhiteSpace(text) || !Regex.Match(text, "\\S+").Success)
			{
				throw new InvalidCommandException("Command", text, this);
			}
			IReadOnlyDictionary<string, Command> commands = ChatCommandAPI.Instance.Commands;
			if (commands.TryGetValue(text, out var value))
			{
				ChatCommandAPI.Logger.LogDebug((object)string.Format("{0} '{1}' >> {2}", "Command", text, value));
				string[] aliases = Aliases;
				int num = 0;
				while (true)
				{
					if (num < aliases.Length)
					{
						string text2 = aliases[num];
						text = text2.ToLowerInvariant();
						if (string.IsNullOrWhiteSpace(text) || !Regex.Match(text, "\\S+").Success)
						{
							throw new InvalidCommandException("Aliases", text, this);
						}
						if (!commands.TryGetValue(text, out value))
						{
							break;
						}
						ChatCommandAPI.Logger.LogDebug((object)string.Format("{0} '{1}' >> {2}", "Aliases", text, value));
						num++;
						continue;
					}
					text = base.FullName.ToLowerInvariant();
					if (!commands.TryGetValue(text, out value))
					{
						break;
					}
					ChatCommandAPI.Logger.LogDebug((object)string.Format("{0} '{1}' >> {2}", "FullName", text, value));
					throw new DuplicateCommandException(this);
				}
			}
			ChatCommandAPI.Instance.commands[text] = this;
			ChatCommandAPI.Logger.LogInfo((object)("Registered as '" + text + "'"));
		}

		public abstract void Invoke(string args);
	}
	public class CommandException : Exception
	{
		public CommandException(string message)
			: base(message)
		{
		}
	}
	internal sealed class DuplicateCommandException : Exception
	{
		public DuplicateCommandException(BaseCommand command)
			: base("Duplicate command registry: " + command.FullName + " in " + command.GetType().Assembly.FullName)
		{
		}
	}
	public sealed class InvalidArgumentsException : CommandException
	{
		public InvalidArgumentsException()
			: base("Invalid arguments")
		{
		}
	}
	internal class InvalidCommandException : Exception
	{
		public InvalidCommandException(string propertyName, string propertyValue, BaseCommand command)
			: base("Error registering " + command.FullName + ": Invalid " + propertyName + " '" + propertyValue + "'")
		{
		}
	}
	public abstract class MultiOptionCommand<T> : Command where T : Enum
	{
		public sealed override string[] Syntax
		{
			get
			{
				Array values = Enum.GetValues(typeof(T));
				if (values.Length <= 5)
				{
					return new string[1] { "{ " + string.Join(" | ", values) + " }" };
				}
				return new string[1] { "[value]" };
			}
		}

		public virtual T CurrentValue { get; set; }

		protected MultiOptionCommand()
		{
			Array values = Enum.GetValues(typeof(T));
			if (values.Length == 0)
			{
				throw new ArgumentException("Invalid enum type " + typeof(T).AssemblyQualifiedName + " (contains no values)", "T");
			}
		}

		public sealed override void Invoke(string args)
		{
			if (string.IsNullOrWhiteSpace(args))
			{
				Array values = Enum.GetValues(typeof(T));
				Chat.Print(string.Format("{0} values:\n<indent=15%>{1}</indent>\n{2} value: <color=#{3}>{4}</color>", typeof(T).Name, string.Join('\n', values), Name, Enum.IsDefined(typeof(T), CurrentValue) ? "00ffff" : "ff0000", CurrentValue));
			}
			else
			{
				if (!Enum.TryParse(typeof(T), args, out object result))
				{
					throw new InvalidArgumentsException();
				}
				T currentValue = CurrentValue;
				CurrentValue = (T)result;
				Changed(currentValue);
			}
		}

		protected virtual void Changed(T oldValue)
		{
			Chat.Print($"{Name} changed to {CurrentValue}");
		}
	}
	public abstract class ServerCommand : BaseCommand
	{
		public ServerCommand()
		{
			ChatCommandAPI.Logger.LogInfo((object)("Registering server command " + base.FullName + "..."));
			string name = Name;
			if (string.IsNullOrWhiteSpace(name))
			{
				throw new InvalidCommandException("Name", name, this);
			}
			string text = Command.ToLowerInvariant();
			if (string.IsNullOrWhiteSpace(text) || !Regex.Match(text, "\\S+").Success)
			{
				throw new InvalidCommandException("Command", text, this);
			}
			IReadOnlyDictionary<string, ServerCommand> serverCommands = ChatCommandAPI.Instance.ServerCommands;
			if (serverCommands.TryGetValue(text, out var value))
			{
				ChatCommandAPI.Logger.LogDebug((object)string.Format("{0} '{1}' >> {2}", "Command", text, value));
				string[] aliases = Aliases;
				int num = 0;
				while (true)
				{
					if (num < aliases.Length)
					{
						string text2 = aliases[num];
						text = text2.ToLowerInvariant();
						if (string.IsNullOrWhiteSpace(text) || !Regex.Match(text, "\\S+").Success)
						{
							throw new InvalidCommandException("Aliases", text, this);
						}
						if (!serverCommands.TryGetValue(text, out value))
						{
							break;
						}
						ChatCommandAPI.Logger.LogDebug((object)string.Format("{0} '{1}' >> {2}", "Aliases", text, value));
						num++;
						continue;
					}
					text = base.FullName.ToLowerInvariant();
					if (!serverCommands.TryGetValue(text, out value))
					{
						break;
					}
					ChatCommandAPI.Logger.LogDebug((object)string.Format("{0} '{1}' >> {2}", "FullName", text, value));
					throw new DuplicateCommandException(this);
				}
			}
			ChatCommandAPI.Instance.serverCommands[text] = this;
			ChatCommandAPI.Logger.LogInfo((object)("Registered as '" + text + "'"));
		}

		public abstract void Invoke(PlayerControllerB caller, string args);
	}
	public abstract class ToggleCommand : Command
	{
		public sealed override string[] Syntax => new string[1] { "{ true | false }" };

		public virtual bool CurrentValue { get; set; }

		public sealed override void Invoke(string args)
		{
			bool result;
			if (string.IsNullOrWhiteSpace(args))
			{
				result = !CurrentValue;
			}
			else if (!bool.TryParse(args, out result))
			{
				throw new InvalidArgumentsException();
			}
			bool currentValue = CurrentValue;
			CurrentValue = result;
			Changed(currentValue);
		}

		protected virtual void Changed(bool oldValue)
		{
			Chat.Print($"{Name} is now {CurrentValue}");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "baer1.ChatCommandAPI";

		public const string PLUGIN_NAME = "ChatCommandAPI";

		public const string PLUGIN_VERSION = "1.1.2";
	}
}
namespace ChatCommandAPI.Utils
{
	public static class Args
	{
		private enum QuotationMarks : byte
		{
			None,
			Double,
			PostDouble,
			Single,
			PostSingle
		}

		public static IEnumerable<string> Parse(string args, uint? max = null, bool escape = true)
		{
			args = args.TrimEnd();
			QuotationMarks q = QuotationMarks.None;
			StringBuilder sb = new StringBuilder();
			bool escaped = false;
			int i = 0;
			string text = args;
			int num = 0;
			while (true)
			{
				if (num < text.Length)
				{
					char c = text[num];
					int num2 = i + 1;
					i = num2;
					switch (c)
					{
					case '"':
						if (escaped)
						{
							sb.Append(c);
							escaped = false;
						}
						else
						{
							switch (q)
							{
							case QuotationMarks.None:
								if (sb.Length <= 0)
								{
									q = QuotationMarks.Double;
								}
								else
								{
									sb.Append(c);
								}
								goto IL_051e;
							case QuotationMarks.Double:
								break;
							case QuotationMarks.Single:
								sb.Append(c);
								goto IL_051e;
							default:
								throw new InvalidArgumentsException();
							}
							yield return sb.ToString();
							if (max.HasValue)
							{
								uint? num3 = max - 1;
								max = num3;
								if (num3 == 0)
								{
									break;
								}
							}
							sb.Clear();
							q = QuotationMarks.PostDouble;
						}
						goto IL_051e;
					case '\'':
						if (escaped)
						{
							sb.Append(c);
							escaped = false;
						}
						else
						{
							switch (q)
							{
							case QuotationMarks.None:
								if (sb.Length <= 0)
								{
									q = QuotationMarks.Single;
								}
								else
								{
									sb.Append(c);
								}
								goto IL_051e;
							case QuotationMarks.Single:
								break;
							case QuotationMarks.Double:
								sb.Append(c);
								goto IL_051e;
							default:
								throw new InvalidArgumentsException();
							}
							yield return sb.ToString();
							if (max.HasValue)
							{
								uint? num3 = max - 1;
								max = num3;
								if (num3 == 0)
								{
									break;
								}
							}
							sb.Clear();
							q = QuotationMarks.PostSingle;
						}
						goto IL_051e;
					case '\\':
						if (escaped || !escape)
						{
							sb.Append(c);
							escaped = false;
						}
						else
						{
							escaped = escape;
						}
						goto IL_051e;
					default:
						if (char.IsWhiteSpace(c))
						{
							switch (q)
							{
							case QuotationMarks.PostDouble:
							case QuotationMarks.PostSingle:
								q = QuotationMarks.None;
								goto IL_051e;
							case QuotationMarks.None:
								break;
							default:
								sb.Append(c);
								goto IL_051e;
							}
							if (escaped)
							{
								sb.Append(c);
								escaped = false;
							}
							else if (sb.Length > 0)
							{
								yield return sb.ToString();
								if (max.HasValue)
								{
									uint? num3 = max - 1;
									max = num3;
									if (num3 == 0)
									{
										break;
									}
								}
								sb.Clear();
							}
						}
						else
						{
							QuotationMarks quotationMarks = q;
							if (quotationMarks == QuotationMarks.PostDouble || quotationMarks == QuotationMarks.PostSingle)
							{
								throw new InvalidArgumentsException();
							}
							if (escaped)
							{
								sb.Append(c switch
								{
									'0' => '\0', 
									'a' => '\a', 
									'b' => '\b', 
									'e' => '\u001b', 
									'f' => '\f', 
									'n' => '\n', 
									'r' => '\r', 
									't' => '\t', 
									'v' => '\v', 
									_ => throw new InvalidArgumentsException(), 
								});
								escaped = false;
							}
							else
							{
								sb.Append(c);
							}
						}
						goto IL_051e;
					}
					break;
				}
				switch (q)
				{
				case QuotationMarks.None:
				case QuotationMarks.PostDouble:
				case QuotationMarks.PostSingle:
					if (sb.Length > 0)
					{
						yield return sb.ToString();
					}
					break;
				default:
					throw new InvalidArgumentsException();
				}
				yield break;
				IL_051e:
				num++;
			}
			string text2 = args.Substring(i);
			if (text2.Length > 0)
			{
				yield return text2.Trim();
			}
		}
	}
	public static class Chat
	{
		public static readonly System.Drawing.Color DEFAULT_CHAT_COLOR = System.Drawing.Color.FromArgb(112, 105, 255);

		internal static ulong? targetClientId;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static string Clean(string message)
		{
			return message.Replace("\0", "\\0");
		}

		private static void Print(string message, System.Drawing.Color color)
		{
			HUDManager.Instance.AddChatMessage($"<color=#{color.R:X2}{color.G:X2}{color.B:X2}{color.A:X2}>{Clean(message)}</color>", "", -1, false);
		}

		internal static void Print(ulong targetClientId, string message, System.Drawing.Color color)
		{
			Chat.targetClientId = targetClientId;
			HUDManager.Instance.AddTextMessageClientRpc($"<color=#{color.R:X2}{color.G:X2}{color.B:X2}{color.A:X2}>{Clean(message)}</color>");
			Chat.targetClientId = null;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static void Print(PlayerControllerB target, string message, System.Drawing.Color color)
		{
			Print(target.actualClientId, message, color);
		}

		private static void PrintGlobal(string message, System.Drawing.Color color)
		{
			HUDManager.Instance.AddTextMessageServerRpc($"<color=#{color.R:X2}{color.G:X2}{color.B:X2}{color.A:X2}>{Clean(message)}</color>");
		}

		public static void Print(string message, System.Drawing.Color? color = null)
		{
			ChatCommandAPI.Logger.LogInfo((object)("Print: " + message));
			Print(message, color ?? ChatCommandAPI.Instance.DefaultMessageColor);
		}

		public static void PrintWarning(string message)
		{
			ChatCommandAPI.Logger.LogWarning((object)("PrintWarning: " + message));
			Print(message, System.Drawing.Color.Yellow);
		}

		public static void PrintError(string message)
		{
			ChatCommandAPI.Logger.LogError((object)("PrintError: " + message));
			Print(message, System.Drawing.Color.Red);
		}

		public static void Print(PlayerControllerB target, string message, System.Drawing.Color? color = null)
		{
			ChatCommandAPI.Logger.LogInfo((object)("Print(" + target.PlayerString() + "): " + message));
			Print(target, message, color ?? ChatCommandAPI.Instance.DefaultMessageColor);
		}

		public static void PrintWarning(PlayerControllerB target, string message)
		{
			ChatCommandAPI.Logger.LogWarning((object)("PrintWarning(" + target.PlayerString() + "): " + message));
			Print(target, message, System.Drawing.Color.Yellow);
		}

		public static void PrintError(PlayerControllerB target, string message)
		{
			ChatCommandAPI.Logger.LogError((object)("PrintError(" + target.PlayerString() + "): " + message));
			Print(target, message, System.Drawing.Color.Red);
		}

		public static void PrintGlobal(string message, System.Drawing.Color? color = null)
		{
			ChatCommandAPI.Logger.LogInfo((object)("PrintGlobal: " + message));
			PrintGlobal(message, color ?? ChatCommandAPI.Instance.DefaultMessageColor);
		}

		public static void PrintWarningGlobal(string message)
		{
			ChatCommandAPI.Logger.LogWarning((object)("PrintWarningGlobal: " + message));
			PrintGlobal(message, System.Drawing.Color.Yellow);
		}

		public static void PrintErrorGlobal(string message)
		{
			ChatCommandAPI.Logger.LogError((object)("PrintErrorGlobal: " + message));
			PrintGlobal(message, System.Drawing.Color.Red);
		}

		public static string Escape(string message)
		{
			return message.Replace('<', '<').Replace('>', '>');
		}
	}
	public static class Color
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static System.Drawing.Color ToSystem(this Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Color32.op_Implicit(color).ToSystem();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static System.Drawing.Color ToSystem(this Color32 color)
		{
			//IL_0000: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return System.Drawing.Color.FromArgb(color.a, color.r, color.g, color.b);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Color ToUnity(this System.Drawing.Color color)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			return new Color((float)(int)color.R / 255f, (float)(int)color.G / 255f, (float)(int)color.B / 255f, (float)(int)color.A / 255f);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Color32 ToUnity32(this System.Drawing.Color color)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			return new Color32(color.R, color.G, color.B, color.A);
		}
	}
	public static class Player
	{
		public sealed class UnknownPlayerException : CommandException
		{
			public UnknownPlayerException(string identifier)
				: base("Unknown player '" + identifier + "'")
			{
			}
		}

		private static readonly Regex PLAYER_IDENTIFIER_REGEX = new Regex("(?:#?(\\d+))(?: (.+))?", RegexOptions.Compiled);

		public static bool TryGetPlayer(int playerId, out PlayerControllerB result)
		{
			result = null;
			if (playerId < 0)
			{
				return false;
			}
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			PlayerControllerB[] allPlayerScripts = instance.allPlayerScripts;
			if (allPlayerScripts.Length <= playerId)
			{
				return false;
			}
			result = allPlayerScripts[playerId];
			return result.IsPlayerControlled();
		}

		public static bool TryGetPlayer(string identifier, out PlayerControllerB result)
		{
			result = null;
			if (string.IsNullOrWhiteSpace(identifier))
			{
				return false;
			}
			identifier = identifier.Trim();
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			if (identifier == "@s")
			{
				result = instance.localPlayerController;
				return true;
			}
			PlayerControllerB[] array = instance.allPlayerScripts.Where((PlayerControllerB i) => i.IsPlayerControlled()).ToArray();
			if (array.Length == 0)
			{
				return false;
			}
			if (identifier == "@r")
			{
				result = array[new Random().Next(array.Length)];
				return true;
			}
			if (Object.op_Implicit((Object)(object)(result = ((IEnumerable<PlayerControllerB>)array).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB i) => string.Equals(i.playerUsername.Trim(), identifier, StringComparison.InvariantCulture))))))
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)(result = ((IEnumerable<PlayerControllerB>)array).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB i) => string.Equals(i.playerUsername.Trim(), identifier, StringComparison.InvariantCultureIgnoreCase))))))
			{
				return true;
			}
			Match match = PLAYER_IDENTIFIER_REGEX.Match(identifier);
			if (match.Success)
			{
				Group obj = match.Groups[1];
				if (obj.Success && int.TryParse(obj.Value, out var result2) && TryGetPlayer(result2, out result))
				{
					return true;
				}
				Group obj2 = match.Groups[2];
				if (obj2.Success && TryGetPlayer(obj2.Value, out result))
				{
					return true;
				}
			}
			PlayerControllerB[] array2 = array;
			foreach (PlayerControllerB val in array2)
			{
				if (val.playerUsername.StartsWith(identifier, StringComparison.InvariantCultureIgnoreCase))
				{
					result = val;
					return true;
				}
			}
			return false;
		}

		public static PlayerControllerB[] GetPlayers(string identifier)
		{
			if (string.IsNullOrWhiteSpace(identifier))
			{
				return Array.Empty<PlayerControllerB>();
			}
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return Array.Empty<PlayerControllerB>();
			}
			identifier = identifier.Trim();
			if (identifier == "@s")
			{
				return (PlayerControllerB[])(object)new PlayerControllerB[1] { instance.localPlayerController };
			}
			Match match = PLAYER_IDENTIFIER_REGEX.Match(identifier);
			if (match.Success)
			{
				Group obj = match.Groups[1];
				if (obj.Success && int.TryParse(obj.Value, out var result) && TryGetPlayer(result, out PlayerControllerB result2))
				{
					return (PlayerControllerB[])(object)new PlayerControllerB[1] { result2 };
				}
			}
			PlayerControllerB[] array = instance.allPlayerScripts.Where((PlayerControllerB i) => i.IsPlayerControlled()).ToArray();
			if (array.Length == 0)
			{
				return Array.Empty<PlayerControllerB>();
			}
			string text = identifier;
			if (!(text == "@a"))
			{
				if (text == "@r")
				{
					return (PlayerControllerB[])(object)new PlayerControllerB[1] { array[new Random().Next(array.Length)] };
				}
				return array.Where((PlayerControllerB i) => i.playerUsername.Trim().StartsWith(identifier, StringComparison.InvariantCultureIgnoreCase)).ToArray();
			}
			return array;
		}

		public static string PlayerString(this PlayerControllerB player)
		{
			return $"#{player.playerClientId} {player.playerUsername}";
		}

		public static bool IsPlayerControlled(this PlayerControllerB player)
		{
			if (Object.op_Implicit((Object)(object)player) && player != null && !player.disconnectedMidGame && !player.isTestingPlayer)
			{
				if (!player.isPlayerControlled)
				{
					return player.isPlayerDead;
				}
				return true;
			}
			return false;
		}
	}
	public static class Pos
	{
		private static readonly Regex POSITION_REGEX = new Regex("(~)?(-?(?:(?:\\d+)(?:.\\d+)?|(?:\\d+)?(?:.\\d+)))", RegexOptions.Compiled);

		public static bool TryParse(string pos, out Vector3 result, Vector3? playerPosition = null, Quaternion? cameraAngles = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			result = default(Vector3);
			string[] array = Args.Parse(pos).ToArray();
			if (array.Length != 3)
			{
				return false;
			}
			return TryParse(array[0], array[1], array[2], out result, playerPosition, cameraAngles);
		}

		public static bool TryParse(string x, string y, string z, out Vector3 result, Vector3? playerPosition = null, Quaternion? cameraAngles = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			result = default(Vector3);
			float result2;
			float result3;
			float result4;
			if (x.StartsWith('^'))
			{
				if (!y.StartsWith('^') || !z.StartsWith('^') || !playerPosition.HasValue || !cameraAngles.HasValue)
				{
					return false;
				}
				if (string.IsNullOrWhiteSpace(x = x.Substring(1)))
				{
					result2 = 0f;
				}
				else if (!float.TryParse(x, NumberStyles.Float, CultureInfo.InvariantCulture, out result2))
				{
					return false;
				}
				if (string.IsNullOrWhiteSpace(y = y.Substring(1)))
				{
					result3 = 0f;
				}
				else if (!float.TryParse(y, NumberStyles.Float, CultureInfo.InvariantCulture, out result3))
				{
					return false;
				}
				if (string.IsNullOrWhiteSpace(z = z.Substring(1)))
				{
					result4 = 0f;
				}
				else if (!float.TryParse(z, NumberStyles.Float, CultureInfo.InvariantCulture, out result4))
				{
					return false;
				}
				result = playerPosition.Value + cameraAngles.Value * Vector3.forward * result4 + cameraAngles.Value * Vector3.up * result3 + cameraAngles.Value * Vector3.right * (0f - result2);
				return true;
			}
			if (y.StartsWith('^') || z.StartsWith('^'))
			{
				return false;
			}
			bool flag = false;
			bool flag2 = false;
			bool flag3 = false;
			if (x.StartsWith('~'))
			{
				if (!playerPosition.HasValue)
				{
					return false;
				}
				flag = true;
				x = x.Substring(1);
				if (string.IsNullOrWhiteSpace(x))
				{
					result2 = 0f;
					goto IL_0191;
				}
			}
			if (!float.TryParse(x, NumberStyles.Float, CultureInfo.InvariantCulture, out result2))
			{
				return false;
			}
			goto IL_0191;
			IL_01d8:
			if (z.StartsWith('~'))
			{
				if (!playerPosition.HasValue)
				{
					return false;
				}
				flag3 = true;
				z = z.Substring(1);
				if (string.IsNullOrWhiteSpace(z))
				{
					result4 = 0f;
					goto IL_021f;
				}
			}
			if (!float.TryParse(z, NumberStyles.Float, CultureInfo.InvariantCulture, out result4))
			{
				return false;
			}
			goto IL_021f;
			IL_0191:
			if (y.StartsWith('~'))
			{
				if (!playerPosition.HasValue)
				{
					return false;
				}
				flag2 = true;
				y = y.Substring(1);
				if (string.IsNullOrWhiteSpace(y))
				{
					result3 = 0f;
					goto IL_01d8;
				}
			}
			if (!float.TryParse(y, NumberStyles.Float, CultureInfo.InvariantCulture, out result3))
			{
				return false;
			}
			goto IL_01d8;
			IL_021f:
			result = new Vector3(flag ? (result2 + playerPosition.Value.x) : result2, flag2 ? (result3 + playerPosition.Value.y) : result3, flag3 ? (result4 + playerPosition.Value.z) : result4);
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool TryParse(string pos, out Vector3 result, PlayerControllerB player)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			return TryParse(pos, out result, ((Component)player).transform.position, ((Component)player.gameplayCamera).transform.rotation);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool TryParse(string x, string y, string z, out Vector3 result, PlayerControllerB player)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			return TryParse(x, y, z, out result, ((Component)player).transform.position, ((Component)player.gameplayCamera).transform.rotation);
		}
	}
}
namespace ChatCommandAPI.ServerCommands
{
	public class Help : ServerCommand
	{
		public override string Description => "Displays all available commands or details about a single one";

		public override string[] Aliases => new string[1] { "?" };

		public override string[] Syntax => new string[1] { "[command]" };

		public override bool Hidden => true;

		public override void Invoke(PlayerControllerB caller, string args)
		{
			char prefix = ChatCommandAPI.Instance.ServerCommandPrefix;
			if (!string.IsNullOrWhiteSpace(args))
			{
				Match match = Regex.Match(args.Trim(), "\\S+");
				if (!match.Success)
				{
					throw new CommandException("Invalid command name");
				}
				if (!ChatCommandAPI.Instance.TryGetServerCommand(match.Value, out ServerCommand command, out string primaryName))
				{
					throw new CommandException("Unknown command '" + match.Value + "'");
				}
				Chat.Print(caller, global::ChatCommandAPI.Commands.Help.DetailedHelp(prefix, command, primaryName));
			}
			else
			{
				KeyValuePair<string, ServerCommand>[] array = ChatCommandAPI.Instance.ServerCommands.Where<KeyValuePair<string, ServerCommand>>((KeyValuePair<string, ServerCommand> kvp) => !kvp.Value.Hidden).ToArray();
				Chat.Print(caller, global::ChatCommandAPI.Commands.Help.DetailedHelp(prefix, this, null, includeSource: false) + "\n<color=#00FFFF>===============</color>\n" + ((array.Length == 0) ? "<color=#ff0000>No commands available</color>" : ("Available commands:\n" + string.Join('\n', array.Select((KeyValuePair<string, ServerCommand> kvp) => $"{prefix}{kvp.Key}")))));
			}
		}
	}
}
namespace ChatCommandAPI.Patches
{
	[HarmonyPatch(typeof(HUDManager), "AddPlayerChatMessageServerRpc")]
	internal static class HUDManager_AddPlayerChatMessageServerRpc
	{
		private static bool Prefix(ref HUDManager __instance, ref string chatMessage, ref int playerId)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			if ((int)((NetworkBehaviour)__instance).__rpc_exec_stage != 1 || !((NetworkBehaviour)__instance).IsServer || string.IsNullOrWhiteSpace(chatMessage))
			{
				return true;
			}
			if (!Player.TryGetPlayer(playerId, out PlayerControllerB result))
			{
				ChatCommandAPI.Logger.LogWarning((object)$"Chat message sent by invalid player #{playerId}");
				return true;
			}
			if (!ChatCommandAPI.Instance.TryParseServerCommand(chatMessage, out string name, out string args))
			{
				return true;
			}
			if (ChatCommandAPI.Instance.TryGetServerCommand(name, out ServerCommand command, out string _))
			{
				ChatCommandAPI.Logger.LogInfo((object)("Executing server command as '" + result.PlayerString() + "': " + name + " (" + command.FullName + ")"));
				try
				{
					command.Invoke(result, args);
					ChatCommandAPI.Logger.LogInfo((object)"Command executed successfully");
				}
				catch (CommandException ex)
				{
					Chat.PrintError(result, string.IsNullOrWhiteSpace(ex.Message) ? ("An unspecified error occurred while executing command '" + name + "'") : ("An error occurred while executing command '" + name + "': " + ex.Message.Trim()));
					ChatCommandAPI.Logger.LogError((object)ex);
				}
				catch (Exception ex2)
				{
					Chat.PrintError(result, "An unexpected " + ex2.GetType().Name + " error occurred while executing command '" + name + "'");
					Chat.PrintWarning("An unexpected " + ex2.GetType().Name + " error occurred while executing command '" + name + "' as " + result.PlayerString() + "\nCheck the logs for more details");
					ChatCommandAPI.Logger.LogError((object)ex2);
				}
				return false;
			}
			Chat.PrintError(result, "Unknown command: '" + name + "'");
			return false;
		}
	}
	[HarmonyPatch(typeof(HUDManager), "AddTextMessageClientRpc")]
	internal static class HUDManager_AddTextMessageClientRpc
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_003b: Expected O, but got Unknown
			return CodeMatcherExtensions.MatchForward(new CodeMatcher(instructions, (ILGenerator)null), (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(NetworkBehaviour), "__endSendClientRpc", (Type[])null, (Type[])null), (string)null)
			}).Advance(-1).Insert((CodeInstruction[])(object)new CodeInstruction[1] { CodeInstruction.Call(typeof(HUDManager_AddTextMessageClientRpc), "RedirectMessageToClient", (Type[])null, (Type[])null) })
				.InstructionEnumeration();
		}

		private static ClientRpcParams RedirectMessageToClient(ClientRpcParams clientRpcParams)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (Chat.targetClientId.HasValue)
			{
				return new ClientRpcParams
				{
					Send = 
					{
						TargetClientIds = new <>z__ReadOnlySingleElementList<ulong>(Chat.targetClientId.Value)
					}
				};
			}
			return clientRpcParams;
		}
	}
	[HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")]
	[HarmonyPriority(int.MaxValue)]
	internal static class HUDManager_SubmitChat_performed
	{
		private static bool Prefix(ref HUDManager __instance, ref CallbackContext context)
		{
			string text = __instance.chatTextField.text;
			if (!((CallbackContext)(ref context)).performed || string.IsNullOrWhiteSpace(text))
			{
				return true;
			}
			if (!ChatCommandAPI.Instance.TryParseCommand(text, out string name, out string args))
			{
				return true;
			}
			if (ChatCommandAPI.Instance.TryGetCommand(name, out Command command, out string _))
			{
				resetChat(ref __instance);
				ChatCommandAPI.Logger.LogInfo((object)("Executing command: " + name + " (" + command.FullName + ")"));
				try
				{
					command.Invoke(args);
					ChatCommandAPI.Logger.LogInfo((object)"Command executed successfully");
				}
				catch (CommandException ex)
				{
					Chat.PrintError(string.IsNullOrWhiteSpace(ex.Message) ? ("An unspecified error occurred while executing command '" + name + "'") : ("An error occurred while executing command '" + name + "': " + ex.Message.Trim()));
					ChatCommandAPI.Logger.LogError((object)ex);
				}
				catch (Exception ex2)
				{
					Chat.PrintError("An unexpected " + ex2.GetType().Name + " error occurred while executing command '" + name + "'\nCheck the logs for more details");
					ChatCommandAPI.Logger.LogError((object)ex2);
				}
				return false;
			}
			Chat.PrintError("Unknown command: '" + name + "'");
			if (ChatCommandAPI.Instance.CompatibilityModeEnabled)
			{
				return true;
			}
			resetChat(ref __instance);
			return false;
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			static void resetChat(ref HUDManager reference)
			{
				reference.localPlayer.isTypingChat = false;
				reference.chatTextField.text = "";
				EventSystem.current.SetSelectedGameObject((GameObject)null);
				reference.PingHUDElement(reference.Chat, 2f, 1f, 0.2f);
				((Behaviour)reference.typingIndicator).enabled = false;
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "SyncAlreadyHeldObjectsServerRpc")]
	internal static class StartOfRound_SyncAlreadyHeldObjectsServerRpc
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_004d: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			return CodeMatcherExtensions.MatchForward(new CodeMatcher(instructions, (ILGenerator)null), (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(Debug), "Log", new Type[1] { typeof(string) }, (Type[])null), (string)null)
			}).Insert((CodeInstruction[])(object)new CodeInstruction[2]
			{
				new CodeInstruction(OpCodes.Ldarg_1, (object)null),
				CodeInstruction.Call(typeof(StartOfRound_SyncAlreadyHeldObjectsServerRpc), "SendWelcomeMessage", (Type[])null, (Type[])null)
			}).InstructionEnumeration();
		}

		private static void SendWelcomeMessage(ulong clientId)
		{
			string serverWelcomeMessage = ChatCommandAPI.Instance.ServerWelcomeMessage;
			if (!string.IsNullOrWhiteSpace(serverWelcomeMessage) && !ChatCommandAPI.Instance.ServerCommands.All<KeyValuePair<string, ServerCommand>>((KeyValuePair<string, ServerCommand> kvp) => kvp.Value.Hidden))
			{
				Chat.Print(clientId, serverWelcomeMessage, Chat.DEFAULT_CHAT_COLOR);
			}
		}
	}
}
namespace ChatCommandAPI.Old
{
	[Obsolete("This is provided for easier porting of old mods.\nTHIS IS A TEMPORARY SOLUTION AND IT MAY BE COMPLETELY REMOVED IN FUTURE VERSIONS")]
	public abstract class LegacyCommand : Command
	{
		internal const string OBSOLETE_MESSAGE = "This is provided for easier porting of old mods.\nTHIS IS A TEMPORARY SOLUTION AND IT MAY BE COMPLETELY REMOVED IN FUTURE VERSIONS";

		public virtual string[] Commands => new string[1] { Name.ToLowerInvariant() };

		public sealed override string Command => Commands[0];

		public sealed override string[] Aliases
		{
			get
			{
				string[] commands = Commands;
				if (commands.Length == 0)
				{
					return Array.Empty<string>();
				}
				return commands[1..];
			}
		}

		protected LegacyCommand()
		{
			ChatCommandAPI.Logger.LogWarning((object)$"The command {base.FullName} ({this}) is using the Legacy API. Please upgrade it to the new API");
			if (Commands.Length == 0)
			{
				throw new Exception("You need to provide at least one command");
			}
		}

		public sealed override void Invoke(string args)
		{
			if (!Invoke(Args.Parse(args).ToArray(), out string error))
			{
				throw new CommandException(error);
			}
		}

		public abstract bool Invoke(string[] args, out string? error);
	}
	[Obsolete("This is provided for easier porting of old mods.\nTHIS IS A TEMPORARY SOLUTION AND IT MAY BE COMPLETELY REMOVED IN FUTURE VERSIONS")]
	public abstract class LegacyServerCommand : ServerCommand
	{
		public virtual string[] Commands => new string[1] { Name.ToLowerInvariant() };

		public sealed override string Command => Commands[0];

		public sealed override string[] Aliases
		{
			get
			{
				string[] commands = Commands;
				if (commands.Length == 0)
				{
					return Array.Empty<string>();
				}
				return commands[1..];
			}
		}

		protected LegacyServerCommand()
		{
			ChatCommandAPI.Logger.LogWarning((object)$"The server command {base.FullName} ({this}) is using the Legacy API. Please upgrade it to the new API");
			if (Commands.Length == 0)
			{
				throw new Exception("You need to provide at least one command");
			}
		}

		public sealed override void Invoke(PlayerControllerB caller, string args)
		{
			if (!Invoke(caller, Args.Parse(args).ToArray(), out string error))
			{
				throw new CommandException(error);
			}
		}

		public abstract bool Invoke(PlayerControllerB caller, string[] args, out string? error);
	}
	[Obsolete("This is provided for easier porting of old mods.\nTHIS IS A TEMPORARY SOLUTION AND IT MAY BE COMPLETELY REMOVED IN FUTURE VERSIONS")]
	public abstract class LegacyToggleCommand : ToggleCommand
	{
		public virtual string[] Commands => new string[1] { Name.ToLowerInvariant() };

		public sealed override string Command => Commands[0];

		public sealed override string[] Aliases
		{
			get
			{
				string[] commands = Commands;
				if (commands.Length == 0)
				{
					return Array.Empty<string>();
				}
				return commands[1..];
			}
		}

		public sealed override bool CurrentValue
		{
			get
			{
				return Value;
			}
			set
			{
				Value = value;
			}
		}

		public abstract bool Value { get; set; }

		public virtual string EnabledString => "enabled";

		public virtual string DisabledString => "disabled";

		public virtual string ValueString
		{
			get
			{
				if (!Value)
				{
					return DisabledString;
				}
				return EnabledString;
			}
		}

		public virtual string? ToggleDescription => null;

		public sealed override string Description
		{
			get
			{
				string toggleDescription = ToggleDescription;
				if (!string.IsNullOrWhiteSpace(toggleDescription))
				{
					return toggleDescription + " - " + ValueString;
				}
				return ValueString;
			}
		}

		protected LegacyToggleCommand()
		{
			ChatCommandAPI.Logger.LogWarning((object)$"The toggle command {base.FullName} ({this}) is using the Legacy API. Please upgrade it to the new API");
			if (Commands.Length == 0)
			{
				throw new Exception("You need to provide at least one command");
			}
		}

		public virtual void PrintValue()
		{
			Chat.Print(Name + " " + ValueString);
		}

		protected sealed override void Changed(bool oldValue)
		{
			PrintValue();
		}
	}
}
namespace ChatCommandAPI.Commands
{
	public class Help : Command
	{
		internal const string SEPARATOR = "<color=#00FFFF>===============</color>\n";

		public override string Description => "Displays all available commands or details about a single one";

		public override string[] Aliases => new string[1] { "?" };

		public override string[] Syntax => new string[1] { "[command]" };

		public override bool Hidden => true;

		public override void Invoke(string args)
		{
			char prefix = ChatCommandAPI.Instance.CommandPrefix;
			if (!string.IsNullOrWhiteSpace(args))
			{
				Match match = Regex.Match(args.Trim(), "\\S+");
				if (!match.Success)
				{
					throw new CommandException("Invalid command name");
				}
				if (!ChatCommandAPI.Instance.TryGetCommand(match.Value, out Command command, out string primaryName))
				{
					throw new CommandException("Unknown command '" + match.Value + "'");
				}
				Chat.Print(DetailedHelp(prefix, command, primaryName));
			}
			else
			{
				KeyValuePair<string, Command>[] array = ChatCommandAPI.Instance.Commands.Where<KeyValuePair<string, Command>>((KeyValuePair<string, Command> kvp) => !kvp.Value.Hidden).ToArray();
				Chat.Print(DetailedHelp(prefix, this, null, includeSource: false) + "\n<color=#00FFFF>===============</color>\n" + ((array.Length == 0) ? "<color=#ff0000>No commands available</color>" : ("Available commands:\n" + string.Join('\n', array.Select((KeyValuePair<string, Command> kvp) => $"{prefix}{kvp.Key}")))));
			}
		}

		public static string DetailedHelp(char prefix, BaseCommand command, string primaryName = null, bool includeSource = true)
		{
			if (string.IsNullOrWhiteSpace(primaryName))
			{
				primaryName = command.Command.ToLowerInvariant();
			}
			string description = command.Description;
			string[] syntax = command.Syntax;
			return command.Name + (string.IsNullOrWhiteSpace(description) ? null : (" - " + description)) + "\n" + string.Join('\n', ((syntax.Length == 0) ? new string[1] : syntax).Select((string i) => string.Format("<color=#ffff00>{0}{1}</color>{2}", prefix, primaryName, string.IsNullOrWhiteSpace(i) ? null : (" <color=#dddd00><noparse>" + i + "</noparse></color>")))) + (includeSource ? ("\n<color=#888888><size=60%><b>" + command.FullName + "</b> in " + command.GetType().Assembly.GetName().Name + "</size></color>") : null);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}