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+df21115ffbacf6c2cb7f26d9ecda508690c44441")]
[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<string> Locales = new List<string>(2) { "zh-CN", "en-US" };
private const string VanillaNamespace = "Vanilla";
public static void Register()
{
ConsoleAPI.RegisterCommand(new CommandDef("export-AllText", "[调试指令]将游戏内置的 AllText 原版文本导出为符合YuanAPI格式的嵌套 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_042b: Unknown result type (might be due to invalid IL or missing references)
//IL_0430: Unknown result type (might be due to invalid IL or missing references)
//IL_0438: Unknown result type (might be due to invalid IL or missing references)
//IL_0442: Expected O, but got Unknown
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Expected O, but got Unknown
//IL_0219: Unknown result type (might be due to invalid IL or missing references)
//IL_021f: Expected O, but got Unknown
//IL_0267: Unknown result type (might be due to invalid IL or missing references)
//IL_026d: 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();
}
List<FieldInfo> list = (from f in typeof(AllText).GetFields(BindingFlags.Static | BindingFlags.Public)
where f.FieldType == typeof(List<List<string>>)
select f).ToList();
if (list.Count == 0)
{
ctx.Logger.LogWarning((object)"未能找到任何 List<List<string>> 字段,AllText 可能尚未初始化");
}
foreach (FieldInfo item in list)
{
string name = item.Name;
List<List<string>> list2 = (List<List<string>>)item.GetValue(null);
JObject[] array2 = (JObject[])(object)new JObject[Locales.Count];
for (int j = 0; j < Locales.Count; j++)
{
array2[j] = new JObject();
}
for (int k = 0; k < list2.Count; k++)
{
List<string> list3 = list2[k];
for (int l = 0; l < Locales.Count; l++)
{
string text = ((list3 != null && l < list3.Count) ? (list3[l] ?? "") : "");
array2[l][k.ToString()] = JToken.op_Implicit(text);
}
}
for (int m = 0; m < Locales.Count; m++)
{
array[m][name] = (JToken)(object)array2[m];
}
}
ctx.Print($"已处理 {list.Count} 个普通字段", ConsoleLevel.Info);
try
{
List<List<List<string>>> text_AllShenFen = AllText.Text_AllShenFen;
JObject[] array3 = (JObject[])(object)new JObject[Locales.Count];
for (int n = 0; n < Locales.Count; n++)
{
array3[n] = new JObject();
}
for (int num = 0; num < text_AllShenFen.Count; num++)
{
List<List<string>> list4 = text_AllShenFen[num];
JObject[] array4 = (JObject[])(object)new JObject[Locales.Count];
for (int num2 = 0; num2 < Locales.Count; num2++)
{
array4[num2] = new JObject();
}
for (int num3 = 0; num3 < list4.Count; num3++)
{
List<string> list5 = list4[num3];
for (int num4 = 0; num4 < Locales.Count; num4++)
{
string text2 = ((list5 != null && num4 < list5.Count) ? (list5[num4] ?? "") : "");
array4[num4][num3.ToString()] = JToken.op_Implicit(text2);
}
}
for (int num5 = 0; num5 < Locales.Count; num5++)
{
array3[num5][num.ToString()] = (JToken)(object)array4[num5];
}
}
for (int num6 = 0; num6 < Locales.Count; num6++)
{
array[num6]["Text_AllShenFen"] = (JToken)(object)array3[num6];
}
ctx.Print("已处理特殊字段 Text_AllShenFen", ConsoleLevel.Info);
}
catch (Exception ex)
{
ctx.Logger.LogWarning((object)("Text_AllShenFen 处理失败:" + ex.Message));
}
for (int num7 = 0; num7 < Locales.Count; num7++)
{
string path = Locales[num7];
string text3 = Path.Combine(outputRoot, "locales", path);
Directory.CreateDirectory(text3);
string text4 = Path.Combine(text3, "Vanilla.json");
using FileStream stream = new FileStream(text4, 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[num7]).WriteTo((JsonWriter)(object)val);
ctx.Print("已写出:" + text4, ConsoleLevel.Info);
}
finally
{
((IDisposable)val)?.Dispose();
}
}
}
}
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<DragRecord> list = new List<DragRecord>();
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<GameObject>($"allbuild/0/scene/{i}/{j}");
if ((Object)(object)val == (Object)null)
{
break;
}
Transform val2 = val.transform.Find("UI/AllDrag");
List<Vector2Int> list2 = new List<Vector2Int>();
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<DragRecord> 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 <PropID> [Count] [--cost[=true|false]] [--silent|-s]", GiveHandler));
}
private static string GiveHandler(CommandContext ctx, ParsedArgs args)
{
if (args.Positionals.Count < 1)
{
return "Usage: give <PropID> [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<string, ICommand> _commands = new Dictionary<string, ICommand>(StringComparer.OrdinalIgnoreCase);
private static Dictionary<string, string> _aliases = new Dictionary<string, string>(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<string> ListCommandNames()
{
return _commands.Keys;
}
}
internal static class ConsoleCore
{
[CompilerGenerated]
private sealed class <SplitLines>d__8 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IEnumerator, IDisposable
{
private int <>1__state;
private string <>2__current;
private int <>l__initialThreadId;
private string text;
public string <>3__text;
private string[] <arr>5__1;
private string[] <>s__2;
private int <>s__3;
private string <s>5__4;
string IEnumerator<string>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <SplitLines>d__8(int <>1__state)
{
this.<>1__state = <>1__state;
<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<arr>5__1 = null;
<>s__2 = null;
<s>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;
}
<arr>5__1 = text.Replace("\r\n", "\n").Replace("\r", "\n").Split(new char[1] { '\n' });
<>s__2 = <arr>5__1;
<>s__3 = 0;
break;
case 1:
<>1__state = -1;
<s>5__4 = null;
<>s__3++;
break;
}
if (<>s__3 < <>s__2.Length)
{
<s>5__4 = <>s__2[<>s__3];
<>2__current = <s>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<string> IEnumerable<string>.GetEnumerator()
{
<SplitLines>d__8 <SplitLines>d__;
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
<SplitLines>d__ = this;
}
else
{
<SplitLines>d__ = new <SplitLines>d__8(0);
}
<SplitLines>d__.text = <>3__text;
return <SplitLines>d__;
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<string>)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(<SplitLines>d__8))]
private static IEnumerable<string> SplitLines(string text)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <SplitLines>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<CommandContext, ParsedArgs, string?> 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<CommandContext, ParsedArgs, string?> Handler { get; }
public CommandDef(string name, string description, string usage, Func<CommandContext, ParsedArgs, string?> handler, bool hidden = false)
{
Name = name;
Description = description;
Usage = usage;
Handler = handler;
Hidden = hidden;
}
}
public sealed class CommandContext
{
public ManualLogSource Logger = null;
public Action<string, ConsoleLevel> Print = null;
}
public interface ICommandCompleter
{
Func<CompletionContext, IEnumerable<string>> Complete { get; }
}
public sealed class CompletionContext
{
public string CommandName = "";
public string FullInput = "";
public List<string> Tokens = new List<string>();
public string Seed = "";
public int TokenIndex;
public bool CompletingCommandName;
}
public sealed class ParsedArgs
{
public readonly List<string> Positionals = new List<string>();
public readonly Dictionary<string, string?> Flags = new Dictionary<string, string>(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<string> 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<string> Tokens = new List<string>();
}
public sealed class CompletionSplit
{
public readonly List<string> Tokens = new List<string>();
public bool HasTrailingSpace;
public int TokenCount => Tokens.Count;
public string LastToken => (Tokens.Count == 0) ? "" : Tokens.Last();
}
[CompilerGenerated]
private sealed class <Tokenize>d__4 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IEnumerator, IDisposable
{
private int <>1__state;
private string <>2__current;
private int <>l__initialThreadId;
private string input;
public string <>3__input;
private StringBuilder <sb>5__1;
private bool <inQuotes>5__2;
private char <quoteChar>5__3;
private int <i>5__4;
private char <c>5__5;
private char <n>5__6;
string IEnumerator<string>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <Tokenize>d__4(int <>1__state)
{
this.<>1__state = <>1__state;
<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<sb>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;
}
<sb>5__1 = new StringBuilder();
<inQuotes>5__2 = false;
<quoteChar>5__3 = '"';
<i>5__4 = 0;
goto IL_026d;
case 1:
<>1__state = -1;
<sb>5__1.Clear();
goto IL_025b;
case 2:
{
<>1__state = -1;
break;
}
IL_025b:
<i>5__4++;
goto IL_026d;
IL_01e1:
if (!<inQuotes>5__2 && (<c>5__5 == '"' || <c>5__5 == '\''))
{
<inQuotes>5__2 = true;
<quoteChar>5__3 = <c>5__5;
}
else if (<inQuotes>5__2 && <c>5__5 == <quoteChar>5__3)
{
<inQuotes>5__2 = false;
}
else
{
<sb>5__1.Append(<c>5__5);
}
goto IL_025b;
IL_026d:
if (<i>5__4 < input.Length)
{
<c>5__5 = input[<i>5__4];
if (!<inQuotes>5__2 && char.IsWhiteSpace(<c>5__5))
{
if (<sb>5__1.Length > 0)
{
<>2__current = <sb>5__1.ToString();
<>1__state = 1;
return true;
}
}
else
{
if (<c>5__5 != '\\' || <i>5__4 + 1 >= input.Length)
{
goto IL_01e1;
}
<n>5__6 = input[<i>5__4 + 1];
if (<n>5__6 == '"' || <n>5__6 == '\'' || <n>5__6 == '\\')
{
<sb>5__1.Append(<n>5__6);
<i>5__4++;
}
else if (<n>5__6 == 'n')
{
<sb>5__1.Append('\n');
<i>5__4++;
}
else
{
if (<n>5__6 != 't')
{
goto IL_01e1;
}
<sb>5__1.Append('\t');
<i>5__4++;
}
}
goto IL_025b;
}
if (<sb>5__1.Length > 0)
{
<>2__current = <sb>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<string> IEnumerable<string>.GetEnumerator()
{
<Tokenize>d__4 <Tokenize>d__;
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
<Tokenize>d__ = this;
}
else
{
<Tokenize>d__ = new <Tokenize>d__4(0);
}
<Tokenize>d__.input = <>3__input;
return <Tokenize>d__;
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<string>)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(<Tokenize>d__4))]
private static IEnumerable<string> Tokenize(string input)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <Tokenize>d__4(-2)
{
<>3__input = input
};
}
}
[BepInDependency("cc.lymone.HoL.YuanAPI", "0.1.2")]
[BepInPlugin("cc.lymone.HoL.HoLConsole", "HoLConsole", "1.0.0")]
public class ConsolePlugin : BaseUnityPlugin, IConsoleHost
{
public const string MODNAME = "HoLConsole";
public const string MODGUID = "cc.lymone.HoL.HoLConsole";
public const string VERSION = "1.0.0";
internal static ManualLogSource Logger;
private ConfigEntry<KeyCode> _toggleKey = null;
private ConfigEntry<int> _maxOutputLines = null;
private ConfigEntry<int> _maxInputHistory = null;
private ConfigEntry<bool> _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<ConsoleLine> _outputLines = new List<ConsoleLine>();
private readonly ConcurrentQueue<ConsoleLine> _pendingLines = new ConcurrentQueue<ConsoleLine>();
private readonly List<string> _inputHistory = new List<string>();
private int _historyIndex = -1;
private string _historyStash = "";
private string[] _candidates = Array.Empty<string>();
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<KeyCode>("按键绑定 Bind Key", "命令行热键 Toggle Key", (KeyCode)96, "唤醒命令行窗口\nKey to toggle the console window.");
_maxOutputLines = ((BaseUnityPlugin)this).Config.Bind<int>("配置 Config", "最大输出行数 Max Output Lines", 600, (ConfigDescription)null);
_maxInputHistory = ((BaseUnityPlugin)this).Config.Bind<int>("配置 Config", "最大输入历史 Max Input History", 200, (ConfigDescription)null);
_startOpen = ((BaseUnityPlugin)this).Config.Bind<bool>("配置 Config", "启动时开启命令行 Start Open", false, (ConfigDescription)null);
_visible = _startOpen.Value;
ConsoleCore.Initialize(this, Logger);
RegisterBuiltinCommands();
ConsoleCore.Print("______________________________________________________");
ConsoleCore.Print("HoLConsole v1.0.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.0.0", _styleWindow, Array.Empty<GUILayoutOption>());
_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<GUILayoutOption>());
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<GUILayoutOption>());
}
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<GUILayoutOption>());
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<string>();
_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<string> BuildCandidates(string fullInput, CommandLineParser.CompletionSplit split, string cmdName, int tokenIndex, bool completingCommandName, string seed)
{
string seed2 = seed;
if (completingCommandName)
{
IEnumerable<string> 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<string>(StringComparer.OrdinalIgnoreCase)
orderby s
select s;
}
return Array.Empty<string>();
}
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 <command> for details.");
return stringBuilder.ToString().TrimEnd(Array.Empty<char>());
}
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 <text...>", (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();
}
}
}