Decompiled source of QuantumConsole v1.0.0

BepInEx/plugins/Hikaria.QuantumConsole/Hikaria.QuantumConsole.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using Clonesoft.Json;
using Hikaria.QC.Bootstrap;
using Hikaria.QC.Comparators;
using Hikaria.QC.Containers;
using Hikaria.QC.Extras;
using Hikaria.QC.Internal;
using Hikaria.QC.Logging;
using Hikaria.QC.Pooling;
using Hikaria.QC.Suggestors.Tags;
using Hikaria.QC.UI;
using Hikaria.QC.Utilities;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Microsoft.CodeAnalysis;
using TMPro;
using TheArchive;
using TheArchive.Core;
using TheArchive.Core.Attributes;
using TheArchive.Core.Attributes.Feature.Settings;
using TheArchive.Core.FeaturesAPI;
using TheArchive.Core.Localization;
using TheArchive.Core.Models;
using TheArchive.Core.ModulesAPI;
using TheArchive.Interfaces;
using TheArchive.Loader;
using TheArchive.Utilities;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Hikaria.QuantumConsole")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+763c711f33b42ea606574f2478da895146a61a3c")]
[assembly: AssemblyProduct("Hikaria.QuantumConsole")]
[assembly: AssemblyTitle("Hikaria.QuantumConsole")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
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;
		}
	}
}
public class DeferredSynchronizeInvoke : ISynchronizeInvoke
{
	private class UnityAsyncResult : IAsyncResult
	{
		public Delegate method;

		public object[] args;

		public bool IsCompleted { get; set; }

		public WaitHandle AsyncWaitHandle { get; internal set; }

		public object AsyncState { get; set; }

		public bool CompletedSynchronously => IsCompleted;
	}

	private Queue<UnityAsyncResult> fifoToExecute = new Queue<UnityAsyncResult>();

	private Thread mainThread;

	public bool InvokeRequired => mainThread.ManagedThreadId != Thread.CurrentThread.ManagedThreadId;

	public DeferredSynchronizeInvoke()
	{
		mainThread = Thread.CurrentThread;
	}

	public IAsyncResult BeginInvoke(Delegate method, object[] args)
	{
		UnityAsyncResult unityAsyncResult = new UnityAsyncResult
		{
			method = method,
			args = args,
			IsCompleted = false,
			AsyncWaitHandle = new ManualResetEvent(initialState: false)
		};
		lock (fifoToExecute)
		{
			fifoToExecute.Enqueue(unityAsyncResult);
			return unityAsyncResult;
		}
	}

	public object EndInvoke(IAsyncResult result)
	{
		if (!result.IsCompleted)
		{
			result.AsyncWaitHandle.WaitOne();
		}
		return result.AsyncState;
	}

	public object Invoke(Delegate method, object[] args)
	{
		if (InvokeRequired)
		{
			IAsyncResult result = BeginInvoke(method, args);
			return EndInvoke(result);
		}
		return method.DynamicInvoke(args);
	}

	public void ProcessQueue()
	{
		if (Thread.CurrentThread != mainThread)
		{
			throw new TargetException(GetType()?.ToString() + "." + MethodBase.GetCurrentMethod().Name + "() must be called from the same thread it was created on (created on thread id: " + mainThread.ManagedThreadId + ", called from thread id: " + Thread.CurrentThread.ManagedThreadId);
		}
		bool flag = true;
		UnityAsyncResult unityAsyncResult = null;
		while (flag)
		{
			lock (fifoToExecute)
			{
				flag = fifoToExecute.Count > 0;
				if (!flag)
				{
					break;
				}
				unityAsyncResult = fifoToExecute.Dequeue();
			}
			unityAsyncResult.AsyncState = Invoke(unityAsyncResult.method, unityAsyncResult.args);
			unityAsyncResult.IsCompleted = true;
		}
	}
}
namespace Hikaria.QC
{
	[ArchiveModule("Hikaria.QuantumConsole", "QuantumConsole", "1.0.0")]
	public class EntryPoint : IArchiveModule
	{
		public bool ApplyHarmonyPatches => false;

		public bool UsesLegacyPatches => false;

		public ArchiveLegacyPatcher Patcher { get; set; }

		public string ModuleGroup => FeatureGroup.op_Implicit(FeatureGroups.GetOrCreateModuleGroup("Quantum Console", new Dictionary<Language, string>
		{
			{
				(Language)0,
				"Quantum Console"
			},
			{
				(Language)1,
				"量子终端"
			}
		}));

		public void Init()
		{
			Logs.LogMessage("OK");
		}

		public void OnExit()
		{
		}

		public void OnLateUpdate()
		{
		}

		public void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
		}
	}
	internal static class Logs
	{
		private static IArchiveLogger _logger;

		private static IArchiveLogger Logger => _logger ?? (_logger = LoaderWrapper.CreateLoggerInstance("Hikaria.QuantumConsole", ConsoleColor.White));

		public static void LogDebug(object data)
		{
			Logger.Debug(data.ToString());
		}

		public static void LogError(object data)
		{
			Logger.Error(data.ToString());
		}

		public static void LogInfo(object data)
		{
			Logger.Info(data.ToString());
		}

		public static void LogMessage(object data)
		{
			Logger.Msg(ConsoleColor.White, data.ToString());
		}

		public static void LogWarning(object data)
		{
			Logger.Warning(data.ToString());
		}

		public static void LogNotice(object data)
		{
			Logger.Notice(data.ToString());
		}

		public static void LogSuccess(object data)
		{
			Logger.Success(data.ToString());
		}

		public static void LogException(Exception ex)
		{
			Logger.Exception(ex);
		}
	}
	public static class PluginInfo
	{
		public const string GUID = "Hikaria.QuantumConsole";

		public const string NAME = "QuantumConsole";

		public const string VERSION = "1.0.0";
	}
	public struct ActionContext
	{
		public QuantumConsole Console;
	}
	public static class ActionExecuter
	{
		public static ActionState Execute(this IEnumerator<ICommandAction> action, ActionContext context)
		{
			ActionState state = ActionState.Running;
			bool idle = false;
			while (!idle)
			{
				if (action.Current == null)
				{
					MoveNext();
				}
				else if (action.Current.IsFinished)
				{
					action.Current.Finalize(context);
					MoveNext();
				}
				else
				{
					idle = true;
				}
			}
			return state;
			void MoveNext()
			{
				if (action.MoveNext())
				{
					action.Current?.Start(context);
					idle = action.Current?.StartsIdle ?? false;
				}
				else
				{
					idle = true;
					state = ActionState.Complete;
					action.Dispose();
				}
			}
		}
	}
	public enum ActionState
	{
		Unknown,
		Running,
		Complete
	}
	public interface ICommandAction
	{
		bool IsFinished { get; }

		bool StartsIdle { get; }

		void Start(ActionContext context);

		void Finalize(ActionContext context);
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true, Inherited = false)]
	public sealed class CommandAttribute : Attribute
	{
		public readonly string Alias;

		public readonly string Description;

		public readonly Platform SupportedPlatforms;

		public readonly MonoTargetType MonoTarget;

		public readonly bool Valid = true;

		private static readonly char[] _bannedAliasChars = new char[9] { ' ', '(', ')', '{', '}', '[', ']', '<', '>' };

		public CommandAttribute([CallerMemberName] string aliasOverride = "", Platform supportedPlatforms = Platform.AllPlatforms, MonoTargetType targetType = MonoTargetType.Single)
		{
			Alias = aliasOverride;
			MonoTarget = targetType;
			SupportedPlatforms = supportedPlatforms;
			for (int i = 0; i < _bannedAliasChars.Length; i++)
			{
				if (Alias.Contains(_bannedAliasChars[i]))
				{
					string text = QuantumConsoleBootstrap.Localization.Format(40u, new object[2]
					{
						Alias,
						_bannedAliasChars[i]
					});
					Logs.LogError(text);
					Valid = false;
					throw new ArgumentException(text, "aliasOverride");
				}
			}
		}

		public CommandAttribute(string aliasOverride, MonoTargetType targetType, Platform supportedPlatforms = Platform.AllPlatforms)
			: this(aliasOverride, supportedPlatforms, targetType)
		{
		}

		public CommandAttribute(string aliasOverride, string description, Platform supportedPlatforms = Platform.AllPlatforms, MonoTargetType targetType = MonoTargetType.Single)
			: this(aliasOverride, supportedPlatforms, targetType)
		{
			Description = description;
		}

		public CommandAttribute(string aliasOverride, string description, MonoTargetType targetType, Platform supportedPlatforms = Platform.AllPlatforms)
			: this(aliasOverride, description, supportedPlatforms, targetType)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	public sealed class CommandDescriptionAttribute : Attribute
	{
		public readonly string Description;

		public readonly bool Valid;

		public CommandDescriptionAttribute(string description)
		{
			Description = description;
			Valid = !string.IsNullOrWhiteSpace(description);
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	public sealed class CommandParameterDescriptionAttribute : Attribute
	{
		public readonly string Description;

		public readonly bool Valid;

		public CommandParameterDescriptionAttribute(string description)
		{
			Description = description;
			Valid = !string.IsNullOrWhiteSpace(description);
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	public sealed class CommandPlatformAttribute : Attribute
	{
		public readonly Platform SupportedPlatforms;

		public CommandPlatformAttribute(Platform supportedPlatforms)
		{
			SupportedPlatforms = supportedPlatforms;
		}
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true, Inherited = false)]
	public sealed class CommandPrefixAttribute : Attribute
	{
		public readonly string Prefix;

		public readonly bool Valid = true;

		private static readonly char[] _bannedAliasChars = new char[9] { ' ', '(', ')', '{', '}', '[', ']', '<', '>' };

		public CommandPrefixAttribute([CallerMemberName] string prefixName = "")
		{
			Prefix = prefixName;
			char[] bannedAliasChars = _bannedAliasChars;
			foreach (char c in bannedAliasChars)
			{
				if (Prefix.Contains(c))
				{
					string text = QuantumConsoleBootstrap.Localization.Format(41u, new object[2] { Prefix, c });
					Logs.LogError(text);
					Valid = false;
					throw new ArgumentException(text, "prefixName");
				}
			}
		}
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
	public sealed class QcIgnoreAttribute : Attribute
	{
	}
	public enum AutoScrollOptions
	{
		Never,
		OnInvoke,
		Always
	}
	public class CommandData
	{
		public readonly string CommandName;

		public readonly string CommandDescription;

		public readonly string CommandSignature;

		public readonly string ParameterSignature;

		public readonly string GenericSignature;

		public readonly string LocalizationSignature;

		public readonly ParameterInfo[] MethodParamData;

		public readonly Type[] ParamTypes;

		public readonly Type[] GenericParamTypes;

		public readonly MethodInfo MethodData;

		public readonly MonoTargetType MonoTarget;

		private readonly object[] _defaultParameters;

		private Dictionary<Language, CommandLocalizationData> _localization;

		public bool IsGeneric => GenericParamTypes.Length != 0;

		public bool IsStatic => MethodData.IsStatic;

		public bool HasDescription => !string.IsNullOrWhiteSpace(CommandDescription);

		public int ParamCount => ParamTypes.Length - _defaultParameters.Length;

		internal void ApplyLocalization(Dictionary<Language, CommandLocalizationData> localization)
		{
			_localization = localization;
		}

		internal bool TryGetLocalization(out CommandLocalizationData localization)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return _localization.TryGetValue(QuantumConsoleBootstrap.Localization.CurrentLanguage, out localization);
		}

		internal bool TryGetLocalization(Language language, out CommandLocalizationData localization)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return _localization.TryGetValue(language, out localization);
		}

		public Type[] MakeGenericArguments(params Type[] genericTypeArguments)
		{
			if (genericTypeArguments.Length != GenericParamTypes.Length)
			{
				throw new ArgumentException(QuantumConsoleBootstrap.Localization.Get(69u));
			}
			Dictionary<string, Type> dictionary = new Dictionary<string, Type>();
			for (int i = 0; i < genericTypeArguments.Length; i++)
			{
				dictionary.Add(GenericParamTypes[i].Name, genericTypeArguments[i]);
			}
			Type[] array = new Type[ParamTypes.Length];
			for (int j = 0; j < array.Length; j++)
			{
				if (ParamTypes[j].ContainsGenericParameters)
				{
					Type type = ConstructGenericType(ParamTypes[j], dictionary);
					array[j] = type;
				}
				else
				{
					array[j] = ParamTypes[j];
				}
			}
			return array;
		}

		private Type ConstructGenericType(Type genericType, Dictionary<string, Type> substitutionTable)
		{
			if (!genericType.ContainsGenericParameters)
			{
				return genericType;
			}
			if (substitutionTable.ContainsKey(genericType.Name))
			{
				return substitutionTable[genericType.Name];
			}
			if (genericType.IsArray)
			{
				return ConstructGenericType(genericType.GetElementType(), substitutionTable).MakeArrayType();
			}
			if (genericType.IsGenericType)
			{
				Type genericTypeDefinition = genericType.GetGenericTypeDefinition();
				Type[] genericArguments = genericType.GetGenericArguments();
				for (int i = 0; i < genericArguments.Length; i++)
				{
					genericArguments[i] = ConstructGenericType(genericArguments[i], substitutionTable);
				}
				return genericTypeDefinition.MakeGenericType(genericArguments);
			}
			throw new ArgumentException(QuantumConsoleBootstrap.Localization.Format(70u, new object[1] { genericType }));
		}

		public object Invoke(object[] paramData, Type[] genericTypeArguments)
		{
			int num = 0;
			int num2 = paramData.Length;
			if (MonoTarget == MonoTargetType.Argument || MonoTarget == MonoTargetType.ArgumentMulti)
			{
				num++;
				num2--;
			}
			object[] array = new object[num2 + _defaultParameters.Length];
			Array.Copy(paramData, num, array, 0, num2);
			Array.Copy(_defaultParameters, 0, array, num2, _defaultParameters.Length);
			MethodInfo invokingMethod = GetInvokingMethod(genericTypeArguments);
			if (IsStatic)
			{
				return invokingMethod.Invoke(null, array);
			}
			return InvocationTargetFactory.InvokeOnTargets(invokingMethod, MonoTarget switch
			{
				MonoTargetType.Argument => paramData[0].Yield(), 
				MonoTargetType.ArgumentMulti => paramData[0] as IEnumerable<object>, 
				_ => GetInvocationTargets(invokingMethod), 
			}, array);
		}

		protected virtual IEnumerable<object> GetInvocationTargets(MethodInfo invokingMethod)
		{
			return InvocationTargetFactory.FindTargets(invokingMethod.ReflectedType, MonoTarget);
		}

		private MethodInfo GetInvokingMethod(Type[] genericTypeArguments)
		{
			if (!IsGeneric)
			{
				return MethodData;
			}
			Type declaringType = MethodData.DeclaringType;
			MethodInfo method = MethodData;
			if (declaringType.IsGenericTypeDefinition)
			{
				int count = declaringType.GetGenericArguments().Length;
				Type[] genericTypes = genericTypeArguments.Take(count).ToArray();
				genericTypeArguments = genericTypeArguments.Skip(count).ToArray();
				declaringType = WrapConstruction<Type>(() => declaringType.MakeGenericType(genericTypes));
				method = method.RebaseMethod(declaringType);
			}
			if (genericTypeArguments.Length != 0)
			{
				return WrapConstruction<MethodInfo>(() => method.MakeGenericMethod(genericTypeArguments));
			}
			return method;
			T WrapConstruction<T>(Func<T> f)
			{
				try
				{
					return f();
				}
				catch (ArgumentException)
				{
					throw new ArgumentException(QuantumConsoleBootstrap.Localization.Format(71u, new object[1] { CommandName }));
				}
			}
		}

		private string BuildPrefix(Type declaringType)
		{
			List<string> prefixes = new List<string>();
			Assembly assembly = declaringType.Assembly;
			while (declaringType != null)
			{
				AddPrefixes(declaringType.GetCustomAttributes<CommandPrefixAttribute>(), declaringType.Name);
				declaringType = declaringType.DeclaringType;
			}
			AddPrefixes(assembly.GetCustomAttributes<CommandPrefixAttribute>(), assembly.GetName().Name);
			return string.Join("", prefixes.Reversed());
			void AddPrefixes(IEnumerable<CommandPrefixAttribute> prefixAttributes, string defaultName)
			{
				foreach (CommandPrefixAttribute item in prefixAttributes.Reverse())
				{
					if (item.Valid)
					{
						string text = item.Prefix;
						if (string.IsNullOrWhiteSpace(text))
						{
							text = defaultName;
						}
						prefixes.Add(text);
					}
				}
			}
		}

		private string BuildGenericSignature(Type[] genericParamTypes)
		{
			if (genericParamTypes.Length == 0)
			{
				return string.Empty;
			}
			IEnumerable<string> values = genericParamTypes.Select((Type x) => x.Name);
			return "<" + string.Join(", ", values) + ">";
		}

		private string BuildParameterSignature(ParameterInfo[] methodParams, int defaultParameterCount)
		{
			string text = string.Empty;
			for (int i = 0; i < methodParams.Length - defaultParameterCount; i++)
			{
				text = text + ((i == 0) ? string.Empty : " ") + methodParams[i].Name;
			}
			return text;
		}

		private Type[] BuildGenericParamTypes(MethodInfo method, Type declaringType)
		{
			List<Type> list = new List<Type>();
			if (declaringType.IsGenericTypeDefinition)
			{
				list.AddRange(declaringType.GetGenericArguments());
			}
			if (method.IsGenericMethodDefinition)
			{
				list.AddRange(method.GetGenericArguments());
			}
			return list.ToArray();
		}

		public CommandData(MethodInfo methodData, string commandName, MonoTargetType monoTarget, int defaultParameterCount = 0)
		{
			_localization = new Dictionary<Language, CommandLocalizationData>();
			CommandName = commandName;
			MethodData = methodData;
			MonoTarget = monoTarget;
			if (string.IsNullOrWhiteSpace(commandName))
			{
				CommandName = methodData.Name;
			}
			Type declaringType = methodData.DeclaringType;
			string text = BuildPrefix(declaringType);
			CommandName = text + CommandName;
			List<ParameterInfo> list = methodData.GetParameters().ToList();
			if (MonoTarget == MonoTargetType.Argument)
			{
				list.Insert(0, new DummyParameter(methodData.DeclaringType, "target", 0));
			}
			else if (MonoTarget == MonoTargetType.ArgumentMulti)
			{
				list.Insert(0, new DummyParameter(methodData.DeclaringType.MakeArrayType(), "targets", 0));
			}
			MethodParamData = list.ToArray();
			ParamTypes = MethodParamData.Select((ParameterInfo x) => x.ParameterType).ToArray();
			_defaultParameters = new object[defaultParameterCount];
			for (int i = 0; i < defaultParameterCount; i++)
			{
				int num = MethodParamData.Length - defaultParameterCount + i;
				_defaultParameters[i] = MethodParamData[num].DefaultValue;
			}
			GenericParamTypes = BuildGenericParamTypes(methodData, declaringType);
			ParameterSignature = BuildParameterSignature(MethodParamData, defaultParameterCount);
			GenericSignature = BuildGenericSignature(GenericParamTypes);
			CommandSignature = ((ParamCount > 0) ? (CommandName + GenericSignature + " " + ParameterSignature) : (CommandName + GenericSignature));
			LocalizationSignature = ((MethodParamData.Length != 0) ? (CommandName + GenericSignature + " " + BuildParameterSignature(MethodParamData, 0)) : (CommandName + GenericSignature));
			this.LoadCommandLocalizationData();
		}

		public CommandData(MethodInfo methodData, MonoTargetType monoTarget, int defaultParameterCount = 0)
			: this(methodData, methodData.Name, monoTarget, defaultParameterCount)
		{
		}

		public CommandData(MethodInfo methodData, CommandAttribute commandAttribute, int defaultParameterCount = 0)
			: this(methodData, commandAttribute.Alias, commandAttribute.MonoTarget, defaultParameterCount)
		{
			CommandDescription = commandAttribute.Description;
			this.LoadCommandLocalizationData();
		}

		public CommandData(MethodInfo methodData, CommandAttribute commandAttribute, CommandDescriptionAttribute descriptionAttribute, int defaultParameterCount = 0)
			: this(methodData, commandAttribute, defaultParameterCount)
		{
			if (descriptionAttribute != null && descriptionAttribute.Valid)
			{
				CommandDescription = descriptionAttribute.Description;
			}
			this.LoadCommandLocalizationData();
		}
	}
	[AttributeUsage(AttributeTargets.Class, Inherited = false)]
	public sealed class NoInjectAttribute : Attribute
	{
	}
	public class InjectionLoader<T>
	{
		private Type[] _injectableTypes;

		public Type[] GetInjectableTypes(bool forceReload = false)
		{
			if (_injectableTypes == null || forceReload)
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				List<Type> list = new List<Type>();
				Assembly[] array = assemblies;
				foreach (Assembly assembly in array)
				{
					try
					{
						list.AddRange((from type in assembly.GetTypes()
							where typeof(T).IsAssignableFrom(type)
							where !type.IsAbstract
							where !type.IsDefined(typeof(NoInjectAttribute), inherit: false)
							select type).ToArray());
					}
					catch
					{
					}
				}
				_injectableTypes = list.ToArray();
			}
			return _injectableTypes;
		}

		public IEnumerable<T> GetInjectedInstances(bool forceReload = false)
		{
			IEnumerable<Type> injectableTypes = GetInjectableTypes(forceReload);
			return GetInjectedInstances(injectableTypes);
		}

		public IEnumerable<T> GetInjectedInstances(IEnumerable<Type> injectableTypes)
		{
			foreach (Type injectableType in injectableTypes)
			{
				T val = default(T);
				bool flag = false;
				try
				{
					val = (T)Activator.CreateInstance(injectableType);
					flag = true;
				}
				catch (MissingMethodException)
				{
					Logs.LogError(QuantumConsoleBootstrap.Localization.Format(72u, new object[2]
					{
						typeof(T),
						injectableType
					}));
				}
				catch (Exception ex2)
				{
					Logs.LogException(ex2);
				}
				if (flag)
				{
					yield return val;
				}
			}
		}
	}
	public static class InputHelper
	{
		private static bool IsKeySupported(KeyCode key)
		{
			return true;
		}

		public static bool GetKey(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return Input.GetKey(key);
		}

		public static bool GetKeyDown(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return Input.GetKeyDown(key);
		}

		public static bool GetKeyUp(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return Input.GetKeyDown(key);
		}

		public static Vector2 GetMousePosition()
		{
			//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)
			return Vector2.op_Implicit(Input.mousePosition);
		}
	}
	public static class InvocationTargetFactory
	{
		private static readonly Dictionary<(MonoTargetType, Type), object> TargetCache = new Dictionary<(MonoTargetType, Type), object>();

		public static IEnumerable<T> FindTargets<T>(MonoTargetType method) where T : MonoBehaviour
		{
			foreach (object item in FindTargets(typeof(T), method))
			{
				yield return (T)((item is T) ? item : null);
			}
		}

		public static IEnumerable<object> FindTargets(Type classType, MonoTargetType method)
		{
			switch (method)
			{
			case MonoTargetType.Single:
			{
				Object val = Object.FindObjectOfType(Il2CppType.From(classType));
				if (!(val == (Object)null))
				{
					return val.Yield<Object>();
				}
				return Enumerable.Empty<object>();
			}
			case MonoTargetType.SingleInactive:
				return WrapSingleCached(classType, method, (Type type) => ((IEnumerable<Object>)Resources.FindObjectsOfTypeAll(Il2CppType.From(type))).FirstOrDefault((Func<Object, bool>)((Object x) => !((Enum)x.hideFlags).HasFlag((Enum)(object)(HideFlags)1))));
			case MonoTargetType.All:
				return ((IEnumerable<Object>)Object.FindObjectsOfType(Il2CppType.From(classType))).OrderBy((Object x) => x.name, new AlphanumComparator());
			case MonoTargetType.AllInactive:
				return ((IEnumerable<Object>)Resources.FindObjectsOfTypeAll(Il2CppType.From(classType))).Where((Object x) => !((Enum)x.hideFlags).HasFlag((Enum)(object)(HideFlags)1)).OrderBy((Object x) => x.name, new AlphanumComparator());
			case MonoTargetType.Registry:
				return QuantumRegistry.GetRegistryContents(classType);
			case MonoTargetType.Singleton:
				return GetSingletonInstance(classType).Yield();
			default:
				throw new ArgumentException(QuantumConsoleBootstrap.Localization.Format(73u, new object[1] { method }));
			}
		}

		private static IEnumerable<object> WrapSingleCached(Type classType, MonoTargetType method, Func<Type, object> targetFinder)
		{
			if (!TargetCache.TryGetValue((method, classType), out var value) || (Object)((value is Object) ? value : null) == (Object)null)
			{
				value = targetFinder(classType);
				TargetCache[(method, classType)] = value;
			}
			if (value != null)
			{
				return value.Yield();
			}
			return Enumerable.Empty<object>();
		}

		public static object InvokeOnTargets(MethodInfo invokingMethod, IEnumerable<object> targets, object[] arguments)
		{
			int num = 0;
			int num2 = 0;
			Dictionary<object, object> dictionary = new Dictionary<object, object>();
			foreach (object target in targets)
			{
				num2++;
				object obj = invokingMethod.Invoke(target, arguments);
				if (obj != null)
				{
					dictionary.Add(target, obj);
					num++;
				}
			}
			if (num > 1)
			{
				return dictionary;
			}
			if (num == 1)
			{
				return dictionary.Values.First();
			}
			if (num2 == 0)
			{
				string displayName = invokingMethod.DeclaringType.GetDisplayName();
				throw new Exception(QuantumConsoleBootstrap.Localization.Format(74u, new object[1] { displayName }));
			}
			return null;
		}

		private static string FormatInvocationMessage(int invocationCount, object lastTarget = null)
		{
			switch (invocationCount)
			{
			case 0:
				throw new Exception(QuantumConsoleBootstrap.Localization.Get(75u));
			case 1:
			{
				Object val = (Object)((lastTarget is Object) ? lastTarget : null);
				string text = ((val == null) ? lastTarget?.ToString() : val.name);
				return QuantumConsoleBootstrap.Localization.Format(76u, new object[1] { text });
			}
			default:
				return QuantumConsoleBootstrap.Localization.Format(77u, new object[1] { invocationCount });
			}
		}

		private static object GetSingletonInstance(Type classType)
		{
			if (QuantumRegistry.GetRegistrySize(classType) > 0)
			{
				return QuantumRegistry.GetRegistryContents(classType).First();
			}
			object obj = CreateCommandSingletonInstance(classType);
			QuantumRegistry.RegisterObject(classType, obj);
			return obj;
		}

		private static Component CreateCommandSingletonInstance(Type classType)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			GameObject val = new GameObject($"{classType}Singleton");
			Object.DontDestroyOnLoad((Object)val);
			return ((Il2CppObjectBase)val.AddComponent(Il2CppType.From(classType, true))).Cast<Component>();
		}
	}
	public class LambdaCommandData : CommandData
	{
		private readonly object _lambdaTarget;

		public LambdaCommandData(Delegate lambda, string commandName, string commandDescription = "")
			: base(lambda.Method, new CommandAttribute(commandName, commandDescription, MonoTargetType.Registry, Platform.AllPlatforms))
		{
			_lambdaTarget = lambda.Target;
		}

		protected override IEnumerable<object> GetInvocationTargets(MethodInfo invokingMethod)
		{
			yield return _lambdaTarget;
		}
	}
	internal static class CommandLocalizationHelper
	{
		private static ConcurrentDictionary<Assembly, Dictionary<string, Dictionary<Language, CommandLocalizationData>>> _commandLocalizationLookup = new ConcurrentDictionary<Assembly, Dictionary<string, Dictionary<Language, CommandLocalizationData>>>();

		public static void Init()
		{
			Application.quitting += Action.op_Implicit((Action)OnApplicationQuit);
		}

		public static void LoadCommandLocalizationData(this CommandData command)
		{
			Assembly assembly = command.MethodData.DeclaringType.Assembly;
			if (_commandLocalizationLookup.TryAdd(assembly, new Dictionary<string, Dictionary<Language, CommandLocalizationData>>()))
			{
				string text = Path.Combine(Path.GetDirectoryName(assembly.Location), "Localization");
				if (!Directory.Exists(text))
				{
					Directory.CreateDirectory(text);
				}
				string path = Path.Combine(text, assembly.GetName().Name + "_QuantumCommands_Localization.json");
				if (File.Exists(path))
				{
					foreach (KeyValuePair<string, Dictionary<Language, CommandLocalizationData>> item in JsonConvert.DeserializeObject<Dictionary<string, Dictionary<Language, CommandLocalizationData>>>(File.ReadAllText(path), ArchiveMod.JsonSerializerSettings))
					{
						_commandLocalizationLookup[assembly][item.Key] = item.Value;
					}
				}
			}
			command.ApplyLocalization(CheckAndGenerateCommandLocalization(command));
		}

		private static Dictionary<Language, CommandLocalizationData> CheckAndGenerateCommandLocalization(CommandData command)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			Assembly assembly = command.MethodData.DeclaringType.Assembly;
			if (!_commandLocalizationLookup[assembly].TryGetValue(command.LocalizationSignature, out var value))
			{
				value = new Dictionary<Language, CommandLocalizationData>();
			}
			Language[] values = Enum.GetValues<Language>();
			foreach (Language key in values)
			{
				value.TryGetValue(key, out var value2);
				if (value2 == null)
				{
					value2 = new CommandLocalizationData();
				}
				if (string.IsNullOrEmpty(value2.Description))
				{
					value2.Description = command.CommandDescription;
				}
				CommandLocalizationData commandLocalizationData = value2;
				if (commandLocalizationData.ParameterDescriptions == null)
				{
					Dictionary<string, string> dictionary2 = (commandLocalizationData.ParameterDescriptions = new Dictionary<string, string>());
				}
				ParameterInfo[] methodParamData = command.MethodParamData;
				foreach (ParameterInfo parameterInfo in methodParamData)
				{
					value2.ParameterDescriptions.TryGetValue(parameterInfo.Name, out var value3);
					if (string.IsNullOrEmpty(value3))
					{
						value2.ParameterDescriptions[parameterInfo.Name] = parameterInfo.GetCustomAttribute<CommandParameterDescriptionAttribute>()?.Description ?? null;
					}
				}
				value[key] = value2;
				_commandLocalizationLookup[assembly][command.LocalizationSignature] = value;
			}
			return value;
		}

		private static void OnApplicationQuit()
		{
			foreach (KeyValuePair<Assembly, Dictionary<string, Dictionary<Language, CommandLocalizationData>>> item in _commandLocalizationLookup)
			{
				CheckAndSaveLocalization(item.Key);
			}
		}

		private static void CheckAndSaveLocalization(Assembly assembly)
		{
			string text = Path.Combine(Path.GetDirectoryName(assembly.Location), "Localization");
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			string path = Path.Combine(text, assembly.GetName().Name + "_QuantumCommands_Localization.json");
			if (!File.Exists(path))
			{
				if (!_commandLocalizationLookup.TryGetValue(assembly, out var value))
				{
					value = new Dictionary<string, Dictionary<Language, CommandLocalizationData>>();
				}
				File.WriteAllText(path, JsonConvert.SerializeObject((object)value, ArchiveMod.JsonSerializerSettings));
				return;
			}
			string text2 = JsonConvert.SerializeObject((object)JsonConvert.DeserializeObject<Dictionary<string, Dictionary<Language, CommandLocalizationData>>>(File.ReadAllText(path), ArchiveMod.JsonSerializerSettings), ArchiveMod.JsonSerializerSettings);
			string text3 = JsonConvert.SerializeObject((object)_commandLocalizationLookup[assembly].OrderBy((KeyValuePair<string, Dictionary<Language, CommandLocalizationData>> dict) => dict.Key).ToDictionary((KeyValuePair<string, Dictionary<Language, CommandLocalizationData>> kvp) => kvp.Key, (KeyValuePair<string, Dictionary<Language, CommandLocalizationData>> kvp) => kvp.Value), ArchiveMod.JsonSerializerSettings);
			if (Utils.HashString(text3) != Utils.HashString(text2))
			{
				File.WriteAllText(path, text3);
			}
		}
	}
	internal class CommandLocalizationData
	{
		public string Description { get; set; }

		public Dictionary<string, string> ParameterDescriptions { get; set; }
	}
	public interface ILog
	{
		string Text { get; }

		LogLevel Level { get; }

		bool NewLine { get; }
	}
	public interface ILogQueue
	{
		int MaxStoredLogs { get; set; }

		bool IsEmpty { get; }

		void QueueLog(ILog log);

		bool TryDequeue(out ILog log);

		void Clear();
	}
	public interface ILogStorage
	{
		int MaxStoredLogs { get; set; }

		IReadOnlyList<ILog> Logs { get; }

		void AddLog(ILog log);

		void RemoveLog();

		void Clear();

		string GetLogString();
	}
	public readonly struct Log : ILog
	{
		public string Text { get; }

		public LogLevel Level { get; }

		public bool NewLine { get; }

		public Log(string text, LogLevel level = LogLevel.Message, bool newLine = true)
		{
			Text = text;
			Level = level;
			NewLine = newLine;
		}
	}
	[Flags]
	public enum LogLevel
	{
		None = 0,
		Fatal = 1,
		Error = 2,
		Warning = 4,
		Message = 8,
		Info = 0x10,
		Debug = 0x20,
		All = 0x3F
	}
	public class LogQueue : ILogQueue
	{
		private readonly ConcurrentQueue<ILog> _queuedLogs = new ConcurrentQueue<ILog>();

		public int MaxStoredLogs { get; set; }

		public bool IsEmpty => _queuedLogs.IsEmpty;

		public LogQueue(int maxStoredLogs = -1)
		{
			MaxStoredLogs = maxStoredLogs;
		}

		public void QueueLog(ILog log)
		{
			_queuedLogs.Enqueue(log);
			if (MaxStoredLogs > 0 && _queuedLogs.Count > MaxStoredLogs)
			{
				_queuedLogs.TryDequeue(out var _);
			}
		}

		public bool TryDequeue(out ILog log)
		{
			return _queuedLogs.TryDequeue(out log);
		}

		public void Clear()
		{
			ILog log;
			while (TryDequeue(out log))
			{
			}
		}
	}
	public class LogStorage : ILogStorage
	{
		private readonly List<ILog> _consoleLogs = new List<ILog>(10);

		private readonly StringBuilder _logTraceBuilder = new StringBuilder(2048);

		public int MaxStoredLogs { get; set; }

		public IReadOnlyList<ILog> Logs => _consoleLogs;

		public LogStorage(int maxStoredLogs = -1)
		{
			MaxStoredLogs = maxStoredLogs;
		}

		public void AddLog(ILog log)
		{
			_consoleLogs.Add(log);
			int num = _logTraceBuilder.Length + log.Text.Length;
			if (log.NewLine && _logTraceBuilder.Length > 0)
			{
				num += Environment.NewLine.Length;
			}
			if (MaxStoredLogs > 0)
			{
				while (_consoleLogs.Count > MaxStoredLogs)
				{
					int num2 = _consoleLogs[0].Text.Length;
					if (_consoleLogs.Count > 1 && _consoleLogs[1].NewLine)
					{
						num2 += Environment.NewLine.Length;
					}
					num2 = Mathf.Min(num2, _logTraceBuilder.Length);
					num -= num2;
					_logTraceBuilder.Remove(0, num2);
					_consoleLogs.RemoveAt(0);
				}
			}
			int num3;
			for (num3 = _logTraceBuilder.Capacity; num3 < num; num3 *= 2)
			{
			}
			_logTraceBuilder.EnsureCapacity(num3);
			if (log.NewLine && _logTraceBuilder.Length > 0)
			{
				_logTraceBuilder.Append(Environment.NewLine);
			}
			_logTraceBuilder.Append(log.Text);
		}

		public void RemoveLog()
		{
			if (_consoleLogs.Count > 0)
			{
				ILog log = _consoleLogs[_consoleLogs.Count - 1];
				_consoleLogs.RemoveAt(_consoleLogs.Count - 1);
				int num = log.Text.Length;
				if (log.NewLine && _consoleLogs.Count > 0)
				{
					num += Environment.NewLine.Length;
				}
				_logTraceBuilder.Remove(_logTraceBuilder.Length - num, num);
			}
		}

		public void Clear()
		{
			_consoleLogs.Clear();
			_logTraceBuilder.Length = 0;
		}

		public string GetLogString()
		{
			return _logTraceBuilder.ToString();
		}
	}
	public struct ModifierKeyCombo
	{
		public KeyCode Key { get; set; }

		public bool Ctrl { get; set; }

		public bool Alt { get; set; }

		public bool Shift { get; set; }

		public bool ModifiersActive
		{
			get
			{
				bool num = !Ctrl ^ (InputHelper.GetKey((KeyCode)306) || InputHelper.GetKey((KeyCode)305) || InputHelper.GetKey((KeyCode)310) || InputHelper.GetKey((KeyCode)309));
				bool flag = !Alt ^ (InputHelper.GetKey((KeyCode)308) || InputHelper.GetKey((KeyCode)307));
				bool flag2 = !Shift ^ (InputHelper.GetKey((KeyCode)304) || InputHelper.GetKey((KeyCode)303));
				return num && flag && flag2;
			}
		}

		public bool IsHeld()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (ModifiersActive)
			{
				return InputHelper.GetKey(Key);
			}
			return false;
		}

		public bool IsPressed()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (ModifiersActive)
			{
				return InputHelper.GetKeyDown(Key);
			}
			return false;
		}

		public static implicit operator ModifierKeyCombo(KeyCode key)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			ModifierKeyCombo result = default(ModifierKeyCombo);
			result.Key = key;
			return result;
		}
	}
	public enum MonoTargetType
	{
		Single,
		All,
		Registry,
		Singleton,
		SingleInactive,
		AllInactive,
		Argument,
		ArgumentMulti
	}
	public abstract class BasicCachedQcParser<T> : BasicQcParser<T>
	{
		private readonly Dictionary<string, T> _cacheLookup = new Dictionary<string, T>();

		public override object Parse(string value, Type type, Func<string, Type, object> recursiveParser)
		{
			if (_cacheLookup.ContainsKey(value))
			{
				return _cacheLookup[value];
			}
			T val = (T)base.Parse(value, type, recursiveParser);
			_cacheLookup[value] = val;
			return val;
		}
	}
	public abstract class BasicQcParser<T> : IQcParser
	{
		private Func<string, Type, object> _recursiveParser;

		public virtual int Priority => 0;

		public bool CanParse(Type type)
		{
			return type == typeof(T);
		}

		public virtual object Parse(string value, Type type, Func<string, Type, object> recursiveParser)
		{
			_recursiveParser = recursiveParser;
			return Parse(value);
		}

		protected object ParseRecursive(string value, Type type)
		{
			return _recursiveParser(value, type);
		}

		protected TElement ParseRecursive<TElement>(string value)
		{
			return (TElement)_recursiveParser(value, typeof(TElement));
		}

		public abstract T Parse(string value);
	}
	public class ParserException : Exception
	{
		public ParserException(string message)
			: base(message)
		{
		}

		public ParserException(string message, Exception innerException)
			: base(message, innerException)
		{
		}
	}
	public class ParserInputException : ParserException
	{
		public ParserInputException(string message)
			: base(message)
		{
		}

		public ParserInputException(string message, Exception innerException)
			: base(message, innerException)
		{
		}
	}
	public abstract class GenericCachedQcParser : GenericQcParser
	{
		private readonly Dictionary<(string, Type), object> _cacheLookup = new Dictionary<(string, Type), object>();

		public override object Parse(string value, Type type, Func<string, Type, object> recursiveParser)
		{
			(string, Type) key = (value, type);
			if (_cacheLookup.ContainsKey(key))
			{
				return _cacheLookup[key];
			}
			object obj = base.Parse(value, type, recursiveParser);
			_cacheLookup[key] = obj;
			return obj;
		}
	}
	public abstract class GenericQcParser : IQcParser
	{
		private Func<string, Type, object> _recursiveParser;

		protected abstract Type GenericType { get; }

		public virtual int Priority => -500;

		protected GenericQcParser()
		{
			if (!GenericType.IsGenericType)
			{
				throw new ArgumentException(QuantumConsoleBootstrap.Localization.Get(61u));
			}
			if (GenericType.IsConstructedGenericType)
			{
				throw new ArgumentException(QuantumConsoleBootstrap.Localization.Get(62u));
			}
		}

		public bool CanParse(Type type)
		{
			return type.IsGenericTypeOf(GenericType);
		}

		public virtual object Parse(string value, Type type, Func<string, Type, object> recursiveParser)
		{
			_recursiveParser = recursiveParser;
			return Parse(value, type);
		}

		protected object ParseRecursive(string value, Type type)
		{
			return _recursiveParser(value, type);
		}

		protected TElement ParseRecursive<TElement>(string value)
		{
			return (TElement)_recursiveParser(value, typeof(TElement));
		}

		public abstract object Parse(string value, Type type);
	}
	public interface IQcGrammarConstruct
	{
		int Precedence { get; }

		bool Match(string value, Type type);

		object Parse(string value, Type type, Func<string, Type, object> recursiveParser);
	}
	public interface IQcParser
	{
		int Priority { get; }

		bool CanParse(Type type);

		object Parse(string value, Type type, Func<string, Type, object> recursiveParser);
	}
	public abstract class MassGenericQcParser : IQcParser
	{
		private Func<string, Type, object> _recursiveParser;

		protected abstract HashSet<Type> GenericTypes { get; }

		public virtual int Priority => -2000;

		protected MassGenericQcParser()
		{
			foreach (Type genericType in GenericTypes)
			{
				if (!genericType.IsGenericType)
				{
					throw new ArgumentException(QuantumConsoleBootstrap.Localization.Get(61u));
				}
				if (genericType.IsConstructedGenericType)
				{
					throw new ArgumentException(QuantumConsoleBootstrap.Localization.Get(62u));
				}
			}
		}

		public bool CanParse(Type type)
		{
			if (type.IsGenericType)
			{
				return GenericTypes.Contains(type.GetGenericTypeDefinition());
			}
			return false;
		}

		public virtual object Parse(string value, Type type, Func<string, Type, object> recursiveParser)
		{
			_recursiveParser = recursiveParser;
			return Parse(value, type);
		}

		protected object ParseRecursive(string value, Type type)
		{
			return _recursiveParser(value, type);
		}

		protected TElement ParseRecursive<TElement>(string value)
		{
			return (TElement)_recursiveParser(value, typeof(TElement));
		}

		public abstract object Parse(string value, Type type);
	}
	public abstract class PolymorphicCachedQcParser<T> : PolymorphicQcParser<T> where T : class
	{
		private readonly Dictionary<(string, Type), T> _cacheLookup = new Dictionary<(string, Type), T>();

		public override object Parse(string value, Type type, Func<string, Type, object> recursiveParser)
		{
			(string, Type) key = (value, type);
			if (_cacheLookup.ContainsKey(key))
			{
				return _cacheLookup[key];
			}
			T val = (T)base.Parse(value, type, recursiveParser);
			_cacheLookup[key] = val;
			return val;
		}
	}
	public abstract class PolymorphicQcParser<T> : IQcParser where T : class
	{
		private Func<string, Type, object> _recursiveParser;

		public virtual int Priority => -1000;

		public bool CanParse(Type type)
		{
			return typeof(T).IsAssignableFrom(type);
		}

		public virtual object Parse(string value, Type type, Func<string, Type, object> recursiveParser)
		{
			_recursiveParser = recursiveParser;
			return Parse(value, type);
		}

		protected object ParseRecursive(string value, Type type)
		{
			return _recursiveParser(value, type);
		}

		protected TElement ParseRecursive<TElement>(string value)
		{
			return (TElement)_recursiveParser(value, typeof(TElement));
		}

		public abstract T Parse(string value, Type type);
	}
	public class QuantumParser
	{
		private readonly IQcParser[] _parsers;

		private readonly IQcGrammarConstruct[] _grammarConstructs;

		private readonly ConcurrentDictionary<Type, IQcParser> _parserLookup = new ConcurrentDictionary<Type, IQcParser>();

		private readonly HashSet<Type> _unparseableLookup = new HashSet<Type>();

		private readonly Func<string, Type, object> _recursiveParser;

		private static readonly Dictionary<Type, string> _typeDisplayNames = new Dictionary<Type, string>
		{
			{
				typeof(int),
				"int"
			},
			{
				typeof(float),
				"float"
			},
			{
				typeof(decimal),
				"decimal"
			},
			{
				typeof(double),
				"double"
			},
			{
				typeof(string),
				"string"
			},
			{
				typeof(bool),
				"bool"
			},
			{
				typeof(byte),
				"byte"
			},
			{
				typeof(sbyte),
				"sbyte"
			},
			{
				typeof(uint),
				"uint"
			},
			{
				typeof(short),
				"short"
			},
			{
				typeof(ushort),
				"ushort"
			},
			{
				typeof(long),
				"long"
			},
			{
				typeof(ulong),
				"ulong"
			},
			{
				typeof(char),
				"char"
			},
			{
				typeof(object),
				"object"
			}
		};

		private static readonly Dictionary<string, Type> _reverseTypeDisplayNames = _typeDisplayNames.Invert();

		private static readonly Assembly[] _loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();

		private static readonly string[] _defaultNamespaces = new string[6] { "System", "System.Collections", "System.Collections.Generic", "UnityEngine", "UnityEngine.UI", "Hikaria.QC" };

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

		private static readonly Regex _arrayTypeRegex = new Regex("^.*\\[,*\\]$");

		private static readonly Regex _genericTypeRegex = new Regex("^.+<.*>$");

		private static readonly Regex _tupleTypeRegex = new Regex("^\\(.*\\)$");

		private static readonly Regex _nullableTypeRegex = new Regex("^.*\\?$");

		private static readonly Type[] _valueTupleTypes = new Type[8]
		{
			typeof(ValueTuple<>),
			typeof(ValueTuple<, >),
			typeof(ValueTuple<, , >),
			typeof(ValueTuple<, , , >),
			typeof(ValueTuple<, , , , >),
			typeof(ValueTuple<, , , , , >),
			typeof(ValueTuple<, , , , , , >),
			typeof(ValueTuple<, , , , , , , >)
		};

		public QuantumParser(IEnumerable<IQcParser> parsers, IEnumerable<IQcGrammarConstruct> grammarConstructs)
		{
			_recursiveParser = Parse;
			_parsers = parsers.OrderByDescending((IQcParser x) => x.Priority).ToArray();
			_grammarConstructs = grammarConstructs.OrderBy((IQcGrammarConstruct x) => x.Precedence).ToArray();
		}

		public QuantumParser()
			: this(new InjectionLoader<IQcParser>().GetInjectedInstances(), new InjectionLoader<IQcGrammarConstruct>().GetInjectedInstances())
		{
		}

		public IQcParser GetParser(Type type)
		{
			if (_parserLookup.ContainsKey(type))
			{
				return _parserLookup[type];
			}
			if (!_unparseableLookup.Contains(type))
			{
				IQcParser[] parsers = _parsers;
				foreach (IQcParser qcParser in parsers)
				{
					try
					{
						if (qcParser.CanParse(type))
						{
							return _parserLookup[type] = qcParser;
						}
					}
					catch (Exception ex)
					{
						Logs.LogError(QuantumConsoleBootstrap.Localization.Format(93u, new object[1] { qcParser.GetType().GetDisplayName() + ".CanParse" }));
						Logs.LogException(ex);
					}
				}
				_unparseableLookup.Add(type);
			}
			return null;
		}

		public bool CanParse(Type type)
		{
			return GetParser(type) != null;
		}

		private IQcGrammarConstruct GetMatchingGrammar(string value, Type type)
		{
			IQcGrammarConstruct[] grammarConstructs = _grammarConstructs;
			foreach (IQcGrammarConstruct qcGrammarConstruct in grammarConstructs)
			{
				try
				{
					if (qcGrammarConstruct.Match(value, type))
					{
						return qcGrammarConstruct;
					}
				}
				catch (Exception ex)
				{
					Logs.LogError(QuantumConsoleBootstrap.Localization.Format(93u, new object[1] { qcGrammarConstruct.GetType().GetDisplayName() + ".Match" }));
					Logs.LogException(ex);
				}
			}
			return null;
		}

		public T Parse<T>(string value)
		{
			return (T)Parse(value, typeof(T));
		}

		public object Parse(string value, Type type)
		{
			value = value.ReduceScope('(', ')');
			if (type.IsClass && value == "null")
			{
				return null;
			}
			IQcGrammarConstruct matchingGrammar = GetMatchingGrammar(value, type);
			if (matchingGrammar != null)
			{
				try
				{
					return matchingGrammar.Parse(value, type, _recursiveParser);
				}
				catch (ParserException)
				{
					throw;
				}
				catch (Exception ex2)
				{
					throw new Exception(QuantumConsoleBootstrap.Localization.Format(94u, new object[3]
					{
						type.GetDisplayName(),
						matchingGrammar,
						ex2.Message
					}), ex2);
				}
			}
			IQcParser parser = GetParser(type);
			if (parser == null)
			{
				throw new ArgumentException(QuantumConsoleBootstrap.Localization.Format(95u, new object[1] { type.GetDisplayName() }));
			}
			try
			{
				return parser.Parse(value, type, _recursiveParser);
			}
			catch (ParserException)
			{
				throw;
			}
			catch (Exception ex4)
			{
				throw new Exception(QuantumConsoleBootstrap.Localization.Format(94u, new object[3]
				{
					type.GetDisplayName(),
					parser,
					ex4.Message
				}), ex4);
			}
		}

		[Command("reset-namespaces", "Resets the namespace table to its initial state", Platform.AllPlatforms, MonoTargetType.Single)]
		public static void ResetNamespaceTable()
		{
			_namespaceTable.Clear();
			_namespaceTable.AddRange(_defaultNamespaces);
		}

		[Command("use-namespace", "Adds a namespace to the table so that it can be used to type resolution", Platform.AllPlatforms, MonoTargetType.Single)]
		public static void AddNamespace(string namespaceName)
		{
			if (!_namespaceTable.Contains(namespaceName))
			{
				_namespaceTable.Add(namespaceName);
			}
		}

		[Command("remove-namespace", "Removes a namespace from the table", Platform.AllPlatforms, MonoTargetType.Single)]
		public static void RemoveNamespace(string namespaceName)
		{
			if (_namespaceTable.Contains(namespaceName))
			{
				_namespaceTable.Remove(namespaceName);
				return;
			}
			throw new ArgumentException(QuantumConsoleBootstrap.Localization.Format(42u, new object[1] { namespaceName }));
		}

		[Command("all-namespaces", "Displays all of the namespaces currently in use by the namespace table", Platform.AllPlatforms, MonoTargetType.Single)]
		private static string ShowNamespaces()
		{
			_namespaceTable.Sort();
			if (_namespaceTable.Count == 0)
			{
				return QuantumConsoleBootstrap.Localization.Get(43u);
			}
			return string.Join("\n", _namespaceTable);
		}

		public static IEnumerable<string> GetAllNamespaces()
		{
			return _namespaceTable;
		}

		public static Type ParseType(string typeName)
		{
			typeName = typeName.Trim();
			if (_reverseTypeDisplayNames.ContainsKey(typeName))
			{
				return _reverseTypeDisplayNames[typeName];
			}
			if (_tupleTypeRegex.IsMatch(typeName))
			{
				return ParseTupleType(typeName);
			}
			if (_arrayTypeRegex.IsMatch(typeName))
			{
				return ParseArrayType(typeName);
			}
			if (_genericTypeRegex.IsMatch(typeName))
			{
				return ParseGenericType(typeName);
			}
			if (_nullableTypeRegex.IsMatch(typeName))
			{
				return ParseNullableType(typeName);
			}
			if (typeName.Contains('`'))
			{
				string key = typeName.Split('`')[0];
				if (_reverseTypeDisplayNames.ContainsKey(key))
				{
					return _reverseTypeDisplayNames[key];
				}
			}
			return ParseTypeBaseCase(typeName);
		}

		private static Type ParseArrayType(string typeName)
		{
			int num = typeName.LastIndexOf('[');
			int num2 = typeName.CountFromIndex(',', num) + 1;
			Type type = ParseType(typeName.Substring(0, num));
			if (num2 <= 1)
			{
				return type.MakeArrayType();
			}
			return type.MakeArrayType(num2);
		}

		private static Type ParseGenericType(string typeName)
		{
			string[] array = typeName.Split(new char[1] { '<' }, 2);
			string[] array2 = ("<" + array[1]).ReduceScope('<', '>').SplitScoped(',');
			Type type = ParseType($"{array[0]}`{Math.Max(1, array2.Length)}");
			if (array2.All(string.IsNullOrWhiteSpace))
			{
				return type;
			}
			Type[] typeArguments = array2.Select(ParseType).ToArray();
			return type.MakeGenericType(typeArguments);
		}

		private static Type ParseNullableType(string typeName)
		{
			Type type = ParseType(typeName.Substring(0, typeName.Length - 1));
			if (!type.IsClass)
			{
				return typeof(Nullable<>).MakeGenericType(type);
			}
			return type;
		}

		private static Type ParseTupleType(string typeName)
		{
			return CreateTupleType(typeName.Substring(1, typeName.Length - 2).SplitScoped(',').Select(ParseType)
				.ToArray());
		}

		private static Type CreateTupleType(Type[] types)
		{
			if (types.Length > 7)
			{
				Type[] types2 = types.Skip(7).ToArray();
				types = types.Take(7).Concat(CreateTupleType(types2).Yield()).ToArray();
			}
			return _valueTupleTypes[types.Length - 1].MakeGenericType(types);
		}

		private static Type ParseTypeBaseCase(string typeName)
		{
			return GetTypeFromAssemblies(typeName, _loadedAssemblies, throwOnError: false, ignoreCase: false) ?? GetTypeFromAssemblies(typeName, _namespaceTable, _loadedAssemblies, throwOnError: false, ignoreCase: false) ?? GetTypeFromAssemblies(typeName, _loadedAssemblies, throwOnError: false, ignoreCase: true) ?? GetTypeFromAssemblies(typeName, _namespaceTable, _loadedAssemblies, throwOnError: true, ignoreCase: true);
		}

		private static Type GetTypeFromAssemblies(string typeName, IEnumerable<string> namespaces, IEnumerable<Assembly> assemblies, bool throwOnError, bool ignoreCase)
		{
			foreach (string @namespace in namespaces)
			{
				Type typeFromAssemblies = GetTypeFromAssemblies(@namespace + "." + typeName, assemblies, throwOnError: false, ignoreCase);
				if (typeFromAssemblies != null)
				{
					return typeFromAssemblies;
				}
			}
			if (throwOnError)
			{
				throw new TypeLoadException(QuantumConsoleBootstrap.Localization.Format(44u, new object[1] { typeName }));
			}
			return null;
		}

		private static Type GetTypeFromAssemblies(string typeName, IEnumerable<Assembly> assemblies, bool throwOnError, bool ignoreCase)
		{
			foreach (Assembly assembly in assemblies)
			{
				Type type = Type.GetType(typeName + ", " + assembly.FullName, throwOnError: false, ignoreCase);
				if (type != null)
				{
					return type;
				}
			}
			if (throwOnError)
			{
				throw new TypeLoadException(QuantumConsoleBootstrap.Localization.Format(45u, new object[1] { typeName }));
			}
			return null;
		}
	}
	[Flags]
	public enum Platform : long
	{
		OSXEditor = 1L,
		OSXPlayer = 2L,
		WindowsPlayer = 4L,
		OSXWebPlayer = 8L,
		OSXDashboardPlayer = 0x10L,
		WindowsWebPlayer = 0x20L,
		WindowsEditor = 0x80L,
		IPhonePlayer = 0x100L,
		PS3 = 0x200L,
		XBOX360 = 0x400L,
		Android = 0x800L,
		NaCl = 0x1000L,
		LinuxPlayer = 0x2000L,
		FlashPlayer = 0x8000L,
		LinuxEditor = 0x10000L,
		WebGLPlayer = 0x20000L,
		MetroPlayerX86 = 0x40000L,
		WSAPlayerX86 = 0x40000L,
		MetroPlayerX64 = 0x80000L,
		WSAPlayerX64 = 0x80000L,
		MetroPlayerARM = 0x100000L,
		WSAPlayerARM = 0x100000L,
		WP8Player = 0x200000L,
		BlackBerryPlayer = 0x400000L,
		TizenPlayer = 0x800000L,
		PSP2 = 0x1000000L,
		PS4 = 0x2000000L,
		PSM = 0x4000000L,
		XboxOne = 0x8000000L,
		SamsungTVPlayer = 0x10000000L,
		WiiU = 0x40000000L,
		tvOS = 0x80000000L,
		Switch = 0x100000000L,
		Lumin = 0x200000000L,
		Stadia = 0x400000000L,
		None = 0L,
		AllPlatforms = -1L,
		EditorPlatforms = 0x10081L,
		BuildPlatforms = -65666L,
		MobilePlatforms = 0x200900L
	}
	public static class PlatformExtensions
	{
		public static Platform ToPlatform(this RuntimePlatform pl)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Expected I4, but got Unknown
			int num = (int)pl;
			return (Platform)(1L << num);
		}
	}
	public interface IQcPreprocessor
	{
		int Priority { get; }

		string Process(string text);
	}
	public class QuantumPreprocessor
	{
		private readonly IQcPreprocessor[] _preprocessors;

		public QuantumPreprocessor(IEnumerable<IQcPreprocessor> preprocessors)
		{
			_preprocessors = preprocessors.OrderByDescending((IQcPreprocessor x) => x.Priority).ToArray();
		}

		public QuantumPreprocessor()
			: this(new InjectionLoader<IQcPreprocessor>().GetInjectedInstances())
		{
		}

		public string Process(string text)
		{
			IQcPreprocessor[] preprocessors = _preprocessors;
			foreach (IQcPreprocessor qcPreprocessor in preprocessors)
			{
				try
				{
					text = qcPreprocessor.Process(text);
				}
				catch (Exception ex)
				{
					throw new Exception(QuantumConsoleBootstrap.Localization.Format(63u, new object[2] { qcPreprocessor, ex.Message }), ex);
				}
			}
			return text;
		}
	}
	public class QuantumConsole : MonoBehaviour, ILocalizedTextUpdater
	{
		private RectTransform _containerRect;

		private ScrollRect _scrollRect;

		private RectTransform _suggestionPopupRect;

		private RectTransform _jobCounterRect;

		private Image[] _panels;

		private QuantumTheme _theme;

		private QuantumKeyConfig _keyConfig;

		private QuantumLocalization _localization;

		private QuantumConsolePreferences _preferences;

		[Command("verbose-errors", "If errors caused by the Quantum Console Processor or commands should be logged in verbose mode.", MonoTargetType.Registry, Platform.AllPlatforms)]
		private bool _verboseErrors;

		[Command("verbose-logging", "Log levels required to use verbose logging.", MonoTargetType.Registry, Platform.AllPlatforms)]
		private LogLevel _verboseLogging;

		[Command("logging-level", "Log levels required to intercept and display the log.", MonoTargetType.Registry, Platform.AllPlatforms)]
		private LogLevel _loggingLevel = LogLevel.Fatal | LogLevel.Error | LogLevel.Message | LogLevel.Info | LogLevel.Debug;

		private LogLevel _openOnLogLevel;

		private bool _interceptDebugLogger = true;

		private bool _interceptWhilstInactive = true;

		private bool _prependTimestamps = true;

		private SupportedState _supportedState;

		private bool _activateOnStartup;

		private bool _initialiseOnStartup = true;

		private bool _focusOnActivate = true;

		private bool _closeOnSubmit;

		private bool _singletonMode = true;

		private AutoScrollOptions _autoScroll = AutoScrollOptions.OnInvoke;

		private bool _enableAutocomplete = true;

		private bool _showPopupDisplay = true;

		private SortOrder _suggestionDisplayOrder = SortOrder.Descending;

		private int _maxSuggestionDisplaySize = 20;

		private bool _useFuzzySearch = true;

		private bool _caseSensitiveSearch;

		private bool _collapseSuggestionOverloads = true;

		private bool _showCurrentJobs = true;

		private bool _blockOnAsync;

		private bool _storeCommandHistory = true;

		private bool _storeDuplicateCommands = true;

		private bool _storeAdjacentDuplicateCommands;

		private int _commandHistorySize = 30;

		private int _maxStoredLogs = 768;

		private int _maxLogSize = 8192;

		private bool _showInitLogs = true;

		private TMP_InputField _consoleInput;

		private TextMeshProUGUI _inputPlaceholderText;

		private TextMeshProUGUI _consoleLogText;

		private TextMeshProUGUI _consoleSuggestionText;

		private TextMeshProUGUI _suggestionPopupText;

		private TextMeshProUGUI _jobCounterText;

		private TextMeshProUGUI _submitButtonText;

		private TextMeshProUGUI _clearButtonText;

		private TextMeshProUGUI _closeButtonText;

		private LogCallback _logCallback;

		private readonly QuantumSerializer _serializer = new QuantumSerializer();

		private SuggestionStack _suggestionStack;

		private ILogStorage _logStorage;

		private ILogQueue _logQueue;

		private readonly List<string> _previousCommands = new List<string>();

		private readonly List<Task> _currentTasks = new List<Task>();

		private readonly List<IEnumerator<ICommandAction>> _currentActions = new List<IEnumerator<ICommandAction>>();

		private readonly StringBuilderPool _stringBuilderPool = new StringBuilderPool();

		private int _selectedPreviousCommandIndex = -1;

		private string _currentInput;

		private string _previousInput;

		private bool _isGeneratingTable;

		private bool _consoleRequiresFlush;

		private bool _isHandlingUserResponse;

		private ResponseConfig _currentResponseConfig;

		private Action<string> _onSubmitResponseCallback;

		private TextMeshProUGUI[] _textComponents;

		private readonly Type _voidTaskType = typeof(Task<>).MakeGenericType(Type.GetType("System.Threading.Tasks.VoidTaskResult"));

		private float _prePos;

		private float _preSize;

		private Vector2 _anchoredPos = Vector2.zero;

		private bool _initialized;

		public static QuantumConsole Instance { get; private set; }

		public QuantumTheme Theme
		{
			get
			{
				return _theme;
			}
			set
			{
				_theme = value;
			}
		}

		public QuantumKeyConfig KeyConfig
		{
			get
			{
				return _keyConfig;
			}
			set
			{
				_keyConfig = value;
			}
		}

		public QuantumLocalization Localization
		{
			get
			{
				return _localization;
			}
			set
			{
				_localization = value;
				ApplyLocalization(value);
			}
		}

		public QuantumConsolePreferences Preferences
		{
			get
			{
				return _preferences;
			}
			set
			{
				_preferences = value;
				ApplyPreferences(value);
			}
		}

		[Command("max-logs", MonoTargetType.Registry, Platform.AllPlatforms)]
		[CommandDescription("The maximum number of logs that may be stored in the log storage before old logs are removed.")]
		public int MaxStoredLogs
		{
			get
			{
				return _maxStoredLogs;
			}
			set
			{
				_maxStoredLogs = value;
				if (_logStorage != null)
				{
					_logStorage.MaxStoredLogs = value;
				}
				if (_logQueue != null)
				{
					_logQueue.MaxStoredLogs = value;
				}
			}
		}

		private bool IsBlockedByAsync
		{
			get
			{
				if ((_blockOnAsync && _currentTasks.Count > 0) || _currentActions.Count > 0)
				{
					return !_isHandlingUserResponse;
				}
				return false;
			}
		}

		public bool IsActive { get; private set; }

		public bool IsFocused
		{
			get
			{
				if (IsActive && Object.op_Implicit((Object)(object)_consoleInput))
				{
					return _consoleInput.isFocused;
				}
				return false;
			}
		}

		public bool AreActionsExecuting => _currentActions.Count > 0;

		public event Action OnStateChange;

		public event Action<string> OnInvoke;

		public event Action OnClear;

		public event Action<ILog> OnLog;

		public event Action OnActivate;

		public event Action OnDeactivate;

		public event Action<SuggestionSet> OnSuggestionSetGenerated;

		private void ApplyLocalization(QuantumLocalization localization)
		{
			_localization = localization;
			if (localization != null)
			{
				((TMP_Text)_submitButtonText).text = localization.SubmitButtonText;
				((TMP_Text)_clearButtonText).text = localization.ClearButtonText;
				((TMP_Text)_closeButtonText).text = localization.CloseButtonText;
			}
		}

		private void ApplyPreferences(QuantumConsolePreferences pref)
		{
			((TMP_Text)_suggestionPopupText).fontSize = pref.SuggestionFontSize;
			((TMP_Text)_consoleLogText).fontSize = pref.LogFontSize;
			_verboseErrors = pref.VerboseErrors;
			_verboseLogging = pref.VerboseLogging;
			_loggingLevel = pref.LoggingLevel;
			_openOnLogLevel = pref.OpenOnLogLevel;
			_interceptDebugLogger = pref.InterceptDebugLogger;
			_interceptWhilstInactive = pref.InterceptWhilstInactive;
			_prependTimestamps = pref.PrependTimestamps;
			_activateOnStartup = pref.ActivateOnStartup;
			_initialiseOnStartup = pref.InitialiseOnStartup;
			_focusOnActivate = pref.FocusOnActivate;
			_closeOnSubmit = pref.CloseOnSubmit;
			_autoScroll = pref.AutoScroll;
			_enableAutocomplete = pref.EnableAutocomplete;
			_showPopupDisplay = pref.ShowPopupDisplay;
			_suggestionDisplayOrder = pref.SuggestionDisplayOrder;
			_maxSuggestionDisplaySize = pref.MaxSuggestionDisplaySize;
			_useFuzzySearch = pref.UseFuzzySearch;
			_caseSensitiveSearch = pref.CaseSensitiveSearch;
			_collapseSuggestionOverloads = pref.CollapseSuggestionOverloads;
			_showCurrentJobs = pref.ShowCurrentJobs;
			_blockOnAsync = pref.BlockOnAsync;
			_storeCommandHistory = pref.StoreCommandHistory;
			_storeDuplicateCommands = pref.StoreDuplicateCommands;
			_storeAdjacentDuplicateCommands = pref.StoreAdjacentDuplicateCommands;
			_commandHistorySize = pref.CommandHistorySize;
			_maxStoredLogs = pref.MaxStoredLogs;
			_maxLogSize = pref.MaxLogSize;
			_showInitLogs = pref.ShowInitLogs;
		}

		public void ApplyTheme(QuantumTheme theme, bool forceRefresh = false)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			_theme = theme;
			if (theme == null)
			{
				return;
			}
			if (_textComponents == null || forceRefresh)
			{
				_textComponents = Il2CppArrayBase<TextMeshProUGUI>.op_Implicit(((Component)this).GetComponentsInChildren<TextMeshProUGUI>(true));
			}
			TextMeshProUGUI[] textComponents = _textComponents;
			foreach (TextMeshProUGUI val in textComponents)
			{
				if (Object.op_Implicit((Object)(object)theme.Font))
				{
					((TMP_Text)val).font = theme.Font;
				}
			}
			Image[] panels = _panels;
			foreach (Image obj in panels)
			{
				((Graphic)obj).material = theme.PanelMaterial;
				((Graphic)obj).color = theme.PanelColor;
			}
		}

		protected virtual void Update()
		{
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			if (!IsActive)
			{
				if (_keyConfig.ShowConsoleKey.IsPressed() || _keyConfig.ToggleConsoleVisibilityKey.IsPressed())
				{
					Activate();
				}
				return;
			}
			ProcessAsyncTasks();
			ProcessActions();
			HandleAsyncJobCounter();
			if (_keyConfig.HideConsoleKey.IsPressed() || _keyConfig.ToggleConsoleVisibilityKey.IsPressed())
			{
				Deactivate();
				return;
			}
			if (QuantumConsoleProcessor.TableIsGenerating)
			{
				((Selectable)_consoleInput).interactable = false;
				string text = (_logStorage.GetLogString() + "\n" + GetTableGenerationText()).Trim();
				if (text != ((TMP_Text)_consoleLogText).text)
				{
					if (_showInitLogs)
					{
						this.OnStateChange?.Invoke();
						((TMP_Text)_consoleLogText).text = text;
					}
					if (Object.op_Implicit((Object)(object)_inputPlaceholderText))
					{
						((TMP_Text)_inputPlaceholderText).text = _localization.Loading;
					}
				}
				return;
			}
			if (IsBlockedByAsync)
			{
				this.OnStateChange?.Invoke();
				((Selectable)_consoleInput).interactable = false;
				if (Object.op_Implicit((Object)(object)_inputPlaceholderText))
				{
					((TMP_Text)_inputPlaceholderText).text = _localization.ExecutingAsyncCommand;
				}
			}
			else if (!((Selectable)_consoleInput).interactable)
			{
				this.OnStateChange?.Invoke();
				((Selectable)_consoleInput).interactable = true;
				if (Object.op_Implicit((Object)(object)_inputPlaceholderText))
				{
					((TMP_Text)_inputPlaceholderText).text = _localization.EnterCommand;
				}
				OverrideConsoleInput(string.Empty);
				if (_isGeneratingTable)
				{
					if (_showInitLogs)
					{
						AppendLog(new Log(GetTableGenerationText()));
						((TMP_Text)_consoleLogText).text = _logStorage.GetLogString();
					}
					_isGeneratingTable = false;
					ScrollConsoleToLatest();
				}
			}
			_previousInput = _currentInput;
			_currentInput = _consoleInput.text;
			if (_currentInput != _previousInput)
			{
				OnInputChange();
			}
			else if (!IsBlockedByAsync)
			{
				if (InputHelper.GetKeyDown(_keyConfig.SubmitCommandKey))
				{
					InvokeCommand();
				}
				if (_storeCommandHistory)
				{
					ProcessCommandHistory();
				}
				ProcessAutocomplete();
			}
		}

		private void LateUpdate()
		{
			if (IsActive)
			{
				FlushQueuedLogs();
				FlushToConsoleText();
			}
		}

		private string GetTableGenerationText()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			string text = string.Format(_localization.InitializationProgress, QuantumConsoleProcessor.LoadedCommandCount);
			if (QuantumConsoleProcessor.TableIsGenerating)
			{
				return text + "...";
			}
			string text2 = ((_theme == null) ? _localization.InitializationComplete : _localization.InitializationComplete.ColorText(_theme.SuccessColor));
			return text + "\n" + text2;
		}

		private void ProcessCommandHistory()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (InputHelper.GetKeyDown(_keyConfig.NextCommandKey) || InputHelper.GetKeyDown(_keyConfig.PreviousCommandKey))
			{
				if (InputHelper.GetKeyDown(_keyConfig.NextCommandKey))
				{
					_selectedPreviousCommandIndex++;
				}
				else if (_selectedPreviousCommandIndex > 0)
				{
					_selectedPreviousCommandIndex--;
				}
				_selectedPreviousCommandIndex = Mathf.Clamp(_selectedPreviousCommandIndex, -1, _previousCommands.Count - 1);
				if (_selectedPreviousCommandIndex > -1)
				{
					string newInput = _previousCommands[_previousCommands.Count - _selectedPreviousCommandIndex - 1];
					OverrideConsoleInput(newInput);
				}
			}
		}

		private void UpdateSuggestions()
		{
			if (_isHandlingUserResponse)
			{
				ClearSuggestions();
				ClearPopup();
				return;
			}
			SuggestorOptions suggestorOptions = default(SuggestorOptions);
			suggestorOptions.CaseSensitive = _caseSensitiveSearch;
			suggestorOptions.Fuzzy = _useFuzzySearch;
			suggestorOptions.CollapseOverloads = _collapseSuggestionOverloads;
			SuggestorOptions options = suggestorOptions;
			_suggestionStack.UpdateStack(_currentInput, options);
			UpdateSuggestionText();
			if (_showPopupDisplay)
			{
				UpdatePopupDisplay();
			}
		}

		private void ProcessAutocomplete()
		{
			if (!_enableAutocomplete || (!_keyConfig.SelectNextSuggestionKey.IsPressed() && !_keyConfig.SelectPreviousSuggestionKey.IsPressed()))
			{
				return;
			}
			SuggestionSet topmostSuggestionSet = _suggestionStack.TopmostSuggestionSet;
			if (topmostSuggestionSet != null && topmostSuggestionSet.Suggestions.Count > 0)
			{
				if (_keyConfig.SelectNextSuggestionKey.IsPressed())
				{
					topmostSuggestionSet.SelectionIndex++;
				}
				if (_keyConfig.SelectPreviousSuggestionKey.IsPressed())
				{
					topmostSuggestionSet.SelectionIndex--;
				}
				topmostSuggestionSet.SelectionIndex += topmostSuggestionSet.Suggestions.Count;
				topmostSuggestionSet.SelectionIndex %= topmostSuggestionSet.Suggestions.Count;
				SetSuggestion(topmostSuggestionSet.SelectionIndex);
			}
		}

		private void FormatSuggestion(IQcSuggestion suggestion, bool selected, StringBuilder buffer)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			if (_theme == null)
			{
				buffer.Append(suggestion.FullSignature);
				return;
			}
			Color val = Color.white;
			Color val2 = _theme.SuggestionColor;
			if (selected)
			{
				val *= _theme.SelectedSuggestionColor;
				val2 *= _theme.SelectedSuggestionColor;
			}
			buffer.AppendColoredText(suggestion.PrimarySignature, val);
			buffer.AppendColoredText(suggestion.SecondarySignature, val2);
		}

		private string GetFormattedSuggestions(SuggestionSet suggestionSet)
		{
			StringBuilder stringBuilder = _stringBuilderPool.GetStringBuilder();
			GetFormattedSuggestions(suggestionSet, stringBuilder);
			return _stringBuilderPool.ReleaseAndToString(stringBuilder);
		}

		private void GetFormattedSuggestions(SuggestionSet suggestionSet, StringBuilder buffer)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			int num = suggestionSet.Suggestions.Count;
			if (_maxSuggestionDisplaySize > 0)
			{
				num = Mathf.Min(num, _maxSuggestionDisplaySize + 1);
			}
			for (int i = 0; i < num; i++)
			{
				if (_maxSuggestionDisplaySize > 0 && i >= _maxSuggestionDisplaySize)
				{
					if (_theme != null && suggestionSet.SelectionIndex >= _maxSuggestionDisplaySize)
					{
						buffer.AppendColoredText("...", _theme.SelectedSuggestionColor);
					}
					else
					{
						buffer.Append("...");
					}
					continue;
				}
				bool selected = i == suggestionSet.SelectionIndex;
				buffer.Append("<link=");
				buffer.Append(i);
				buffer.Append('>');
				FormatSuggestion(suggestionSet.Suggestions[i], selected, buffer);
				buffer.AppendLine("</link>");
			}
		}

		private void UpdatePopupDisplay()
		{
			SuggestionSet topmostSuggestionSet = _suggestionStack.TopmostSuggestionSet;
			if (topmostSuggestionSet == null || topmostSuggestionSet.Suggestions.Count == 0)
			{
				ClearPopup();
			}
			else if (Object.op_Implicit((Object)(object)_suggestionPopupRect) && Object.op_Implicit((Object)(object)_suggestionPopupText))
			{
				string text = GetFormattedSuggestions(topmostSuggestionSet);
				if (_suggestionDisplayOrder == SortOrder.Ascending)
				{
					text = text.ReverseItems('\n');
				}
				((Component)_suggestionPopupRect).gameObject.SetActive(true);
				((TMP_Text)_suggestionPopupText).text = text;
			}
		}

		public void SetSuggestion(int suggestionIndex)
		{
			if (!_suggestionStack.SetSuggestionIndex(suggestionIndex))
			{
				throw new ArgumentException(QuantumConsoleBootstrap.Localization.Format(92u, new object[1] { suggestionIndex }));
			}
			OverrideConsoleInput(_suggestionStack.GetCompletion());
			UpdateSuggestionText();
		}

		private void UpdateSuggestionText()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			Color color = ((_theme != null) ? _theme.SuggestionColor : Color.gray);
			StringBuilder stringBuilder = _stringBuilderPool.GetStringBuilder();
			stringBuilder.AppendColoredText(_currentInput, Color.clear);
			stringBuilder.AppendColoredText(_suggestionStack.GetCompletionTail(), color);
			((TMP_Text)_consoleSuggestionText).text = _stringBuilderPool.ReleaseAndToString(stringBuilder);
		}

		public void OverrideConsoleInput(string newInput, bool shouldFocus = true)
		{
			_currentInput = newInput;
			_previousInput = newInput;
			_consoleInput.text = newInput;
			if (shouldFocus)
			{
				FocusConsoleInput();
			}
			OnInputChange();
		}

		public void FocusConsoleInput()
		{
			((Selectable)_consoleInput).Select();
			_consoleInput.caretPosition = _consoleInput.text.Length;
			_consoleInput.selectionAnchorPosition = _consoleInput.text.Length;
			_consoleInput.MoveTextEnd(false);
			_consoleInput.ActivateInputField();
		}

		private void OnInputChange()
		{
			if (_selectedPreviousCommandIndex >= 0 && _currentInput.Trim() != _previousCommands[_previousCommands.Count - _selectedPreviousCommandIndex - 1])
			{
				ClearHistoricalSuggestions();
			}
			if (_enableAutocomplete)
			{
				UpdateSuggestions();
			}
		}

		private void ClearHistoricalSuggestions()
		{
			_selectedPreviousCommandIndex = -1;
		}

		private void ClearSuggestions()
		{
			_suggestionStack.Clear();
			((TMP_Text)_consoleSuggestionText).text = string.Empty;
		}

		private void ClearPopup()
		{
			if (Object.op_Implicit((Object)(object)_suggestionPopupRect))
			{
				((Component)_suggestionPopupRect).gameObject.SetActive(false);
			}
			if (Object.op_Implicit((Object)(object)_suggestionPopupText))
			{
				((TMP_Text)_suggestionPopupText).text = string.Empty;
			}
		}

		public void InvokeCommand()
		{
			string text = _consoleInput.text;
			if (!string.IsNullOrWhiteSpace(text))
			{
				string command = text.Trim();
				if (_isHandlingUserResponse)
				{
					HandleUserResponse(command);
					return;
				}
				InvokeCommand(command);
				OverrideConsoleInput(string.Empty);
				StoreCommand(command);
			}
		}

		private void HandleUserResponse(string command)
		{
			if (_currentResponseConfig.LogInput)
			{
				LogUserInput(command);
				StoreCommand(command);
			}
			_onSubmitResponseCallback(command);
			_onSubmitResponseCallback = null;
			((Selectable)_consoleInput).interactable = false;
			_isHandlingUserResponse = false;
			this.OnStateChange?.Invoke();
		}

		private void LogUserInput(string input)
		{
			ILog log = GenerateCommandLog(input);
			LogToConsole(log);
		}

		protected ILog GenerateCommandLog(string command)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			string format = _theme?.CommandLogFormat ?? "> {0}";
			if (command.Contains('<'))
			{
				command = "<noparse>" + command + "</noparse>";
			}
			string text = string.Format(format, command);
			if (_theme != null)
			{
				text = text.ColorText(_theme.CommandLogColor);
			}
			return new Log(text);
		}

		public object InvokeCommand(string command)
		{
			object obj = null;
			if (!string.IsNullOrWhiteSpace(command))
			{
				LogUserInput(command);
				string logText = string.Empty;
				try
				{
					obj = QuantumConsoleProcessor.InvokeCommand(command);
					if (!(obj is Task item))
					{
						if (!(obj is IEnumerator<ICommandAction> action))
						{
							if (obj is IEnumerable<ICommandAction> enumerable)
							{
								StartAction(enumerable.GetEnumerator());
							}
							else
							{
								logText = Serialize(obj);
							}
						}
						else
						{
							StartAction(action);
						}
					}
					else
					{
						_currentTasks.Add(item);
					}
				}
				catch (TargetInvocationException ex)
				{
					logText = GetInvocationErrorMessage(ex.InnerException);
				}
				catch (Exception e)
				{
					logText = GetErrorMessage(e);
				}
				LogToConsole(logText);
				this.OnInvoke?.Invoke(command);
				if (_autoScroll == AutoScrollOptions.OnInvoke)
				{
					ScrollConsoleToLatest();
				}
				if (_closeOnSubmit)
				{
					Deactivate();
				}
			}
			else
			{
				OverrideConsoleInput(string.Empty);
			}
			return obj;
		}

		[Command("qc-script-extern", "Executes an external source of QC script file, where each line is a separate QC command.", MonoTargetType.Registry, ~Platform.WebGLPlayer)]
		public async Task InvokeExternalCommandsAsync(string filePath)
		{
			using StreamReader reader = new StreamReader(filePath);
			while (!reader.EndOfStream)
			{
				if (InvokeCommand(await reader.ReadLineAsync()) is Task task)
				{
					await task;
					ProcessAsyncTasks();
				}
			}
		}

		public async Task InvokeCommandsAsync(IEnumerable<string> commands)
		{
			foreach (string command in commands)
			{
				if (InvokeCommand(command) is Task task)
				{
					await task;
					ProcessAsyncTasks();
				}
			}
		}

		private string GetErrorMessage(Exception e)
		{
			return GetErrorMessage(e, _localization.ConsoleError);
		}

		private string GetInvocationErrorMessage(Exception e)
		{
			return GetErrorMessage(e, _localization.CommandError);
		}

		private string GetErrorMessage(Exception e, string label)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			string text = (_verboseErrors ? $"{label} ({e.GetType()}): {e.Message}\n{e.StackTrace}" : (label + ": " + e.Message));
			if (_theme == null)
			{
				return text;
			}
			return text.ColorText(_theme.ErrorColor);
		}

		public void LogToConsoleAsync(string logText, LogLevel logLevel = LogLevel.Message)
		{
			if (!string.IsNullOrWhiteSpace(logText))
			{
				Log log = new Log(logText, logLevel);
				LogToConsoleAsync(log);
			}
		}

		public void LogToConsoleAsync(ILog log)
		{
			this.OnLog?.Invoke(log);
			_logQueue.QueueLog(log);
		}

		private void FlushQueuedLogs()
		{
			bool flag = false;
			bool flag2 = false;
			ILog log;
			while (_logQueue.TryDequeue(out log))
			{
				AppendLog(log);
				flag |= _autoScroll == AutoScrollOptions.Always;
				flag2 |= _openOnLogLevel.HasFlag(log.Level.GetHighestLevel());
			}
			if (flag)
			{
				ScrollConsoleToLatest();
			}
			if (flag2)
			{
				Activate(shouldFocus: false);
			}
		}

		private void ProcessAsyncTasks()
		{
			for (int num = _currentTasks.Count - 1; num >= 0; num--)
			{
				if (_currentTasks[num].IsCompleted)
				{
					if (_currentTasks[num].IsFaulted)
					{
						foreach (Exception innerException in _currentTasks[num].Exception.InnerExceptions)
						{
							string invocationErrorMessage = GetInvocationErrorMessage(innerException);
							LogToConsole(invocationErrorMessage, LogLevel.Fatal);
						}
					}
					else
					{
						Type type = _currentTasks[num].GetType();
						if (type.IsGenericTypeOf(typeof(Task<>)) && !_voidTaskType.IsAssignableFrom(type))
						{
							object value = _currentTasks[num].GetType().GetProperty("Result").GetValue(_currentTasks[num]);
							string logText = _serializer.SerializeFormatted(value, _theme);
							LogToConsole(logText);
						}
					}
					_currentTasks.RemoveAt(num);
				}
			}
		}

		public void BeginResponse(Action<string> onSubmitResponseCallback, ResponseConfig config)
		{
			if (onSubmitResponseCallback == null)
			{
				throw new ArgumentNullException("onSubmitResponseCallback");
			}
			_onSubmitResponseCallback = onSubmitResponseCallback;
			_currentResponseConfig = config;
			_isHandlingUserResponse = true;
			this.OnStateChange?.Invoke();
			((Selectable)_consoleInput).interactable = true;
			if (Object.op_Implicit((Object)(object)_inputPlaceholderText))
			{
				((TMP_Text)_inputPlaceholderText).text = _currentResponseConfig.InputPrompt;
			}
			FocusConsoleInput();
		}

		public void StartAction(IEnumerator<ICommandAction> action)
		{
			_currentActions.Add(action);
			ProcessActions();
		}

		public void CancelAllActions()
		{
			_currentActions.Clear();
		}

		private void ProcessActions()
		{
			if (_keyConfig.CancelActionsKey.IsPressed())
			{
				CancelAllActions();
				return;
			}
			ActionContext actionContext = default(ActionContext);
			actionContext.Console = this;
			ActionContext context = actionContext;
			for (int num = _currentActions.Count - 1; num >= 0; num--)
			{
				IEnumerator<ICommandAction> action = _currentActions[num];
				try
				{
					if (action.Execute(context) != ActionState.Running)
					{
						_currentActions.RemoveAt(num);
					}
				}
				catch (Exception e)
				{
					_currentActions.RemoveAt(num);
					string invocationErrorMessage = GetInvocationErrorMessage(e);
					LogToConsole(invocationErrorMessage, LogLevel.Fatal);
					break;
				}
			}
		}

		private void HandleAsyncJobCounter()
		{
			if (_showCurrentJobs && Object.op_Implicit((Object)(object)_jobCounterRect) && Object.op_Implicit((Object)(object)_jobCounterText))
			{
				if (_currentTasks.Count == 0)
				{
					((Component)_jobCounterRect).gameObject.SetActive(false);
					return;
				}
				((Component)_jobCounterRect).gameObject.SetActive(true);
				((TMP_Text)_jobCounterText).text = $"{_currentTasks.Count} job{((_currentTasks.Count == 1) ? "" : "s")} in progress";
			}
		}

		public string Serialize(object value)
		{
			return _serializer.SerializeFormatted(value, _theme);
		}

		public void LogToConsole(string logText, LogLevel logLevel = LogLevel.Message, bool prependTimestamps = false, bool newLine = true)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(logText))
			{
				if (prependTimestamps && _prependTimestamps)
				{
					DateTime now = DateTime.Now;
					logText = string.Format((_theme != null) ? _theme.TimestampFormat : "[{0:00}:{1:00}:{2:00}]", now.Hour, now.Minute, now.Second) + " " + logText;
				}
				logText = logText.ColorText(logLevel.GetUnityColorFromTheme(_theme));
				LogToConsole(new Log(logText, logLevel, newLine));
			}
		}

		public void LogToConsole(ILog log)
		{
			FlushQueuedLogs();
			AppendLog(log);
			this.OnLog?.Invoke(log);
			if (_autoScroll == AutoScrollOptions.Always)
			{
				ScrollConsoleToLatest();
			}
		}

		private void FlushToConsoleText()
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			if (_consoleRequiresFlush)
			{
				_consoleRequiresFlush = false;
				if (_scrollRect.verticalNormalizedPosition == 0f)
				{
					((TMP_Text)_consoleLogText).text = _logStorage.GetLogString();
				}
				else if (_scrollRect.verticalNormalizedPosition == 1f)
				{
					((TMP_Text)_consoleLogText).text = _logStorage.GetLogString();
					LayoutRebuilder.ForceRebuildLayoutImmediate(_scrollRect.content);
					((Vector2)(ref _anchoredPos)).Set(0f, 0f - _scrollRect.content.sizeDelta.y);
					_scrollRect.SetContentAnchoredPosition(_anchoredPos);
				}
				else
				{
					_prePos = _scrollRect.content.anchoredPosition.y;
					_preSize = _scrollRect.content.sizeDelta.y;
					((TMP_Text)_consoleLogText).text = _logStorage.GetLogString();
					LayoutRebuilder.ForceRebuildLayoutImmediate(_scrollRect.content);
					((Vector2)(ref _anchoredPos)).Set(0f, _prePos + _preSize - _scrollRect.content.sizeDelta.y);
					_scrollRect.SetContentAnchoredPosition(_anchoredPos);
				}
			}
		}

		private ILog TruncateLog(ILog log)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if (log.Text.Length <= _maxLogSize || _maxLogSize < 0)
			{
				return log;
			}
			string text = string.Format(_localization.MaxLogSizeExceeded, log.Text.Length, _maxLogSize);
			if (_theme != null)
			{
				text = text.ColorText(_theme.ErrorColor);
			}
			return new Log(text, LogLevel.Error);
		}

		protected void AppendLog(ILog log)
		{
			_logStorage.AddLog(TruncateLog(log));
			RequireFlush();
		}

		protected void RequireFlush()
		{
			_consoleRequiresFlush = true;
		}

		public void RemoveLogTrace()
		{
			_logStorage.RemoveLog();
			RequireFlush();
		}

		private void ScrollConsoleToLatest()
		{
			if (Object.op_Implicit((Object)(object)_scrollRect))
			{
				_scrollRect.verticalNormalizedPosition = 0f;
			}
		}

		private void StoreCommand(string command)
		{
			if (_storeCommandHistory)
			{
				if (!_storeDuplicateCommands)
				{
					_previousCommands.Remove(command);
				}
				if (_storeAdjacentDuplicateCommands || _previousCommands.Count == 0 || _previousCommands[_previousCommands.Count - 1] != command)
				{
					_previousCommands.Add(command);
				}
				if (_commandHistorySize > 0 && _previousCommands.Count > _commandHistorySize)
				{
					_previousCommands.RemoveAt(0);
				}
			}
		}

		[Command("clear", "Clears the Quantum Console", MonoTargetType.Registry, Platform.AllPlatforms)]
		public void ClearConsole()
		{
			_logStorage.Clear();
			_logQueue.Clear();
			((TMP_Text)_consoleLogText).text = string.Empty;
			((Graphic)_consoleLogText).SetLayoutDirty();
			ClearBuffers();
			this.OnClear?.Invoke();
		}

		[Command("close", "Closes the Quantum Console", MonoTargetType.Registry, Platform.AllPlatforms)]
		public void CloseConsole()
		{
			Deactivate();
		}

		public string GetConsoleText()
		{
			return ((TMP_Text)_consoleLogText).text;
		}

		protected virtual void ClearBuffers()
		{
			ClearHistoricalSuggestions();
			ClearSuggestions();
			ClearPopup();
		}

		private void SetupComponents()
		{
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Expected O, but got Unknown
			_theme = QuantumTheme.DefaultTheme();
			Transform val = ((Component)this).transform.FindChild("ConsoleRect");
			_containerRect = ((Component)val).GetComponent<RectTransform>();
			DynamicCanvasScaler dynamicCanvasScaler = ((Component)this).gameObject.AddComponent<DynamicCanvasScaler>();
			dynamicCanvasScaler.Setup(((Component)this).GetComponent<CanvasScaler>(), _containerRect);
			Transform val2 = val.FindChild("Console");
			((Component)this).gameObject.AddComponent<BlurShaderController>().Setup(_theme.PanelMaterial);
			_scrollRect = ((Component)val2).GetComponent<ScrollRect>();
			((Component)val2.FindChild("Resize Anchor")).gameObject.AddComponent<ResizableUI>().Setup(_containerRect, ((Component)this).gameObject.GetComponent<Canvas>());
			Transform val3 = val2.FindChild("Console View");
			((Component)val3).gameObject.AddComponent<DraggableUI>().Setup(_containerRect, this, _scrollRect);
			_consoleLogText = ((Component)val3.FindChild("View Port/Text")).GetComponent<TextMeshProUGUI>();
			((TMP_Text)_consoleLogText).fontSize = 14f;
			((TMP_Text)_consoleLogText).maxVisibleLines = int.MaxValue;
			((TMP_Text)_consoleLogText).maxVisibleWords = int.MaxValue;
			((TMP_Text)_consoleLogText).maxVisibleCharacters = int.MaxValue;
			Transform val4 = val2.FindChild("Popup");
			_suggestionPopupRect = ((Component)val4).GetComponent<RectTransform>();
			_suggestionPopupText = ((Component)val4.FindChild("Text")).GetComponent<TextMeshProUGUI>();
			((TMP_Text)_suggestionPopupText).fontSize = 16f;
			((Component)val4).gameObject.AddComponent<SuggestionDisplay>().Setup(this, _suggestionPopupText);
			Transform val5 = val.FindChild("IOBar");
			Transform val6 = val5.FindChild("JobCounter");
			_jobCounterRect = ((Component)val6).GetComponent<RectTransform>();
			_jobCounterText = ((Component)val6.FindChild("Text")).GetComponent<TextMeshProUGUI>();
			Transform val7 = val5.FindChild("InputField");
			_consoleInput = ((Component)val7).GetComponent<TMP_InputField>();
			_inputPlaceholderText = ((Component)val7.FindChild("Text Area/Placeholder")).GetComponent<TextMeshProUGUI>();
			_consoleSuggestionText = ((Component)val7.FindChild("Text Area/Backing Text")).GetComponent<TextMeshProUGUI>();
			Transform val8 = val2.FindChild("UI Controls Tab");
			ZoomUIController zoomUIController = ((Component)val8).gameObject.AddComponent<ZoomUIController>();
			Button component = ((Component)val8.FindChild("Zoom+")).GetComponent<Button>();
			((UnityEvent)component.onClick).AddListener(UnityAction.op_Implicit((Action)zoomUIController.ZoomUp));
			Button component2 = ((Component)val8.FindChild("Zoom-")).GetComponent<Button>();
			((UnityEvent)component2.onClick).AddListener(UnityAction.op_Implicit((Action)zoomUIController.ZoomDown));
			zoomUIController.Setup(component2, component, dynamicCanvasScaler, this, ((Component)val8.FindChild("Text")).GetComponent<TextMeshProUGUI>());
			_submitButtonText = ((Component)val5.FindChild("Submit/Text")).GetComponent<TextMeshProUGUI>();
			_clearButtonText = ((Component)val5.FindChild("Clear/Text")).GetComponent<TextMeshProUGUI>();
			_closeButtonText = ((Component)val5.FindChild("Close/Text")).GetComponent<TextMeshProUGUI>();
			_panels = (Image[])(object)new Image[5];
			_panels[0] = ((Component)val2).GetComponent<Image>();
			_panels[1] = ((Component)val7).GetComponent<Image>();
			_panels[2] = ((Component)val4).GetComponent<Image>();
			_panels[3] = ((Component)val6).GetComponent<Image>();
			_panels[4] = ((Component)val8).GetComponent<Image>();
			EventTrigger component3 = ((Component)_consoleInput).GetComponent<EventTrigger>();
			Entry val9 = new Entry
			{
				eventID = (EventTriggerType)15
			};
			((UnityEvent<BaseEventData>)(object)val9.callback).AddListener(UnityAction<BaseEventData>.op_Implicit((Action<BaseEventData>)delegate
			{
				InvokeCommand();
			}));
			component3.triggers.Add(val9);
			((UnityEvent)((Component)val5.FindChild("Submit")).GetComponent<Button>().onClick).AddListener(UnityAction.op_Implicit((Action)InvokeCommand));
			((UnityEvent)((Component)val5.FindChild("Clear")).GetComponent<Button>().onClick).AddListener(UnityAction.op_Implicit((Action)ClearConsole));
			((UnityEvent)((Component)val5.FindChild("Close")).GetComponent<Button>().onClick).AddListener(UnityAction.op_Implicit((Action)Deactivate));
		}

		private void Awake()
		{
			QuantumConsoleBootstrap.Localization.AddTextUpdater((ILocalizedTextUpdater)(object)this);
			SetupComponents();
			InitializeLogging();
			_logCallback = DelegateSupport.ConvertDelegate<LogCallback>((Delegate)new Action<string, string, LogType>(DebugIntercept));
			Application.s_LogCallbackHandlerThreaded += _logCallback;
		}

		private void OnEnable()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Invalid comparison between Unknown and I4
			QuantumRegistry.RegisterObject(this);
			if (IsSupportedState())
			{
				if (_singletonMode)
				{
					if ((Object)(object)Instance == (Object)null)
					{
						Instance = this;
						Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
					}
					else if ((Object)(object)Instance != (Object)(object)this)
					{
						Object.Destroy((Object)(object)((Component)this).gameObject);
					}
				}
				if (_activateOnStartup)
				{
					bool shouldFocus = (int)SystemInfo.deviceType == 3;
					Activate(shouldFocus);
					return;
				}
				if (_initialiseOnStartup)
				{
					Initialize();
				}
				Deactivate();
			}
			else
			{
				DisableQC();
			}
		}

		private bool IsSupportedState()
		{
			SupportedState supportedState = SupportedState.Always;
			return _supportedState <= supportedState;
		}

		private void OnDisable()
		{
			QuantumRegistry.DeregisterObject(this);
			Deactivate();
		}

		private void OnDestroy()
		{
			QuantumConsoleBootstrap.Localization.RemoveTextUpdater((ILocalizedTextUpdater)(object)this);
			Application.s_LogCallbackHandlerThreaded -= _logCallback;
		}

		private void DisableQC()
		{
			Deactivate();
			((Behaviour)this).enabled = false;
		}

		private void Initialize()
		{
			if (!_initialized)
			{
				if (!QuantumConsoleProcessor.TableGenerated)
				{
					QuantumConsoleProcessor.GenerateCommandTable(deployThread: true);
					((Selectable)_consoleInput).interactable = false;
					_isGeneratingTable = true;
				}
				InitializeSuggestionStack();
				InitializeLogging();
				((TMP_Text)_consoleLogText).richText = true;
				((TMP_Text)_consoleSuggestionText).richText = true;
				if (_theme == null)
				{
					_theme = QuantumTheme.DefaultTheme();
				}
				if (_keyConfig == null)
				{
					_keyConfig = QuantumKeyConfig.DefaultKeyConfig();
				}
				if (_localization == null)
				{
					_localization = new QuantumLocalization();
				}
				if (_preferences == null)
				{
					_preferences = new QuantumConsolePreferences();
				}
				ApplyTheme(_theme);
				ApplyLocalization(_localization);
				ApplyPreferences(_preferences);
				_initialized = true;
			}
		}

		private void InitializeSuggestionStack()
		{
			if (_suggestionStack == null)
			{
				_suggestionStack = CreateSuggestionStack();
				_suggestionStack.OnSuggestionSetCreated += this.OnSuggestionSetGenerated;
			}
		}

		private void InitializeLogging()
		{
			if (_logStorage == null)
			{
				_logStorage = CreateLogStorage();
			}
			if (_logQueue == null)
			{
				_logQueue = CreateLogQueue();
			}
		}

		protected virtual ILogStorage CreateLogStorage()
		{
			return new LogStorage(_maxStoredLogs);
		}

		protected virtual ILogQueue CreateLogQueue()
		{
			return new LogQueue(_maxStoredLogs);
		}

		protected virtual SuggestionStack CreateSuggestionStack()
		{
			return new SuggestionStack();
		}

		public void Toggle()
		{
			if (IsActive)
			{
				Deactivate();
			}
			else
			{
				Activate();
			}
		}

		public void Activate()
		{
			Activate(_focusOnActivate);
		}

		public void Activate(bool shouldFocus)
		{
			if (!PlayerChatManager.InChatMode)
			{
				Initialize();
				IsActive = true;
				((Component)_containerRect).gameObject.SetActive(true);
				OverrideConsoleInput(string.Empty, shouldFocus);
				if (!Object.op_Implicit((Object)(object)EventSystem.current))
				{
					Logs.LogWarning("Quantum Console's UI requires an EventSystem in the scene but there were none present.");
				}
				this.OnActivate?.Invoke();
			}
		}

		public void Deactivate()
		{
			IsActive = false;
			((Component)_containerRect).gameObject.SetActive(false);
			this.OnDeactivate?.Invoke();
		}

		private void DebugIntercept(string condition, string stackTrace, LogType type)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (_interceptDebugLogger && (IsActive || _interceptWhilstInactive) && _loggingLevel.HasFlag(type.ToLogLevel()))
			{
				bool appendStackTrace = _verboseLogging.HasFlag(type.ToLogLevel());
				ILog log = ConstructDebugLog(condition, stackTrace, type, _prependTimestamps, appendStackTrace);
				LogToConsoleAsync(log);
			}
		}

		protected virtual ILog ConstructDebugLog(string condition, string stackTrace, LogType type, bool prependTimeStamp, bool appendStackTrace)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected I4, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			if (prependTimeStamp)
			{
				DateTime now = DateTime.Now;
				condition = string.Format(_theme?.TimestampFormat ?? "[{0:00}:{1:00}:{2:00}]", now.Hour, now.Minute, now.Second) + " " + condition;
			}
			if (appendStackTrace)
			{
				condition = condition + "\n" + stackTrace;
			}
			LogLevel level = LogLevel.Debug;
			if (_theme != null)
			{
				switch ((int)type)
				{
				case 3:
					condition = condition.ColorText(_theme.MessageColor);
					break;
				case 2:
					condition = condition.ColorText(_theme.WarningColor);
					level = LogLevel.Warning;
					break;
				case 0:
					condition = condition.ColorText(_theme.ErrorColor);
					level = LogLevel.Error;
					break;
				case 1:
				case 4:
					condition = condition.ColorText(_theme.FatalColor);
					level = LogLevel.Fatal;
					break;
				}
			}
			return new Log(condition, level);
		}

		protected virtual void OnValidate()
		{
			MaxStoredLogs = _maxStoredLogs;
		}

		public void UpdateText()
		{
			ApplyLocalization(_localization);
		}
	}
	public static class QuantumConsoleProcessor
	{
		public static LoggingLevel loggingLevel = LoggingLevel.Full;

		private static readonly QuantumParser _parser = new QuantumParser();

		private static readonly QuantumPreprocessor _preprocessor = new QuantumPreprocessor();

		private static readonly QuantumScanRuleset _scanRuleset = new QuantumScanRuleset();

		private static readonly ConcurrentDictionary<string, CommandData> _commandTable = new ConcurrentDictionary<string, CommandData>();

		private static readonly List<CommandData> _commandCache = new List<CommandData>();

		private static int _loadedCommandCount = 0;

		private static bool _commandCacheDirty = true;

		private static readonly Assembly[] _loadedAssemblies