Decompiled source of HoLConsole v1.0.1

BepInEx/plugins/HoLConsole.dll

Decompiled 2 weeks ago
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();
		}
	}
}