Files
Ultimate-Fishing-Simulator-…/Assets/Plugins/Assembly-CSharp-firstpass/DebuggingEssentials/RuntimeConsole.cs
2026-03-04 09:37:33 +08:00

2281 lines
60 KiB
C#

using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
namespace DebuggingEssentials
{
[DefaultExecutionOrder(-4000000)]
[ConsoleAlias("console")]
public class RuntimeConsole : MonoBehaviour
{
public delegate void RemoteCommand(string command);
public class StringDictionarySorted
{
public Dictionary<string, CommandData> lookup = new Dictionary<string, CommandData>();
public string[] names;
public void Sort()
{
names = new string[lookup.Count];
lookup.Keys.CopyTo(names, 0);
Array.Sort(names);
}
public void Clear()
{
lookup.Clear();
names = null;
}
}
public enum MemberType
{
Method = 0,
Property = 1,
Field = 2,
Delegate = 3
}
public struct CommandData
{
public static CommandData empty;
public ConsoleCommand consoleCommand;
public object obj;
public bool isStatic;
public string syntax;
public MemberType memberType;
public MemberInfo member;
public ParameterInfo[] paramInfos;
private object[] args;
public CommandData(ConsoleCommand consoleCommand, object obj, string syntax, MemberType memberType, MemberInfo member, ParameterInfo[] paramInfos, bool isStatic)
{
this.consoleCommand = consoleCommand;
this.obj = obj;
this.syntax = syntax;
this.memberType = memberType;
this.member = member;
this.isStatic = isStatic;
if (paramInfos == null || (paramInfos != null && paramInfos.Length == 0))
{
this.paramInfos = null;
args = null;
}
else
{
this.paramInfos = paramInfos;
args = new object[paramInfos.Length];
}
}
public object GetValue()
{
object instance;
if (isStatic)
{
instance = obj;
}
else
{
int instanceWhenOnlyOne = GetInstanceWhenOnlyOne(out instance);
if (instanceWhenOnlyOne == 0)
{
return "null";
}
if (instanceWhenOnlyOne > 1)
{
return ">";
}
}
if (memberType == MemberType.Method || memberType == MemberType.Delegate)
{
return null;
}
if (memberType == MemberType.Field)
{
return ((FieldInfo)member).GetValue(instance);
}
if (memberType == MemberType.Property)
{
MethodInfo getMethod = ((PropertyInfo)member).GetGetMethod(nonPublic: true);
if (getMethod != null)
{
return getMethod.Invoke(instance, null);
}
}
return null;
}
public bool IsRegistered()
{
if (isStatic)
{
return true;
}
registeredInstancesLookup.TryGetValue((Type)obj, out var value);
if (value != null)
{
return value.Count > 0;
}
return false;
}
public int GetInstanceCount()
{
if (isStatic || obj == null)
{
return -1;
}
registeredInstancesLookup.TryGetValue((Type)obj, out var value);
if (value == null)
{
return 0;
}
CheckDestroyedMonoBehaviours(value);
return value.Count;
}
public int GetInstanceWhenOnlyOne(out object instance)
{
registeredInstancesLookup.TryGetValue((Type)obj, out var value);
if (value == null)
{
instance = null;
return 0;
}
CheckDestroyedMonoBehaviours(value);
if (value.Count != 1)
{
instance = null;
return value.Count;
}
using (HashSet<object>.Enumerator enumerator = value.GetEnumerator())
{
if (enumerator.MoveNext())
{
object current = enumerator.Current;
instance = current;
return 1;
}
}
instance = null;
return 0;
}
public void Execute(FastQueue<string> arguments, string argumentString)
{
if (memberType == MemberType.Method || memberType == MemberType.Delegate)
{
ExecuteMethodOrDelegate(arguments, argumentString);
}
else if (memberType == MemberType.Field)
{
ExecuteField(arguments, argumentString);
}
else if (memberType == MemberType.Property)
{
ExecuteProperty(arguments, argumentString);
}
}
private void ExecuteMethodOrDelegate(FastQueue<string> arguments, string argumentString)
{
if (paramInfos != null)
{
int count = arguments.Count;
for (int i = 0; i < paramInfos.Length; i++)
{
ParameterInfo parameterInfo = paramInfos[i];
Type parameterType = parameterInfo.ParameterType;
if (i >= count)
{
if (!parameterInfo.IsOptional)
{
LogResultError("Can't execute because of wrong number of arguments");
return;
}
args[i] = parameterInfo.DefaultValue;
}
else if (!Parser.TryParse(parameterType, arguments, out args[i]))
{
return;
}
}
}
if (arguments.Count > 0)
{
LogResultError("Too many arguments");
return;
}
if (memberType == MemberType.Method)
{
if (isStatic)
{
ExecuteMethod(member, (MethodInfo)member, obj, args, argumentString);
return;
}
HashSet<object> hashSet = registeredInstancesLookup[(Type)obj];
CheckDestroyedMonoBehaviours(hashSet);
{
foreach (object item in hashSet)
{
if (item as MonoBehaviour == null && item.GetType().IsSubclassOf(typeof(MonoBehaviour)))
{
Debug.Log("Mono = isDestroyed");
}
else
{
ExecuteMethod(member, (MethodInfo)member, item, args, argumentString);
}
}
return;
}
}
if (isStatic)
{
ExecuteDelegateMethod(member, obj, args, argumentString);
return;
}
HashSet<object> hashSet2 = registeredInstancesLookup[(Type)obj];
CheckDestroyedMonoBehaviours(hashSet2);
foreach (object item2 in hashSet2)
{
ExecuteDelegateMethod(member, item2, args, argumentString);
}
}
private void ExecuteDelegateMethod(MemberInfo member, object obj, object[] args, string argumentString)
{
object value = ((FieldInfo)member).GetValue(obj);
if (value == null)
{
LogResultError(obj.ToString() + " : " + member.Name + " delegate is not assigned");
return;
}
MethodInfo method = value.GetType().GetMethod("Invoke");
ExecuteMethod(member, method, value, args, argumentString);
}
private void ExecuteMethod(MemberInfo member, MethodInfo method, object obj, object[] args, string argumentString)
{
try
{
object obj2 = method.Invoke(obj, args);
if (obj2 != null)
{
LogResult(obj.ToString() + " : " + member.Name + " " + argumentString + " = " + obj2);
}
}
catch (Exception exception)
{
Debug.LogException(exception);
}
}
private void ExecuteField(FastQueue<string> arguments, string argumentString)
{
FieldInfo fieldInfo = (FieldInfo)member;
if (arguments.Count == 0)
{
if (!isStatic)
{
HashSet<object> hashSet = registeredInstancesLookup[(Type)obj];
CheckDestroyedMonoBehaviours(hashSet);
{
foreach (object item in hashSet)
{
LogValue(fieldInfo, item);
}
return;
}
}
LogValue(fieldInfo, obj);
}
else
{
if (!Parser.TryParse(fieldInfo.FieldType, arguments, out var result))
{
return;
}
if (arguments.Count > 0)
{
LogResultError("Too many arguments");
return;
}
if (!isStatic)
{
HashSet<object> hashSet2 = registeredInstancesLookup[(Type)obj];
CheckDestroyedMonoBehaviours(hashSet2);
{
foreach (object item2 in hashSet2)
{
SetField(fieldInfo, item2, result);
}
return;
}
}
SetField(fieldInfo, obj, result);
}
}
private void LogValue(FieldInfo field, object obj)
{
try
{
LogResult(obj.ToString() + " : " + field.Name + " = " + field.GetValue(obj));
}
catch (Exception exception)
{
Debug.LogException(exception);
}
}
private void SetField(FieldInfo field, object obj, object arg)
{
try
{
if (arg != null)
{
field.SetValue(obj, arg);
}
LogResult(obj.ToString() + " : " + field.Name + " = " + field.GetValue(obj));
}
catch (Exception exception)
{
Debug.LogException(exception);
}
}
private void ExecuteProperty(FastQueue<string> arguments, string argumentString)
{
PropertyInfo propertyInfo = (PropertyInfo)member;
if (arguments.Count == 0)
{
if (propertyInfo.GetGetMethod(nonPublic: true) == null)
{
LogResultError(propertyInfo.Name + " doesn't have a getter");
return;
}
if (!isStatic)
{
HashSet<object> hashSet = registeredInstancesLookup[(Type)obj];
CheckDestroyedMonoBehaviours(hashSet);
{
foreach (object item in hashSet)
{
LogValue(propertyInfo, item);
}
return;
}
}
LogValue(propertyInfo, obj);
}
else if (propertyInfo.GetSetMethod(nonPublic: true) == null)
{
LogResultError(propertyInfo.Name + " doesn't have a setter");
}
else
{
if (!Parser.TryParse(propertyInfo.PropertyType, arguments, out var result))
{
return;
}
if (arguments.Count > 0)
{
LogResultError("Too many arguments");
return;
}
if (!isStatic)
{
HashSet<object> hashSet2 = registeredInstancesLookup[(Type)obj];
CheckDestroyedMonoBehaviours(hashSet2);
{
foreach (object item2 in hashSet2)
{
SetProperty(propertyInfo, item2, result);
}
return;
}
}
SetProperty(propertyInfo, obj, result);
}
}
private void LogValue(PropertyInfo prop, object obj)
{
try
{
LogResult(obj.ToString() + " : " + prop.Name + " = " + prop.GetValue(obj, null));
}
catch (Exception exception)
{
Debug.LogException(exception);
}
}
private void SetProperty(PropertyInfo prop, object obj, object arg)
{
try
{
if (arg != null)
{
prop.SetValue(obj, arg, null);
}
if (prop.GetGetMethod(nonPublic: true) != null)
{
LogResult(obj.ToString() + " : " + prop.Name + " = " + prop.GetValue(obj, null));
}
}
catch (Exception exception)
{
Debug.LogException(exception);
}
}
private bool CheckParameterCount(int required, int count)
{
if (required == count)
{
return true;
}
LogResultError("Can't execute because " + required + " arguments are needed");
return false;
}
}
public enum AccessMode
{
EnabledOnConsoleCommand = 0,
Enabled = 1,
Disabled = 2
}
public struct AutoComplete
{
public string command;
public CommandData commandData;
public AutoComplete(string command, CommandData commandData)
{
this.command = command;
this.commandData = commandData;
}
}
public static RuntimeConsole instance;
public static AccessLevel accessLevel;
public static bool show;
private static Dictionary<Type, HashSet<object>> registeredInstancesLookup = new Dictionary<Type, HashSet<object>>();
private static StringDictionarySorted commandsTable = new StringDictionarySorted();
private static FastList<AutoComplete> autoCompleteList = new FastList<AutoComplete>();
private static FastQueue<string> inputCommands = new FastQueue<string>(32);
private static FastList<LogEntry> threadLogEntries = new FastList<LogEntry>(256);
private static FastList<LogEntry> logEntries = new FastList<LogEntry>(256);
private SortedFastList<string> commands = new SortedFastList<string>();
private const int logSize = 8192;
private const int commandLogs = 0;
private const int frameLogs = 1;
private const int unityLogs = 2;
private const int warningLogs = 3;
private const int errorLogs = 4;
private const int exceptionLogs = 5;
private static bool setFocus;
private static int lastFrame = -1;
private static LogEntry lastFrameEntry;
private WindowSettings consoleWindow;
private int commandIndex;
private int moveInputCursor;
private int autoCompleteIndex;
private string inputCommand;
private GUIChangeBool _showStack = new GUIChangeBool(value: true);
private GUIChangeBool showUnityLogs = new GUIChangeBool(value: true);
private GUIChangeBool showLastLog = new GUIChangeBool(value: true);
private Vector2 autoCompleteScrollView;
private Double2 scrollView;
private Double2 scrollViewHeights;
private CullGroup cullGroup;
private FastList<CullList> cullLists = new FastList<CullList>();
private static CullList[] logs;
private bool calcDraw;
private bool isEnabled;
private int oldAutoCompleteCount = -1;
private bool updateAutoCompleteScrollView;
private bool isDebugBuild;
public bool showConsoleOnStart = true;
[ConsoleCommand(AccessLevel.Admin)]
public bool showConsoleOnWarning;
[ConsoleCommand(AccessLevel.Admin)]
public bool showConsoleOnError;
[ConsoleCommand(AccessLevel.Admin)]
public bool showConsoleOnException;
[ConsoleCommand(AccessLevel.Admin)]
public bool showConsoleWhenInvokingMethod = true;
[ConsoleCommand(AccessLevel.Admin)]
public bool disableUnityDevelopmentConsole = true;
public bool useSameEditorAsBuildShowKey = true;
public AdvancedKey showToggleKeyEditor = new AdvancedKey(KeyCode.F9);
public AdvancedKey showToggleKeyBuild = new AdvancedKey(KeyCode.F9);
[Tooltip("This ignores cases in commands")]
[ConsoleCommand(AccessLevel.Admin)]
public bool ignoreCasesInCommands;
[Tooltip("This ignores cases for auto-complete lookup, but still cases are needed for commands")]
[ConsoleCommand(AccessLevel.Admin)]
public bool ignoreCasesInAutoCompleteInput = true;
public AccessMode adminModeInBuild;
public string adminModeConsoleCommand = "*GetAdminAccess*";
public AccessMode specialModeInBuild;
public string specialModeConsoleCommand = "*GetSpecialAccess*";
[Tooltip("This will disable admin/special commands in Unity Editor")]
public bool testOnlyFreeConsoleCommands;
public char searchCommandPrefix = '!';
[ConsoleCommand(AccessLevel.Admin)]
public bool ignoreCasesInSearch = true;
public char executeOnAllPrefix = '#';
public char executeOnlyOnRemotePrefix = '$';
public int titleFontSize = 18;
public int frameFontSize = 14;
public int logFontSize = 14;
public int stackFontSize = 12;
public SO_ConsoleWindow windowData;
private Color selectColor = new Color(0.25f, 0.8f, 0.25f);
private Color backgroundColor = new Color(0f, 0f, 0f, 0.9f);
private Rect rectAutoComplete;
private Rect rectScroll;
private string lastAutoCompleteCommand;
private double scrollViewEndHeight;
private bool drawLogsScrollBar;
private bool addInput;
public static event RemoteCommand onRemoteCommand;
public static event SetActiveMethod onSetActive;
private void ResetStatic()
{
RuntimeConsole.onRemoteCommand = null;
accessLevel = AccessLevel.Admin;
show = false;
autoCompleteList.Clear();
inputCommands.Clear();
threadLogEntries.Clear();
logEntries.Clear();
commands.Clear();
LogEntry.ResetStatic();
logs = null;
}
private void Awake()
{
isDebugBuild = Debug.isDebugBuild;
ResetStatic();
consoleWindow = windowData.consoleWindow;
logs = new CullList[6];
cullGroup = new CullGroup(8192 * logs.Length);
for (int i = 0; i < logs.Length; i++)
{
logs[i] = new CullList(8192);
}
SetActive(showConsoleOnStart);
inputCommand = string.Empty;
logs[0].cullItems.Add(new LogEntry("-------------------------------------------------------------------------------", Color.white, titleFontSize, FontStyle.Bold));
logs[0].cullItems.Add(new LogEntry(Helper.GetApplicationInfo(), Color.white, titleFontSize, FontStyle.Bold));
logs[0].cullItems.Add(new LogEntry("-------------------------------------------------------------------------------", Color.white, titleFontSize, FontStyle.Bold));
logs[0].cullItems.Add(new LogEntry(string.Empty, Color.white, titleFontSize, FontStyle.Bold));
logs[0].cullItems.Add(new LogEntry("Type '?' to list all commands", Color.white, titleFontSize, FontStyle.Bold));
logs[0].cullItems.Add(new LogEntry(string.Empty, Color.white, titleFontSize, FontStyle.Bold));
GUIChangeBool.ApplyUpdates();
Register(this);
CalcDraw(reset: true);
if (adminModeInBuild == AccessMode.Enabled)
{
accessLevel = AccessLevel.Admin;
}
}
private void OnEnable()
{
isEnabled = true;
}
private void OnDisable()
{
isEnabled = false;
}
private void OnDestroy()
{
if (instance == this)
{
instance = null;
}
Unregister(this);
}
public void ManualUpdate()
{
if (isDebugBuild && disableUnityDevelopmentConsole)
{
Debug.developerConsoleVisible = false;
}
UpdateLogs();
if (isEnabled && EventInput.isMouseButtonUp0)
{
consoleWindow.drag = 0;
}
}
public static void SetActive(bool active)
{
instance.consoleWindow.drag = 0;
show = active;
instance.gameObject.SetActive(active);
if (show)
{
setFocus = true;
}
if (RuntimeConsole.onSetActive != null)
{
RuntimeConsole.onSetActive(show);
}
WindowManager.CheckMouseCursorState();
}
public static void Log(string logString, bool showConsole)
{
if (!(instance == null))
{
AddLog(new LogEntry(logString, null, LogType.Log, EntryType.Console, Color.white));
if (showConsole && !show)
{
SetActive(active: true);
}
}
}
public static void Log(string logString, Color color, bool showConsole)
{
if (!(instance == null))
{
AddLog(new LogEntry(logString, null, LogType.Log, EntryType.Console, color));
if (showConsole && !show)
{
SetActive(active: true);
}
}
}
public static void Log(string logString, LogType logType = LogType.Log, Color color = default(Color), bool showConsole = false)
{
if (!(instance == null))
{
AddLog(new LogEntry(logString, null, logType, EntryType.Console, color));
if (showConsole && !show)
{
SetActive(active: true);
}
}
}
public static void Log(string logString, string[] lines, LogType logType = LogType.Log, Color color = default(Color), int threadId = -1)
{
if (!(instance == null))
{
AddLog(new LogEntry(logString, lines, logType, EntryType.Unity, color, instance.logFontSize, FontStyle.Normal, threadId));
}
}
public static void Log(LogEntry logEntry)
{
if (!(instance == null))
{
AddLog(logEntry);
}
}
private static void AddLog(LogEntry logEntry)
{
if (CheckNewFrame())
{
logEntry.id = LogEntry.currentId++;
}
threadLogEntries.AddThreadSafe(logEntry);
}
private void UpdateLogs()
{
logEntries.GrabListThreadSafe(threadLogEntries);
for (int i = 0; i < logEntries.Count; i++)
{
LogEntry logEntry = logEntries.items[i];
if (logEntry.entryType == EntryType.Unity)
{
if (logEntry.logType == LogType.Log)
{
instance.windowData.logIcon.count++;
lastFrameEntry.flag |= 1;
logs[2].cullItems.Add(logEntry);
}
else if (logEntry.logType == LogType.Warning)
{
if (instance.showConsoleOnWarning && !show)
{
SetActive(active: true);
}
instance.windowData.warningIcon.count++;
lastFrameEntry.flag |= 2;
logs[3].cullItems.Add(logEntry);
}
else if (logEntry.logType == LogType.Error)
{
if (instance.showConsoleOnError && !show)
{
SetActive(active: true);
}
instance.windowData.errorIcon.count++;
lastFrameEntry.flag |= 4;
logs[4].cullItems.Add(logEntry);
}
else if (logEntry.logType == LogType.Exception)
{
if (instance.showConsoleOnException && !show)
{
SetActive(active: true);
}
instance.windowData.exceptionIcon.count++;
lastFrameEntry.flag |= 8;
logs[5].cullItems.Add(logEntry);
}
}
else if (logEntry.entryType == EntryType.Frame)
{
logs[1].cullItems.Add(lastFrameEntry);
}
else
{
lastFrameEntry.flag |= 16;
logs[0].cullItems.Add(logEntry);
}
}
logEntries.Clear();
instance.CalcDraw(reset: false);
}
private static bool CheckNewFrame()
{
if (HtmlDebug.currentFrame != lastFrame)
{
lastFrame = HtmlDebug.currentFrame;
lastFrameEntry = new LogEntry("[Frame " + lastFrame.ToString("D6") + "][Time " + Helper.ToTimeFormat(HtmlDebug.frameTime) + "] -----------------------------------------------------------------------------------------------", null, LogType.Log, EntryType.Frame, new Color(0.31f, 0.55f, 0.63f), instance.frameFontSize, FontStyle.Bold);
threadLogEntries.AddThreadSafe(lastFrameEntry);
return true;
}
return false;
}
public static void SortCommandsTable()
{
commandsTable.Sort();
}
public static void Register(object instance)
{
if (Application.isPlaying)
{
Type type = instance.GetType();
if (!registeredInstancesLookup.TryGetValue(type, out var value))
{
value = new HashSet<object>();
registeredInstancesLookup[type] = value;
}
else if (value.Contains(instance))
{
Debug.LogError("Instance " + type.Name + " is already registered");
return;
}
value.Add(instance);
}
}
public static void Unregister(object instance)
{
Type type = instance.GetType();
registeredInstancesLookup.TryGetValue(type, out var value);
if (instance == null || !value.Contains(instance))
{
Debug.LogError("Instance " + type.Name + " is not registered");
return;
}
value.Remove(instance);
if (value.Count == 0)
{
registeredInstancesLookup.Remove(type);
}
}
public static void RegisterStaticType(Type objType)
{
if (instance == null)
{
return;
}
ConsoleAlias[] array = (ConsoleAlias[])objType.GetCustomAttributes(typeof(ConsoleAlias), inherit: true);
if (array.Length != 0)
{
commandsTable.lookup[array[0].alias] = CommandData.empty;
}
MemberInfo[] members = objType.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
foreach (MemberInfo memberInfo in members)
{
ConsoleCommand[] array2 = (ConsoleCommand[])memberInfo.GetCustomAttributes(typeof(ConsoleCommand), inherit: false);
if (array2.Length == 0)
{
continue;
}
ConsoleCommand consoleCommand = array2[0];
if (array.Length != 0)
{
consoleCommand.alias = array[0].alias + ((consoleCommand.alias.Length > 0) ? ("." + consoleCommand.alias) : string.Empty);
}
if (AddMethod(objType, consoleCommand, memberInfo, memberInfo as MethodInfo, MemberType.Method, memberInfo.Name))
{
continue;
}
FieldInfo fieldInfo = memberInfo as FieldInfo;
if (fieldInfo != null)
{
Type fieldType = fieldInfo.FieldType;
if (typeof(Delegate).IsAssignableFrom(fieldType))
{
AddMethod(objType, consoleCommand, memberInfo, fieldType.GetMethod("Invoke"), MemberType.Delegate, fieldInfo.Name);
}
else if (ValidParam(objType, fieldInfo, fieldType))
{
if (fieldType.IsEnum && consoleCommand.description == string.Empty)
{
consoleCommand.description = string.Join(", ", Enum.GetNames(fieldType));
}
string syntax = fieldInfo.Name + " " + fieldType.Name;
AddCommand(memberInfo, consoleCommand, memberInfo.Name, new CommandData(consoleCommand, objType, syntax, MemberType.Field, memberInfo, null, fieldInfo.IsStatic));
}
continue;
}
PropertyInfo propertyInfo = memberInfo as PropertyInfo;
if (!(propertyInfo != null))
{
continue;
}
Type propertyType = propertyInfo.PropertyType;
if (!ValidParam(objType, propertyInfo, propertyType))
{
continue;
}
MethodInfo getMethod = propertyInfo.GetGetMethod(nonPublic: true);
MethodInfo setMethod = propertyInfo.GetSetMethod(nonPublic: true);
bool flag = getMethod != null;
bool flag2 = setMethod != null;
bool isStatic;
if (flag)
{
isStatic = getMethod.IsStatic;
}
else
{
if (!flag2)
{
Debug.Log("Property has no getter or setter");
continue;
}
isStatic = setMethod.IsStatic;
}
string text = propertyInfo.Name + " " + propertyType.Name;
AddCommand(commandData: new CommandData(consoleCommand, objType, (flag && !flag2) ? (text + " (get)") : ((!(flag && flag2)) ? (text + " (set)") : (text + " (get set)")), MemberType.Property, memberInfo, null, isStatic), member: memberInfo, consoleCommand: consoleCommand, commandName: memberInfo.Name);
}
}
private static bool AddMethod(Type objType, ConsoleCommand consoleCommand, MemberInfo member, MethodInfo method, MemberType memberType, string methodName, bool logFailed = true)
{
if (method != null)
{
ParameterInfo[] parameters = method.GetParameters();
if (!ValidParams(objType, method, parameters))
{
return true;
}
string syntax = method.ToString();
AddCommand(member, consoleCommand, methodName, new CommandData(consoleCommand, objType, syntax, memberType, member, parameters, method.IsStatic), logFailed);
return true;
}
return false;
}
private static void AddCommand(MemberInfo member, ConsoleCommand consoleCommand, string commandName, CommandData commandData, bool logFailed = true)
{
if (instance.ignoreCasesInCommands)
{
commandName = commandName.ToLower();
}
if (consoleCommand.command == string.Empty)
{
consoleCommand.command = commandName;
}
else
{
commandName = consoleCommand.command;
if (instance.ignoreCasesInCommands)
{
commandName = commandName.ToLower();
}
}
if (consoleCommand.alias != string.Empty)
{
if (!commandsTable.lookup.ContainsKey(consoleCommand.alias))
{
commandsTable.lookup[consoleCommand.alias] = CommandData.empty;
}
commandName = consoleCommand.alias + "." + consoleCommand.command;
}
if (commandsTable.lookup.ContainsKey(commandName))
{
if (logFailed)
{
Debug.LogError("Duplicate command: `" + commandName + "` on " + member.Name + " in " + commandData.obj.ToString() + " class ");
}
}
else
{
commandsTable.lookup[commandName] = commandData;
}
}
public static bool ValidParams(Type objType, MethodInfo method, ParameterInfo[] paramInfos, bool logFailed = true)
{
foreach (ParameterInfo parameterInfo in paramInfos)
{
Type parameterType = parameterInfo.ParameterType;
if (!ValidParam(objType, parameterInfo.Member, parameterType, logFailed))
{
return false;
}
}
return true;
}
private static bool ValidParam(Type objType, MemberInfo member, Type type, bool logFailed = true)
{
bool flag = false;
if (type.IsPrimitive)
{
flag = true;
}
else if (type == typeof(decimal))
{
flag = true;
}
else if (type == typeof(string))
{
flag = true;
}
else if (type == typeof(Vector2) || type == typeof(Vector3) || type == typeof(Vector4))
{
flag = true;
}
else if (type.IsEnum)
{
flag = true;
}
if (!flag)
{
if (logFailed)
{
Debug.LogError("Cannot register: " + objType.Name + " => " + member.Name + " method contains parameter of type " + type.Name + ". Only primitive and string parameters are allowed at the moment.");
}
return false;
}
return true;
}
private static void CheckDestroyedMonoBehaviours(HashSet<object> instances)
{
instances.RemoveWhere((object s) => s as MonoBehaviour == null && s.GetType().IsSubclassOf(typeof(MonoBehaviour)));
}
private static int IsRemoteCommand(ref string command)
{
int result;
if (command[0] == instance.executeOnAllPrefix)
{
result = 1;
command = command.Substring(1);
}
else if (command[0] == instance.executeOnlyOnRemotePrefix)
{
result = 2;
command = command.Substring(1);
}
else
{
result = 0;
}
return result;
}
public static void ExecuteCommand(string command)
{
command = command.Replace(',', ' ');
command = command.Trim(' ');
if (command == string.Empty)
{
return;
}
if (command == instance.adminModeConsoleCommand && (instance.adminModeInBuild == AccessMode.EnabledOnConsoleCommand || instance.testOnlyFreeConsoleCommands))
{
accessLevel = AccessLevel.Admin;
LogResult("AccessLevel = Admin");
}
else if (command == instance.specialModeConsoleCommand && (instance.specialModeInBuild == AccessMode.EnabledOnConsoleCommand || instance.testOnlyFreeConsoleCommands))
{
accessLevel = AccessLevel.Special;
LogResult("AccessLevel = Special");
}
else
{
if (command[0] == instance.searchCommandPrefix)
{
return;
}
int num = IsRemoteCommand(ref command);
int num2 = command.IndexOf(" ");
string argumentString = ((num2 == -1) ? string.Empty : command.Substring(num2 + 1));
GetArguments(command, inputCommands);
string text = inputCommands.Dequeue();
if (!commandsTable.lookup.TryGetValue(text, out var value) || value.obj == null)
{
CannotFindCommand(command, text);
return;
}
if (value.consoleCommand != null && !value.consoleCommand.HasAccess(accessLevel))
{
CannotFindCommand(command, text);
return;
}
if (!value.IsRegistered())
{
LogResultError("There is no registered instance for command '" + text + "'");
return;
}
if (num > 0)
{
if (RuntimeConsole.onRemoteCommand != null)
{
RuntimeConsole.onRemoteCommand(command);
}
command = ((num != 2) ? ("Execute on all '" + command + "'") : ("Execute only on remote '" + command + "'"));
}
Log(new LogEntry(command, null, LogType.Log, EntryType.Command, Color.green, instance.logFontSize, FontStyle.Bold));
if ((bool)HtmlDebug.instance)
{
HtmlDebug.instance.UnityDebugLog(command, null, LogType.Log, isMainThread: true, -1, null, EntryType2.Command, closeLi: false);
}
if (num != 2)
{
value.Execute(inputCommands, argumentString);
}
}
}
public static void GetArguments(string argumentString, FastQueue<string> inputCommands)
{
argumentString = argumentString.Trim(' ');
inputCommands.FastClear();
int num = 0;
for (int i = 0; i < argumentString.Length; i++)
{
char c = argumentString[i];
if (i == argumentString.Length - 1)
{
inputCommands.Enqueue(argumentString.Substring(num, i - num + 1).Trim());
break;
}
if (c == ' ')
{
if (i < argumentString.Length - 1 && argumentString[i + 1] == ' ')
{
continue;
}
int num2 = argumentString.IndexOf(' ', i + 1);
int num3 = i - num;
inputCommands.Enqueue(argumentString.Substring(num, num3).Trim());
if (num2 == -1)
{
inputCommands.Enqueue(argumentString.Substring(i + 1).Trim());
break;
}
num += num3 + 1;
}
if (c == '"')
{
int num4 = argumentString.IndexOf('"', i + 1);
if (num4 == -1)
{
LogCommandFailed(argumentString, "String closing \" is missing");
break;
}
int num5 = num4 - num;
inputCommands.Enqueue(argumentString.Substring(num + 1, num5 - 1).Trim());
num += num5 + 1;
i = num4 + 1;
}
}
}
private static void CannotFindCommand(string command, string firstCommand)
{
string result = "Cannot find command '" + firstCommand + "'";
LogCommandFailed(command, result);
}
private static void LogCommandFailed(string command, string result)
{
Log(new LogEntry(command, null, LogType.Log, EntryType.Command, Color.green, instance.logFontSize, FontStyle.Bold));
Log(new LogEntry(result, null, LogType.Log, EntryType.CommandResult, Helper.colCommandResultFailed, instance.logFontSize, FontStyle.Bold));
if ((bool)HtmlDebug.instance)
{
HtmlDebug.instance.UnityDebugLog(result, null, LogType.Log, isMainThread: true, -1, null, EntryType2.CommandFault);
}
}
public static bool FindCommand(string command)
{
string[] array = command.Split(' ');
if (!commandsTable.lookup.TryGetValue(array[0], out var value) || value.obj == null)
{
return false;
}
return true;
}
private static void LogResult(string result)
{
Log(new LogEntry(result, null, LogType.Log, EntryType.CommandResult, Helper.colCommandResult, instance.logFontSize, FontStyle.Bold));
if ((bool)HtmlDebug.instance)
{
HtmlDebug.instance.UnityDebugLog(result, null, LogType.Log, isMainThread: true, -1, null, EntryType2.CommandResult);
}
}
public static void LogResultError(string result, bool onlyConsoleAndHtml = true)
{
if (onlyConsoleAndHtml)
{
Log(new LogEntry(result, null, LogType.Log, EntryType.CommandResult, Helper.colCommandResultFailed, instance.logFontSize, FontStyle.Bold));
if ((bool)HtmlDebug.instance)
{
HtmlDebug.instance.UnityDebugLog(result, null, LogType.Log, isMainThread: true, -1, null, EntryType2.CommandFault);
}
}
else
{
Debug.LogError(result);
}
}
[ConsoleCommand("", "Clears all logs in the Console Window", AccessLevel.Admin)]
private static void Clear()
{
for (int i = 0; i < logs.Length; i++)
{
logs[i].cullItems.Clear();
}
instance.CalcDraw(reset: true);
instance.windowData.logIcon.count = 0;
instance.windowData.warningIcon.count = 0;
instance.windowData.errorIcon.count = 0;
instance.windowData.exceptionIcon.count = 0;
}
[ConsoleCommand("", "Change the height of the Console Window based on line height", AccessLevel.Admin)]
private static void Lines(int count = 20)
{
instance.consoleWindow.rect.height = 25 * count;
}
[ConsoleCommand("", "Open the Console Window", AccessLevel.Admin)]
private static void Open()
{
SetActive(active: true);
}
[ConsoleCommand("", "Close the Console Window", AccessLevel.Admin)]
private static void Close()
{
SetActive(active: false);
}
[ConsoleCommand("", "Unload unused Assets", AccessLevel.Admin)]
private static void UnloadUnusedAssets()
{
Resources.UnloadUnusedAssets();
}
[ConsoleCommand("", "Runs Garbage Collect", AccessLevel.Admin)]
private static void GarbageCollect()
{
GC.Collect();
}
[ConsoleCommand("", "Search for methods in assemblies", AccessLevel.Admin)]
private static void SearchMethod(string name)
{
FastList<CustomAssembly> customAssemblies = RuntimeInspector.customAssemblies;
for (int i = 0; i < customAssemblies.Count; i++)
{
CustomAssembly customAssembly = customAssemblies.items[i];
FastList<CustomType> allTypes = customAssembly.allTypes;
if (customAssembly.type != AssemblyType.Unity)
{
continue;
}
for (int j = 0; j < allTypes.Count; j++)
{
Type type = allTypes.items[j].type;
MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
for (int k = 0; k < methods.Length; k++)
{
string text = methods[k].ToString();
if (text.IndexOf(name, StringComparison.CurrentCultureIgnoreCase) != -1)
{
Log(customAssembly.name + "." + type.Name + "." + text);
}
}
}
}
}
private Vector2 GetDockPos()
{
float num = WindowManager.instance.windowData.guiScale.value * 2f;
return new Vector2(((float)Screen.width / num - consoleWindow.rect.width / 2f) / (float)Screen.width, 0f);
}
private void CalcDraw(bool reset)
{
LogEntry.showCommandLogs = logs[0].show.Value;
LogEntry.showUnityLogs = logs[2].show.Value;
LogEntry.showWarningLogs = logs[3].show.Value;
LogEntry.showErrorLogs = logs[4].show.Value;
LogEntry.showExceptionLogs = logs[5].show.Value;
LogEntry.showStack = _showStack.Value;
if (reset)
{
LogEntry.lastLog = null;
}
cullLists.Clear();
if (logs[0].show.Value)
{
cullLists.Add(logs[0]);
}
if (showUnityLogs.Value)
{
for (int i = 1; i <= 5; i++)
{
if (logs[i].show.Value)
{
cullLists.Add(logs[i]);
}
}
}
cullGroup.CalcDraw(reset, cullLists);
}
public void MyOnGUI()
{
Event current = Event.current;
if (Helper.IsShowKeyPressed(current, useSameEditorAsBuildShowKey, showToggleKeyEditor, showToggleKeyBuild))
{
SetActive(!show);
}
else
{
if (!show)
{
return;
}
if (current.type == EventType.Layout && calcDraw)
{
calcDraw = false;
CalcDraw(reset: true);
}
if (consoleWindow.isDocked.Value)
{
if (consoleWindow.drag == 1)
{
if (consoleWindow.position != GetDockPos())
{
consoleWindow.isDocked.Value = false;
}
}
else
{
consoleWindow.position = GetDockPos();
}
}
consoleWindow.Update(700f, 94f);
GUI.skin = windowData.skin;
if (WindowManager.instance.useCanvas)
{
GUI.backgroundColor = new Color(1f, 1f, 1f, 0f);
}
else
{
GUI.backgroundColor = windowData.color;
}
Helper.DrawWindow(23423022, consoleWindow, DrawConsole);
DrawAutoComplete();
}
}
private void DrawConsole(int windowId)
{
WindowManager.BeginRenderTextureGUI();
Event current = Event.current;
windowData.skin.box.fontStyle = FontStyle.Bold;
Rect rect = consoleWindow.rect;
GUI.backgroundColor = Helper.GetColor(windowData, backgroundColor);
GUI.Box(new Rect(0f, 0f, rect.width, rect.height), "");
GUILayout.Box("Console");
Helper.Drag(consoleWindow, null, null, titleDrag: true, onlyRightCorner: true);
GUI.backgroundColor = Color.white;
DrawButtons();
DrawLogs(current, rect);
GUILayout.Space(1f);
DrawInput(current, rect);
drawLogsScrollBar = DrawLogsScrollBar(current);
GUILayout.Space(-1f);
Helper.Drag(consoleWindow, null, null, titleDrag: false, onlyRightCorner: true);
WindowManager.SetToolTip(windowId);
WindowManager.EndRenderTextureGUI();
}
private void DrawButtons()
{
GUISkin skin = windowData.skin;
int num = 80;
GUILayout.BeginHorizontal();
if (Helper.DrawShowButton(windowData, Helper.GetGUIContent("Commands", "Show/Hide Command Logs"), logs[0].show, selectColor, num))
{
calcDraw = true;
}
if (Helper.DrawShowButton(windowData, Helper.GetGUIContent("Unity Log", "Show/Hide Debug Logs"), showUnityLogs, selectColor, num))
{
calcDraw = true;
}
if (showUnityLogs.Value)
{
GUIContent gUIContent = windowData.logIcon.GetGUIContent();
gUIContent.tooltip = "Show/Hide Debug Logs";
float width = skin.button.CalcSize(gUIContent).x + 2f;
if (Helper.DrawShowButton(windowData, gUIContent, logs[2].show, selectColor, width))
{
calcDraw = true;
}
GUIContent gUIContent2 = windowData.warningIcon.GetGUIContent();
gUIContent2.tooltip = "Show/Hide Debug Warnings";
width = skin.button.CalcSize(gUIContent2).x + 2f;
if (Helper.DrawShowButton(windowData, gUIContent2, logs[3].show, selectColor, width))
{
calcDraw = true;
}
GUIContent gUIContent3 = windowData.errorIcon.GetGUIContent();
gUIContent3.tooltip = "Show/Hide Debug Errors";
width = skin.button.CalcSize(gUIContent3).x + 2f;
if (Helper.DrawShowButton(windowData, gUIContent3, logs[4].show, selectColor, width))
{
calcDraw = true;
}
GUIContent gUIContent4 = windowData.exceptionIcon.GetGUIContent();
gUIContent4.tooltip = "Show/Hide Debug Exceptions";
width = skin.button.CalcSize(gUIContent4).x + 2f;
if (Helper.DrawShowButton(windowData, gUIContent4, logs[5].show, selectColor, width))
{
calcDraw = true;
}
if (Helper.DrawShowButton(windowData, Helper.GetGUIContent("Stack", _showStack.Value ? windowData.texStackOn : windowData.texStackOff, "Show/Hide Stack Trace"), _showStack, selectColor, num))
{
calcDraw = true;
}
}
if (GUILayout.Button(Helper.GetGUIContent("Html Log", "Open Html Log in browser"), GUILayout.Width(num)))
{
if ((bool)HtmlDebug.instance)
{
Application.OpenURL("file://" + HtmlDebug.instance.logPathIncludingFilename);
}
else
{
Debug.LogError("Can't find Html Debug, make sure you have the 'Html Debug' GameObject in your Scene and that it's enabled");
}
}
if (GUILayout.Button(Helper.GetGUIContent("Logs Folder", "Open Logs Folder in File Exlorer"), GUILayout.Width(num)))
{
if ((bool)HtmlDebug.instance)
{
if ((bool)HtmlDebug.instance)
{
Application.OpenURL("file://" + HtmlDebug.instance.logPath);
}
else
{
Application.OpenURL("file://" + Application.persistentDataPath);
}
}
else
{
Debug.LogError("Can't find Html Debug, make sure you have the 'Html Debug' GameObject in your Scene and that it's enabled");
}
}
if (!consoleWindow.isDocked.Value && GUILayout.Button(Helper.GetGUIContent("Dock", "Centers the window in the top of the screen"), GUILayout.Width(num)))
{
consoleWindow.isDocked.Value = true;
}
GUILayout.EndHorizontal();
GUI.backgroundColor = Color.white;
}
private void DrawLogs(Event currentEvent, Rect window)
{
GUISkin skin = windowData.skin;
rectScroll = new Rect(4f, 54f, window.width - (float)(drawLogsScrollBar ? 22 : 10), window.height - 80f);
bool value = _showStack.Value;
CullList cullList = cullGroup.cullList;
if (currentEvent.type == EventType.Layout)
{
scrollViewEndHeight = 0.0;
if (cullList.cullItems.Count > 0)
{
scrollViewEndHeight = cullList.cullItems.items[cullList.cullItems.Count - 1].endHeight;
}
double y = scrollViewEndHeight - (double)rectScroll.height;
if (scrollViewEndHeight > (double)rectScroll.height && showLastLog.Value)
{
scrollView.y = y;
}
scrollViewHeights = new Double2(scrollView.y, scrollView.y + (double)rectScroll.height);
cullList.Cull(scrollViewHeights);
}
if (cullList.cullItems.Count == 0)
{
return;
}
GUILayout.BeginArea(rectScroll);
GUILayout.Space((float)(cullList.cullItems.items[cullList.startIndex].startHeight - scrollView.y));
for (int i = cullList.startIndex; i <= cullList.endIndex; i++)
{
LogEntry logEntry = (LogEntry)cullList.cullItems.items[i];
skin.label.fontSize = logEntry.fontSize;
skin.label.fontStyle = logEntry.fontStyle;
if (logEntry.entryType == EntryType.Frame)
{
GUILayout.Space(20f);
}
GUILayout.BeginHorizontal();
if (logEntry.entryType == EntryType.Unity)
{
if (logEntry.logType == LogType.Warning)
{
GUI.color = Color.yellow;
}
else if (logEntry.logType == LogType.Error)
{
GUI.color = Color.red;
}
else if (logEntry.logType == LogType.Exception)
{
GUI.color = Color.magenta;
}
else if (logEntry.logType == LogType.Log)
{
GUI.color = Color.white;
}
}
else
{
GUI.color = logEntry.color;
}
if (logEntry.entryType == EntryType.Unity || logEntry.entryType == EntryType.Console || logEntry.entryType == EntryType.Command || logEntry.entryType == EntryType.CommandResult)
{
GUILayout.Space(30f);
}
if (logEntry.threadString != null)
{
float x = GUI.skin.label.CalcSize(Helper.GetGUIContent(logEntry.logString)).x;
GUILayout.Label(logEntry.logString, GUILayout.Width(x));
}
else
{
GUILayout.Label(logEntry.logString);
}
if (logEntry.entryType == EntryType.Unity || logEntry.entryType == EntryType.Console || logEntry.entryType == EntryType.Command)
{
Rect lastRect = GUILayoutUtility.GetLastRect();
lastRect.x -= 12f;
lastRect.y += logEntry.fontSize / 2;
if (logEntry.entryType == EntryType.Unity)
{
lastRect.width = 4f;
lastRect.height = 4f;
GUI.DrawTexture(lastRect, windowData.texDot);
}
else
{
lastRect.y -= 2f;
lastRect.width = 8f;
lastRect.height = 8f;
GUI.DrawTexture(lastRect, windowData.texArrow);
}
}
if (logEntry.threadString != null)
{
GUI.skin.label.fontStyle = FontStyle.Italic;
GUILayout.Label(logEntry.threadString);
GUI.skin.label.fontStyle = FontStyle.Normal;
}
GUILayout.EndHorizontal();
if (value && logEntry.stackLines != null)
{
skin.label.fontSize = stackFontSize;
GUILayout.Space(-3f);
GUI.color *= 0.825f;
for (int j = 0; j < logEntry.stackLines.Length; j++)
{
GUILayout.BeginHorizontal();
GUILayout.Space(30f);
GUILayout.Label(logEntry.stackLines[j]);
GUILayout.EndHorizontal();
}
}
GUI.color = Color.white;
if (!logs[0].show.RealValue && !showUnityLogs.RealValue)
{
showUnityLogs.Value = true;
}
}
skin.label.fontSize = 12;
skin.label.fontStyle = FontStyle.Normal;
GUILayout.EndArea();
}
private bool DrawLogsScrollBar(Event currentEvent)
{
Rect position = new Rect
{
y = 55f,
x = rectScroll.width + 5f,
width = 20f,
height = consoleWindow.rect.height - 80f
};
double num = scrollViewEndHeight - (double)rectScroll.height;
if (scrollViewEndHeight > (double)rectScroll.height)
{
if (currentEvent.isScrollWheel && autoCompleteList.Count == 0)
{
scrollView.y += currentEvent.delta.y * 10f;
showLastLog.Value = scrollView.y >= num;
}
if (showLastLog.Value)
{
scrollView.y = num;
}
GUI.changed = false;
scrollView.y = GUI.VerticalScrollbar(position, (float)scrollView.y, rectScroll.height, 0f, (float)scrollViewEndHeight);
if (GUI.changed)
{
showLastLog.Value = scrollView.y >= num - 0.10000000149011612;
}
return true;
}
scrollView.y = 0.0;
return false;
}
private void DrawInput(Event currentEvent, Rect window)
{
GUILayout.Space(window.height - 82f);
int num = 45;
TextEditor textEditor = (TextEditor)GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl);
int num2 = textEditor?.cursorIndex ?? 0;
bool flag = GUI.GetNameOfFocusedControl() == "ConsoleInput";
if (flag)
{
if (currentEvent.type == EventType.KeyDown && currentEvent.keyCode == KeyCode.Return)
{
showLastLog.Value = true;
commands.Add(inputCommand);
commandIndex = commands.Count;
if (!FindCommand(inputCommand))
{
AutoCompleteInputCommand();
}
ExecuteCommand(inputCommand);
inputCommand = string.Empty;
setFocus = true;
}
if (currentEvent.type == EventType.KeyDown)
{
if (currentEvent.keyCode == KeyCode.DownArrow && num2 > 0)
{
autoCompleteIndex++;
updateAutoCompleteScrollView = true;
}
else if (currentEvent.keyCode == KeyCode.UpArrow && num2 > 0)
{
moveInputCursor = 1;
autoCompleteIndex--;
updateAutoCompleteScrollView = true;
}
else if (currentEvent.keyCode != KeyCode.Tab)
{
autoCompleteIndex = 0;
updateAutoCompleteScrollView = true;
}
}
}
autoCompleteIndex = Helper.Repeat(autoCompleteIndex, autoCompleteList.Count);
GUILayout.BeginHorizontal();
GUILayout.Space(4f);
GUI.SetNextControlName("ConsoleInput");
GUI.color = Color.white;
GUI.backgroundColor = Color.white;
GUI.changed = false;
if (currentEvent.type == EventType.KeyDown)
{
if (currentEvent.keyCode == showToggleKeyEditor.keyCode)
{
addInput = false;
}
else if (addInput)
{
inputCommand = GUILayout.TextField(inputCommand, GUILayout.Width(window.width - 8f - (float)((num + 4) * 2 + 18)));
}
else
{
addInput = true;
}
}
else
{
GUILayout.TextField(inputCommand, GUILayout.Width(window.width - 8f - (float)((num + 4) * 2 + 18)));
}
if (GUI.changed && addInput)
{
if (inputCommand.Length >= 2 && inputCommand[0] == searchCommandPrefix)
{
LogEntry.search = inputCommand.Substring(1);
LogEntry.ignoreCasesInSearch = ignoreCasesInSearch;
CalcDraw(reset: true);
}
else if (LogEntry.search != string.Empty)
{
LogEntry.search = string.Empty;
CalcDraw(reset: true);
}
}
if (moveInputCursor != 0 && textEditor != null)
{
if (moveInputCursor == 1)
{
textEditor.MoveTextEnd();
}
else if (moveInputCursor == -1)
{
textEditor.MoveTextStart();
}
moveInputCursor = 0;
}
if (GUILayout.Button(Helper.GetGUIContent("Clear", "Clear all Logs"), GUILayout.Width(num)))
{
Clear();
}
Helper.DrawShowButton(windowData, Helper.GetGUIContent("Last", "Scroll to last Log"), showLastLog, selectColor, num);
Rect lastRect = GUILayoutUtility.GetLastRect();
lastRect.x += num + 7;
lastRect.y += 9f;
lastRect.width = 10f;
lastRect.height = 10f;
if (new Rect(lastRect.x, lastRect.y, 16f, 16f).Contains(currentEvent.mousePosition))
{
GUI.color = Color.white;
}
else
{
GUI.color = Color.grey;
}
GUI.Label(lastRect, Helper.GetGUIContent(windowData.texCornerScale, "Resize console window"));
GUI.color = Color.white;
GUILayout.EndHorizontal();
if (commands.Count > 0 && num2 == 0)
{
if (currentEvent.keyCode == KeyCode.UpArrow && currentEvent.type == EventType.KeyUp)
{
commandIndex--;
if (commandIndex < 0)
{
commandIndex = 0;
}
inputCommand = commands.items[commandIndex];
}
else if (currentEvent.keyCode == KeyCode.DownArrow)
{
if (currentEvent.type == EventType.KeyUp)
{
commandIndex++;
if (commandIndex > commands.Count - 1)
{
commandIndex = commands.Count - 1;
inputCommand = string.Empty;
}
else
{
inputCommand = commands.items[commandIndex];
}
}
moveInputCursor = -1;
}
}
if (flag)
{
GetAutoCompleteList(inputCommand);
}
else
{
ClearAutoCompleteList();
}
if (currentEvent.type == EventType.Repaint && setFocus)
{
setFocus = false;
GUI.FocusControl("ConsoleInput");
}
}
private void DrawAutoComplete()
{
Event current = Event.current;
if (autoCompleteList.Count != oldAutoCompleteCount && current.type == EventType.Layout)
{
oldAutoCompleteCount = autoCompleteList.Count;
updateAutoCompleteScrollView = true;
}
if (autoCompleteList.Count > 0 && autoCompleteList.Count == oldAutoCompleteCount)
{
rectAutoComplete = consoleWindow.rect;
rectAutoComplete.y += rectAutoComplete.height;
rectAutoComplete.height = Mathf.Min(autoCompleteList.Count * 25 + 2, 302);
rectAutoComplete.width += 10f;
GUI.skin = windowData.skinAutoComplete;
GUILayout.Window(23423023, rectAutoComplete, DrawAutoComplete, GUIContent.none);
GUI.skin = windowData.skin;
}
if (current.type == EventType.KeyDown && current.keyCode == KeyCode.Tab)
{
AutoCompleteInputCommand();
}
}
private void DrawAutoComplete(int windowId)
{
WindowManager.BeginRenderTextureGUI();
GUISkin skin = windowData.skin;
GUI.backgroundColor = backgroundColor;
GUI.Box(new Rect(0f, 0f, rectAutoComplete.width - 10f, rectAutoComplete.height), string.Empty);
GUI.backgroundColor = Color.white;
if (updateAutoCompleteScrollView)
{
updateAutoCompleteScrollView = false;
autoCompleteScrollView.y = Mathf.Max((float)(autoCompleteIndex * 25) - rectAutoComplete.height / 2f, 0f);
}
autoCompleteScrollView = GUILayout.BeginScrollView(autoCompleteScrollView);
float num = 0f;
float num2 = 0f;
float num3 = 0f;
float num4 = 0f;
for (int i = 0; i < autoCompleteList.Count; i++)
{
AutoComplete autoComplete = autoCompleteList.items[i];
CommandData commandData = autoComplete.commandData;
float x = skin.button.CalcSize(Helper.GetGUIContent(autoComplete.command)).x;
if (x > num)
{
num = x;
}
if (commandData.memberType == MemberType.Field || commandData.memberType == MemberType.Property)
{
object value = commandData.GetValue();
if (value != null)
{
x = skin.label.CalcSize(Helper.GetGUIContent(value.ToString())).x;
if (x > num3)
{
num3 = x;
}
}
}
x = skin.label.CalcSize(Helper.GetGUIContent(commandData.syntax)).x;
if (x > num2)
{
num2 = x;
}
int instanceCount = commandData.GetInstanceCount();
if (instanceCount > 0)
{
x = skin.label.CalcSize(Helper.GetGUIContent("Instances: " + instanceCount)).x;
if (x > num4)
{
num4 = x;
}
}
}
num2 += 15f;
if (num3 > 0f)
{
num3 += 15f;
}
if (num4 > 0f)
{
num4 += 15f;
}
GUILayout.Space(-2f);
for (int j = 0; j < autoCompleteList.Count; j++)
{
AutoComplete autoComplete2 = autoCompleteList.items[j];
CommandData commandData2 = autoComplete2.commandData;
string command = autoComplete2.command;
if (j % 2 == 0)
{
Rect rect = GUILayoutUtility.GetRect(0f, 27f);
rect.width = rectAutoComplete.width - 11f;
rect.y += 2f;
rect.height -= 2f;
GUILayout.Space(-27f);
GUI.backgroundColor = new Color(0.0675f, 0.0675f, 0.0675f, 1f);
GUI.Box(rect, string.Empty);
GUI.backgroundColor = Color.white;
}
GUILayout.BeginHorizontal();
GUI.backgroundColor = ((j == autoCompleteIndex) ? Color.green : Color.white);
if (GUILayout.Button(command, GUILayout.Width(num)))
{
inputCommand = command;
moveInputCursor = 1;
}
GUILayout.BeginVertical();
GUILayout.Space(7f);
GUILayout.BeginHorizontal();
GUILayout.Label(commandData2.syntax, GUILayout.Width(num2));
if (num3 > 0f)
{
if (commandData2.memberType == MemberType.Field || commandData2.memberType == MemberType.Property)
{
object value2 = commandData2.GetValue();
if (value2 != null)
{
GUI.color = Color.green;
GUILayout.Label(value2.ToString(), GUILayout.Width(num3));
GUI.color = Color.white;
}
else
{
GUILayout.Space(num3);
}
}
else
{
GUILayout.Space(num3);
}
}
if (num4 > 0f)
{
int instanceCount2 = commandData2.GetInstanceCount();
if (instanceCount2 > 0)
{
GUI.color = new Color(0.3f, 0.5f, 1f, 1f);
GUILayout.Label("Instances: " + instanceCount2, GUILayout.Width(num4));
GUI.color = Color.white;
}
else
{
GUILayout.Space(num4);
}
}
if (commandData2.consoleCommand != null && commandData2.consoleCommand.description != string.Empty)
{
GUI.color = Color.yellow;
GUILayout.Label(commandData2.consoleCommand.description);
GUI.color = Color.white;
}
GUILayout.EndHorizontal();
GUILayout.Space(-7f);
GUILayout.EndVertical();
GUILayout.EndHorizontal();
}
GUI.backgroundColor = Color.white;
GUILayout.EndScrollView();
WindowManager.EndRenderTextureGUI();
}
private void AutoCompleteInputCommand()
{
if (autoCompleteList.Count > 0)
{
inputCommand = inputCommand.TrimStart(' ');
int num = IsRemoteCommand(ref inputCommand);
string text = string.Empty;
int num2 = inputCommand.IndexOf(' ');
if (num2 != -1)
{
text = inputCommand.Substring(num2);
}
inputCommand = autoCompleteList.items[autoCompleteIndex].command + text;
switch (num)
{
case 1:
inputCommand = "#" + inputCommand;
break;
case 2:
inputCommand = "$" + inputCommand;
break;
}
if (inputCommand[inputCommand.Length - 1] == '.')
{
inputCommand = inputCommand.Substring(0, inputCommand.Length - 1);
}
moveInputCursor = 1;
}
}
private void ClearAutoCompleteList()
{
lastAutoCompleteCommand = string.Empty;
autoCompleteList.FastClear();
}
private void GetAutoCompleteList(string command)
{
if (command == lastAutoCompleteCommand)
{
if (command == string.Empty && autoCompleteList.Count > 0)
{
ClearAutoCompleteList();
}
return;
}
lastAutoCompleteCommand = command;
ClearAutoCompleteList();
command = command.Trim(' ');
if (command == string.Empty || command[0] == searchCommandPrefix)
{
return;
}
int num = command.IndexOf(" ");
if (num != -1)
{
command = command.Substring(0, num);
}
IsRemoteCommand(ref command);
if (command == string.Empty)
{
return;
}
if (command[0] == '?')
{
command = command.Substring(1);
}
string[] names = commandsTable.names;
for (int i = 0; i < names.Length; i++)
{
if (!(ignoreCasesInAutoCompleteInput ? names[i].StartsWith(command, StringComparison.CurrentCultureIgnoreCase) : names[i].StartsWith(command)))
{
continue;
}
string text = names[i];
CommandData commandData = commandsTable.lookup[text];
if (commandData.consoleCommand == null)
{
if (accessLevel != AccessLevel.Admin)
{
continue;
}
bool flag = false;
for (int j = i + 1; j < names.Length && (ignoreCasesInAutoCompleteInput ? names[j].StartsWith(text, StringComparison.CurrentCultureIgnoreCase) : names[j].StartsWith(text)); j++)
{
CommandData commandData2 = commandsTable.lookup[names[j]];
if (commandData2.consoleCommand != null && commandData2.consoleCommand.HasAccess(accessLevel) && commandData2.IsRegistered())
{
flag = true;
break;
}
}
if (!flag)
{
continue;
}
}
else if (!commandData.consoleCommand.HasAccess(accessLevel) || !commandData.IsRegistered())
{
continue;
}
autoCompleteList.Add(new AutoComplete(text, commandData));
}
}
private static bool TryParse(Type t, FastQueue<string> paramQueue, out object result)
{
bool valid = true;
if (t == typeof(Vector2))
{
Vector2 vector = default(Vector2);
for (int i = 0; i < 2; i++)
{
object obj = ChangeType(typeof(float), paramQueue, ref valid);
if (obj != null)
{
vector[i] = (float)obj;
continue;
}
result = null;
return false;
}
result = vector;
}
else if (t == typeof(Vector3))
{
Vector3 vector2 = default(Vector3);
for (int j = 0; j < 3; j++)
{
object obj2 = ChangeType(typeof(float), paramQueue, ref valid);
if (obj2 != null)
{
vector2[j] = (float)obj2;
continue;
}
result = null;
return false;
}
result = vector2;
}
else if (t == typeof(Vector4))
{
Vector4 vector3 = default(Vector4);
for (int k = 0; k < 4; k++)
{
object obj3 = ChangeType(typeof(float), paramQueue, ref valid);
if (obj3 != null)
{
vector3[k] = (float)obj3;
continue;
}
result = null;
return false;
}
result = vector3;
}
else if (t == typeof(Quaternion))
{
Quaternion quaternion = default(Quaternion);
for (int l = 0; l < 4; l++)
{
object obj4 = ChangeType(typeof(float), paramQueue, ref valid);
if (obj4 != null)
{
quaternion[l] = (float)obj4;
continue;
}
result = null;
return false;
}
result = quaternion;
}
else
{
result = ChangeType(t, paramQueue, ref valid);
}
return valid;
}
private static object ChangeType(Type t, FastQueue<string> paramQueue, ref bool valid)
{
if (paramQueue.Count == 0)
{
LogResultError("Not enough parameters");
valid = false;
return null;
}
string text = paramQueue.Dequeue();
text = text.Trim();
if (t == typeof(string))
{
return text;
}
if (t == typeof(bool))
{
bool.TryParse(text, out var result);
return result;
}
if (t == typeof(byte))
{
byte.TryParse(text, out var result2);
return result2;
}
if (t == typeof(sbyte))
{
sbyte.TryParse(text, out var result3);
return result3;
}
if (t == typeof(char))
{
char.TryParse(text, out var result4);
return result4;
}
if (t == typeof(decimal))
{
decimal.TryParse(text, out var result5);
return result5;
}
if (t == typeof(double))
{
double.TryParse(text, out var result6);
return result6;
}
if (t == typeof(float))
{
float.TryParse(text, out var result7);
return result7;
}
if (t == typeof(int))
{
int.TryParse(text, out var result8);
return result8;
}
if (t == typeof(uint))
{
uint.TryParse(text, out var result9);
return result9;
}
if (t == typeof(long))
{
long.TryParse(text, out var result10);
return result10;
}
if (t == typeof(ulong))
{
ulong.TryParse(text, out var result11);
return result11;
}
if (t == typeof(short))
{
short.TryParse(text, out var result12);
return result12;
}
if (t == typeof(ushort))
{
ushort.TryParse(text, out var result13);
return result13;
}
if (t.IsEnum)
{
try
{
return Enum.Parse(t, text, ignoreCase: true);
}
catch (Exception)
{
LogResultError("Cannot find '" + text + "'");
}
}
valid = false;
return null;
}
}
}