Decompiled source of Console v1.1.0

Console.dll

Decompiled 4 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ComputerysModdingUtilities;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: StraftatMod(true)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Console")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+7bdc02d0ae2e9b8ae8794b3d0c852ce375e42442")]
[assembly: AssemblyProduct("Console")]
[assembly: AssemblyTitle("Console")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 StraftatConsole
{
	public static class BuiltinCommands
	{
		public static void Register(ManualLogSource log)
		{
			ConsoleCommands.Register("help", "help [command]", "List commands, or show help for one.", Help);
			ConsoleCommands.Register("clear", "clear", "Clear the console.", delegate
			{
				SourceConsole.Clear();
			});
			ConsoleCommands.Register("history", "history", "Show the command history.", History);
			ConsoleCommands.Register("echo", "echo <text>", "Print text to the console.", Echo);
			ConsoleCommands.Register("scene", "scene", "Name of the active scene.", Scene);
			log.LogInfo((object)$"[Console] commands registered: {ConsoleCommands.All.Count()}");
		}

		private static void Help(string[] args)
		{
			if (args.Length > 1)
			{
				if (ConsoleCommands.TryGet(args[1], out var cmd))
				{
					SourceConsole.Print(cmd.Usage ?? "");
					SourceConsole.Print("  " + cmd.Help);
				}
				else
				{
					SourceConsole.Print("Unknown command: " + args[1]);
				}
				return;
			}
			SourceConsole.Print("Commands:");
			foreach (ConsoleCommand item in ConsoleCommands.All)
			{
				SourceConsole.Print($"  {item.Usage,-38} {item.Help}");
			}
			List<KeyValuePair<string, int>> list = ConfigCvars.CountsByPrefix();
			if (list.Count > 0)
			{
				int num = list.Sum((KeyValuePair<string, int> kv) => kv.Value);
				SourceConsole.Print("");
				SourceConsole.Print($"Settings: {num} across {list.Count} plugin(s).");
				foreach (KeyValuePair<string, int> item2 in list)
				{
					SourceConsole.Print(string.Format("  {0,-38} {1}", item2.Key + "_*", item2.Value));
				}
			}
			SortedDictionary<string, int> sortedDictionary = ChatCommandsBridge.CountsByCategory();
			if (sortedDictionary.Count != 0)
			{
				int num2 = sortedDictionary.Sum((KeyValuePair<string, int> kv) => kv.Value);
				SourceConsole.Print("");
				SourceConsole.Print($"Chat commands: {num2} across {sortedDictionary.Count} categories - see cchelp.");
			}
		}

		private static void History(string[] args)
		{
			int num = 1;
			foreach (string item in SourceConsole.History)
			{
				SourceConsole.Print($"  {num++}: {item}");
			}
		}

		private static void Echo(string[] args)
		{
			SourceConsole.Print((args.Length > 1) ? string.Join(" ", args.Skip(1).ToArray()) : "");
		}

		private static void Scene(string[] args)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			SourceConsole.Print($"scene: \"{((Scene)(ref activeScene)).name}\" (build index {((Scene)(ref activeScene)).buildIndex}, loaded {((Scene)(ref activeScene)).isLoaded})");
		}
	}
	internal static class ChatCommandsBridge
	{
		private const string ChatCommandsGuid = "kestrel.straftat.chatcommands";

		private const string RegistryTypeName = "ChatCommands.CommandRegistry";

		private const string EvaluatorTypeName = "ChatCommands.Evaluator";

		private const string CommandTypeName = "ChatCommands.Command";

		private const string ChatPatchesTypeName = "ChatCommands.ChatPatches";

		private const string WeaponLoaderTypeName = "ChatCommands.BuiltinCommands.WeaponLoader";

		private static readonly Dictionary<string, string> ValueSources = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			{ "weaponName", "m_weaponPrefabs" },
			{ "propName", "m_propPrefabs" }
		};

		private static Type _weaponLoader;

		private static ManualLogSource _log;

		private static bool _installed;

		private static PropertyInfo _commandsProperty;

		private static PropertyInfo _evaluatorInstance;

		private static MethodInfo _evaluate;

		private static FieldInfo _fName;

		private static FieldInfo _fAliases;

		private static FieldInfo _fDescription;

		private static FieldInfo _fCategory;

		private static FieldInfo _fParameters;

		private static FieldInfo _fMaxParameters;

		private static FieldInfo _fFlags;

		private static int _silentFlag;

		private static bool _capturing;

		private static bool _redirectReady;

		private static List<ConsoleCommand> _cache;

		private static int _cacheCount = -1;

		private static readonly ConsoleCommand[] None = new ConsoleCommand[0];

		public static bool Available => _installed;

		public static void Install(ManualLogSource log)
		{
			_log = log;
			if (!Chainloader.PluginInfos.TryGetValue("kestrel.straftat.chatcommands", out var value))
			{
				log.LogInfo((object)"[ChatCommands] not installed - nothing to bridge");
				return;
			}
			Type type = AccessTools.TypeByName("ChatCommands.CommandRegistry");
			Type type2 = AccessTools.TypeByName("ChatCommands.Evaluator");
			Type type3 = AccessTools.TypeByName("ChatCommands.Command");
			if (type == null || type2 == null || type3 == null)
			{
				log.LogWarning((object)($"[ChatCommands] {value.Metadata.Version} found but its types are not where " + "they were - the API changed, bridge skipped"));
				return;
			}
			_commandsProperty = AccessTools.Property(type, "Commands");
			_evaluatorInstance = AccessTools.Property(type2, "Instance");
			_evaluate = AccessTools.Method(type2, "Evaluate", new Type[1] { typeof(string) }, (Type[])null);
			_fName = AccessTools.Field(type3, "name");
			_fAliases = AccessTools.Field(type3, "aliases");
			_fDescription = AccessTools.Field(type3, "description");
			_fCategory = AccessTools.Field(type3, "categoryName");
			_fParameters = AccessTools.Field(type3, "parameterInfos");
			_fMaxParameters = AccessTools.Field(type3, "maxParameters");
			_fFlags = AccessTools.Field(type3, "flags");
			string text = FirstMissing();
			if (text != null)
			{
				log.LogWarning((object)($"[ChatCommands] {value.Metadata.Version}: {text} is absent - " + "the API changed, bridge skipped"));
				return;
			}
			_weaponLoader = AccessTools.TypeByName("ChatCommands.BuiltinCommands.WeaponLoader");
			InstallOutputRedirect(log);
			InstallSilentResultCapture(log);
			ConsoleCommands.AddDynamicProvider(Provide);
			ConsoleCommands.Register("cchelp", "cchelp [name]", "Chat commands: categories, one category, one command, or 'all'.", ChatHelp, CompleteHelpTopic);
			_installed = true;
			log.LogInfo((object)($"[ChatCommands] bridged {Provide().Count} names from {value.Metadata.Version}" + (_redirectReady ? "" : " - output stays in the chat")));
		}

		private static string FirstMissing()
		{
			if (_commandsProperty == null)
			{
				return "CommandRegistry.Commands";
			}
			if (_evaluatorInstance == null)
			{
				return "Evaluator.Instance";
			}
			if (_evaluate == null)
			{
				return "Evaluator.Evaluate(string)";
			}
			if (_fName == null)
			{
				return "Command.name";
			}
			if (_fAliases == null)
			{
				return "Command.aliases";
			}
			if (_fDescription == null)
			{
				return "Command.description";
			}
			if (_fCategory == null)
			{
				return "Command.categoryName";
			}
			if (_fParameters == null)
			{
				return "Command.parameterInfos";
			}
			if (_fMaxParameters == null)
			{
				return "Command.maxParameters";
			}
			return null;
		}

		private static void InstallSilentResultCapture(ManualLogSource log)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Type type = AccessTools.TypeByName("ChatCommands.CommandFlags");
				Type type2 = AccessTools.TypeByName("ChatCommands.Evaluator");
				MethodInfo methodInfo = ((type2 == null) ? null : AccessTools.DeclaredMethod(type2, "RunCommand", (Type[])null, (Type[])null));
				if (type == null || methodInfo == null || _fFlags == null)
				{
					log.LogInfo((object)"[ChatCommands] silent results not captured - commands that only return a value will print nothing");
					return;
				}
				_silentFlag = Convert.ToInt32(Enum.Parse(type, "Silent"));
				HarmonyMethod val = new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ChatCommandsBridge), "CaptureSilentResult", (Type[])null, (Type[])null));
				new Harmony("cmr.console.chatcommands.results").Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			catch (Exception ex)
			{
				_silentFlag = 0;
				log.LogWarning((object)("[ChatCommands] silent results not captured (" + ex.GetType().Name + ": " + ex.Message + ")"));
			}
		}

		private static void CaptureSilentResult(string name, bool sendResult, object __result)
		{
			if (_capturing && sendResult && __result != null && _silentFlag != 0 && IsSilent(name))
			{
				SourceConsole.Print(StripMarkup(__result.ToString()));
			}
		}

		private static bool IsSilent(string name)
		{
			try
			{
				IDictionary dictionary = LiveCommands();
				object obj = ((dictionary == null || name == null) ? null : dictionary[name]);
				if (obj == null)
				{
					return false;
				}
				return (Convert.ToInt32(_fFlags.GetValue(obj)) & _silentFlag) != 0;
			}
			catch
			{
				return false;
			}
		}

		private static void InstallOutputRedirect(ManualLogSource log)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Type type = AccessTools.TypeByName("ChatCommands.ChatPatches");
				MethodInfo methodInfo = ((type == null) ? null : AccessTools.DeclaredMethod(type, "SendSystemMessage", (Type[])null, (Type[])null));
				if (methodInfo == null)
				{
					log.LogWarning((object)"[ChatCommands] ChatPatches.SendSystemMessage is absent - command output will appear in the chat instead");
					return;
				}
				HarmonyMethod val = new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ChatCommandsBridge), "RedirectSystemMessage", (Type[])null, (Type[])null));
				new Harmony("cmr.console.chatcommands").Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_redirectReady = true;
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("[ChatCommands] output redirect not installed (" + ex.GetType().Name + ": " + ex.Message + ") - command output will appear in the chat instead"));
			}
		}

		private static bool RedirectSystemMessage(object message)
		{
			if (!_capturing)
			{
				return true;
			}
			SourceConsole.Print((message == null) ? "" : StripMarkup(message.ToString()));
			return false;
		}

		private static string StripMarkup(string text)
		{
			if (string.IsNullOrEmpty(text) || text.IndexOf('<') < 0)
			{
				return text;
			}
			StringBuilder stringBuilder = new StringBuilder(text.Length);
			for (int i = 0; i < text.Length; i++)
			{
				if (text[i] == '<')
				{
					int num = ClosingBracket(text, i);
					if (num > 0)
					{
						i = num;
						continue;
					}
				}
				stringBuilder.Append(text[i]);
			}
			return stringBuilder.ToString();
		}

		private static int ClosingBracket(string text, int open)
		{
			int i = open + 1;
			if (i < text.Length && text[i] == '/')
			{
				i++;
			}
			if (i >= text.Length)
			{
				return -1;
			}
			if (!char.IsLetter(text[i]) && text[i] != '#')
			{
				return -1;
			}
			for (int num = Math.Min(text.Length, open + 40); i < num; i++)
			{
				if (text[i] == '>')
				{
					return i;
				}
				if (text[i] == '<')
				{
					return -1;
				}
			}
			return -1;
		}

		private static List<ConsoleCommand> Provide()
		{
			IDictionary dictionary = LiveCommands();
			if (dictionary == null)
			{
				return new List<ConsoleCommand>(None);
			}
			if (_cache != null && _cacheCount == dictionary.Count)
			{
				return _cache;
			}
			List<ConsoleCommand> list = new List<ConsoleCommand>(dictionary.Count);
			foreach (DictionaryEntry item in dictionary)
			{
				if (item.Key is string key && item.Value != null)
				{
					ConsoleCommand consoleCommand = Describe(key, item.Value);
					if (consoleCommand != null)
					{
						list.Add(consoleCommand);
					}
				}
			}
			_cache = list;
			_cacheCount = dictionary.Count;
			return list;
		}

		private static IDictionary LiveCommands()
		{
			if (_commandsProperty == null)
			{
				return null;
			}
			try
			{
				return _commandsProperty.GetValue(null, null) as IDictionary;
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)("[ChatCommands] registry unreadable: " + ex.GetType().Name + ": " + ex.Message));
				return null;
			}
		}

		private static ConsoleCommand Describe(string key, object command)
		{
			try
			{
				string name = (_fName.GetValue(command) as string) ?? key;
				string text = _fDescription.GetValue(command) as string;
				string category = _fCategory.GetValue(command) as string;
				ParameterInfo[] parameters = _fParameters.GetValue(command) as ParameterInfo[];
				string[] aliases = _fAliases.GetValue(command) as string[];
				int maxParameters = (int)_fMaxParameters.GetValue(command);
				string text2 = BuildParameters(parameters, maxParameters);
				return new ConsoleCommand
				{
					Name = key,
					Usage = ((text2.Length == 0) ? key : (key + " " + text2)),
					Help = (string.IsNullOrEmpty(text) ? "(no description)" : text),
					Preview = text2,
					Note = BuildNote(key, name, aliases, category),
					RunRaw = Run,
					ArgCompletions = CompletionFor(parameters, maxParameters)
				};
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)("[ChatCommands] command '" + key + "' could not be read: " + ex.GetType().Name + ": " + ex.Message));
				return null;
			}
		}

		private static string BuildParameters(ParameterInfo[] parameters, int maxParameters)
		{
			if (parameters == null || maxParameters <= 0)
			{
				return "";
			}
			StringBuilder stringBuilder = new StringBuilder();
			int num = Math.Min(maxParameters, parameters.Length);
			for (int i = 0; i < num; i++)
			{
				ParameterInfo parameterInfo = parameters[i];
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append(parameterInfo.HasDefaultValue ? "[" : "<").Append(parameterInfo.Name).Append(parameterInfo.HasDefaultValue ? "]" : ">");
			}
			return stringBuilder.ToString();
		}

		private static string BuildNote(string key, string name, string[] aliases, string category)
		{
			if (string.IsNullOrEmpty(category))
			{
				category = "Misc";
			}
			if (!string.Equals(key, name, StringComparison.OrdinalIgnoreCase))
			{
				return category + " - alias of " + name;
			}
			if (aliases == null || aliases.Length == 0)
			{
				return category;
			}
			return category + " (" + string.Join(", ", aliases) + ")";
		}

		private static Func<string, IEnumerable<string>> CompletionFor(ParameterInfo[] parameters, int maxParameters)
		{
			if (_weaponLoader == null || parameters == null || maxParameters <= 0)
			{
				return null;
			}
			if (!ValueSources.TryGetValue(parameters[0].Name ?? "", out var value))
			{
				return null;
			}
			FieldInfo field = AccessTools.Field(_weaponLoader, value);
			if (field == null)
			{
				return null;
			}
			return (string partial) => CompleteFrom(field, partial);
		}

		private static IEnumerable<string> CompleteFrom(FieldInfo field, string partial)
		{
			List<string> list = new List<string>();
			try
			{
				if (!(field.GetValue(null) is IDictionary dictionary))
				{
					return list;
				}
				Dictionary<object, string> dictionary2 = new Dictionary<object, string>();
				foreach (DictionaryEntry item in dictionary)
				{
					if (item.Key is string text && item.Value != null && text.StartsWith(partial ?? "", StringComparison.OrdinalIgnoreCase) && (!dictionary2.TryGetValue(item.Value, out var value) || PrefersDisplayName(text, value, item.Value)))
					{
						dictionary2[item.Value] = text;
					}
				}
				list.AddRange(dictionary2.Values);
			}
			catch
			{
				return list;
			}
			list.Sort(StringComparer.OrdinalIgnoreCase);
			return list;
		}

		private static bool PrefersDisplayName(string candidate, string held, object prefab)
		{
			Object val = (Object)((prefab is Object) ? prefab : null);
			if (val == (Object)null)
			{
				return false;
			}
			string b = val.name.ToUpperInvariant().Replace(" ", "");
			if (string.Equals(held, b, StringComparison.OrdinalIgnoreCase))
			{
				return !string.Equals(candidate, b, StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}

		private static void ChatHelp(string[] args)
		{
			if (args.Length <= 1)
			{
				PrintCategories();
				return;
			}
			string text = args[1];
			Run(string.Equals(text, "all", StringComparison.OrdinalIgnoreCase) ? "help" : ("help " + text));
		}

		private static void PrintCategories()
		{
			SortedDictionary<string, int> sortedDictionary = CountsByCategory();
			if (sortedDictionary.Count == 0)
			{
				SourceConsole.Print("No chat commands are registered.");
				return;
			}
			int num = 0;
			foreach (KeyValuePair<string, int> item in sortedDictionary)
			{
				num += item.Value;
			}
			SourceConsole.Print($"Chat commands: {num} across {sortedDictionary.Count} categories.");
			foreach (KeyValuePair<string, int> item2 in sortedDictionary)
			{
				SourceConsole.Print($"  {item2.Key,-38} {item2.Value}");
			}
			SourceConsole.Print("");
			SourceConsole.Print("  cchelp <category>    the commands in one category");
			SourceConsole.Print("  cchelp <command>     what one command does");
			SourceConsole.Print("  cchelp all           every chat command at once");
		}

		private static IEnumerable<string> CompleteHelpTopic(string partial)
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, int> item in CountsByCategory())
			{
				if (item.Key.StartsWith(partial, StringComparison.OrdinalIgnoreCase))
				{
					list.Add(item.Key);
				}
			}
			if ("all".StartsWith(partial, StringComparison.OrdinalIgnoreCase))
			{
				list.Add("all");
			}
			return list;
		}

		private static void Run(string line)
		{
			object value;
			try
			{
				value = _evaluatorInstance.GetValue(null, null);
			}
			catch (Exception ex)
			{
				SourceConsole.Print("ChatCommands is unreachable: " + ex.GetType().Name + ": " + ex.Message);
				return;
			}
			if (value == null)
			{
				SourceConsole.Print("ChatCommands has no evaluator yet - try again once a match has loaded.");
				return;
			}
			_capturing = true;
			try
			{
				_evaluate.Invoke(value, new object[1] { line });
			}
			catch (TargetInvocationException ex2)
			{
				Exception ex3 = ex2.InnerException ?? ex2;
				SourceConsole.Print("ChatCommands failed: " + ex3.GetType().Name + ": " + ex3.Message);
				_log.LogError((object)$"[ChatCommands] '{line}' failed: {ex3}");
			}
			catch (Exception ex4)
			{
				SourceConsole.Print("ChatCommands failed: " + ex4.GetType().Name + ": " + ex4.Message);
				_log.LogError((object)$"[ChatCommands] '{line}' failed: {ex4}");
			}
			finally
			{
				_capturing = false;
			}
		}

		public static SortedDictionary<string, int> CountsByCategory()
		{
			SortedDictionary<string, int> sortedDictionary = new SortedDictionary<string, int>(StringComparer.OrdinalIgnoreCase);
			IDictionary dictionary = LiveCommands();
			if (dictionary == null)
			{
				return sortedDictionary;
			}
			HashSet<object> hashSet = new HashSet<object>();
			foreach (DictionaryEntry item in dictionary)
			{
				if (item.Value != null && hashSet.Add(item.Value))
				{
					string text;
					try
					{
						text = _fCategory.GetValue(item.Value) as string;
					}
					catch
					{
						continue;
					}
					if (string.IsNullOrEmpty(text))
					{
						text = "Misc";
					}
					sortedDictionary[text] = ((!sortedDictionary.TryGetValue(text, out var value)) ? 1 : (value + 1));
				}
			}
			return sortedDictionary;
		}
	}
	public static class ConfigCvars
	{
		private sealed class CvarEntry
		{
			public readonly PluginInfo Plugin;

			public readonly ConfigDefinition Definition;

			public readonly ConfigEntryBase Entry;

			public readonly string Command;

			public string DisplayValue => Entry.GetSerializedValue();

			public string DefaultSuffix => $"( def. \"{Entry.DefaultValue}\" )";

			public CvarEntry(PluginInfo plugin, ConfigDefinition definition, ConfigEntryBase entry, string command)
			{
				Plugin = plugin;
				Definition = definition;
				Entry = entry;
				Command = command;
			}
		}

		private static bool _installed;

		private static readonly HashSet<ConfigFile> _subscribedConfigs = new HashSet<ConfigFile>();

		private static readonly Dictionary<ConfigEntryBase, string> _commandByEntry = new Dictionary<ConfigEntryBase, string>();

		private static bool _consoleWrite;

		public static void Install(ManualLogSource log)
		{
			if (!_installed)
			{
				_installed = true;
				ConsoleCommands.Register("cvar", "cvar [prefix]", "List all config settings (optionally one plugin's), with current values.", CvarList, CompletePrefix);
				ConsoleCommands.Register("find", "find <text>", "Search config settings by key name and description.", Find);
				ConsoleCommands.AddDynamicProvider(DynamicCommands);
				log.LogInfo((object)"[Cvars] installed - every config entry is reachable as <prefix>_<key>");
			}
		}

		private static IEnumerable<CvarEntry> EveryEntry()
		{
			List<PluginInfo> plugins = Chainloader.PluginInfos.Values.Where((PluginInfo p) => (Object)(object)p.Instance != (Object)null && p.Instance.Config != null).ToList();
			foreach (PluginInfo plugin in plugins)
			{
				string prefix = PrefixFor(plugin, plugins);
				HashSet<string> used = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
				foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in plugin.Instance.Config)
				{
					ConfigEntryBase value = item.Value;
					if (value != null)
					{
						string text = prefix + "_" + Sanitize(item.Key.Key);
						if (!used.Add(text))
						{
							text = prefix + "_" + Sanitize(item.Key.Section) + "_" + Sanitize(item.Key.Key);
						}
						if (_subscribedConfigs.Add(plugin.Instance.Config))
						{
							plugin.Instance.Config.SettingChanged += OnConfigChanged;
						}
						_commandByEntry[value] = text;
						yield return new CvarEntry(plugin, item.Key, value, text);
					}
				}
			}
		}

		private static string PrefixFor(PluginInfo plugin, List<PluginInfo> all)
		{
			string name = Sanitize(plugin.Metadata.Name);
			if (!all.Any((PluginInfo p) => p != plugin && Sanitize(p.Metadata.Name) == name))
			{
				return name;
			}
			return Sanitize(plugin.Metadata.GUID);
		}

		private static string Sanitize(string s)
		{
			StringBuilder stringBuilder = new StringBuilder();
			string text = s ?? "";
			foreach (char c in text)
			{
				if (char.IsLetterOrDigit(c))
				{
					stringBuilder.Append(char.ToLowerInvariant(c));
				}
				else if (c == '.' || c == ' ' || c == '-' || c == '_')
				{
					stringBuilder.Append('_');
				}
			}
			return stringBuilder.ToString();
		}

		private static void CvarList(string[] args)
		{
			string text = ((args.Length > 1) ? args[1] : null);
			int num = 0;
			foreach (CvarEntry item in EveryEntry())
			{
				if (text == null || item.Command.StartsWith(text, StringComparison.OrdinalIgnoreCase))
				{
					SourceConsole.Print($"  {item.Command,-44} = {item.DisplayValue,-12} {item.DefaultSuffix}  [{item.Definition.Section}]");
					string description = item.Entry.Description.Description;
					if (!string.IsNullOrEmpty(description))
					{
						SourceConsole.Print("       " + description);
					}
					num++;
				}
			}
			SourceConsole.Print((num == 0) ? "No settings." : $"{num} setting(s).");
		}

		private static IEnumerable<string> CompletePrefix(string partial)
		{
			return from kv in CountsByPrefix()
				select kv.Key into p
				where p.IndexOf(partial ?? "", StringComparison.OrdinalIgnoreCase) >= 0
				select p;
		}

		private static void Find(string[] args)
		{
			if (args.Length < 2)
			{
				SourceConsole.Print("Usage: find <text>");
				return;
			}
			string value = args[1].ToLowerInvariant();
			int num = 0;
			foreach (CvarEntry item in EveryEntry())
			{
				if ((item.Command + " " + item.Entry.Description.Description).ToLowerInvariant().Contains(value))
				{
					SourceConsole.Print("  " + item.Command + " = " + item.DisplayValue + "  " + item.DefaultSuffix);
					if (!string.IsNullOrEmpty(item.Entry.Description.Description))
					{
						SourceConsole.Print("       " + item.Entry.Description.Description);
					}
					num++;
				}
			}
			SourceConsole.Print((num == 0) ? "Nothing found." : $"{num} match(es).");
		}

		public static List<KeyValuePair<string, int>> CountsByPrefix()
		{
			Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
			foreach (CvarEntry item in EveryEntry())
			{
				int num = item.Command.IndexOf('_');
				string key = ((num > 0) ? item.Command.Substring(0, num) : item.Command);
				dictionary.TryGetValue(key, out var value);
				dictionary[key] = value + 1;
			}
			return dictionary.OrderBy<KeyValuePair<string, int>, string>((KeyValuePair<string, int> kv) => kv.Key, StringComparer.OrdinalIgnoreCase).ToList();
		}

		private static IEnumerable<ConsoleCommand> DynamicCommands()
		{
			foreach (CvarEntry e in EveryEntry())
			{
				yield return new ConsoleCommand
				{
					Name = e.Command,
					Usage = e.Command + " [value]",
					Help = DescribeEntry(e),
					Preview = e.DisplayValue,
					Note = e.DefaultSuffix,
					Run = delegate(string[] args)
					{
						RunCvar(e, args);
					},
					ArgCompletions = (string partial) => CompleteValue(e, partial)
				};
			}
		}

		private static string DescribeEntry(CvarEntry e)
		{
			List<string> list = new List<string>
			{
				e.Definition.Section,
				e.Entry.SettingType.Name,
				$"default {e.Entry.DefaultValue}"
			};
			AcceptableValueBase acceptableValues = e.Entry.Description.AcceptableValues;
			if (acceptableValues != null)
			{
				list.Add(acceptableValues.ToDescriptionString().TrimStart('#', ' '));
			}
			string description = e.Entry.Description.Description;
			string text = string.Join(" | ", list.ToArray());
			if (!string.IsNullOrEmpty(description))
			{
				return text + "\n  " + description;
			}
			return text;
		}

		private static void RunCvar(CvarEntry e, string[] args)
		{
			if (args.Length < 2)
			{
				SourceConsole.Print(e.Command + " = " + e.DisplayValue + "  " + e.DefaultSuffix);
				return;
			}
			string text = string.Join(" ", args.Skip(1).ToArray());
			if (e.Entry.SettingType == typeof(bool) && ConsoleCommands.TryParseBool(text, out var value))
			{
				text = (value ? "true" : "false");
			}
			if (!TomlTypeConverter.CanConvert(e.Entry.SettingType))
			{
				SourceConsole.Print(e.Command + ": type " + e.Entry.SettingType.Name + " has no converter - read only");
				return;
			}
			object obj;
			try
			{
				obj = TomlTypeConverter.ConvertToValue(text, e.Entry.SettingType);
			}
			catch (Exception)
			{
				PrintRejected(e, text, null);
				return;
			}
			AcceptableValueBase acceptableValues = e.Entry.Description.AcceptableValues;
			if (acceptableValues != null && !acceptableValues.IsValid(obj))
			{
				PrintRejected(e, text, acceptableValues);
				return;
			}
			_consoleWrite = true;
			try
			{
				e.Entry.SetSerializedValue(text);
			}
			finally
			{
				_consoleWrite = false;
			}
			SourceConsole.Print(e.Command + " = " + e.DisplayValue);
		}

		private static void PrintRejected(CvarEntry e, string text, AcceptableValueBase acc)
		{
			SourceConsole.Print(e.Command + ": invalid value \"" + text + "\"");
			if (acc != null)
			{
				SourceConsole.Print("  acceptable: " + acc.ToDescriptionString());
			}
			SourceConsole.Print("  now: " + e.DisplayValue);
		}

		private static IEnumerable<string> CompleteValue(CvarEntry e, string partial)
		{
			AcceptableValueBase acceptableValues = e.Entry.Description.AcceptableValues;
			if (acceptableValues == null)
			{
				return Enumerable.Empty<string>();
			}
			List<string> list = AcceptableValuesOf(acceptableValues);
			if (list == null)
			{
				return Enumerable.Empty<string>();
			}
			return list.Where((string v) => v.StartsWith(partial, StringComparison.OrdinalIgnoreCase));
		}

		private static List<string> AcceptableValuesOf(AcceptableValueBase acc)
		{
			object obj = null;
			MemberInfo[] member = ((object)acc).GetType().GetMember("AcceptableValues", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MemberInfo memberInfo in member)
			{
				if (!(memberInfo is PropertyInfo propertyInfo))
				{
					if (memberInfo is FieldInfo fieldInfo)
					{
						obj = fieldInfo.GetValue(acc);
					}
				}
				else
				{
					obj = propertyInfo.GetValue(acc);
				}
				if (obj != null)
				{
					break;
				}
			}
			if (!(obj is IEnumerable enumerable))
			{
				return null;
			}
			List<string> list = new List<string>();
			foreach (object item in enumerable)
			{
				list.Add(item?.ToString() ?? "");
			}
			return list;
		}

		private static void OnConfigChanged(object sender, SettingChangedEventArgs e)
		{
			if (_consoleWrite)
			{
				return;
			}
			if (e.ChangedSetting == null)
			{
				SourceConsole.Print("[Config] a config file was reloaded");
				return;
			}
			ConfigEntryBase changedSetting = e.ChangedSetting;
			if (!_commandByEntry.TryGetValue(changedSetting, out var value))
			{
				value = Sanitize(changedSetting.Definition.Section) + "_" + Sanitize(changedSetting.Definition.Key);
			}
			SourceConsole.Print("[Config] " + value + " = " + changedSetting.GetSerializedValue() + " (changed outside the console)");
		}
	}
	public sealed class ConsoleCommand
	{
		public string Name;

		public string Usage;

		public string Help;

		public Action<string[]> Run;

		public Action<string> RunRaw;

		public Func<string, IEnumerable<string>> ArgCompletions;

		public string Preview;

		public string Note;

		public override string ToString()
		{
			return Name;
		}
	}
	public static class ConsoleCommands
	{
		private static readonly Dictionary<string, ConsoleCommand> _byName = new Dictionary<string, ConsoleCommand>(StringComparer.OrdinalIgnoreCase);

		private static readonly List<Func<IEnumerable<ConsoleCommand>>> _dynamic = new List<Func<IEnumerable<ConsoleCommand>>>();

		public static IEnumerable<ConsoleCommand> All => _byName.Values.OrderBy<ConsoleCommand, string>((ConsoleCommand c) => c.Name, StringComparer.OrdinalIgnoreCase);

		public static void Register(string name, string usage, string help, Action<string[]> run)
		{
			Register(name, usage, help, run, null);
		}

		public static void Register(string name, string usage, string help, Action<string[]> run, Func<string, IEnumerable<string>> argCompletions)
		{
			_byName[name] = new ConsoleCommand
			{
				Name = name,
				Usage = usage,
				Help = help,
				Run = run,
				ArgCompletions = argCompletions
			};
		}

		public static void AddDynamicProvider(Func<IEnumerable<ConsoleCommand>> provider)
		{
			if (provider != null)
			{
				_dynamic.Add(provider);
			}
		}

		public static bool TryGet(string name, out ConsoleCommand cmd)
		{
			if (_byName.TryGetValue(name, out cmd))
			{
				return true;
			}
			for (int i = 0; i < _dynamic.Count; i++)
			{
				foreach (ConsoleCommand item in _dynamic[i]())
				{
					if (string.Equals(item.Name, name, StringComparison.OrdinalIgnoreCase))
					{
						cmd = item;
						return true;
					}
				}
			}
			return false;
		}

		public static List<ConsoleCommand> Complete(string prefix)
		{
			List<ConsoleCommand> list = new List<ConsoleCommand>();
			if (string.IsNullOrEmpty(prefix))
			{
				return list;
			}
			foreach (ConsoleCommand value in _byName.Values)
			{
				if (value.Name.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
				{
					list.Add(value);
				}
			}
			for (int i = 0; i < _dynamic.Count; i++)
			{
				foreach (ConsoleCommand c in _dynamic[i]())
				{
					if (c.Name.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) && !list.Any((ConsoleCommand r) => string.Equals(r.Name, c.Name, StringComparison.OrdinalIgnoreCase)))
					{
						list.Add(c);
					}
				}
			}
			list.Sort((ConsoleCommand a, ConsoleCommand b) => StringComparer.OrdinalIgnoreCase.Compare(a.Name, b.Name));
			return list;
		}

		public static string[] Split(string line)
		{
			List<string> list = new List<string>();
			if (string.IsNullOrEmpty(line))
			{
				return list.ToArray();
			}
			bool flag = false;
			StringBuilder stringBuilder = new StringBuilder();
			foreach (char c in line)
			{
				if (c == '"')
				{
					flag = !flag;
				}
				else if (char.IsWhiteSpace(c) && !flag)
				{
					if (stringBuilder.Length > 0)
					{
						list.Add(stringBuilder.ToString());
						stringBuilder.Length = 0;
					}
				}
				else
				{
					stringBuilder.Append(c);
				}
			}
			if (stringBuilder.Length > 0)
			{
				list.Add(stringBuilder.ToString());
			}
			return list.ToArray();
		}

		public static bool TryParseBool(string s, out bool value)
		{
			value = false;
			if (string.IsNullOrEmpty(s))
			{
				return false;
			}
			switch (s.ToLowerInvariant())
			{
			case "1":
			case "on":
			case "yes":
			case "true":
				value = true;
				return true;
			case "0":
			case "no":
			case "off":
			case "false":
				value = false;
				return true;
			default:
				return false;
			}
		}
	}
	internal sealed class ConsoleHost : MonoBehaviour
	{
		private static GameObject _go;

		private static ManualLogSource _log;

		private static bool _installed;

		public static event Action Tick;

		public static event Action GuiDraw;

		public static void Install(ManualLogSource log)
		{
			_log = log;
			if (!_installed)
			{
				_installed = true;
				SceneManager.sceneLoaded += delegate
				{
					Ensure();
				};
				Ensure();
			}
		}

		private static void Ensure()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!((Object)(object)_go != (Object)null))
			{
				_go = new GameObject("Console_Host");
				Object.DontDestroyOnLoad((Object)(object)_go);
				_go.AddComponent<ConsoleHost>();
				_log.LogInfo((object)"[Host] Console_Host created");
			}
		}

		private void Update()
		{
			Action tick = ConsoleHost.Tick;
			if (tick == null)
			{
				return;
			}
			try
			{
				tick();
			}
			catch (Exception ex)
			{
				_log.LogError((object)("[Host] Tick failed: " + ex.GetType().Name + ": " + ex.Message));
			}
		}

		private void OnGUI()
		{
			Action guiDraw = ConsoleHost.GuiDraw;
			if (guiDraw == null)
			{
				return;
			}
			try
			{
				guiDraw();
			}
			catch (Exception ex)
			{
				_log.LogError((object)("[Host] GuiDraw failed: " + ex.GetType().Name + ": " + ex.Message));
			}
		}

		private void OnDestroy()
		{
			if (_log != null)
			{
				_log.LogInfo((object)"[Host] Console_Host destroyed - will be recreated on the next scene");
			}
			_go = null;
		}
	}
	[BepInPlugin("cmr.console", "Console", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class ConsolePlugin : BaseUnityPlugin
	{
		public const string ModGuid = "cmr.console";

		public const string ModName = "Console";

		public const string ModVersion = "1.1.0";

		private void Awake()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Console 1.1.0 - starting");
			ConfigEntry<float> scale = ((BaseUnityPlugin)this).Config.Bind<float>("Console", "Scale", 1f, new ConfigDescription("Console size.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>()));
			Install("host", delegate
			{
				ConsoleHost.Install(((BaseUnityPlugin)this).Logger);
			});
			Install("console", delegate
			{
				SourceConsole.Install(((BaseUnityPlugin)this).Logger, scale.Value);
				BuiltinCommands.Register(((BaseUnityPlugin)this).Logger);
				scale.SettingChanged += delegate
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Console] scale -> {scale.Value:0.##}");
					SourceConsole.SetUserScale(scale.Value);
				};
			});
			Install("config cvars", delegate
			{
				ConfigCvars.Install(((BaseUnityPlugin)this).Logger);
			});
			Install("chat commands bridge (optional)", delegate
			{
				ChatCommandsBridge.Install(((BaseUnityPlugin)this).Logger);
			});
			Install("mod menu card (optional)", delegate
			{
				ModMenuCard.Apply(((BaseUnityPlugin)this).Logger);
			});
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Console 1.1.0 - ready");
		}

		private void Install(string name, Action install)
		{
			try
			{
				install();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("[Init] " + name + ": installed"));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[Init] " + name + ": NOT installed - " + ex.GetType().Name + ": " + ex.Message));
			}
		}
	}
	public static class ConsoleScheme
	{
		public static readonly Color FrameBg = C(108, 111, 114, 250);

		public static readonly Color FrameOutOfFocusBg = C(97, 100, 102, 240);

		public const float FrameClientInsetX = 8f;

		public const float FrameClientInsetY = 6f;

		public const float FrameTitleTextInsetX = 16f;

		public static readonly Color LogText = C(221, 221, 221, 255);

		public static readonly Color LogBg = C(0, 0, 0, 128);

		public static readonly Color LogSelectedText = C(255, 255, 255, 255);

		public static readonly Color LogSelectedBg = C(0, 168, 255, 204);

		public static readonly Color DevText = C(255, 255, 255, 255);

		public static readonly Color EntryText = C(10, 10, 10, 255);

		public static readonly Color EntryBg = C(255, 255, 255, 255);

		public static readonly Color EntryCursor = C(10, 10, 10, 255);

		public static readonly Color EntrySelectedBg = C(0, 168, 255, 204);

		public static readonly Color EntryFocusEdge = C(0, 0, 0, 196);

		public static readonly Color MenuText = C(80, 80, 80, 255);

		public static readonly Color MenuBg = C(233, 233, 233, 255);

		public static readonly Color MenuArmedText = C(255, 255, 255, 255);

		public static readonly Color MenuArmedBg = C(132, 183, 241, 255);

		public const float MenuTextInset = 6f;

		public static readonly Color ButtonText = C(82, 82, 82, 255);

		public static readonly Color ButtonBg = C(227, 227, 227, 255);

		public static readonly Color ButtonArmedText = C(46, 114, 178, 255);

		public static readonly Color ButtonArmedBg = C(240, 240, 240, 255);

		public static readonly Color ButtonDepressedText = C(255, 255, 255, 255);

		public static readonly Color ButtonDepressedBg = C(84, 178, 245, 255);

		public static readonly Color ButtonFocusBorder = C(82, 82, 82, 255);

		public const float ScrollBarWide = 15f;

		public static readonly Color SliderNob = C(220, 220, 220, 255);

		public static readonly Color SliderTrack = C(184, 184, 184, 229);

		public static readonly Color BorderDarkSolid = C(40, 40, 40, 255);

		public static readonly Color BorderSubtle = C(80, 80, 80, 255);

		public const float ReferenceHeight = 1080f;

		private const float BaseFontSize = 13f;

		public static float UserScale = 1f;

		public const string FontName = "Lucida Console";

		public static float Scale => Mathf.Clamp((float)Screen.height / 1080f * UserScale, 0.85f, 1.75f);

		public static int FontSize => Mathf.Max(11, Mathf.RoundToInt(13f * Scale));

		private static Color C(int r, int g, int b, int a)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			return new Color((float)r / 255f, (float)g / 255f, (float)b / 255f, (float)a / 255f);
		}

		public static float Px(float units)
		{
			return units * Scale;
		}

		public static Vector2 DefaultWindowSize()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			float num = (float)Screen.height * 0.58f;
			return new Vector2(Mathf.Min((float)Screen.height * 1.35f, (float)Screen.width * 0.8f), num);
		}
	}
	internal static class ModMenuCard
	{
		private const string ModMenuGuid = "kestrel.straftat.modmenu";

		private const string ApiType = "ModMenu.Api.ModMenuCustomisation";

		private const string IconResource = "StraftatConsole.Resources.icon.png";

		private const string Description = "Source-style developer console. Every installed mod's settings become console commands automatically.";

		public static void Apply(ManualLogSource log)
		{
			if (!Chainloader.PluginInfos.TryGetValue("kestrel.straftat.modmenu", out var value))
			{
				log.LogInfo((object)"[ModMenu] not installed - the console works on its own");
				return;
			}
			Type type = AccessTools.TypeByName("ModMenu.Api.ModMenuCustomisation");
			if (type == null)
			{
				log.LogWarning((object)(string.Format("[ModMenu] plugin {0} found but type {1} is missing - ", value.Metadata.Version, "ModMenu.Api.ModMenuCustomisation") + "the API changed, decoration skipped"));
				return;
			}
			log.LogInfo((object)$"[ModMenu] detected {value.Metadata.Version}, settings will appear in the menu automatically");
			TrySetDescription(type, log);
			TrySetIcon(type, log);
		}

		private static bool TryRegister(Type api, string property, object value, ManualLogSource log)
		{
			PropertyInfo propertyInfo = AccessTools.Property(api, property);
			if (propertyInfo == null)
			{
				log.LogWarning((object)("[ModMenu] " + property + " is absent - the API changed"));
				return false;
			}
			if (!(propertyInfo.GetValue(null, null) is IDictionary dictionary))
			{
				log.LogWarning((object)("[ModMenu] " + property + " is not a dictionary - the API changed"));
				return false;
			}
			dictionary["cmr.console"] = value;
			return true;
		}

		private static void TrySetDescription(Type api, ManualLogSource log)
		{
			try
			{
				if (TryRegister(api, "Descriptions", "Source-style developer console. Every installed mod's settings become console commands automatically.", log))
				{
					log.LogInfo((object)"[ModMenu] description registered for cmr.console");
				}
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("[ModMenu] description not set: " + ex.GetType().Name + ": " + ex.Message));
			}
		}

		private static void TrySetIcon(Type api, ManualLogSource log)
		{
			try
			{
				Sprite val = LoadIcon(log);
				if (!((Object)(object)val == (Object)null) && TryRegister(api, "Icons", val, log))
				{
					log.LogInfo((object)"[ModMenu] icon registered for cmr.console");
				}
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("[ModMenu] icon not set: " + ex.GetType().Name + ": " + ex.Message));
			}
		}

		private static Sprite LoadIcon(ManualLogSource log)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			byte[] array;
			using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("StraftatConsole.Resources.icon.png"))
			{
				if (stream == null)
				{
					log.LogWarning((object)"[ModMenu] icon resource StraftatConsole.Resources.icon.png not found");
					return null;
				}
				array = new byte[stream.Length];
				int num;
				for (int i = 0; i < array.Length; i += num)
				{
					num = stream.Read(array, i, array.Length - i);
					if (num <= 0)
					{
						break;
					}
				}
			}
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, array))
			{
				log.LogWarning((object)"[ModMenu] icon PNG could not be decoded");
				return null;
			}
			((Object)val).hideFlags = (HideFlags)61;
			((Object)val).name = "Console_Icon";
			Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
			((Object)obj).hideFlags = (HideFlags)61;
			((Object)obj).name = "Console_Icon";
			log.LogInfo((object)$"[ModMenu] icon loaded: {((Texture)val).width}x{((Texture)val).height}");
			return obj;
		}
	}
	internal sealed class NullInputModule : BaseInputModule
	{
		public override void Process()
		{
		}
	}
	public static class SourceConsole
	{
		[Flags]
		private enum Edge
		{
			None = 0,
			Left = 1,
			Right = 2,
			Top = 4,
			Bottom = 8
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static Action <0>__OnTick;

			public static Action <1>__OnGui;

			public static WindowFunction <2>__DrawWindow;
		}

		private const int WindowId = 3133;

		private const string InputControlName = "cmr_console_input";

		private const int MaxLines = 2048;

		private const int MaxHistory = 64;

		private static ManualLogSource _log;

		private static bool _installed;

		private static bool _open;

		private static Rect _rect;

		private static Vector2 _scroll;

		private static bool _scrollToEnd = true;

		private static string _input = "";

		private static readonly List<string> _lines = new List<string>();

		private static readonly List<string> _history = new List<string>();

		private static int _historyIndex = -1;

		private static string _historyDraft = "";

		private static List<ConsoleCommand> _suggestions = new List<ConsoleCommand>();

		private static List<string> _argSuggestions = new List<string>();

		private static bool _suggestingArgs;

		private static string _argCmdName;

		private static int _suggestionIndex = -1;

		private static int _suggestionScroll;

		private const int MaxVisibleSuggestions = 10;

		private static CursorLockMode _savedLockState;

		private static bool _savedCursorVisible;

		private static readonly List<BaseInputModule> _disabledModules = new List<BaseInputModule>();

		private static readonly List<BaseInputModule> _moduleBuffer = new List<BaseInputModule>();

		private static NullInputModule _nullModule;

		private static Mouse _disabledMouse;

		private static Keyboard _disabledKeyboard;

		private static GUIStyle _logStyle;

		private static GUIStyle _entryStyle;

		private static GUIStyle _buttonStyle;

		private static GUIStyle _titleStyle;

		private static GUIStyle _menuStyle;

		private static GUIStyle _menuArmedStyle;

		private static GUIStyle _scrollTrackStyle;

		private static GUIStyle _scrollThumbStyle;

		private static GUIStyle _scrollNoneStyle;

		private static Texture2D _texFrame;

		private static Texture2D _texLogBg;

		private static Texture2D _texEntryBg;

		private static Texture2D _texButton;

		private static Texture2D _texButtonArmed;

		private static Texture2D _texMenuBg;

		private static Texture2D _texMenuArmed;

		private static Texture2D _texEdge;

		private static Texture2D _texGrip;

		private static Texture2D _texScrollTrack;

		private static Texture2D _texScrollThumb;

		private static int _builtForFont = -1;

		private static Edge _resizeEdge = Edge.None;

		private static bool _moveCaretToEnd;

		private static bool _rectReady;

		private static int _rectForHeight = -1;

		public static bool IsOpen => _open;

		private static bool HasSuggestions
		{
			get
			{
				if (_suggestions.Count <= 0)
				{
					return _argSuggestions.Count > 0;
				}
				return true;
			}
		}

		private static int SuggestionCount
		{
			get
			{
				if (!_suggestingArgs)
				{
					return _suggestions.Count;
				}
				return _argSuggestions.Count;
			}
		}

		public static IEnumerable<string> History => _history;

		public static void SetUserScale(float scale)
		{
			ConsoleScheme.UserScale = scale;
			_builtForFont = -1;
		}

		public static void Install(ManualLogSource log, float userScale)
		{
			_log = log;
			if (!_installed)
			{
				_installed = true;
				ConsoleScheme.UserScale = userScale;
				ConsoleHost.Tick += OnTick;
				ConsoleHost.GuiDraw += OnGui;
				Logger.Listeners.Add((ILogListener)(object)new ConsoleLogListener());
				Print("Straftat CMR console. Type 'help' for a list of commands.");
				_log.LogInfo((object)$"[Console] installed, scale {ConsoleScheme.Scale:0.##}, font {ConsoleScheme.FontSize}px");
			}
		}

		public static void Print(string text)
		{
			if (text == null)
			{
				return;
			}
			string[] array = text.Split(new char[1] { '\n' });
			foreach (string text2 in array)
			{
				_lines.Add(text2.TrimEnd(new char[1] { '\r' }));
				if (_lines.Count > 2048)
				{
					_lines.RemoveAt(0);
				}
			}
			_scrollToEnd = true;
		}

		public static void Clear()
		{
			_lines.Clear();
			_scrollToEnd = true;
		}

		private static void OnTick()
		{
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				return;
			}
			if (!_open)
			{
				if (((ButtonControl)current.backquoteKey).wasPressedThisFrame)
				{
					Open();
				}
			}
			else
			{
				HoldInput();
			}
		}

		private static void Open()
		{
			_open = true;
			EnsureRect();
			_moveCaretToEnd = true;
			_scrollToEnd = true;
			CaptureInput();
		}

		private static void Close()
		{
			_open = false;
			ClearSuggestions();
			ReleaseInput();
		}

		private static void HandleCloseKeys()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			Event current = Event.current;
			if ((int)current.type != 4)
			{
				return;
			}
			if ((int)current.keyCode == 96)
			{
				Close();
				current.Use();
			}
			else if ((int)current.keyCode == 27)
			{
				if (HasSuggestions)
				{
					ClearSuggestions();
				}
				else
				{
					Close();
				}
				current.Use();
			}
		}

		private static void CaptureInput()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			_savedLockState = Cursor.lockState;
			_savedCursorVisible = Cursor.visible;
		}

		private static void HoldInput()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if ((int)Cursor.lockState != 0)
			{
				Cursor.lockState = (CursorLockMode)0;
			}
			if (!Cursor.visible)
			{
				Cursor.visible = true;
			}
			EventSystem current = EventSystem.current;
			if ((Object)(object)current != (Object)null)
			{
				if ((Object)(object)_nullModule == (Object)null)
				{
					_nullModule = ((Component)current).gameObject.AddComponent<NullInputModule>();
				}
				((Component)current).GetComponents<BaseInputModule>(_moduleBuffer);
				for (int i = 0; i < _moduleBuffer.Count; i++)
				{
					BaseInputModule val = _moduleBuffer[i];
					if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)_nullModule) && ((Behaviour)val).enabled)
					{
						((Behaviour)val).enabled = false;
						_disabledModules.Add(val);
					}
				}
				_moduleBuffer.Clear();
			}
			Mouse current2 = Mouse.current;
			if (current2 != null && ((InputDevice)current2).enabled)
			{
				_disabledMouse = current2;
				InputSystem.DisableDevice((InputDevice)(object)current2, false);
			}
			Keyboard current3 = Keyboard.current;
			if (current3 != null && ((InputDevice)current3).enabled)
			{
				_disabledKeyboard = current3;
				InputSystem.DisableDevice((InputDevice)(object)current3, false);
			}
		}

		private static void ReleaseInput()
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			if (_disabledMouse != null)
			{
				InputSystem.EnableDevice((InputDevice)(object)_disabledMouse);
				_disabledMouse = null;
			}
			if (_disabledKeyboard != null)
			{
				InputSystem.EnableDevice((InputDevice)(object)_disabledKeyboard);
				_disabledKeyboard = null;
			}
			for (int i = 0; i < _disabledModules.Count; i++)
			{
				BaseInputModule val = _disabledModules[i];
				if ((Object)(object)val != (Object)null)
				{
					((Behaviour)val).enabled = true;
				}
			}
			_disabledModules.Clear();
			if ((Object)(object)_nullModule != (Object)null)
			{
				Object.Destroy((Object)(object)_nullModule);
				_nullModule = null;
			}
			Cursor.lockState = _savedLockState;
			Cursor.visible = _savedCursorVisible;
		}

		private static void EnsureRect()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			if (!_rectReady || _rectForHeight != Screen.height)
			{
				_rectForHeight = Screen.height;
				if (!_rectReady)
				{
					Vector2 val = ConsoleScheme.DefaultWindowSize();
					_rect = new Rect(((float)Screen.width - val.x) * 0.5f, (float)Screen.height * 0.08f, val.x, val.y);
					_rectReady = true;
					_log.LogInfo((object)($"[Console] window {val.x:0}x{val.y:0} on a {Screen.width}x{Screen.height} screen, " + $"scale {ConsoleScheme.Scale:0.##}, font {ConsoleScheme.FontSize}px"));
				}
			}
		}

		private static void OnGui()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected I4, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			if (!_open)
			{
				return;
			}
			HandleCloseKeys();
			if (!_open)
			{
				return;
			}
			EnsureRect();
			EnsureStyles();
			GUI.skin.settings.cursorColor = ConsoleScheme.EntryCursor;
			GUI.skin.settings.cursorFlashSpeed = 0f;
			GUI.skin.settings.selectionColor = ConsoleScheme.EntrySelectedBg;
			HandleResize();
			GUI.depth = -1000;
			Rect rect = _rect;
			object obj = <>O.<2>__DrawWindow;
			if (obj == null)
			{
				WindowFunction val = DrawWindow;
				<>O.<2>__DrawWindow = val;
				obj = (object)val;
			}
			_rect = GUI.Window(3133, rect, (WindowFunction)obj, GUIContent.none, GUIStyle.none);
			EventType type = Event.current.type;
			switch ((int)type)
			{
			case 0:
			case 1:
			case 3:
			case 6:
				if (!((Rect)(ref _rect)).Contains(Event.current.mousePosition))
				{
					Event.current.Use();
				}
				break;
			case 2:
			case 4:
			case 5:
				break;
			}
		}

		private static void DrawWindow(int id)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			float scale = ConsoleScheme.Scale;
			float num = ConsoleScheme.Px(8f);
			float num2 = ConsoleScheme.Px(6f);
			float num3 = Mathf.Round(26f * scale);
			float num4 = Mathf.Round(26f * scale);
			GUI.DrawTexture(new Rect(0f, 0f, ((Rect)(ref _rect)).width, ((Rect)(ref _rect)).height), (Texture)(object)_texFrame);
			GUI.DrawTexture(new Rect(0f, 0f, ((Rect)(ref _rect)).width, 1f), (Texture)(object)_texGrip);
			GUI.DrawTexture(new Rect(0f, ((Rect)(ref _rect)).height - 1f, ((Rect)(ref _rect)).width, 1f), (Texture)(object)_texGrip);
			GUI.DrawTexture(new Rect(0f, 0f, 1f, ((Rect)(ref _rect)).height), (Texture)(object)_texGrip);
			GUI.DrawTexture(new Rect(((Rect)(ref _rect)).width - 1f, 0f, 1f, ((Rect)(ref _rect)).height), (Texture)(object)_texGrip);
			GUI.Label(new Rect(ConsoleScheme.Px(16f), 0f, ((Rect)(ref _rect)).width, num3), "Console", _titleStyle);
			float num5 = num3;
			float num6 = ((Rect)(ref _rect)).height - num3 - num4 - num2 * 2f;
			Rect val = new Rect(num, num5, ((Rect)(ref _rect)).width - num * 2f, num6);
			GUI.DrawTexture(val, (Texture)(object)_texLogBg);
			DrawLog(val);
			float num7 = ((Rect)(ref _rect)).height - num4 - num2;
			float num8 = Mathf.Round(80f * scale);
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(num, num7, ((Rect)(ref _rect)).width - num * 2f - num8 - num, num4);
			Rect r = new Rect(((Rect)(ref val2)).xMax + num, num7, num8, num4);
			DrawEntry(val2);
			DrawSubmit(r);
			if (HasSuggestions)
			{
				DrawSuggestions(val2);
			}
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _rect)).width - ConsoleScheme.Px(20f), num3));
		}

		private static void HandleResize()
		{
			//IL_0018: 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)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected I4, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			Event current = Event.current;
			float band = Mathf.Round(6f * ConsoleScheme.Scale);
			EventType type = current.type;
			switch ((int)type)
			{
			case 0:
			{
				Edge edge = EdgeAt(current.mousePosition, band);
				if (edge != Edge.None)
				{
					_resizeEdge = edge;
					current.Use();
				}
				break;
			}
			case 3:
				if (_resizeEdge != Edge.None)
				{
					ApplyResize(current.delta);
					current.Use();
				}
				break;
			case 1:
				if (_resizeEdge != Edge.None)
				{
					_resizeEdge = Edge.None;
					current.Use();
				}
				break;
			case 2:
				break;
			}
		}

		private static Edge EdgeAt(Vector2 m, float band)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((Rect)(ref _rect)).x - band, ((Rect)(ref _rect)).y - band, ((Rect)(ref _rect)).width + band * 2f, ((Rect)(ref _rect)).height + band * 2f);
			if (!((Rect)(ref val)).Contains(m))
			{
				return Edge.None;
			}
			Edge edge = Edge.None;
			if (m.x <= ((Rect)(ref _rect)).x + band)
			{
				edge |= Edge.Left;
			}
			else if (m.x >= ((Rect)(ref _rect)).xMax - band)
			{
				edge |= Edge.Right;
			}
			if (m.y <= ((Rect)(ref _rect)).y + band)
			{
				edge |= Edge.Top;
			}
			else if (m.y >= ((Rect)(ref _rect)).yMax - band)
			{
				edge |= Edge.Bottom;
			}
			return edge;
		}

		private static void ApplyResize(Vector2 delta)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			float num = ConsoleScheme.Px(320f);
			float num2 = ConsoleScheme.Px(180f);
			if ((_resizeEdge & Edge.Right) != Edge.None)
			{
				((Rect)(ref _rect)).width = Mathf.Max(num, ((Rect)(ref _rect)).width + delta.x);
			}
			if ((_resizeEdge & Edge.Bottom) != Edge.None)
			{
				((Rect)(ref _rect)).height = Mathf.Max(num2, ((Rect)(ref _rect)).height + delta.y);
			}
			if ((_resizeEdge & Edge.Left) != Edge.None)
			{
				float num3 = Mathf.Max(num, ((Rect)(ref _rect)).width - delta.x);
				((Rect)(ref _rect)).x = ((Rect)(ref _rect)).x + (((Rect)(ref _rect)).width - num3);
				((Rect)(ref _rect)).width = num3;
			}
			if ((_resizeEdge & Edge.Top) != Edge.None)
			{
				float num4 = Mathf.Max(num2, ((Rect)(ref _rect)).height - delta.y);
				((Rect)(ref _rect)).y = ((Rect)(ref _rect)).y + (((Rect)(ref _rect)).height - num4);
				((Rect)(ref _rect)).height = num4;
			}
		}

		private static void DrawLog(Rect area)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			GUIStyle verticalScrollbar = GUI.skin.verticalScrollbar;
			GUIStyle verticalScrollbarThumb = GUI.skin.verticalScrollbarThumb;
			GUIStyle verticalScrollbarUpButton = GUI.skin.verticalScrollbarUpButton;
			GUIStyle verticalScrollbarDownButton = GUI.skin.verticalScrollbarDownButton;
			GUI.skin.verticalScrollbar = _scrollTrackStyle;
			GUI.skin.verticalScrollbarThumb = _scrollThumbStyle;
			GUI.skin.verticalScrollbarUpButton = _scrollNoneStyle;
			GUI.skin.verticalScrollbarDownButton = _scrollNoneStyle;
			try
			{
				DrawLogInner(area);
			}
			finally
			{
				GUI.skin.verticalScrollbar = verticalScrollbar;
				GUI.skin.verticalScrollbarThumb = verticalScrollbarThumb;
				GUI.skin.verticalScrollbarUpButton = verticalScrollbarUpButton;
				GUI.skin.verticalScrollbarDownButton = verticalScrollbarDownButton;
			}
		}

		private static void DrawLogInner(Rect area)
		{
			//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)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Invalid comparison between Unknown and I4
			_scroll = GUI.BeginScrollView(area, _scroll, new Rect(0f, 0f, ((Rect)(ref area)).width - ConsoleScheme.Px(15f), (float)_lines.Count * _logStyle.lineHeight + 4f));
			float num = 2f;
			float lineHeight = _logStyle.lineHeight;
			int num2 = Mathf.Max(0, Mathf.FloorToInt(_scroll.y / lineHeight) - 1);
			int num3 = Mathf.Min(_lines.Count, num2 + Mathf.CeilToInt(((Rect)(ref area)).height / lineHeight) + 2);
			for (int i = num2; i < num3; i++)
			{
				GUI.Label(new Rect(4f, num + (float)i * lineHeight, ((Rect)(ref area)).width - 8f, lineHeight), _lines[i], _logStyle);
			}
			GUI.EndScrollView();
			if (_scrollToEnd && (int)Event.current.type == 7)
			{
				_scroll.y = Mathf.Max(0f, (float)_lines.Count * lineHeight - ((Rect)(ref area)).height + 4f);
				_scrollToEnd = false;
			}
		}

		private static void DrawEntry(Rect r)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Invalid comparison between Unknown and I4
			GUI.DrawTexture(new Rect(((Rect)(ref r)).x - 1f, ((Rect)(ref r)).y - 1f, ((Rect)(ref r)).width + 2f, ((Rect)(ref r)).height + 2f), (Texture)(object)_texEdge);
			GUI.DrawTexture(r, (Texture)(object)_texEntryBg);
			HandleEntryKeys();
			GUI.SetNextControlName("cmr_console_input");
			string text = GUI.TextField(r, _input, _entryStyle);
			if (text != _input)
			{
				_input = text;
				RefreshSuggestions();
			}
			if (GUI.GetNameOfFocusedControl() != "cmr_console_input")
			{
				GUI.FocusControl("cmr_console_input");
				_moveCaretToEnd = true;
			}
			if (_moveCaretToEnd && (int)Event.current.type == 7)
			{
				object stateObject = GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl);
				TextEditor val = (TextEditor)((stateObject is TextEditor) ? stateObject : null);
				if (val != null)
				{
					val.text = _input;
					val.cursorIndex = _input.Length;
					val.selectIndex = _input.Length;
					_moveCaretToEnd = false;
				}
			}
		}

		private static void DrawSubmit(Rect r)
		{
			//IL_0007: 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)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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)
			bool flag = ((Rect)(ref r)).Contains(Event.current.mousePosition);
			GUI.DrawTexture(r, (Texture)(object)(flag ? _texButtonArmed : _texButton));
			GUIStyle buttonStyle = _buttonStyle;
			buttonStyle.normal.textColor = (flag ? ConsoleScheme.ButtonArmedText : ConsoleScheme.ButtonText);
			if (GUI.Button(r, "Submit", buttonStyle))
			{
				Submit();
			}
		}

		private static void DrawSuggestions(Rect entryRect)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Invalid comparison between Unknown and I4
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Expected O, but got Unknown
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Expected O, but got Unknown
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			int suggestionCount = SuggestionCount;
			float num = Mathf.Round(22f * ConsoleScheme.Scale);
			int num2 = Mathf.Min(suggestionCount, 10);
			ClampSuggestionScroll(num2);
			bool num3 = suggestionCount > num2;
			float num4 = (num3 ? (num * 0.8f) : 0f);
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((Rect)(ref entryRect)).x, ((Rect)(ref entryRect)).y - num * (float)num2 - num4, ((Rect)(ref entryRect)).width, num * (float)num2 + num4);
			GUI.DrawTexture(val, (Texture)(object)_texMenuBg);
			if (num3)
			{
				GUI.Label(new Rect(((Rect)(ref val)).x + ConsoleScheme.Px(6f), ((Rect)(ref val)).y, ((Rect)(ref val)).width, num4), $"{_suggestionScroll + 1}-{_suggestionScroll + num2} of {suggestionCount}   (arrows / wheel)", _menuStyle);
			}
			if ((int)Event.current.type == 6 && ((Rect)(ref val)).Contains(Event.current.mousePosition))
			{
				_suggestionScroll += (int)Mathf.Sign(Event.current.delta.y);
				ClampSuggestionScroll(num2);
				Event.current.Use();
			}
			float num5 = ConsoleScheme.Px(6f) * 2f;
			float num6 = 0f;
			float num7 = 0f;
			if (!_suggestingArgs)
			{
				for (int i = 0; i < num2; i++)
				{
					int num8 = _suggestionScroll + i;
					if (num8 >= suggestionCount)
					{
						break;
					}
					num6 = Mathf.Max(num6, _menuStyle.CalcSize(new GUIContent(_suggestions[num8].Name)).x);
					string preview = _suggestions[num8].Preview;
					if (!string.IsNullOrEmpty(preview))
					{
						num7 = Mathf.Max(num7, _menuStyle.CalcSize(new GUIContent(preview)).x);
					}
				}
				num6 += num5;
				if (num7 > 0f)
				{
					num7 += num5;
				}
			}
			Rect val2 = default(Rect);
			Rect val3 = default(Rect);
			for (int j = 0; j < num2; j++)
			{
				int num9 = _suggestionScroll + j;
				if (num9 < suggestionCount)
				{
					((Rect)(ref val2))..ctor(((Rect)(ref val)).x, ((Rect)(ref val)).y + num4 + (float)j * num, ((Rect)(ref val)).width, num);
					bool flag = num9 == _suggestionIndex;
					if (flag)
					{
						GUI.DrawTexture(val2, (Texture)(object)_texMenuArmed);
					}
					string text = (_suggestingArgs ? _argSuggestions[num9] : _suggestions[num9].Name);
					string text2 = (_suggestingArgs ? null : _suggestions[num9].Preview);
					string text3 = (_suggestingArgs ? null : _suggestions[num9].Note);
					((Rect)(ref val3))..ctor(((Rect)(ref val2)).x + ConsoleScheme.Px(6f), ((Rect)(ref val2)).y, ((Rect)(ref val2)).width, ((Rect)(ref val2)).height);
					GUI.Label(val3, text, flag ? _menuArmedStyle : _menuStyle);
					GUIStyle val4 = (flag ? _menuArmedStyle : _menuStyle);
					if (!string.IsNullOrEmpty(text2))
					{
						float num10 = ((Rect)(ref val3)).x + num6;
						GUI.Label(new Rect(num10, ((Rect)(ref val2)).y, Mathf.Max(0f, ((Rect)(ref val2)).xMax - num10), ((Rect)(ref val2)).height), text2, val4);
					}
					if (!string.IsNullOrEmpty(text3))
					{
						float num11 = ((Rect)(ref val3)).x + num6 + num7;
						GUI.Label(new Rect(num11, ((Rect)(ref val2)).y, Mathf.Max(0f, ((Rect)(ref val2)).xMax - num11), ((Rect)(ref val2)).height), text3, val4);
					}
					if ((int)Event.current.type == 0 && ((Rect)(ref val2)).Contains(Event.current.mousePosition))
					{
						AcceptSuggestion(num9);
						Event.current.Use();
					}
					continue;
				}
				break;
			}
		}

		private static void ClampSuggestionScroll(int shown)
		{
			int suggestionCount = SuggestionCount;
			if (_suggestionIndex >= 0)
			{
				if (_suggestionIndex < _suggestionScroll)
				{
					_suggestionScroll = _suggestionIndex;
				}
				else if (_suggestionIndex >= _suggestionScroll + shown)
				{
					_suggestionScroll = _suggestionIndex - shown + 1;
				}
			}
			_suggestionScroll = Mathf.Clamp(_suggestionScroll, 0, Mathf.Max(0, suggestionCount - shown));
		}

		private static void HandleEntryKeys()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected I4, but got Unknown
			Event current = Event.current;
			if ((int)current.type != 4)
			{
				return;
			}
			KeyCode keyCode = current.keyCode;
			if ((int)keyCode != 9)
			{
				if ((int)keyCode != 13)
				{
					switch (keyCode - 271)
					{
					default:
						return;
					case 0:
						break;
					case 2:
						if (!HasSuggestions)
						{
							NavigateHistory(-1);
						}
						else if (_suggestionIndex < 0)
						{
							_suggestionIndex = SuggestionCount - 1;
						}
						else
						{
							_suggestionIndex = Mathf.Max(0, _suggestionIndex - 1);
						}
						current.Use();
						return;
					case 3:
						if (!HasSuggestions)
						{
							NavigateHistory(1);
						}
						else if (_suggestionIndex < 0)
						{
							_suggestionIndex = 0;
						}
						else
						{
							_suggestionIndex = Mathf.Min(SuggestionCount - 1, _suggestionIndex + 1);
						}
						current.Use();
						return;
					case 1:
						return;
					}
				}
				if (HasSuggestions && _suggestionIndex >= 0)
				{
					AcceptSuggestion(_suggestionIndex);
				}
				else
				{
					Submit();
				}
				current.Use();
			}
			else
			{
				if (HasSuggestions)
				{
					AcceptSuggestion(Mathf.Max(0, _suggestionIndex));
				}
				current.Use();
			}
		}

		private static void RefreshSuggestions()
		{
			if (string.IsNullOrEmpty(_input))
			{
				ClearSuggestions();
				return;
			}
			int num = _input.IndexOf(' ');
			if (num < 0)
			{
				_suggestions = ConsoleCommands.Complete(_input);
				_suggestingArgs = false;
				_suggestionIndex = -1;
				_suggestionScroll = 0;
				return;
			}
			string text = _input.Substring(0, num);
			string arg = _input.Substring(num + 1);
			if (!ConsoleCommands.TryGet(text, out var cmd) || cmd.ArgCompletions == null)
			{
				ClearSuggestions();
				return;
			}
			IEnumerable<string> enumerable = cmd.ArgCompletions(arg);
			_argSuggestions = ((enumerable == null) ? new List<string>() : new List<string>(enumerable));
			_suggestingArgs = true;
			_argCmdName = text;
			_suggestionIndex = -1;
			_suggestionScroll = 0;
		}

		private static void ClearSuggestions()
		{
			_suggestions = new List<ConsoleCommand>();
			_argSuggestions = new List<string>();
			_suggestingArgs = false;
			_argCmdName = null;
			_suggestionIndex = -1;
			_suggestionScroll = 0;
		}

		private static void AcceptSuggestion(int index)
		{
			if (index >= 0 && index < SuggestionCount)
			{
				if (_suggestingArgs)
				{
					_input = _argCmdName + " " + _argSuggestions[index] + " ";
				}
				else
				{
					_input = _suggestions[index].Name + " ";
				}
				ClearSuggestions();
				_moveCaretToEnd = true;
			}
		}

		private static void NavigateHistory(int delta)
		{
			if (_history.Count != 0)
			{
				if (_historyIndex == -1)
				{
					_historyDraft = _input;
					_historyIndex = _history.Count;
				}
				_historyIndex = Mathf.Clamp(_historyIndex + delta, 0, _history.Count);
				_input = ((_historyIndex >= _history.Count) ? _historyDraft : _history[_historyIndex]);
				_moveCaretToEnd = true;
			}
		}

		private static void Submit()
		{
			string text = _input.Trim();
			_input = "";
			ClearSuggestions();
			_historyIndex = -1;
			_moveCaretToEnd = true;
			if (text.Length != 0)
			{
				_history.Add(text);
				if (_history.Count > 64)
				{
					_history.RemoveAt(0);
				}
				Print("] " + text);
				Execute(text);
			}
		}

		public static void Execute(string line)
		{
			if (line.Length > 1 && line[0] == '/')
			{
				line = line.Substring(1);
			}
			string[] array = ConsoleCommands.Split(line);
			if (array.Length == 0)
			{
				return;
			}
			if (!ConsoleCommands.TryGet(array[0], out var cmd))
			{
				Print("Unknown command: " + array[0]);
				return;
			}
			try
			{
				if (cmd.RunRaw != null)
				{
					cmd.RunRaw(line);
				}
				else
				{
					cmd.Run(array);
				}
			}
			catch (Exception ex)
			{
				Print("Command '" + cmd.Name + "' failed: " + ex.GetType().Name + ": " + ex.Message);
				_log.LogError((object)$"[Console] command '{cmd.Name}' failed: {ex}");
			}
		}

		private static void EnsureStyles()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Expected O, but got Unknown
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Expected O, but got Unknown
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Expected O, but got Unknown
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Expected O, but got Unknown
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Expected O, but got Unknown
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Expected O, but got Unknown
			int fontSize = ConsoleScheme.FontSize;
			if (_builtForFont != fontSize || _logStyle == null)
			{
				_builtForFont = fontSize;
				_texFrame = Solid(ConsoleScheme.FrameBg);
				_texLogBg = Solid(ConsoleScheme.LogBg);
				_texEntryBg = Solid(ConsoleScheme.EntryBg);
				_texButton = Solid(ConsoleScheme.ButtonBg);
				_texButtonArmed = Solid(ConsoleScheme.ButtonArmedBg);
				_texMenuBg = Solid(ConsoleScheme.MenuBg);
				_texMenuArmed = Solid(ConsoleScheme.MenuArmedBg);
				_texEdge = Solid(ConsoleScheme.EntryFocusEdge);
				_texGrip = Solid(ConsoleScheme.BorderSubtle);
				_texScrollTrack = Solid(ConsoleScheme.SliderTrack);
				_texScrollThumb = Solid(ConsoleScheme.SliderNob);
				float fixedWidth = ConsoleScheme.Px(15f);
				GUIStyle val = new GUIStyle();
				val.normal.background = _texScrollTrack;
				val.fixedWidth = fixedWidth;
				_scrollTrackStyle = val;
				GUIStyle val2 = new GUIStyle();
				val2.normal.background = _texScrollThumb;
				val2.fixedWidth = fixedWidth;
				_scrollThumbStyle = val2;
				_scrollNoneStyle = GUIStyle.none;
				Font font = Font.CreateDynamicFontFromOSFont("Lucida Console", fontSize) ?? Font.CreateDynamicFontFromOSFont("Consolas", fontSize);
				GUIStyle val3 = new GUIStyle
				{
					font = font,
					fontSize = fontSize,
					richText = false,
					wordWrap = false,
					alignment = (TextAnchor)0
				};
				val3.normal.textColor = ConsoleScheme.LogText;
				_logStyle = val3;
				GUIStyle val4 = new GUIStyle
				{
					font = font,
					fontSize = fontSize,
					alignment = (TextAnchor)3,
					padding = new RectOffset(4, 4, 0, 0)
				};
				val4.normal.textColor = ConsoleScheme.EntryText;
				val4.focused.textColor = ConsoleScheme.EntryText;
				val4.hover.textColor = ConsoleScheme.EntryText;
				_entryStyle = val4;
				GUIStyle val5 = new GUIStyle
				{
					font = font,
					fontSize = fontSize,
					alignment = (TextAnchor)4
				};
				val5.normal.textColor = ConsoleScheme.ButtonText;
				_buttonStyle = val5;
				GUIStyle val6 = new GUIStyle
				{
					font = font,
					fontSize = fontSize,
					alignment = (TextAnchor)3
				};
				val6.normal.textColor = ConsoleScheme.DevText;
				_titleStyle = val6;
				GUIStyle val7 = new GUIStyle
				{
					font = font,
					fontSize = fontSize,
					alignment = (TextAnchor)3
				};
				val7.normal.textColor = ConsoleScheme.MenuText;
				_menuStyle = val7;
				GUIStyle val8 = new GUIStyle(_menuStyle);
				val8.normal.textColor = ConsoleScheme.MenuArmedText;
				_menuArmedStyle = val8;
			}
		}

		private static Texture2D Solid(Color c)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1);
			val.SetPixel(0, 0, c);
			val.Apply();
			((Object)val).hideFlags = (HideFlags)61;
			return val;
		}
	}
	internal sealed class ConsoleLogListener : ILogListener, IDisposable
	{
		public void LogEvent(object sender, LogEventArgs e)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			SourceConsole.Print($"[{e.Level}] {e.Data}");
		}

		public void Dispose()
		{
		}
	}
}