using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using UnityEngine; using YuanAPI.Tools; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("HoLConsole")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+64e7b7d6e2c81c905bf53c5bfa1e055decd9c14f")] [assembly: AssemblyProduct("HoLConsole")] [assembly: AssemblyTitle("HoLConsole")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace HoLConsole { public static class AllTextExporter { private static readonly List Locales = new List(2) { "zh-CN", "en-US" }; private const string VanillaNamespace = "Vanilla"; public static void Register() { ConsoleAPI.RegisterCommand(new CommandDef("export-AllText", "[调试指令]将游戏内置的 AllText 和 RandName 原版文本导出为符合 YuanAPI Localization 格式的 JSON 文件", "export-AllText", ExportAllTextCommand)); } private static string ExportAllTextCommand(CommandContext ctx, ParsedArgs args) { try { string text = Path.Combine("Output"); ctx.Print("开始导出,目标目录:" + text, ConsoleLevel.Info); Export(text, ctx); return "导出完成"; } catch (Exception ex) { ctx.Logger.LogError((object)("Error: " + ex.Message)); return "Error:" + ex.Message; } } private static void Export(string outputRoot, CommandContext ctx) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown JObject[] array = (JObject[])(object)new JObject[Locales.Count]; for (int i = 0; i < Locales.Count; i++) { array[i] = new JObject(); } ExportAllTextNormalFields(array, ctx); ExportAllTextShenFen(array, ctx); ExportAllTextZhuangTouShai(array, ctx); ExportRandNameFields(array, ctx); for (int j = 0; j < Locales.Count; j++) { string path = Locales[j]; string text = Path.Combine(outputRoot, "locales", path); Directory.CreateDirectory(text); string text2 = Path.Combine(text, "Vanilla.json"); using FileStream stream = new FileStream(text2, FileMode.Create, FileAccess.Write); using StreamWriter streamWriter = new StreamWriter(stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); JsonTextWriter val = new JsonTextWriter((TextWriter)streamWriter) { Formatting = (Formatting)1, Indentation = 2 }; try { ((JToken)array[j]).WriteTo((JsonWriter)(object)val); ctx.Print("已写出:" + text2, ConsoleLevel.Info); } finally { ((IDisposable)val)?.Dispose(); } } } private static void ExportAllTextNormalFields(JObject[] roots, CommandContext ctx) { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown List list = (from field in typeof(AllText).GetFields(BindingFlags.Static | BindingFlags.Public) where field.FieldType == typeof(List>) select field).ToList(); if (list.Count == 0) { ctx.Logger.LogWarning((object)"未能找到任何 AllText.List> 字段,AllText 可能尚未初始化"); return; } foreach (FieldInfo item in list) { string name = item.Name; List> list2 = (List>)item.GetValue(null); if (list2 == null) { continue; } JObject[] array = (JObject[])(object)new JObject[Locales.Count]; for (int i = 0; i < Locales.Count; i++) { array[i] = new JObject(); } for (int j = 0; j < list2.Count; j++) { List list3 = list2[j]; for (int k = 0; k < Locales.Count; k++) { string text = ((list3 != null && k < list3.Count) ? (list3[k] ?? string.Empty) : string.Empty); array[k][j.ToString()] = JToken.op_Implicit(text); } } for (int l = 0; l < Locales.Count; l++) { roots[l][name] = (JToken)(object)array[l]; } } ctx.Print($"已处理 AllText 普通字段:{list.Count} 个", ConsoleLevel.Info); } private static void ExportAllTextShenFen(JObject[] roots, CommandContext ctx) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown try { List>> text_AllShenFen = AllText.Text_AllShenFen; if (text_AllShenFen == null) { ctx.Logger.LogWarning((object)"Text_AllShenFen 为空,已跳过"); return; } JObject[] array = (JObject[])(object)new JObject[Locales.Count]; for (int i = 0; i < Locales.Count; i++) { array[i] = new JObject(); } for (int j = 0; j < text_AllShenFen.Count; j++) { List> list = text_AllShenFen[j]; JObject[] array2 = (JObject[])(object)new JObject[Locales.Count]; for (int k = 0; k < Locales.Count; k++) { array2[k] = new JObject(); } if (list != null) { for (int l = 0; l < list.Count; l++) { List list2 = list[l]; for (int m = 0; m < Locales.Count; m++) { string text = ((list2 != null && m < list2.Count) ? (list2[m] ?? string.Empty) : string.Empty); array2[m][l.ToString()] = JToken.op_Implicit(text); } } } for (int n = 0; n < Locales.Count; n++) { array[n][j.ToString()] = (JToken)(object)array2[n]; } } for (int num = 0; num < Locales.Count; num++) { roots[num]["Text_AllShenFen"] = (JToken)(object)array[num]; } ctx.Print("已处理 AllText 特殊字段:Text_AllShenFen", ConsoleLevel.Info); } catch (Exception ex) { ctx.Logger.LogWarning((object)("Text_AllShenFen 处理失败:" + ex.Message)); } } private static void ExportAllTextZhuangTouShai(JObject[] roots, CommandContext ctx) { try { List text_ZhuangTouShai = AllText.Text_ZhuangTouShai; if (text_ZhuangTouShai == null) { ctx.Logger.LogWarning((object)"Text_ZhuangTouShai 为空,已跳过"); return; } for (int i = 0; i < Locales.Count; i++) { string text = ((i < text_ZhuangTouShai.Count) ? (text_ZhuangTouShai[i] ?? string.Empty) : string.Empty); roots[i]["Text_ZhuangTouShai"] = JToken.op_Implicit(text); } ctx.Print("已处理 AllText 特殊字段:Text_ZhuangTouShai", ConsoleLevel.Info); } catch (Exception ex) { ctx.Logger.LogWarning((object)("Text_ZhuangTouShai 处理失败:" + ex.Message)); } } private static void ExportRandNameFields(JObject[] roots, CommandContext ctx) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown try { List list = (from field in typeof(RandName).GetFields(BindingFlags.Static | BindingFlags.Public) where field.FieldType == typeof(List) select field).ToList(); if (list.Count == 0) { ctx.Logger.LogWarning((object)"未能找到任何 RandName.List 字段,RandName 可能尚未初始化"); return; } JObject[] array = (JObject[])(object)new JObject[Locales.Count]; for (int i = 0; i < Locales.Count; i++) { array[i] = new JObject(); } foreach (FieldInfo item in list) { string name = item.Name; List list2 = (List)item.GetValue(null); JObject[] array2 = (JObject[])(object)new JObject[Locales.Count]; for (int j = 0; j < Locales.Count; j++) { array2[j] = new JObject(); } if (list2 != null) { for (int k = 0; k < list2.Count; k++) { string[] array3 = (list2[k] ?? string.Empty).Split(new char[1] { '|' }); for (int l = 0; l < Locales.Count; l++) { string text = ((l < array3.Length) ? (array3[l] ?? string.Empty) : string.Empty); array2[l][k.ToString()] = JToken.op_Implicit(text); } } } for (int m = 0; m < Locales.Count; m++) { array[m][name] = (JToken)(object)array2[m]; } } for (int n = 0; n < Locales.Count; n++) { roots[n]["RandName"] = (JToken)(object)array[n]; } ctx.Print($"已处理 RandName 字段:{list.Count} 个", ConsoleLevel.Info); } catch (Exception ex) { ctx.Logger.LogWarning((object)("RandName 导出失败:" + ex.Message)); } } } public static class BuildingCommands { private class DragRecord { public int BuildClassID { get; set; } public int BuildStateID { get; set; } public int MinPositionA { get; set; } public int MinPositionB { get; set; } public int MaxPositionA { get; set; } public int MaxPositionB { get; set; } public int TotalCollisions { get; set; } } public static void Register() { ConsoleAPI.RegisterCommand(new CommandDef("check-BuildingCollision", "[调试指令]依次加载已记录的所有建筑,统计其碰撞体积", "check-BuildingCollision", CalculateBuildingCollisions)); } public static string CalculateBuildingCollisions(CommandContext ctx, ParsedArgs _) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) try { List list = new List(); int count = Mainload.AllBuilddata.Count; ctx.Print($"{count} buildings found", ConsoleLevel.Info); for (int i = 0; i < count; i++) { for (int j = 0; j < 4; j++) { GameObject val = Resources.Load($"allbuild/0/scene/{i}/{j}"); if ((Object)(object)val == (Object)null) { break; } Transform val2 = val.transform.Find("UI/AllDrag"); List list2 = new List(); for (int num = val2.childCount - 1; num >= 0; num--) { Transform child = val2.GetChild(num); if (ParsePosition(((Object)child).name, out var position)) { list2.Add(position); } else { ctx.Logger.LogWarning((object)$"{i}/{j}: Invalid position format '{((Object)child).name}'"); } } if (list2.Count == 0) { ctx.Logger.LogWarning((object)$"{i}/{j}: No valid positions found"); } Vector2Int val3 = list2[0]; Vector2Int val4 = list2[0]; foreach (Vector2Int item2 in list2) { Vector2Int current = item2; if (((Vector2Int)(ref current)).x < ((Vector2Int)(ref val3)).x || (((Vector2Int)(ref current)).x == ((Vector2Int)(ref val3)).x && ((Vector2Int)(ref current)).y < ((Vector2Int)(ref val3)).y)) { val3 = current; } if (((Vector2Int)(ref current)).x > ((Vector2Int)(ref val4)).x || (((Vector2Int)(ref current)).x == ((Vector2Int)(ref val4)).x && ((Vector2Int)(ref current)).y > ((Vector2Int)(ref val4)).y)) { val4 = current; } } DragRecord item = new DragRecord { BuildClassID = i, BuildStateID = j, MinPositionA = ((Vector2Int)(ref val3)).x, MinPositionB = ((Vector2Int)(ref val3)).y, MaxPositionA = ((Vector2Int)(ref val4)).x, MaxPositionB = ((Vector2Int)(ref val4)).y, TotalCollisions = list2.Count }; list.Add(item); } } SaveToCSV(list); return "Done, csv saved"; } catch (Exception ex) { ctx.Logger.LogError((object)("Error: " + ex.Message)); return "Error:" + ex.Message; } } private static bool ParsePosition(string positionStr, out Vector2Int position) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) position = Vector2Int.zero; if (string.IsNullOrEmpty(positionStr)) { return false; } string[] array = positionStr.Split(new char[1] { '|' }); if (array.Length != 2) { return false; } if (!int.TryParse(array[0].Trim(), out var result) || !int.TryParse(array[1].Trim(), out var result2)) { return false; } position = new Vector2Int(result, result2); return true; } private static void SaveToCSV(List records) { string path = "Output/AllBuildingCollision_v" + Mainload.Vision_now.Substring(2) + ".csv"; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("buildClassID,buildStateID,minA,minB,maxA,maxB,totalCoordinates"); foreach (DragRecord record in records) { stringBuilder.AppendLine($"{record.BuildClassID},{record.BuildStateID},{record.MinPositionA},{record.MinPositionB},{record.MaxPositionA},{record.MaxPositionB},{record.TotalCollisions}"); } File.WriteAllText(path, stringBuilder.ToString()); } } public static class DebugCommands { public static void Register() { ConsoleAPI.RegisterCommand(new CommandDef("kill-TouMing", "[调试指令]删除本场景里所有建筑节点TouMing下属的对象(删除刚体,郡城无效)", "kill-TouMing", KillTouMingHandler)); ConsoleAPI.RegisterCommand(new CommandDef("kill-AllDrag", "[调试指令]删除本场景里所有建筑节点AllDrag下属的对象(删除刚体,郡城无效)", "kill-AllDrag", KillAllDragHandler)); ConsoleAPI.RegisterCommand(new CommandDef("kill-LineCollider", "[调试指令]删除本场景里所有建筑节点LineCollider下属的对象(删除刚体,郡城无效)", "kill-LineCollider", KillLineColliderHandler)); } public static string KillSomething(CommandContext ctx, string rmTarget) { GameObject val = GameObject.Find("AllBuild"); if ((Object)(object)val == (Object)null) { ctx.Logger.LogWarning((object)"[ClearTouMingChildren] Cannot find GameObject: AllBuild"); return "失败"; } Transform val2 = val.transform.Find("BackMap"); if ((Object)(object)val2 == (Object)null) { ctx.Logger.LogWarning((object)"[ClearTouMingChildren] Cannot find Transform: AllBuild/BackMap"); return "失败"; } if (val2.childCount < 1) { ctx.Logger.LogWarning((object)"[ClearTouMingChildren] BackMap has no child."); return "失败"; } if (val2.childCount > 1) { ctx.Logger.LogWarning((object)$"[ClearTouMingChildren] BackMap has {val2.childCount} children, expected 1. Will use the first."); } Transform child = val2.GetChild(0); Transform val3 = child.Find("BuildShow"); if ((Object)(object)val3 == (Object)null) { ctx.Logger.LogWarning((object)("[ClearTouMingChildren] Cannot find Transform: " + ((Object)child).name + "/BuildShow")); return "失败"; } int num = 0; int num2 = 0; for (int i = 0; i < val3.childCount; i++) { Transform child2 = val3.GetChild(i); if (child2.childCount < 1) { ctx.Logger.LogWarning((object)("[ClearTouMingChildren] Skip '" + ((Object)child2).name + "' because it has no child (expected 1).")); continue; } if (child2.childCount > 1) { ctx.Logger.LogWarning((object)$"[ClearTouMingChildren] '{((Object)child2).name}' has {child2.childCount} children, expected 1. Will use the first."); } Transform child3 = child2.GetChild(0); Transform val4 = child3.Find(rmTarget); if ((Object)(object)val4 == (Object)null) { ctx.Logger.LogInfo((object)("[ClearTouMingChildren] Not found UI/TouMing under: " + GetHierarchyPath(child3))); continue; } int num3 = DestroyAllChildren(val4); if (num3 > 0) { ctx.Logger.LogInfo((object)$"[ClearTouMingChildren] Cleared {num3} child(ren) under: {GetHierarchyPath(val4)}"); } num++; num2 += num3; } ctx.Logger.LogInfo((object)$"[ClearTouMingChildren] Done. TouMing found = {num}, children removed total = {num2}"); return $"成功移除{num2}个对象"; } public static string KillTouMingHandler(CommandContext ctx, ParsedArgs _) { return KillSomething(ctx, "UI/TouMing"); } public static string KillAllDragHandler(CommandContext ctx, ParsedArgs _) { return KillSomething(ctx, "UI/AllDrag"); } public static string KillLineColliderHandler(CommandContext ctx, ParsedArgs _) { return KillSomething(ctx, "LineCollider"); } private static int DestroyAllChildren(Transform parent) { if ((Object)(object)parent == (Object)null) { return 0; } int num = 0; for (int num2 = parent.childCount - 1; num2 >= 0; num2--) { Transform child = parent.GetChild(num2); if (!((Object)(object)child == (Object)null)) { Object.Destroy((Object)(object)((Component)child).gameObject); num++; } } return num; } private static string GetHierarchyPath(Transform t) { if ((Object)(object)t == (Object)null) { return "(null)"; } string text = ((Object)t).name; while ((Object)(object)t.parent != (Object)null) { t = t.parent; text = ((Object)t).name + "/" + text; } return text; } } internal static class PropCommands { private const int MAX_GIVE_COUNT = 10000000; public static void Register() { ConsoleAPI.RegisterCommand(new CommandDef("give", "Give a prop (default: no storage cost)", "give [Count] [--cost[=true|false]] [--silent|-s]", GiveHandler)); } private static string GiveHandler(CommandContext ctx, ParsedArgs args) { if (args.Positionals.Count < 1) { return "Usage: give [Count] [--cost[=true|false]] [--silent|-s]\nExample: give 12 5 --cost=true"; } if (!int.TryParse(args.Positionals[0], out var result)) { return "Invalid PropID: \"" + args.Positionals[0] + "\" (must be integer)"; } int result2 = 1; if (args.Positionals.Count >= 2 && !int.TryParse(args.Positionals[1], out result2)) { return "Invalid Count: \"" + args.Positionals[1] + "\" (must be integer)"; } if (result2 <= 0) { return "Count must be > 0"; } if (result2 > 10000000) { return $"Count too large (max {10000000})"; } bool flag = ResolveStorageFlag(args); bool flag2 = args.HasFlag("silent") || args.HasFlag("silence") || args.HasFlag("s"); bool flag3; try { flag3 = PropTool.AddProp(result, result2, flag, flag2); } catch (Exception ex) { ctx.Logger.LogError((object)ex); return "Fatal error: exception thrown by PropTool.AddProp"; } if (!flag3) { if (flag) { return $"Failed to add prop [{result}]*{result2} (invalid PropID or insufficient storage)"; } return $"Failed to add prop [{result}]*{result2} (invalid PropID)"; } return flag ? $"OK: added prop [{result}]*{result2} (storage consumed)" : $"OK: added prop [{result}]*{result2}"; } private static bool ResolveStorageFlag(ParsedArgs args) { if (args.HasFlag("cost")) { string flag = args.GetFlag("cost"); if (flag == null) { return false; } if (TryParseBoolLoose(flag, out var b)) { return b; } } return false; } private static bool TryParseBoolLoose(string s, out bool b) { s = s.Trim(); if (bool.TryParse(s, out b)) { return true; } switch (s.ToLowerInvariant()) { case "1": case "yes": case "y": case "on": b = true; return true; case "0": case "no": case "n": case "off": b = false; return true; default: b = false; return false; } } } public static class ConsoleAPI { private static Dictionary _commands = new Dictionary(StringComparer.OrdinalIgnoreCase); private static Dictionary _aliases = new Dictionary(StringComparer.OrdinalIgnoreCase); public static void RegisterCommand(ICommand cmd) { _commands[cmd.Name] = cmd; } public static bool UnregisterCommand(string name) { return _aliases.Remove(name) || _commands.Remove(name); } public static void RegisterAlias(string alias, string target) { _aliases[alias] = target; } public static bool TryResolveCommand(string name, out ICommand? cmd) { cmd = null; if (_aliases.TryGetValue(name, out string value)) { name = value; } return _commands.TryGetValue(name, out cmd); } public static ICommand? TryGetCommand(string name) { TryResolveCommand(name, out ICommand cmd); return cmd; } public static IEnumerable ListCommandNames() { return _commands.Keys; } } internal static class ConsoleCore { [CompilerGenerated] private sealed class d__8 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private string <>2__current; private int <>l__initialThreadId; private string text; public string <>3__text; private string[] 5__1; private string[] <>s__2; private int <>s__3; private string 5__4; string IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__8(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; <>s__2 = null; 5__4 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (string.IsNullOrEmpty(text)) { return false; } 5__1 = text.Replace("\r\n", "\n").Replace("\r", "\n").Split(new char[1] { '\n' }); <>s__2 = 5__1; <>s__3 = 0; break; case 1: <>1__state = -1; 5__4 = null; <>s__3++; break; } if (<>s__3 < <>s__2.Length) { 5__4 = <>s__2[<>s__3]; <>2__current = 5__4; <>1__state = 1; return true; } <>s__2 = null; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__8 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__8(0); } d__.text = <>3__text; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } private static IConsoleHost? _host; private static ManualLogSource? _logger; private static CommandContext? _context; public static bool IsInitialized => _host != null; public static void Initialize(IConsoleHost host, ManualLogSource logger) { _host = host; _logger = logger; CommandContext commandContext = new CommandContext(); commandContext.Logger = _logger; commandContext.Print = Print; _context = commandContext; } public static void Print(string text, ConsoleLevel level = ConsoleLevel.Info) { if (!IsInitialized) { return; } foreach (string item in SplitLines(text)) { _host.Enqueue(new ConsoleLine(level, item)); } } public static void Execute(string line) { Print("> " + line); if (!IsInitialized) { Print("ConsoleCore has not been initialized", ConsoleLevel.Error); return; } CommandLineParser.ParseResult parseResult = CommandLineParser.Parse(line); if (parseResult.Tokens.Count == 0) { return; } string text = parseResult.Tokens[0]; if (!ConsoleAPI.TryResolveCommand(text, out ICommand cmd) || cmd == null) { Print("Unknown command: " + text + " (type: help)"); return; } ParsedArgs arg = ParsedArgs.FromTokens(parseResult.Tokens.Skip(1).ToList()); try { string text2 = cmd.Handler(_context, arg) ?? ""; if (!string.IsNullOrWhiteSpace(text2)) { Print(text2); } } catch (Exception ex) { _logger.LogError((object)("Exception: " + ex.Message)); Print("Fatal error when running command.", ConsoleLevel.Error); } } [IteratorStateMachine(typeof(d__8))] private static IEnumerable SplitLines(string text) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__8(-2) { <>3__text = text }; } } public interface IConsoleHost { void Enqueue(ConsoleLine line); } public enum ConsoleLevel { Info, Warn, Error } public class ConsoleLine { public ConsoleLevel Level; public string Text; public ConsoleLine(ConsoleLevel level, string text) { Level = level; Text = text; } } public interface ICommand { string Name { get; } string Description { get; } string Usage { get; } bool Hidden { get; } Func Handler { get; } } public sealed class CommandDef : ICommand { public string Name { get; } public string Description { get; } public string Usage { get; } public bool Hidden { get; } public Func Handler { get; } public CommandDef(string name, string description, string usage, Func handler, bool hidden = false) { Name = name; Description = description; Usage = usage; Handler = handler; Hidden = hidden; } } public sealed class CommandContext { public ManualLogSource Logger = null; public Action Print = null; } public interface ICommandCompleter { Func> Complete { get; } } public sealed class CompletionContext { public string CommandName = ""; public string FullInput = ""; public List Tokens = new List(); public string Seed = ""; public int TokenIndex; public bool CompletingCommandName; } public sealed class ParsedArgs { public readonly List Positionals = new List(); public readonly Dictionary Flags = new Dictionary(StringComparer.OrdinalIgnoreCase); public bool HasFlag(string key) { return Flags.ContainsKey(key); } public string? GetFlag(string key, string? defaultValue = null) { string value; return Flags.TryGetValue(key, out value) ? value : defaultValue; } public int GetInt(string key, int defaultValue = 0) { int result; return int.TryParse(GetFlag(key), out result) ? result : defaultValue; } public float GetFloat(string key, float defaultValue = 0f) { float result; return float.TryParse(GetFlag(key), out result) ? result : defaultValue; } private static bool LooksLikeShortFlag(string token) { if (token.Length < 2 || token[0] != '-') { return false; } if (token == "-") { return false; } if (char.IsDigit(token[1])) { return false; } return true; } private static bool LooksLikeLongFlag(string token) { if (!token.StartsWith("--", StringComparison.Ordinal) || token.Length <= 2) { return false; } if (char.IsDigit(token[2])) { return false; } return true; } public static ParsedArgs FromTokens(IReadOnlyList tokens) { ParsedArgs parsedArgs = new ParsedArgs(); for (int i = 0; i < tokens.Count; i++) { string text = tokens[i]; if ((LooksLikeLongFlag(text) || LooksLikeShortFlag(text)) && text.Contains("=")) { int num = text.IndexOf('='); string key = text.Substring(0, num).TrimStart(new char[1] { '-' }); string value = text.Substring(num + 1); parsedArgs.Flags[key] = value; } else if (LooksLikeLongFlag(text)) { string key2 = text.Substring(2); string value2 = null; if (i + 1 < tokens.Count && !LooksLikeLongFlag(tokens[i + 1]) && !LooksLikeShortFlag(tokens[i + 1])) { value2 = tokens[i + 1]; i++; } parsedArgs.Flags[key2] = value2; } else if (LooksLikeShortFlag(text)) { string key3 = text.Substring(1); string value3 = null; if (i + 1 < tokens.Count && !LooksLikeLongFlag(tokens[i + 1]) && !LooksLikeShortFlag(tokens[i + 1])) { value3 = tokens[i + 1]; i++; } parsedArgs.Flags[key3] = value3; } else { parsedArgs.Positionals.Add(text); } } return parsedArgs; } } public static class CommandLineParser { public sealed class ParseResult { public readonly List Tokens = new List(); } public sealed class CompletionSplit { public readonly List Tokens = new List(); public bool HasTrailingSpace; public int TokenCount => Tokens.Count; public string LastToken => (Tokens.Count == 0) ? "" : Tokens.Last(); } [CompilerGenerated] private sealed class d__4 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private string <>2__current; private int <>l__initialThreadId; private string input; public string <>3__input; private StringBuilder 5__1; private bool 5__2; private char 5__3; private int 5__4; private char 5__5; private char 5__6; string IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__4(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (string.IsNullOrEmpty(input)) { return false; } 5__1 = new StringBuilder(); 5__2 = false; 5__3 = '"'; 5__4 = 0; goto IL_026d; case 1: <>1__state = -1; 5__1.Clear(); goto IL_025b; case 2: { <>1__state = -1; break; } IL_025b: 5__4++; goto IL_026d; IL_01e1: if (!5__2 && (5__5 == '"' || 5__5 == '\'')) { 5__2 = true; 5__3 = 5__5; } else if (5__2 && 5__5 == 5__3) { 5__2 = false; } else { 5__1.Append(5__5); } goto IL_025b; IL_026d: if (5__4 < input.Length) { 5__5 = input[5__4]; if (!5__2 && char.IsWhiteSpace(5__5)) { if (5__1.Length > 0) { <>2__current = 5__1.ToString(); <>1__state = 1; return true; } } else { if (5__5 != '\\' || 5__4 + 1 >= input.Length) { goto IL_01e1; } 5__6 = input[5__4 + 1]; if (5__6 == '"' || 5__6 == '\'' || 5__6 == '\\') { 5__1.Append(5__6); 5__4++; } else if (5__6 == 'n') { 5__1.Append('\n'); 5__4++; } else { if (5__6 != 't') { goto IL_01e1; } 5__1.Append('\t'); 5__4++; } } goto IL_025b; } if (5__1.Length > 0) { <>2__current = 5__1.ToString(); <>1__state = 2; return true; } break; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__4 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__4(0); } d__.input = <>3__input; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public static ParseResult Parse(string input) { ParseResult parseResult = new ParseResult(); foreach (string item in Tokenize(input)) { parseResult.Tokens.Add(item); } return parseResult; } public static CompletionSplit SplitForCompletion(string input) { CompletionSplit completionSplit = new CompletionSplit { HasTrailingSpace = (input.Length > 0 && char.IsWhiteSpace(input.Last())) }; foreach (string item in Tokenize(input)) { completionSplit.Tokens.Add(item); } return completionSplit; } [IteratorStateMachine(typeof(d__4))] private static IEnumerable Tokenize(string input) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__4(-2) { <>3__input = input }; } } [BepInDependency("cc.lymone.HoL.YuanAPI", "0.1.2")] [BepInPlugin("cc.lymone.HoL.HoLConsole", "HoLConsole", "1.1.0")] public class ConsolePlugin : BaseUnityPlugin, IConsoleHost { public const string MODNAME = "HoLConsole"; public const string MODGUID = "cc.lymone.HoL.HoLConsole"; public const string VERSION = "1.1.0"; internal static ManualLogSource Logger; private ConfigEntry _toggleKey = null; private ConfigEntry _maxOutputLines = null; private ConfigEntry _maxInputHistory = null; private ConfigEntry _startOpen = null; private bool _visible; private Rect _windowRect = new Rect(40f, 40f, 760f, 420f); private float _uiScale = 1f; private const float BASE_WIDTH = 1920f; private const float BASE_HEIGHT = 1080f; private Vector2 _scrollPos; private bool _shouldScrollToBottom; private float _lastScrollViewHeight; private string _input = ""; private int _focusInputCounter; private readonly List _outputLines = new List(); private readonly ConcurrentQueue _pendingLines = new ConcurrentQueue(); private readonly List _inputHistory = new List(); private int _historyIndex = -1; private string _historyStash = ""; private string[] _candidates = Array.Empty(); private int _candidateIndex = -1; private string _sessionKey = ""; private const string INPUT_CONTROL_NAME = "HoLConsole_Input"; private GUIStyle _styleInfo = null; private GUIStyle _styleWarn = null; private GUIStyle _styleError = null; private GUIStyle _styleWindow = null; private GUIStyle _styleTextField = null; private GUIStyle _stylePrompt = null; private Texture2D _bgTexture = null; private Texture2D _inputBgTexture = null; private void Awake() { //IL_0102: Unknown result type (might be due to invalid IL or missing references) Logger = ((BaseUnityPlugin)this).Logger; _toggleKey = ((BaseUnityPlugin)this).Config.Bind("按键绑定 Bind Key", "命令行热键 Toggle Key", (KeyCode)96, "唤醒命令行窗口\nKey to toggle the console window."); _maxOutputLines = ((BaseUnityPlugin)this).Config.Bind("配置 Config", "最大输出行数 Max Output Lines", 600, (ConfigDescription)null); _maxInputHistory = ((BaseUnityPlugin)this).Config.Bind("配置 Config", "最大输入历史 Max Input History", 200, (ConfigDescription)null); _startOpen = ((BaseUnityPlugin)this).Config.Bind("配置 Config", "启动时开启命令行 Start Open", false, (ConfigDescription)null); _visible = _startOpen.Value; ConsoleCore.Initialize(this, Logger); RegisterBuiltinCommands(); ConsoleCore.Print("______________________________________________________"); ConsoleCore.Print("HoLConsole v1.1.0"); ConsoleCore.Print("Copyright (c) 2026 LymoneLM | MIT Licensed Open Source"); ConsoleCore.Print("GitHub Repository: https://github.com/LymoneLM/HoLMods"); ConsoleCore.Print("______________________________________________________"); Logger.LogInfo((object)string.Format("{0} ready. Press [{1}] to open.", "HoLConsole", _toggleKey.Value)); } private void Update() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) float num = (float)Screen.width / 1920f; float num2 = (float)Screen.height / 1080f; _uiScale = Mathf.Min(num, num2); _uiScale = Mathf.Clamp(_uiScale, 0.5f, 2f); if (Input.GetKeyDown(_toggleKey.Value)) { _visible = !_visible; if (_visible) { _focusInputCounter = 2; } } if (_visible && Input.GetKeyDown((KeyCode)27)) { _visible = false; } int num3 = 0; ConsoleLine result; while (_pendingLines.TryDequeue(out result)) { _outputLines.Add(result); num3++; } if (_outputLines.Count > _maxOutputLines.Value) { int count = _outputLines.Count - _maxOutputLines.Value; _outputLines.RemoveRange(0, count); } if (num3 > 0 && IsNearBottom()) { _shouldScrollToBottom = true; } } private void OnGUI() { //IL_0013: 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) //IL_002a: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) if (_visible) { Matrix4x4 matrix = GUI.matrix; GUI.matrix = Matrix4x4.Scale(new Vector3(_uiScale, _uiScale, 1f)); EnsureStyles(); GUI.depth = 0; Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref _windowRect)).x / _uiScale, ((Rect)(ref _windowRect)).y / _uiScale, ((Rect)(ref _windowRect)).width / _uiScale, ((Rect)(ref _windowRect)).height / _uiScale); val = GUILayout.Window(((Object)this).GetInstanceID(), val, new WindowFunction(DrawWindow), "HoLConsole v1.1.0", _styleWindow, Array.Empty()); _windowRect = new Rect(((Rect)(ref val)).x * _uiScale, ((Rect)(ref val)).y * _uiScale, ((Rect)(ref val)).width * _uiScale, ((Rect)(ref val)).height * _uiScale); GUI.matrix = matrix; } } private Texture2D MakeTex(int width, int height, Color col) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown Color[] array = (Color[])(object)new Color[width * height]; for (int i = 0; i < array.Length; i++) { array[i] = col; } Texture2D val = new Texture2D(width, height); val.SetPixels(array); val.Apply(); return val; } private void EnsureStyles() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown //IL_0104: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Expected O, but got Unknown //IL_01c9: Expected O, but got Unknown //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Expected O, but got Unknown //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Expected O, but got Unknown //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Expected O, but got Unknown //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Expected O, but got Unknown //IL_028d: Expected O, but got Unknown //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Expected O, but got Unknown //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Expected O, but got Unknown if (_styleInfo == null) { _bgTexture = MakeTex(2, 2, new Color(0.08f, 0.08f, 0.08f, 0.92f)); _inputBgTexture = MakeTex(2, 2, new Color(0.12f, 0.12f, 0.12f, 0.95f)); GUIStyle val = new GUIStyle(GUI.skin.window); val.normal.background = _bgTexture; val.normal.textColor = new Color(0.85f, 0.85f, 0.85f); val.onNormal.background = _bgTexture; val.onNormal.textColor = new Color(0.85f, 0.85f, 0.85f); val.fontSize = 14; val.padding = new RectOffset(8, 8, 24, 8); val.border = new RectOffset(2, 2, 2, 2); _styleWindow = val; GUIStyle val2 = new GUIStyle(GUI.skin.textField); val2.normal.textColor = new Color(0.9f, 0.9f, 0.9f); val2.normal.background = _inputBgTexture; val2.hover.textColor = new Color(0.9f, 0.9f, 0.9f); val2.hover.background = _inputBgTexture; val2.focused.textColor = Color.white; val2.focused.background = _inputBgTexture; val2.fontSize = 15; val2.padding = new RectOffset(4, 4, 4, 4); val2.border = new RectOffset(0, 0, 0, 0); _styleTextField = val2; GUIStyle val3 = new GUIStyle(GUI.skin.label) { fontSize = 15, fontStyle = (FontStyle)1 }; val3.normal.textColor = new Color(0.5f, 0.9f, 0.5f); val3.padding = new RectOffset(0, 4, 4, 4); val3.alignment = (TextAnchor)4; _stylePrompt = val3; GUIStyle val4 = new GUIStyle(GUI.skin.label) { wordWrap = true, fontSize = 15 }; val4.normal.textColor = new Color(0.85f, 0.85f, 0.85f); val4.padding = new RectOffset(2, 2, 1, 1); val4.margin = new RectOffset(0, 0, 0, 0); _styleInfo = val4; GUIStyle val5 = new GUIStyle(_styleInfo); val5.normal.textColor = new Color(1f, 0.85f, 0.3f); _styleWarn = val5; GUIStyle val6 = new GUIStyle(_styleInfo); val6.normal.textColor = new Color(1f, 0.4f, 0.4f); _styleError = val6; } } private void DrawWindow(int windowId) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginVertical(Array.Empty()); DrawOutputArea(); DrawInputArea(); GUILayout.EndVertical(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f)); } private void DrawOutputArea() { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Invalid comparison between Unknown and I4 //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) _scrollPos = GUILayout.BeginScrollView(_scrollPos, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); foreach (ConsoleLine outputLine in _outputLines) { GUILayout.Label(outputLine.Text, StyleFor(outputLine.Level), Array.Empty()); } GUILayout.EndScrollView(); if ((int)Event.current.type == 7) { Rect lastRect = GUILayoutUtility.GetLastRect(); _lastScrollViewHeight = ((Rect)(ref lastRect)).height; } if (_shouldScrollToBottom) { _scrollPos.y = float.MaxValue; _shouldScrollToBottom = false; } GUILayout.Space(4f); } private void DrawInputArea() { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Invalid comparison between Unknown and I4 //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Invalid comparison between Unknown and I4 //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown HandleInputEvents(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(">", _stylePrompt, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(20f) }); GUI.SetNextControlName("HoLConsole_Input"); _input = GUILayout.TextField(_input, _styleTextField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.EndHorizontal(); if (_focusInputCounter <= 0) { return; } if ((int)Event.current.type == 8) { GUI.FocusControl("HoLConsole_Input"); } else if ((int)Event.current.type == 7) { _focusInputCounter--; TextEditor val = (TextEditor)GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl); if (val != null) { val.text = _input ?? ""; int selectIndex = (val.cursorIndex = val.text.Length); val.selectIndex = selectIndex; } } } private GUIStyle StyleFor(ConsoleLevel lvl) { if (1 == 0) { } GUIStyle result = (GUIStyle)(lvl switch { ConsoleLevel.Warn => _styleWarn, ConsoleLevel.Error => _styleError, _ => _styleInfo, }); if (1 == 0) { } return result; } public void Enqueue(ConsoleLine line) { _pendingLines.Enqueue(line); } private void HandleInputEvents() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Invalid comparison between Unknown and I4 //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Invalid comparison between Unknown and I4 //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Invalid comparison between Unknown and I4 //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Invalid comparison between Unknown and I4 //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Invalid comparison between Unknown and I4 //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Invalid comparison between Unknown and I4 //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Invalid comparison between Unknown and I4 Event current = Event.current; if (current == null || GUI.GetNameOfFocusedControl() != "HoLConsole_Input" || (int)current.type != 4) { return; } if ((int)current.keyCode == 13 || (int)current.keyCode == 271) { current.Use(); string text = _input.Trim(); if (text.Length > 0) { PushInputHistory(text); ConsoleCore.Execute(text); if (IsNearBottom()) { _shouldScrollToBottom = true; } } _input = ""; ResetHistoryNav(); ResetAutocomplete(); _focusInputCounter = 2; } else if ((int)current.keyCode == 273) { current.Use(); if (_inputHistory.Count != 0) { if (_historyIndex < 0) { _historyStash = _input; _historyIndex = _inputHistory.Count - 1; } else { _historyIndex = Mathf.Clamp(_historyIndex - 1, 0, _inputHistory.Count - 1); } _input = _inputHistory[_historyIndex]; ResetAutocomplete(); _focusInputCounter = 2; } } else if ((int)current.keyCode == 274) { current.Use(); if (_inputHistory.Count != 0 && _historyIndex >= 0) { _historyIndex++; if (_historyIndex >= _inputHistory.Count) { _historyIndex = -1; _input = _historyStash; } else { _input = _inputHistory[_historyIndex]; } ResetAutocomplete(); _focusInputCounter = 2; } } else if ((int)current.keyCode == 9) { current.Use(); bool shift = current.shift; ApplyAutocomplete(shift); _focusInputCounter = 2; } else if ((int)current.keyCode == 27) { current.Use(); _visible = false; } else if ((int)current.keyCode != 276 && (int)current.keyCode != 275) { ResetAutocomplete(); } } private void PushInputHistory(string line) { if (_inputHistory.Count == 0 || _inputHistory.Last() != line) { _inputHistory.Add(line); } while (_inputHistory.Count > _maxInputHistory.Value) { _inputHistory.RemoveAt(0); } } private void ResetHistoryNav() { _historyIndex = -1; _historyStash = ""; } private bool IsNearBottom() { if (_scrollPos.y >= 10000000f) { return true; } if (_lastScrollViewHeight <= 0f) { return true; } return _scrollPos.y > 100000f; } private void ResetAutocomplete() { _candidates = Array.Empty(); _candidateIndex = -1; _sessionKey = ""; } private void ApplyAutocomplete(bool reverse) { string input = _input; CommandLineParser.CompletionSplit completionSplit = CommandLineParser.SplitForCompletion(input); bool hasTrailingSpace = completionSplit.HasTrailingSpace; int num = (hasTrailingSpace ? completionSplit.Tokens.Count : Math.Max(0, completionSplit.Tokens.Count - 1)); string text = ((completionSplit.Tokens.Count > 0) ? completionSplit.Tokens[0] : ""); bool flag = completionSplit.Tokens.Count == 0 || num == 0; string text2 = ""; if (!hasTrailingSpace && completionSplit.Tokens.Count > 0) { text2 = completionSplit.LastToken; } string text3 = $"{text}|{num}|{text2}|{(hasTrailingSpace ? 1 : 0)}|{(flag ? 1 : 0)}"; if (_sessionKey != text3) { _sessionKey = text3; _candidateIndex = (reverse ? int.MaxValue : (-1)); _candidates = BuildCandidates(input, completionSplit, text, num, flag, text2).ToArray(); } if (_candidates.Length != 0) { if (!reverse) { _candidateIndex = (_candidateIndex + 1) % _candidates.Length; } else { _candidateIndex = (_candidateIndex - 1 + _candidates.Length) % _candidates.Length; } string picked = _candidates[_candidateIndex]; ApplyCandidateToInput(input, completionSplit, num, hasTrailingSpace, picked); } } private IEnumerable BuildCandidates(string fullInput, CommandLineParser.CompletionSplit split, string cmdName, int tokenIndex, bool completingCommandName, string seed) { string seed2 = seed; if (completingCommandName) { IEnumerable source = ConsoleAPI.ListCommandNames(); return from n in source where n.StartsWith(seed2, StringComparison.OrdinalIgnoreCase) orderby n select n; } ICommand command = ConsoleAPI.TryGetCommand(cmdName); if (command is ICommandCompleter commandCompleter) { CompletionContext arg = new CompletionContext { CommandName = cmdName, FullInput = fullInput, Tokens = split.Tokens.ToList(), Seed = seed2, TokenIndex = tokenIndex, CompletingCommandName = false }; return from s in (from s in commandCompleter.Complete(arg) where !string.IsNullOrWhiteSpace(s) select s).Distinct(StringComparer.OrdinalIgnoreCase) orderby s select s; } return Array.Empty(); } private void ApplyCandidateToInput(string current, CommandLineParser.CompletionSplit split, int tokenIndex, bool completingNewToken, string picked) { if (completingNewToken) { _input = current + picked + " "; return; } if (split.Tokens.Count == 0) { _input = picked + " "; return; } string lastToken = split.LastToken; if (lastToken.Length == 0) { _input = current + picked; return; } string text = current.Substring(0, current.Length - lastToken.Length); _input = text + picked; if (tokenIndex == 0) { _input += " "; } } private void RegisterBuiltinCommands() { ConsoleAPI.RegisterCommand(new CommandDef("help", "List commands or show help for a command.", "help [command]", delegate(CommandContext _, ParsedArgs args) { if (args.Positionals.Count == 0) { string[] array = (from x in ConsoleAPI.ListCommandNames() orderby x select x).ToArray(); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Commands:"); string[] array2 = array; foreach (string text in array2) { ICommand command = ConsoleAPI.TryGetCommand(text); if (command != null && !command.Hidden) { stringBuilder.AppendLine(" " + text + " - " + command.Description); } } stringBuilder.AppendLine("Type: help for details."); return stringBuilder.ToString().TrimEnd(Array.Empty()); } string text2 = args.Positionals[0]; ICommand command2 = ConsoleAPI.TryGetCommand(text2); return (command2 == null) ? ("Unknown command: " + text2) : (command2.Name + "\n " + command2.Description + "\nUsage: " + command2.Usage); })); ConsoleAPI.RegisterCommand(new CommandDef("echo", "Print text.", "echo ", (CommandContext _, ParsedArgs args) => string.Join(" ", args.Positionals))); ConsoleAPI.RegisterCommand(new CommandDef("clear", "Clear console output.", "clear", delegate { _outputLines.Clear(); _shouldScrollToBottom = true; return ""; })); ConsoleAPI.RegisterAlias("cls", "clear"); PropCommands.Register(); DebugCommands.Register(); BuildingCommands.Register(); AllTextExporter.Register(); } } }