Decompiled source of AtlyssCommandLib v0.0.7

AtlyssCommandLib.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using AtlyssCommandLib.API;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CodeTalker;
using CodeTalker.Networking;
using CodeTalker.Packets;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Nessie.ATLYSS.EasySettings;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Soggy_Pancake")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.0.7.0")]
[assembly: AssemblyInformationalVersion("0.0.7+40713065ecb1397c77ae4563d26fbf9e64b35e85")]
[assembly: AssemblyProduct("AtlyssCommandLib")]
[assembly: AssemblyTitle("AtlyssCommandLib")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.7.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AtlyssCommandLib
{
	internal static class BuiltInCmds
	{
		internal static bool Help(Caller caller, string[] args)
		{
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			string[] array = args;
			foreach (string text in array)
			{
				ManualLogSource? logger = Plugin.logger;
				if (logger != null)
				{
					logger.LogDebug((object)("Arg: \"" + text + "\""));
				}
			}
			CommandProvider provider = CommandManager.root;
			string currentArg = "";
			int num = 0;
			while (true)
			{
				ManualLogSource? logger2 = Plugin.logger;
				if (logger2 != null)
				{
					logger2.LogDebug((object)$"help loop {num + 1} len {args.Length}: {string.Concat(args)}");
				}
				if (num == args.Length || args[num] == "")
				{
					string text2 = Utils.buildHelpMessage(caller, provider);
					string[] array2 = Array.Empty<string>();
					try
					{
						array2 = (from a in provider.aliases
							where a.Value.isProvider && a.Value.provider == provider.childProviders[currentArg]
							select a.Key).ToArray();
					}
					catch
					{
					}
					if (array2.Length != 0)
					{
						text2 = text2 + "\nAliases: " + string.Join(", ", array2);
					}
					Utils.NotifyCaller(caller, text2);
					break;
				}
				currentArg = args[num].ToLower();
				if (provider.childProviders.ContainsKey(currentArg))
				{
					provider = provider.childProviders[currentArg];
					ManualLogSource? logger3 = Plugin.logger;
					if (logger3 != null)
					{
						logger3.LogDebug((object)("found provider " + currentArg));
					}
					if (args.Length > 1)
					{
						args = args[1..];
					}
					else
					{
						args[0] = "";
					}
					continue;
				}
				if (provider.commands.ContainsKey(currentArg) || (provider.aliases.ContainsKey(currentArg) && !provider.aliases[currentArg].isProvider))
				{
					ModCommand modCommand = ((!provider.aliases.ContainsKey(currentArg)) ? provider.commands[currentArg] : provider.aliases[currentArg].command);
					string text2 = "\n" + modCommand.getHelpMessage();
					text2 = text2 + "\n" + modCommand.getDetailedHelpMessage();
					text2 = text2.Trim();
					string[] array3 = Array.Empty<string>();
					try
					{
						array3 = (from a in provider.aliases
							where !a.Value.isProvider && a.Value.command == provider.commands[currentArg]
							select a.Key).ToArray();
					}
					catch
					{
					}
					if (array3.Length != 0)
					{
						text2 = text2 + "\nAliases: " + string.Join(", ", array3);
					}
					Utils.NotifyCaller(caller, text2.Trim());
				}
				else
				{
					provider.PrintHelp(caller, currentArg);
				}
				break;
			}
			return false;
		}

		internal static bool ChatColorProtector(Caller caller, string[] args)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if ((caller.isHost || (Object)(object)caller.player != (Object)(object)Player._mainPlayer) && !Plugin.chatColorsInstalled)
			{
				Utils.NotifyCaller(caller, "Chat Colors mod is not installed on the server. Cannot set chat color.", Color.red);
				return false;
			}
			if (args.Length != 1)
			{
				throw new ArgumentException("No arguments given!");
			}
			if (args[0].ToLower() == "clear")
			{
				return true;
			}
			string pattern = "^#([0-9A-Fa-f]{6})$";
			Regex regex = new Regex(pattern);
			if (!regex.IsMatch(args[0]))
			{
				throw new ArgumentException("Invalid color format! Use hex format like #RRGGBB or use /chatcolor clear to reset.");
			}
			return true;
		}

		internal static bool listMods(Caller caller, string[] args)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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)
			ConfigEntry<bool>? enableListingMods = ModConfig.enableListingMods;
			if (enableListingMods == null || !enableListingMods.Value)
			{
				Utils.NotifyCaller(caller, "Listing mods is disabled on this server.", Color.red);
				return true;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("Loaded mods:");
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				stringBuilder.AppendLine($"{pluginInfo.Value.Metadata.Name} - {pluginInfo.Value.Metadata.Version}");
			}
			string message = stringBuilder.ToString().TrimEnd();
			Utils.NotifyCaller(caller, message);
			return true;
		}

		internal static bool testClientSide(Caller caller, string[] args)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Utils.NotifyCaller(caller, "Echo from test clientside command for commandlib!", Color.red);
			return true;
		}

		internal static bool testServerSide(Caller caller, string[] args)
		{
			//IL_0006: 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)
			Utils.NotifyCaller(caller, "Echo from test clientside+serverside command for commandlib!", Color.red);
			if (args.Length == 0)
			{
				Utils.NotifyCaller(caller, "No arguments given to command!", Color.red);
				return false;
			}
			return true;
		}

		internal static bool testHostOnlyCmd(Caller caller, string[] args)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Utils.NotifyCaller(caller, "Echo from test hostonly command for commandlib!", Color.red);
			return true;
		}

		internal static bool testConsoleCmd(Caller caller, string[] args)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Utils.NotifyCaller(caller, "Echo from test consolecmd command for commandlib!", Color.red);
			return true;
		}
	}
	internal class CommandManager
	{
		internal static readonly CommandProvider root = new CommandProvider("/", "");

		internal static Dictionary<string, string> serverCommands = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

		internal static bool CommandIsInstalled(string command)
		{
			if (command == "chatcolor")
			{
				return Plugin.chatColorsInstalled;
			}
			return true;
		}

		internal static void updateServerCommands()
		{
			Player? obj = Player._mainPlayer.NC<Player>();
			if (obj != null && obj.Network_isHostPlayer)
			{
				return;
			}
			serverCommands.Clear();
			foreach (ModCommand value in root.commands.Values)
			{
				if (value.options.chatCommand == ChatCommandType.ServerSide && CommandIsInstalled(value.Command))
				{
					serverCommands[value.Command] = value.getHelpMessage();
				}
			}
			foreach (CommandProvider value2 in root.childProviders.Values)
			{
				if (value2.hasServerCommands)
				{
					serverCommands[value2.prefix] = value2.getHelpMessage();
				}
			}
		}

		internal static void updateServerCommands(PacketHeader header, BinaryPacketBase pkt)
		{
			Player? obj = Player._mainPlayer.NC<Player>();
			if (obj == null || obj.Network_isHostPlayer || !(pkt is ServerCommandPkt serverCommandPkt))
			{
				return;
			}
			serverCommands.Clear();
			foreach (ServerCommandPkt.Entry entry in serverCommandPkt.entries)
			{
				serverCommands[entry.prefix] = entry.helpMessage;
			}
		}

		internal static bool execCommand(ModCommand cmd, Caller caller, string[] args)
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: 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_0151: 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)
			try
			{
				ManualLogSource? logger = Plugin.logger;
				if (logger != null)
				{
					logger.LogDebug((object)$"Processing command {caller.cmdPrefix} - options {cmd.options} - caller {caller}");
				}
				bool flag = cmd.Callback(caller, args);
				if (!flag)
				{
					cmd.printHelp(caller);
				}
				return flag;
			}
			catch (ArgumentException ex)
			{
				if (!string.IsNullOrEmpty(ex.Message) && string.IsNullOrEmpty(ex.ParamName))
				{
					Utils.NotifyCaller(caller, "Recieved invalid arguments for command '" + caller.cmdPrefix + " " + string.Join(" ", args) + "' Reason: " + ex.Message, Color.yellow);
				}
				else if (!string.IsNullOrEmpty(ex.ParamName) && !string.IsNullOrEmpty(ex.Message))
				{
					Utils.NotifyCaller(caller, "'" + ex.ParamName + "' is invalid! Reason: " + ex.Message);
				}
				else
				{
					Utils.NotifyCaller(caller, "Recieved invalid arguments for command '" + caller.cmdPrefix + " " + string.Join(" ", args) + "' Error: " + ex);
				}
				cmd.printHelp(caller);
				return false;
			}
			catch (Exception ex2)
			{
				ManualLogSource? logger2 = Plugin.logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Error executing command '" + caller.cmdPrefix + " " + string.Join(" ", args) + "' Error: " + ex2));
				}
				cmd.printHelp(caller);
				return false;
			}
		}
	}
	internal class ModConfig
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__5_0;

			public static UnityAction <>9__5_1;

			internal void <easySettings>b__5_0()
			{
				ConfigFile? configFile = ModConfig.configFile;
				if (configFile != null)
				{
					configFile.Save();
				}
			}

			internal void <easySettings>b__5_1()
			{
				SettingsTab modTab = Settings.ModTab;
				modTab.AddHeader("Atlyss Command Lib Settings");
				modTab.AddToggle(enableListingMods);
				modTab.AddToggle(sendFailedCommands);
			}
		}

		public static ConfigFile? configFile;

		public static ConfigEntry<bool>? enableListingMods;

		public static ConfigEntry<bool>? enableTestCommands;

		public static ConfigEntry<bool>? sendFailedCommands;

		public static void init(ConfigFile config)
		{
			configFile = config;
			enableListingMods = config.Bind<bool>("General", "EnableModListing", true, "Enable the /mods command to list server mods.");
			enableTestCommands = config.Bind<bool>("General", "EnableTestCommands", true, "Enable commands for testing CommandLib.");
			sendFailedCommands = config.Bind<bool>("General", "sendFailedCommandsToServer", true, "If a command fails to parse on the client side, still send it to the server. Useful for commands that only run server side. CommandLib will no longer print the error help message! The server will still block commands from properly entering chat, but if the server is vanilla it will enter chat!");
			if (!Chainloader.PluginInfos.ContainsKey("EasySettings"))
			{
				return;
			}
			try
			{
				ManualLogSource? logger = Plugin.logger;
				if (logger != null)
				{
					logger.LogInfo((object)"EasySettings detected, adding settings tab.");
				}
				easySettings();
			}
			catch
			{
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void easySettings()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			UnityEvent onApplySettings = Settings.OnApplySettings;
			object obj = <>c.<>9__5_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					ConfigFile? obj3 = configFile;
					if (obj3 != null)
					{
						obj3.Save();
					}
				};
				<>c.<>9__5_0 = val;
				obj = (object)val;
			}
			onApplySettings.AddListener((UnityAction)obj);
			UnityEvent onInitialized = Settings.OnInitialized;
			object obj2 = <>c.<>9__5_1;
			if (obj2 == null)
			{
				UnityAction val2 = delegate
				{
					SettingsTab modTab = Settings.ModTab;
					modTab.AddHeader("Atlyss Command Lib Settings");
					modTab.AddToggle(enableListingMods);
					modTab.AddToggle(sendFailedCommands);
				};
				<>c.<>9__5_1 = val2;
				obj2 = (object)val2;
			}
			onInitialized.AddListener((UnityAction)obj2);
		}
	}
	internal class ServerCommandPkt : BinaryPacketBase
	{
		internal struct Entry
		{
			public string prefix;

			public string helpMessage;
		}

		public List<Entry> entries = new List<Entry>();

		public override string PacketSignature => "ACL_ServerCmds";

		public override byte[] Serialize()
		{
			CommandManager.updateServerCommands();
			MemoryStream memoryStream = new MemoryStream();
			BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
			binaryWriter.Write((byte)CommandManager.serverCommands.Count);
			foreach (KeyValuePair<string, string> serverCommand in CommandManager.serverCommands)
			{
				binaryWriter.Write(Encoding.UTF8.GetBytes(serverCommand.Key + "\0"));
				binaryWriter.Write(Encoding.UTF8.GetBytes(serverCommand.Value + "\0"));
			}
			ManualLogSource? logger = Plugin.logger;
			if (logger != null)
			{
				logger.LogMessage((object)("Full servercmd hex: " + BitConverter.ToString(memoryStream.ToArray()).Replace("-", "")));
			}
			return memoryStream.ToArray();
		}

		public override void Deserialize(byte[] data)
		{
			MemoryStream memoryStream = new MemoryStream(data);
			BinaryReader binaryReader = new BinaryReader(memoryStream);
			byte b = binaryReader.ReadByte();
			short num = 1;
			short num2 = 0;
			short num3 = 0;
			while (memoryStream.Position < memoryStream.Length)
			{
				if (binaryReader.Read() == 0)
				{
					if (num2 == 0)
					{
						num2 = (short)memoryStream.Position;
					}
					else if (num3 == 0)
					{
						num3 = (short)memoryStream.Position;
						string @string = Encoding.UTF8.GetString(data, num, num2 - num - 1);
						string string2 = Encoding.UTF8.GetString(data, num2, num3 - num2 - 1);
						entries.Add(new Entry
						{
							prefix = @string,
							helpMessage = string2
						});
						num2 = 0;
						num3 = 0;
						num = (short)memoryStream.Position;
					}
				}
			}
			if (entries.Count != b)
			{
				ManualLogSource? logger = Plugin.logger;
				if (logger != null)
				{
					logger.LogWarning((object)$"Expected {b} server commands but got {entries.Count}!");
				}
			}
		}
	}
	internal static class Patches
	{
		public static bool blockMsg;

		public static string[] commandSplit(string message)
		{
			return (from Match m in Regex.Matches(message, "[\\\"].+?[\\\"]|[^ ]+")
				select m.Value.Trim('"') into m
				where !string.IsNullOrWhiteSpace(m)
				select m).ToArray();
		}

		public static bool getValidCommand(string message, out string[] args)
		{
			args = Array.Empty<string>();
			Match match = Regex.Match(message, "<color=.*>(.*)<\\/color>");
			if (match.Success)
			{
				message = match.Groups[1].Value;
			}
			if (!message.StartsWith('/') || message.StartsWith("//") || message.Length == 0)
			{
				return false;
			}
			string text = message;
			message = text.Substring(1, text.Length - 1);
			args = commandSplit(message);
			return args.Length != 0;
		}

		[HarmonyPrefix]
		[HarmonyPriority(int.MaxValue)]
		[HarmonyPatch(typeof(ChatBehaviour), "Cmd_SendChatMessage")]
		internal static void Client_SendChatMessage(ref ChatBehaviour __instance, ref bool __runOriginal, string _message)
		{
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			if (!getValidCommand(_message, out string[] args))
			{
				return;
			}
			Caller caller = new Caller(args[0], Player._mainPlayer);
			var (commandProvider, modCommand, args2) = CommandManager.root.resolveCommand(args);
			if (modCommand != null)
			{
				CommandOptions options = modCommand.options;
				if (options.chatCommand == ChatCommandType.ClientSide || (options.chatCommand == ChatCommandType.HostOnly && caller.isHost))
				{
					ManualLogSource? logger = Plugin.logger;
					if (logger != null)
					{
						logger.LogDebug((object)("Procesing command " + _message + " in Client_SendChatMessage"));
					}
					CommandManager.execCommand(modCommand, caller, args2);
					blockMsg = true;
					__runOriginal = false;
				}
				else if (options.chatCommand == ChatCommandType.ServerSide)
				{
					ManualLogSource? logger2 = Plugin.logger;
					if (logger2 != null)
					{
						logger2.LogDebug((object)("Sending command " + _message + " in Client_SendChatMessage to the server"));
					}
					__runOriginal = true;
				}
				else
				{
					ManualLogSource? logger3 = Plugin.logger;
					if (logger3 != null)
					{
						logger3.LogDebug((object)string.Format("Caller {0} is not allowed to use command {1} in {2}", caller, modCommand, "Client_SendChatMessage"));
					}
					blockMsg = true;
					__runOriginal = false;
				}
				return;
			}
			if (commandProvider == CommandProvider.Root)
			{
				if (!caller.isHost && CommandManager.serverCommands.ContainsKey(args[0]))
				{
					ManualLogSource? logger4 = Plugin.logger;
					if (logger4 != null)
					{
						logger4.LogDebug((object)("Sending known server command " + _message + " in Client_SendChatMessage to the server"));
					}
					__runOriginal = true;
					return;
				}
				ConfigEntry<bool>? sendFailedCommands = ModConfig.sendFailedCommands;
				if (sendFailedCommands != null && sendFailedCommands.Value)
				{
					ManualLogSource? logger5 = Plugin.logger;
					if (logger5 != null)
					{
						logger5.LogDebug((object)("Allowing failed root level command " + _message + " to go through in Client_SendChatMessage!"));
					}
					__runOriginal = true;
					return;
				}
			}
			Utils.NotifyCaller(caller, commandProvider.GetNotFoundHelpCommand(args[^1]));
			blockMsg = true;
			__runOriginal = false;
		}

		[HarmonyPrefix]
		[HarmonyPriority(int.MinValue)]
		[HarmonyPatch(typeof(ChatBehaviour), "Cmd_SendChatMessage")]
		internal static void Client_BlockChatMessage(ref ChatBehaviour __instance, ref string _message, ref bool __runOriginal)
		{
			if (blockMsg)
			{
				__runOriginal = false;
			}
			blockMsg = false;
		}

		[HarmonyPrefix]
		[HarmonyPriority(int.MinValue)]
		[HarmonyPatch(typeof(ChatBehaviour), "Rpc_RecieveChatMessage")]
		internal static void Server_RecieveChatMessage(ref ChatBehaviour __instance, ref bool __runOriginal, string message)
		{
			if ((Object)(object)__instance == (Object)null || !getValidCommand(message, out string[] args))
			{
				return;
			}
			Caller caller = new Caller(args[0], ((Component)__instance).gameObject.GetComponent<Player>());
			var (commandProvider, modCommand, args2) = CommandManager.root.resolveCommand(args);
			if (modCommand == null)
			{
				return;
			}
			CommandOptions options = modCommand.options;
			if (options.chatCommand == ChatCommandType.ServerSide)
			{
				ManualLogSource? logger = Plugin.logger;
				if (logger != null)
				{
					logger.LogDebug((object)("Procesing command " + message + " in Server_RecieveChatMessage"));
				}
				CommandManager.execCommand(modCommand, caller, args2);
				__runOriginal = options.mustRunVanillaCode;
			}
			else
			{
				__runOriginal = false;
			}
		}

		[HarmonyPrefix]
		[HarmonyPriority(int.MinValue)]
		[HarmonyPatch(typeof(HostConsole), "Send_ServerMessage")]
		internal static void Console_RecieveCommand(ref HostConsole __instance, string _message, ref bool __runOriginal)
		{
			if (!getValidCommand(_message, out string[] args))
			{
				return;
			}
			Caller caller = new Caller(args[0], null, console: true);
			(CommandProvider provider, ModCommand? resolvedCommand, string[] rest) tuple = CommandManager.root.resolveCommand(args);
			ModCommand item = tuple.resolvedCommand;
			string[] item2 = tuple.rest;
			if (item != null)
			{
				CommandOptions options = item.options;
				if (options.consoleCmd)
				{
					ManualLogSource? logger = Plugin.logger;
					if (logger != null)
					{
						logger.LogDebug((object)("Procesing command " + _message + " in Console_RecieveCommand"));
					}
					CommandManager.execCommand(item, caller, item2);
					__runOriginal = options.mustRunVanillaCode;
				}
				else
				{
					ManualLogSource? logger2 = Plugin.logger;
					if (logger2 != null)
					{
						logger2.LogDebug((object)string.Format("Caller {0} is not allowed to use command {1} in {2}", caller, item, "Console_RecieveCommand"));
					}
					__runOriginal = false;
				}
			}
			__instance._consoleInputField.text = "";
		}

		[HarmonyPatch(typeof(PlayerMove), "Start")]
		[HarmonyPostfix]
		internal static void SendCommandList(PlayerMove __instance)
		{
			Player? obj = Player._mainPlayer.NC<Player>();
			if (obj == null || !obj._isHostPlayer)
			{
				return;
			}
			Player component = ((Component)__instance).GetComponent<Player>();
			if ((Object)(object)component != (Object)null && (Object)(object)component != (Object)(object)Player._mainPlayer)
			{
				ManualLogSource? logger = Plugin.logger;
				if (logger != null)
				{
					logger.LogDebug((object)"sending server command list!");
				}
				CodeTalkerNetwork.SendNetworkPacket(component, (BinaryPacketBase)(object)new ServerCommandPkt(), (CompressionType)1, CompressionLevel.Fastest);
			}
		}

		[HarmonyPatch(typeof(AtlyssNetworkManager), "OnStartServer")]
		[HarmonyPostfix]
		internal static void StartHosting()
		{
			CommandManager.updateServerCommands();
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Soggy_Pancake.CommandLib", "AtlyssCommandLib", "0.0.7")]
	internal class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static BinaryPacketListener <0>__updateServerCommands;

			public static CommandCallback <1>__Help;

			public static CommandCallback <2>__listMods;

			public static CommandCallback <3>__ChatColorProtector;

			public static CommandCallback <4>__testClientSide;

			public static CommandCallback <5>__testServerSide;

			public static CommandCallback <6>__testHostOnlyCmd;

			public static CommandCallback <7>__testConsoleCmd;
		}

		internal static ManualLogSource? logger;

		internal static Harmony? harmony;

		internal static bool chatColorsInstalled;

		private void Awake()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_00c7: 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_00d2: Expected O, but got Unknown
			logger = ((BaseUnityPlugin)this).Logger;
			logger.LogInfo((object)"Plugin AtlyssCommandLib is loaded!");
			if (Application.version != "12026.a3")
			{
				logger.LogWarning((object)("[VERSION MISMATCH] This version of AtlyssCommandLib is made for 12026.a3, you are running " + Application.version + "."));
			}
			harmony = new Harmony("Soggy_Pancake.CommandLib");
			harmony.PatchAll(typeof(Patches));
			ModConfig.init(((BaseUnityPlugin)this).Config);
			chatColorsInstalled = Chainloader.PluginInfos.ContainsKey("StuntedRaccoon.CustomChatColors");
			logger.LogInfo((object)("Chatcolors " + (chatColorsInstalled ? "is" : "isn't") + " installed!"));
			object obj = <>O.<0>__updateServerCommands;
			if (obj == null)
			{
				BinaryPacketListener val = CommandManager.updateServerCommands;
				<>O.<0>__updateServerCommands = val;
				obj = (object)val;
			}
			CodeTalkerNetwork.RegisterBinaryListener<ServerCommandPkt>((BinaryPacketListener)obj);
			Utils.RegisterCommand("help", "Shows this help message", BuiltInCmds.Help, new CommandOptions(ChatCommandType.ClientSide, consoleCmd: true));
			Utils.RegisterCommand("mods", "List server's installed mods!", BuiltInCmds.listMods, new CommandOptions(ChatCommandType.ServerSide));
			registerVanillaCommands();
			addCommandCompatibility();
			ConfigEntry<bool>? enableTestCommands = ModConfig.enableTestCommands;
			if (enableTestCommands != null && enableTestCommands.Value)
			{
				registerTestCommands();
			}
		}

		private void registerVanillaCommands()
		{
			CommandOptions commandOptions = new CommandOptions(ChatCommandType.ClientSide);
			commandOptions.mustRunVanillaCode = true;
			CommandOptions value = commandOptions;
			Utils.RegisterCommand("emotes", "Lists all available emotes", vanillaCommandDummyCallback, value);
			commandOptions = new CommandOptions(ChatCommandType.ServerSide);
			commandOptions.mustRunVanillaCode = true;
			CommandOptions value2 = commandOptions;
			Utils.RegisterCommand("afk", "Go afk", vanillaCommandDummyCallback, value2);
			commandOptions = new CommandOptions(ChatCommandType.None, consoleCmd: true);
			commandOptions.mustRunVanillaCode = true;
			CommandOptions value3 = commandOptions;
			Utils.RegisterCommand("shutdown", "Shuts down the server with optional countdown.", vanillaCommandDummyCallback, value3);
			Utils.RegisterCommand("cancelsd", "Cancel shutting down the server.", vanillaCommandDummyCallback, value3);
			Utils.RegisterCommand("starthost", "initalizes the server. Server instance must be shut down to initalize.", vanillaCommandDummyCallback, value3);
			Utils.RegisterCommand("kick", "kicks a connected client. Must have a output of the connection ID number. (ex: /kick 2)", vanillaCommandDummyCallback, value3);
			Utils.RegisterCommand("ban", "same as kick, but also bans the client's address from connecting to the server. (ex: /ban 2)", vanillaCommandDummyCallback, value3);
			Utils.RegisterCommand("clearbanlist", "clears the list of bans saved in your host settings profile.", vanillaCommandDummyCallback, value3);
			Utils.RegisterCommand("clients", "displays all clients that are connected to the server with Connnection IDs.", vanillaCommandDummyCallback, value3);
			Utils.RegisterCommand("maplist", "displays all loaded map instances on the server.", vanillaCommandDummyCallback, value3);
			Utils.RegisterCommand("savelog", "clears console log.", vanillaCommandDummyCallback, value3);
			commandOptions = new CommandOptions(ChatCommandType.ClientSide, consoleCmd: true);
			commandOptions.mustRunVanillaCode = true;
			CommandOptions value4 = commandOptions;
			Utils.RegisterCommand("clear", "clears chat or console log.", vanillaCommandDummyCallback, value4);
		}

		private void addCommandCompatibility()
		{
			Utils.RegisterCommand(options: new CommandOptions(ChatCommandType.ServerSide), command: "chatcolor", helpMessage: "Set your chat color using a hex code! /chatcolor #[color]. HASHTAG REQUIRED", callback: BuiltInCmds.ChatColorProtector);
		}

		private bool vanillaCommandDummyCallback(Caller caller, string[] args)
		{
			ManualLogSource? obj = logger;
			if (obj != null)
			{
				obj.LogDebug((object)("Vanilla command '" + caller.cmdPrefix + "' called!"));
			}
			return true;
		}

		private void registerTestCommands()
		{
			Utils.RegisterCommand("test-cs", "Run a clientside command", BuiltInCmds.testClientSide, new CommandOptions(ChatCommandType.ClientSide));
			Utils.RegisterCommand("test-ss", "Run a serverside command", BuiltInCmds.testServerSide, new CommandOptions(ChatCommandType.ServerSide));
			Utils.RegisterCommand("test-host", "Run a host only command", BuiltInCmds.testHostOnlyCmd, new CommandOptions(ChatCommandType.HostOnly));
			Utils.RegisterCommand("test-cons", "Run a console command", BuiltInCmds.testConsoleCmd, new CommandOptions(ChatCommandType.None, consoleCmd: true));
		}
	}
	internal static class PluginInfo
	{
		internal const string GUID = "Soggy_Pancake.CommandLib";

		internal const string NAME = "AtlyssCommandLib";

		internal const string GAMEVER = "12026.a3";

		internal const string VERSION = "0.0.7";
	}
	internal static class UnityNullFix
	{
		public static T? NC<T>(this T? obj) where T : Object
		{
			if (!Object.op_Implicit((Object)(object)obj))
			{
				return default(T);
			}
			return obj;
		}
	}
}
namespace AtlyssCommandLib.API
{
	public struct Caller
	{
		public Player? player;

		public readonly bool isConsole;

		internal string cmdPrefix;

		public bool isHost
		{
			get
			{
				Player? obj = player;
				if (obj == null)
				{
					return isConsole;
				}
				return obj.Network_isHostPlayer;
			}
		}

		public readonly bool IsRemote => (Object)(object)player != (Object)(object)Player._mainPlayer;

		internal Caller(string prefix, Player? _player, bool console = false)
		{
			cmdPrefix = prefix;
			player = _player;
			isConsole = console;
		}

		internal Caller(string prefix, ChatBehaviour chatBehaviour)
		{
			isConsole = false;
			cmdPrefix = prefix;
			player = ((Component)chatBehaviour).GetComponent<Player>();
		}

		public override string ToString()
		{
			return $"Player {player?._nickname} (console {isConsole}, remote {IsRemote})";
		}
	}
	public enum ChatCommandType
	{
		None,
		ClientSide,
		HostOnly,
		ServerSide
	}
	public struct CommandOptions
	{
		public ChatCommandType chatCommand;

		public bool consoleCmd;

		internal bool mustRunVanillaCode;

		public CommandOptions()
		{
			mustRunVanillaCode = false;
			chatCommand = ChatCommandType.ClientSide;
			consoleCmd = false;
		}

		public CommandOptions(ChatCommandType chatCommand)
		{
			mustRunVanillaCode = false;
			this.chatCommand = chatCommand;
			consoleCmd = false;
		}

		public CommandOptions(ChatCommandType chatCommand, bool consoleCmd)
		{
			mustRunVanillaCode = false;
			this.chatCommand = chatCommand;
			this.consoleCmd = consoleCmd;
		}

		[Obsolete("Use the ChatCommandType variant")]
		public CommandOptions(bool clientSide = false, bool serverSide = false, bool consoleCmd = false, bool hostOnly = false)
		{
			mustRunVanillaCode = false;
			this.consoleCmd = consoleCmd;
			if (hostOnly)
			{
				chatCommand = ChatCommandType.HostOnly;
			}
			else if (serverSide)
			{
				chatCommand = ChatCommandType.ServerSide;
			}
			else if (clientSide)
			{
				chatCommand = ChatCommandType.ClientSide;
			}
			else
			{
				chatCommand = ChatCommandType.None;
			}
		}

		public override string ToString()
		{
			return $"[chatCommand = {chatCommand}, consoleCmd = {consoleCmd}]";
		}
	}
	public delegate bool CommandCallback(Caller caller, string[] args);
	public class CommandProvider
	{
		internal struct Alias
		{
			public bool isProvider;

			public ModCommand command;

			public CommandProvider provider;
		}

		internal string prefix;

		internal string helpHeader;

		internal bool hasClientCommands;

		internal bool hasServerCommands;

		internal bool hasConsoleCommands;

		internal bool hasHostOnlyCommands;

		internal CommandProvider? _parentProvider;

		internal Dictionary<string, Alias> aliases = new Dictionary<string, Alias>(StringComparer.OrdinalIgnoreCase);

		internal Dictionary<string, ModCommand> commands = new Dictionary<string, ModCommand>(StringComparer.OrdinalIgnoreCase);

		internal Dictionary<string, CommandProvider> childProviders = new Dictionary<string, CommandProvider>(StringComparer.OrdinalIgnoreCase);

		public static CommandProvider Root => CommandManager.root;

		public CommandProvider? ParentProvider => _parentProvider;

		public CommandProvider(string prefix, string header)
		{
			this.prefix = prefix;
			helpHeader = header;
			_parentProvider = null;
		}

		public CommandProvider(string prefix, string header, CommandProvider? parentProvider = null)
		{
			this.prefix = prefix;
			helpHeader = header;
			_parentProvider = parentProvider ?? CommandManager.root;
			ParentProvider?.RegisterProvider(this);
		}

		public ModCommand? RegisterCommand(string command, string helpMessage, CommandCallback callback, CommandOptions? options = null)
		{
			if (command.StartsWith('/'))
			{
				string text = command;
				command = text.Substring(1, text.Length - 1);
			}
			if (command.Contains(' '))
			{
				ManualLogSource? logger = Plugin.logger;
				if (logger != null)
				{
					logger.LogError((object)("Command '" + command + "' contains spaces! Not registering Command!"));
				}
				return null;
			}
			ModCommand modCommand = new ModCommand(command, helpMessage, callback, options ?? new CommandOptions());
			RegisterCommand(modCommand);
			return modCommand;
		}

		public ModCommand? RegisterCommand(string command, string helpMessage, string detailedHelpMessage, CommandCallback callback, CommandOptions? options = null)
		{
			if (command.StartsWith('/'))
			{
				string text = command;
				command = text.Substring(1, text.Length - 1);
			}
			if (command.Contains(' '))
			{
				ManualLogSource? logger = Plugin.logger;
				if (logger != null)
				{
					logger.LogError((object)("Command '" + command + "' contains spaces! Not registering Command!"));
				}
				return null;
			}
			ModCommand modCommand = new ModCommand(command, helpMessage, detailedHelpMessage, callback, options ?? new CommandOptions());
			RegisterCommand(modCommand);
			return modCommand;
		}

		public void RegisterCommand(ModCommand cmd)
		{
			CommandOptions options = cmd.options;
			if (commands.ContainsKey(cmd.Command) || aliases.ContainsKey(cmd.Command))
			{
				ManualLogSource? logger = Plugin.logger;
				if (logger != null)
				{
					logger.LogError((object)("Failed to register Command '" + cmd.Command + "'! Command or alias with that name already exists!"));
				}
				return;
			}
			if (!Enum.IsDefined(typeof(ChatCommandType), options.chatCommand))
			{
				ManualLogSource? logger2 = Plugin.logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Failed to register Command '" + cmd.Command + "'! Command has to have a valid chat command type!"));
				}
				return;
			}
			commands.Add(cmd.Command, cmd);
			CommandProvider commandProvider = this;
			CommandOptions options2 = cmd.options;
			while (commandProvider != null)
			{
				commandProvider.hasClientCommands = commandProvider.hasClientCommands || options2.chatCommand == ChatCommandType.ClientSide;
				commandProvider.hasServerCommands = commandProvider.hasServerCommands || options2.chatCommand == ChatCommandType.ServerSide;
				commandProvider.hasConsoleCommands = commandProvider.hasConsoleCommands || options2.consoleCmd;
				commandProvider.hasHostOnlyCommands = commandProvider.hasHostOnlyCommands || options2.chatCommand == ChatCommandType.HostOnly;
				commandProvider = commandProvider.ParentProvider;
			}
		}

		public void RegisterProvider(CommandProvider provider)
		{
			if (!childProviders.ContainsKey(provider.prefix) && !aliases.ContainsKey(provider.prefix))
			{
				childProviders.Add(provider.prefix, provider);
				provider._parentProvider = this;
				ManualLogSource? logger = Plugin.logger;
				if (logger != null)
				{
					logger.LogInfo((object)("Registered Command command '" + provider.prefix + "' under '" + prefix + "'"));
				}
			}
		}

		public void RegisterAlias(string alias, ModCommand? command)
		{
			if (command != null && !commands.ContainsKey(alias) && !aliases.ContainsKey(alias))
			{
				aliases.Add(alias, new Alias
				{
					isProvider = false,
					command = command
				});
			}
		}

		public void RegisterAlias(string[] aliases, ModCommand? command)
		{
			if (command == null)
			{
				return;
			}
			foreach (string text in aliases)
			{
				if (commands.ContainsKey(text) || this.aliases.ContainsKey(text))
				{
					break;
				}
				RegisterAlias(text, command);
			}
		}

		public void RegisterAlias(string alias, CommandProvider? provider)
		{
			if (provider != null && !commands.ContainsKey(alias) && !aliases.ContainsKey(alias))
			{
				aliases.Add(alias, new Alias
				{
					isProvider = true,
					provider = provider
				});
			}
		}

		public void RegisterAlias(string[] aliases, CommandProvider? provider)
		{
			if (provider == null)
			{
				return;
			}
			foreach (string text in aliases)
			{
				if (commands.ContainsKey(text) || this.aliases.ContainsKey(text))
				{
					break;
				}
				RegisterAlias(text, provider);
			}
		}

		internal (CommandProvider provider, ModCommand? resolvedCommand, string[] rest) resolveCommand(string[] args)
		{
			if (args.Length == 0)
			{
				return (this, null, Array.Empty<string>());
			}
			string key = args[0];
			string[] item = ((args.Length > 1) ? args[1..] : Array.Empty<string>());
			if (commands.TryGetValue(key, out ModCommand value))
			{
				return (this, value, item);
			}
			if (aliases.TryGetValue(key, out var value2) && !value2.isProvider)
			{
				return (this, value2.command, item);
			}
			if (childProviders.TryGetValue(key, out CommandProvider value3))
			{
				return value3.resolveCommand(args[1..]);
			}
			if (aliases.TryGetValue(key, out var value4) && value4.isProvider)
			{
				return value4.provider.resolveCommand(args[1..]);
			}
			return (this, null, Array.Empty<string>());
		}

		internal string GetNotFoundHelpCommand(string command)
		{
			return "\nCommand '" + command + "' not found! Use /help " + Utils.GetProviderPath(this) + "to list available comands";
		}

		public string getHelpMessage()
		{
			return helpHeader;
		}

		public virtual void PrintHelp(Caller caller, string cmd)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			string text = "";
			if (helpHeader != "")
			{
				text = text + "\n" + helpHeader + "\n\n";
			}
			text += Utils.buildHelpMessage(caller, this);
			text = text + "\nCommand '" + cmd + "' not found! Use /help " + Utils.GetProviderPath(this) + "to list available comands";
			Utils.NotifyCaller(caller, text);
		}
	}
	public class ModCommand
	{
		internal string Command;

		private string HelpMessage = "";

		private string DetailedHelpMessage = "";

		internal CommandCallback Callback;

		internal CommandOptions options;

		public ModCommand(string command, string helpMessage, CommandCallback callback, CommandOptions options)
		{
			Command = command;
			HelpMessage = helpMessage.Trim();
			Callback = callback;
			this.options = options;
		}

		public ModCommand(string command, string helpMessage, string detailedHelp, CommandCallback callback, CommandOptions options)
		{
			Command = command;
			HelpMessage = helpMessage.Trim();
			DetailedHelpMessage = detailedHelp.Trim();
			Callback = callback;
			this.options = options;
		}

		public void printHelp(Caller caller)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			string message = "/" + Command + " - " + HelpMessage + " " + DetailedHelpMessage;
			Utils.NotifyCaller(caller, message);
		}

		public string getHelpMessage()
		{
			return HelpMessage;
		}

		public string getDetailedHelpMessage()
		{
			return DetailedHelpMessage;
		}

		public override string ToString()
		{
			return $"{Command} {options}";
		}
	}
	public class Utils
	{
		public static ModCommand? RegisterCommand(string command, string helpMessage, CommandCallback callback, CommandOptions? options = null)
		{
			return CommandManager.root.RegisterCommand(command, helpMessage, callback, options ?? new CommandOptions());
		}

		public static ModCommand? RegisterCommand(string command, string helpMessage, string detailedHelpMessage, CommandCallback callback, CommandOptions? options = null)
		{
			return CommandManager.root.RegisterCommand(command, helpMessage, detailedHelpMessage, callback, options ?? new CommandOptions());
		}

		public static void RegisterCommand(ModCommand command)
		{
			CommandManager.root.RegisterCommand(command);
		}

		public static void RegisterProvider(CommandProvider provider)
		{
			CommandManager.root.RegisterProvider(provider);
		}

		public static void RegisterAlias(string alias, ModCommand? command)
		{
			CommandManager.root.RegisterAlias(alias, command);
		}

		public static void RegisterAlias(string[] aliases, ModCommand? command)
		{
			CommandManager.root.RegisterAlias(aliases, command);
		}

		public static void RegisterAlias(string alias, CommandProvider? provider)
		{
			CommandManager.root.RegisterAlias(alias, provider);
		}

		public static void RegisterAlias(string[] aliases, CommandProvider? provider)
		{
			CommandManager.root.RegisterAlias(aliases, provider);
		}

		public static void NotifyCaller(Caller caller, string message, Color color = default(Color))
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			if (caller.isConsole)
			{
				HostConsole? obj = HostConsole._current.NC<HostConsole>();
				if (obj != null)
				{
					obj.New_LogMessage(message);
				}
				return;
			}
			if ((Object)(object)caller.player == (Object)(object)Player._mainPlayer)
			{
				if (color == default(Color))
				{
					color = Color.white;
				}
				Player._mainPlayer._chatBehaviour.New_ChatMessage("<color=#" + ColorUtility.ToHtmlStringRGB(color) + ">" + message + "</color>");
				return;
			}
			if (color == default(Color))
			{
				color = Color.white;
			}
			Player? player = caller.player;
			if (player != null)
			{
				player._chatBehaviour.Target_RecieveMessage("<color=#" + ColorUtility.ToHtmlStringRGB(color) + ">" + message + "</color>");
			}
		}

		public static string GetProviderPath(CommandProvider provider)
		{
			List<string> list = new List<string>();
			CommandProvider commandProvider = provider;
			while (commandProvider?.ParentProvider != null)
			{
				list.Add(commandProvider.prefix);
				commandProvider = commandProvider.ParentProvider;
			}
			string result = "";
			if (list.Count > 0)
			{
				list.Reverse();
				result = string.Join(' ', list);
				result += " ";
			}
			return result;
		}

		public static string buildHelpMessage(Caller caller, CommandProvider provider)
		{
			string path = GetProviderPath(provider);
			string[] array = getCommands(provider);
			if (provider == CommandProvider.Root)
			{
				array = array.Concat(CommandManager.serverCommands.Keys).Distinct().ToArray();
			}
			string[] source = array.Select((string c) => path + c).ToArray();
			int num = source.Max((string c) => c.Length);
			num = ((num - 1) / 4 + 1) * 4;
			string text = "Available commands: \n";
			foreach (string text2 in array)
			{
				string text3 = path + text2;
				text = text + "/" + text3.PadRight(num) + " - " + ((provider.commands.ContainsKey(text2) ? provider.commands[text2].getHelpMessage() : null) ?? (provider.childProviders.ContainsKey(text2) ? provider.childProviders[text2]?.getHelpMessage() : "ERROR")) + "\n";
			}
			return text.TrimEnd();
			string[] getCommands(CommandProvider provider)
			{
				bool remotePlayer = caller.IsRemote;
				return (from cmd in provider.commands.Where<KeyValuePair<string, ModCommand>>(delegate(KeyValuePair<string, ModCommand> cmd)
					{
						CommandOptions options = cmd.Value.options;
						return (caller.isConsole && options.consoleCmd) || (caller.isHost && (options.chatCommand == ChatCommandType.HostOnly || options.chatCommand == ChatCommandType.ServerSide || options.chatCommand == ChatCommandType.ClientSide)) || (!remotePlayer && options.chatCommand == ChatCommandType.ClientSide);
					})
					select cmd.Key).Concat(from s in provider.childProviders.Where<KeyValuePair<string, CommandProvider>>(delegate(KeyValuePair<string, CommandProvider> pbj)
					{
						CommandProvider value = pbj.Value;
						return (caller.isConsole && (value.hasConsoleCommands || value.hasServerCommands)) || (caller.isHost && (value.hasServerCommands || value.hasHostOnlyCommands)) || (!remotePlayer && value.hasClientCommands);
					})
					select s.Key).Distinct().ToArray();
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}