Decompiled source of TerminalCompletion v1.3.0

TerminalCompletion.dll

Decompiled a month ago
using System;
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.RegularExpressions;
using AIGraph;
using Agents;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Microsoft.CodeAnalysis;
using Player;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("TerminalCompletion")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+fdd62b5272d43d898c0ee5e76260433ca745e17a")]
[assembly: AssemblyProduct("TerminalCompletion")]
[assembly: AssemblyTitle("TerminalCompletion")]
[assembly: AssemblyVersion("1.0.0.0")]
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;
		}
	}
}
namespace TerminalCompletion.Plugin
{
	internal class TermItemKeyComparer : IComparer<iTerminalItem>
	{
		public int Compare(iTerminalItem? x, iTerminalItem? y)
		{
			if (x == null || y == null)
			{
				return -1;
			}
			return x.TerminalItemKey.CompareTo(y.TerminalItemKey);
		}
	}
	internal class TermItemZoneComparer : IComparer<iTerminalItem>
	{
		public int Compare(iTerminalItem? x, iTerminalItem? y)
		{
			if (x == null || y == null)
			{
				return -1;
			}
			return x.FloorItemLocation.CompareTo(y.FloorItemLocation);
		}
	}
	internal class CommandExecutor
	{
		private enum QueryMode
		{
			Standard,
			Oneline
		}

		private static readonly string LIST_HELP = "Generate a list of items and provide them as targets for TAB completion.\r\n\r\nUsage: LIST [FLAGS...] [FILTERS...]\r\n\r\nFLAGS:\r\nFlags can be added separately or as part of the same word. (-C -D === -CD)\r\n\r\n[-A]    List all item records.\r\n[-C]    Exclude Containers from the output (Boxes and Lockers).\r\n[-D]    Exclude Doors and Security Doors from the output.\r\n[-S]    Sort the output alphabetically.\r\n[-Z]    Only include items present in the current zone.\r\n\r\nFILTERS:\r\nThese are words that are used to narrow down the output list. \r\nAny word starting with ^ will filter OUT matching words.\r\nProviding a number will be treated as a Zone Number.\r\nFilters can include ITEM TYPE and STATUS\r\n\r\nExample: LIST 49 RES ^TOOL, will list all items in ZONE_49 that are a resource pack but not a TOOL pack.\r\n";

		private static readonly string QUERY_HELP = "Extract extra information about objects.\r\n\r\nUsage: QUERY [FLAGS...] [ITEMS...]\r\n\r\nFLAGS:\r\n[-G]            Group the queried items by Zone number.\r\n[--ONELINE]     Displays ID, CAPACITY, ZONE, STATUS, within a single output line. \r\n                This is effectively a 'SUPERLIST'\r\n\r\nITEMS:\r\nAny full item name (MEDIPACK_732) or beginning of a name followed by an Asterix (*) \r\nin order to query multiple items at the same time. When using the Asterix, Items will\r\nbe pulled from the previously run LIST command.\r\n\r\nExample:\r\nQUERY TOOL* MED* (Queries all TOOL_REFILL and MEDIPACK from the last LIST command).\r\n";

		private static readonly string TC_HELP = "Change Settings for the TerminalCompletion mod. \r\nSettings are saved into the TerminalCompletionsPlugin.cfg file \r\n\r\nUsage: TC <Option> <value>\r\n\r\nvalues: \r\n  0 = false \r\n  1 = true\r\n\r\nOptions:\r\n    DEBUG       {0}    Enable debuging output in the BepinEx console.\r\n    SYNC        {1}    Enable item sub zone syncronization\r\n    SUBZONE     {2}    Enable sub-zone display during QUERY\r\n    CAPACITY    {3}    Enable capacity display for resourc epacks during QUERY\r\n\r\n";

		private static readonly Dictionary<string, List<iTerminalItem>> terminalDataMap = new Dictionary<string, List<iTerminalItem>>();

		private static readonly TermItemKeyComparer m_sortByKey = new TermItemKeyComparer();

		private static readonly TermItemZoneComparer m_sortByZone = new TermItemZoneComparer();

		private static List<iTerminalItem> currentTerminalListData = new List<iTerminalItem>();

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

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

		private static string m_command = string.Empty;

		private static string[] m_args = Array.Empty<string>();

		private static bool m_enableBulkQuery = true;

		private static float m_bulkDelayPerEntry = 0.5f;

		public static bool EnableModBehavior = true;

		public const TERM_Command TCCommandId = 45;

		private static Regex CapRegex = new Regex("([0-9]+)%", RegexOptions.IgnoreCase | RegexOptions.Compiled);

		private static readonly List<string> m_specialCommands = new List<string>
		{
			"GTFO.EXE", "DENOFWOLVES.EXE", "PRIVATE_ENCRYPTION.EXE", "LIGHT_TESTING.EXE", "VENTILATION_OVERRIDE.EXE", "AMMO_QUALITY_CONTROL.EXE MINIMUM", "AMMO_QUALITY_CONTROL.EXE MAXIMUM", "THREAT_LEVEL_M.EXE", "SPAGHETTI_&_MEATBALLS.EXE", "FRIED_CHICKEN.EXE",
			"RASCAL.EXE"
		};

		public static void ClearAllData()
		{
			terminalDataMap.Clear();
			currentTerminalListData.Clear();
			s_LogList.Clear();
			m_command = string.Empty;
			m_args = Array.Empty<string>();
		}

		private static void AddCommandLine(LG_ComputerTerminal term)
		{
			term.AddLine("\\\\Root\\" + m_command, false);
		}

		private static void AddToHistory(LG_ComputerTerminal term)
		{
			AddCommandLine(term);
			term.m_command.m_inputBuffer.Add(m_command);
			term.m_command.m_inputBufferStep = 0;
		}

		public static void ExecCommand(LG_ComputerTerminal term, string command)
		{
			if (terminalDataMap.ContainsKey(term.ItemKey))
			{
				currentTerminalListData = terminalDataMap[term.ItemKey];
			}
			else
			{
				currentTerminalListData = new List<iTerminalItem>();
				terminalDataMap[term.ItemKey] = currentTerminalListData;
			}
			m_command = command;
			m_args = command.Split(" ", StringSplitOptions.RemoveEmptyEntries);
			if (m_args.Length != 0)
			{
				switch (m_args[0])
				{
				case "LIST":
				case "LS":
					AddCommandLine(term);
					RunList(term);
					break;
				case "HIST":
					AddCommandLine(term);
					RunHist(term);
					break;
				case "LOGS":
					AddCommandLine(term);
					RunLogList(term);
					break;
				case "READ":
					AddCommandLine(term);
					RunReadLog(term);
					break;
				case "QUERY":
					AddCommandLine(term);
					RunQuery(term);
					break;
				case "TC":
					AddToHistory(term);
					RunTCSetCommand(term);
					break;
				case "START":
					AddCommandLine(term);
					RunEasterEggs(term);
					break;
				}
			}
			term.m_currentLine = "";
		}

		public static string GetFromHistory(LG_ComputerTerminal term, string histId)
		{
			List<string> inputBuffer = term.m_command.m_inputBuffer;
			if (int.TryParse(histId, out var result))
			{
				if (result < inputBuffer.Count - 1)
				{
					return inputBuffer[result];
				}
			}
			else
			{
				for (int num = inputBuffer.Count - 1; num >= 0; num--)
				{
					if (inputBuffer[num].StartsWith(histId))
					{
						return inputBuffer[num];
					}
				}
			}
			return "";
		}

		private static void RunTCSetCommand(LG_ComputerTerminal term)
		{
			term.m_command.ResetLinesSinceCommand();
			if (m_args.Length < 3)
			{
				term.m_command.AddOutput(string.Format(TC_HELP, TerminalPlugin.DebugEnabled, TerminalPlugin.SynchronizeItemLocations, TerminalPlugin.SubZoneDisplay, TerminalPlugin.CapacityDisplay), true);
				return;
			}
			string text = m_args[1];
			if (text == null)
			{
				return;
			}
			switch (text.Length)
			{
			case 4:
				switch (text[0])
				{
				case 'D':
					if (text == "DUMP")
					{
						RunDebugDump(term);
					}
					break;
				case 'B':
					if (text == "BULK")
					{
						m_enableBulkQuery = int.TryParse(m_args[2], out var result4) && result4 == 1;
					}
					break;
				case 'S':
					if (text == "SYNC")
					{
						TerminalPlugin.SynchronizeItemLocations = int.TryParse(m_args[2], out var result3) && result3 == 1;
					}
					break;
				}
				break;
			case 5:
				switch (text[2])
				{
				case 'L':
				{
					if (text == "DELAY" && float.TryParse(m_args[2], out var result6))
					{
						m_bulkDelayPerEntry = result6;
					}
					break;
				}
				case 'B':
					if (text == "DEBUG")
					{
						TerminalPlugin.DebugEnabled = int.TryParse(m_args[2], out var result5) && result5 == 1;
					}
					break;
				}
				break;
			case 6:
				if (text == "ENABLE")
				{
					EnableModBehavior = int.TryParse(m_args[2], out var result7) && result7 == 1;
				}
				break;
			case 7:
				if (text == "SUBZONE")
				{
					TerminalPlugin.SubZoneDisplay = int.TryParse(m_args[2], out var result2) && result2 == 1;
				}
				break;
			case 8:
				if (text == "CAPACITY")
				{
					TerminalPlugin.CapacityDisplay = int.TryParse(m_args[2], out var result) && result == 1;
				}
				break;
			}
		}

		public static void RunDebugDump(LG_ComputerTerminal term)
		{
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, iTerminalItem> allTerminalInterfaces = LG_LevelInteractionManager.GetAllTerminalInterfaces();
			List<string> list = new List<string>();
			Enumerator<string, iTerminalItem> enumerator = allTerminalInterfaces.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<string, iTerminalItem> current = enumerator.Current;
				list.Add(current.key);
			}
			list.Sort();
			int num = 1;
			foreach (string item in list)
			{
				List<string> val = null;
				iTerminalItem val2 = allTerminalInterfaces[item];
				if (val2.TerminalItemKey.StartsWith("AMMOPACK") || val2.TerminalItemKey.StartsWith("TOOL_REFILL") || val2.TerminalItemKey.StartsWith("MEDIPACK"))
				{
					val = val2.GetDetailedInfo(m_genericListDefaults);
				}
				ManualLogSource logger = TerminalPlugin.Logger;
				object[] obj = new object[7]
				{
					num++,
					val2.TerminalItemKey,
					val2.FloorItemLocation,
					null,
					null,
					null,
					null
				};
				AIG_CourseNode spawnNode = val2.SpawnNode;
				eDimensionIndex? obj2;
				if (spawnNode == null)
				{
					obj2 = null;
				}
				else
				{
					Dimension dimension = spawnNode.m_dimension;
					obj2 = ((dimension != null) ? new eDimensionIndex?(dimension.DimensionIndex) : null);
				}
				obj[3] = obj2;
				obj[4] = val2.FloorItemType;
				obj[5] = val2.FloorItemStatus;
				obj[6] = val?[2];
				logger.LogInfo((object)string.Format("{0,5}: {1,-20} {2,-10} {3,-20} {4,-20} {5,-20} {6, -20}", obj));
			}
			term.m_command.AddOutput((TerminalLineType)4, $"Debug Dump: {list.Count} Entities printed!", 4f, (TerminalSoundType)0, (TerminalSoundType)0);
		}

		public static bool TryAutoCompletion(string command, ref string output)
		{
			string[] array = command.Split(" ", StringSplitOptions.RemoveEmptyEntries);
			if (array == null || array.Length == 0)
			{
				return false;
			}
			if (array.Length > 1 && (array[0] == "QUERY" || array[0] == "PING"))
			{
				return TryCompletePingQuery(array, ref output);
			}
			if (array[0] == "READ")
			{
				return TryCompleteRead(array, ref output);
			}
			return false;
		}

		private static bool TryCompleteRead(string[] words, ref string output)
		{
			string[] words2 = words;
			if (s_LogList.Count == 0)
			{
				return false;
			}
			if (words2.Length == 1)
			{
				output = "READ " + s_LogList[0];
				return true;
			}
			int num = s_LogList.FindIndex((string name) => name.StartsWith(words2[1]));
			if (num == -1)
			{
				output = "READ " + s_LogList[0];
			}
			else if (s_LogList[num] == words2[1])
			{
				output = "READ " + s_LogList[(num + 1) % s_LogList.Count];
			}
			else
			{
				output = "READ " + s_LogList[num];
			}
			return true;
		}

		private static bool TryCompletePingQuery(string[] words, ref string output)
		{
			bool flag = false;
			for (int i = 1; i < words.Length; i++)
			{
				string word = words[i];
				iTerminalItem val = currentTerminalListData.Find((iTerminalItem item) => item.TerminalItemKey.StartsWith(word) && !((Il2CppObjectBase)item).WasCollected);
				if (val != null)
				{
					flag = word.Length != val.TerminalItemKey.Length;
					words[i] = val.TerminalItemKey;
				}
			}
			if (flag)
			{
				output = string.Join(" ", words);
				return true;
			}
			string finalArg = words[^1];
			int num = currentTerminalListData.FindIndex((iTerminalItem item) => item.TerminalItemKey == finalArg && !((Il2CppObjectBase)item).WasCollected);
			if (num < 0)
			{
				return false;
			}
			int num2 = finalArg.LastIndexOf('_');
			if (num2 < 0)
			{
				num2 = finalArg.Length - 1;
			}
			string value = finalArg.Substring(0, num2);
			if (finalArg.StartsWith("KEY"))
			{
				value = "KEY";
			}
			for (int num3 = (num + 1) % currentTerminalListData.Count; num3 != num; num3 = (num3 + 1) % currentTerminalListData.Count)
			{
				if (currentTerminalListData[num3].TerminalItemKey.StartsWith(value))
				{
					words[^1] = currentTerminalListData[num3].TerminalItemKey;
					output = string.Join(" ", words);
					return true;
				}
			}
			return false;
		}

		private static bool ItemMatchesFilter(iTerminalItem item, string filter, LG_ComputerTerminalCommandInterpreter command)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			if (filter[0] == '^')
			{
				string text = filter;
				filter = text.Substring(1, text.Length - 1);
				flag = true;
			}
			bool flag2 = item.TerminalItemKey.Contains(filter) || item.FloorItemLocation.Contains(filter) || command.GetLocalizedFloorItemType(item.FloorItemType).Contains(filter, StringComparison.OrdinalIgnoreCase) || command.GetLocalizedFloorItemStatus(item.FloorItemStatus).Contains(filter, StringComparison.OrdinalIgnoreCase);
			if (!flag)
			{
				return flag2;
			}
			return !flag2;
		}

		private static void ParseListArgs(LG_ComputerTerminal term, out bool sortList, out bool showAll, out List<string> args)
		{
			sortList = false;
			showAll = false;
			args = new List<string>();
			for (int i = 1; i < m_args.Length; i++)
			{
				int result;
				if (m_args[i].StartsWith("-"))
				{
					string text = m_args[i];
					for (int j = 0; j < text.Length; j++)
					{
						switch (text[j])
						{
						case 'Z':
							args.Add(term.m_terminalItem.FloorItemLocation);
							break;
						case 'D':
							args.Add("^DOOR");
							break;
						case 'C':
							args.Add("^LOCKER");
							args.Add("^BOX");
							break;
						case 'S':
							sortList = true;
							break;
						case 'A':
							showAll = true;
							break;
						}
					}
				}
				else if (int.TryParse(m_args[i], out result) || (m_args[i].StartsWith("^") && int.TryParse(m_args[i], out result)))
				{
					args.Add($"ZONE_{result}");
				}
				else
				{
					args.Add(m_args[i]);
				}
			}
		}

		private static void RunList(LG_ComputerTerminal term)
		{
			//IL_007d: 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_00c3: 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_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			currentTerminalListData.Clear();
			if (m_args.Length == 1)
			{
				term.AddLine(LIST_HELP, true);
				return;
			}
			ParseListArgs(term, out bool sortList, out bool showAll, out List<string> args);
			List<string> list = new List<string>();
			Enumerator<string, iTerminalItem> enumerator = LG_LevelInteractionManager.GetAllTerminalInterfaces().GetEnumerator();
			while (enumerator.MoveNext())
			{
				iTerminalItem value = enumerator.Current.value;
				AIG_CourseNode spawnNode = term.SpawnNode;
				eDimensionIndex? obj;
				if (spawnNode == null)
				{
					obj = null;
				}
				else
				{
					Dimension dimension = spawnNode.m_dimension;
					obj = ((dimension != null) ? new eDimensionIndex?(dimension.DimensionIndex) : null);
				}
				eDimensionIndex? val = obj;
				AIG_CourseNode spawnNode2 = value.SpawnNode;
				eDimensionIndex? obj2;
				if (spawnNode2 == null)
				{
					obj2 = null;
				}
				else
				{
					Dimension dimension2 = spawnNode2.m_dimension;
					obj2 = ((dimension2 != null) ? new eDimensionIndex?(dimension2.DimensionIndex) : null);
				}
				if (val != obj2)
				{
					continue;
				}
				bool flag = true;
				if (!showAll)
				{
					foreach (string item in args)
					{
						flag &= ItemMatchesFilter(value, item, term.m_command);
					}
				}
				if (showAll || flag || args.Count == 0)
				{
					currentTerminalListData.Add(value);
					list.Add($"<pos=0>{value.TerminalItemKey}</pos><pos=25%>{value.FloorItemType}</pos><pos=50%>{value.FloorItemStatus}</pos>");
				}
			}
			if (sortList)
			{
				list.Sort();
				currentTerminalListData.Sort(m_sortByKey);
			}
			if (args.Count == 1 && args[0] == "BULKHEAD")
			{
				term.m_command.ShowList(args[0], "");
				return;
			}
			term.AddLine((TerminalLineType)4, "Listing items using filter " + string.Join(", ", m_args, 1, m_args.Length - 1), 1.5f);
			term.AddLine("\n<pos=0>ID</pos><pos=25%>ITEM TYPE</pos><pos=50%>STATUS</pos>", true);
			term.AddLine(string.Join("\n", list.ToArray()), true);
		}

		private static void RunHist(LG_ComputerTerminal term)
		{
			List<string> val = new List<string>();
			val.Add("<pos=0>ID</pos><pos=7%>COMMAND</pos>\n");
			List<string> inputBuffer = term.m_command.m_inputBuffer;
			for (int i = 0; i < inputBuffer.Count; i++)
			{
				val.Add($"<pos=0>{i}</pos><pos=7%>{inputBuffer[i]}</pos>");
			}
			val.Add("\nTo rerun commands use ! followed by a number or Command. Examples: \"!3\" or \"!LI\"");
			term.m_command.AddOutput(val);
		}

		private static string getFullZone(iTerminalItem item)
		{
			string floorItemLocation = item.FloorItemLocation;
			if (item.SpawnNode == null || !TerminalPlugin.SubZoneDisplay)
			{
				return floorItemLocation;
			}
			string suffix = item.SpawnNode.m_area.m_navInfo.Suffix;
			return floorItemLocation + "<color=#CEA800><size=1>" + suffix + "</size></color>";
		}

		private static void RunBulkQuery(LG_ComputerTerminal term, List<iTerminalItem> items, QueryMode mode)
		{
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			List<string> val = new List<string>();
			switch (mode)
			{
			case QueryMode.Standard:
				foreach (iTerminalItem item in items)
				{
					List<string> detailedInfo2 = item.GetDetailedInfo(m_genericListDefaults);
					for (int i = 0; i < detailedInfo2.Count; i++)
					{
						val.Add(detailedInfo2[i]);
					}
					if (!val[val.Count - 1].StartsWith("--------"))
					{
						val.Add("----------------------------------------------------------------");
					}
					val.Add($"ID: {item.TerminalItemKey}\nITEM STATUS: {term.m_command.GetLocalizedFloorItemStatus(item.FloorItemStatus)}\nLOCATION: {getFullZone(item)}\n");
				}
				break;
			case QueryMode.Oneline:
				val.Add("<pos=0>ID</pos><pos=25%>ZONE</pos><pos=50%>STATUS</pos>\n");
				foreach (iTerminalItem item2 in items)
				{
					string value = "";
					List<string> detailedInfo = item2.GetDetailedInfo(m_genericListDefaults);
					if (TerminalPlugin.CapacityDisplay)
					{
						Enumerator<string> enumerator2 = detailedInfo.GetEnumerator();
						while (enumerator2.MoveNext())
						{
							string current2 = enumerator2.Current;
							Match match = CapRegex.Match(current2);
							if (match.Success)
							{
								value = match.Groups[0].Value ?? "";
								break;
							}
						}
					}
					val.Add($"<pos=0>{item2.TerminalItemKey}</pos><pos=25%>{getFullZone(item2)}</pos><pos=50%>{item2.FloorItemStatus} {value}</pos>");
				}
				break;
			}
			term.m_command.AddOutput((TerminalLineType)4, "Bulk Query On: " + string.Join(", ", m_args, 1, m_args.Length - 1), m_bulkDelayPerEntry * (float)Math.Min(items.Count, 8), (TerminalSoundType)0, (TerminalSoundType)0);
			term.m_command.AddOutput(val);
		}

		private static void RunQuery(LG_ComputerTerminal term)
		{
			if (m_args.Length == 1)
			{
				term.AddLine(QUERY_HELP, true);
				return;
			}
			bool flag = false;
			QueryMode mode = QueryMode.Standard;
			List<iTerminalItem> list = new List<iTerminalItem>();
			for (int i = 1; i < m_args.Length; i++)
			{
				string text = m_args[i];
				if (text == "-G")
				{
					flag = true;
					continue;
				}
				if (text == "--ONELINE")
				{
					mode = QueryMode.Oneline;
					continue;
				}
				if (text.Last() == '*')
				{
					text = text.Trim('*');
					foreach (iTerminalItem currentTerminalListDatum in currentTerminalListData)
					{
						if (currentTerminalListDatum.TerminalItemKey.StartsWith(text))
						{
							list.Add(currentTerminalListDatum);
						}
					}
					continue;
				}
				Enumerator<string, iTerminalItem> enumerator2 = LG_LevelInteractionManager.GetAllTerminalInterfaces().GetEnumerator();
				while (enumerator2.MoveNext())
				{
					KeyValuePair<string, iTerminalItem> current2 = enumerator2.Current;
					if (current2.key == text)
					{
						list.Add(current2.value);
					}
				}
			}
			if (flag)
			{
				list.Sort(m_sortByZone);
			}
			if (m_enableBulkQuery)
			{
				RunBulkQuery(term, list, mode);
				return;
			}
			foreach (iTerminalItem item in list)
			{
				term.m_command.Query(item.TerminalItemKey, "");
			}
		}

		private static void RunEasterEggs(LG_ComputerTerminal term)
		{
			int result;
			if (m_args.Length == 1)
			{
				term.AddLine("<pos=0>ID</pos><pos=7%>EASTEREGG</pos>", true);
				for (int i = 0; i < m_specialCommands.Count; i++)
				{
					term.AddLine($"<pos=0>{i}</pos><pos=7%>{m_specialCommands[i]}</pos>", false);
				}
				term.m_command.AddOutput("\nRun \"START [number]\", to run easter egg commands.", true);
			}
			else if (int.TryParse(m_args[1], out result) && result < m_specialCommands.Count)
			{
				string[] array = m_specialCommands[result].Split(" ");
				term.m_command.StartProgramFile(array[0], (array.Length == 2) ? array[1] : "");
			}
			else
			{
				term.m_command.StartProgramFile(m_args[1], (m_args.Length == 3) ? m_args[2] : "");
			}
		}

		private static void RunPing(LG_ComputerTerminal term)
		{
			if (m_args.Length == 1)
			{
				term.m_command.EvaluateInput("PING");
				return;
			}
			for (int i = 1; i < m_args.Length; i++)
			{
				string text = m_args[i];
				if (text.Last() == '*')
				{
					text = text.Trim('*');
					foreach (iTerminalItem currentTerminalListDatum in currentTerminalListData)
					{
						if (currentTerminalListDatum.TerminalItemKey.StartsWith(text))
						{
							term.m_command.EvaluateInput("PING " + currentTerminalListDatum.TerminalItemKey);
						}
					}
				}
				else
				{
					term.m_command.EvaluateInput("PING " + text);
				}
			}
		}

		public static void RunLogList(LG_ComputerTerminal term)
		{
			s_LogList.Clear();
			Enumerator<string, TerminalLogFileData> enumerator = term.GetLocalLogs().GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<string, TerminalLogFileData> current = enumerator.Current;
				s_LogList.Add(current.key);
			}
			term.m_command.ListLogs("", "");
		}

		private static void RunReadLog(LG_ComputerTerminal term)
		{
			string param = ((m_args.Length >= 2) ? m_args[1] : "");
			if (param != "")
			{
				string text = param;
				if (text[text.Length - 1] == '*')
				{
					param = param.Trim('*');
					string text2 = s_LogList.Find((string log) => log.Contains(param));
					term.m_command.ReadLog(text2 ?? param, "");
					return;
				}
			}
			term.m_command.ReadLog(param, "");
		}
	}
	[HarmonyPatch]
	internal class Patch
	{
		[HarmonyPatch(typeof(GameStateManager), "DoChangeState")]
		[HarmonyPostfix]
		public static void CheckForPlayerReady(GameStateManager __instance, eGameStateName nextState)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)nextState == 10 || (int)nextState == 5)
			{
				CommandExecutor.ClearAllData();
			}
		}

		[HarmonyPatch(typeof(LG_ComputerTerminal), "SyncIncomingTerminalCommand")]
		[HarmonyPrefix]
		public static bool ProcessSyncCommand(LG_ComputerTerminal __instance, TERM_Command cmd, string inputLine, string param1, string param2)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Invalid comparison between Unknown and I4
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Invalid comparison between Unknown and I4
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Invalid comparison between Unknown and I4
			if (TerminalPlugin.DebugEnabled)
			{
				ManualLogSource logger = TerminalPlugin.Logger;
				bool flag = default(bool);
				BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(34, 5, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LinesSinceCommand: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(__instance.m_command.m_linesSinceCommand);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\nCMD: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<TERM_Command>(cmd);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" \"");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(inputLine);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" \"");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(param1);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" \"");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(param2);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\"");
				}
				logger.LogDebug(val);
			}
			if (!CommandExecutor.EnableModBehavior)
			{
				return true;
			}
			__instance.m_command.ResetLinesSinceCommand();
			if (cmd - 18 <= 1 || cmd - 28 <= 2 || (int)cmd == 45)
			{
				CommandExecutor.ExecCommand(__instance, inputLine);
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(LG_TERM_PlayerInteracting), "OnReturn")]
		[HarmonyPrefix]
		public static bool ProcessCommand(ref LG_TERM_PlayerInteracting __instance)
		{
			LG_ComputerTerminal terminal = ((LG_TERM_Base)__instance).m_terminal;
			if (CommandExecutor.EnableModBehavior)
			{
				if (terminal.m_currentLine.StartsWith('!'))
				{
					string currentLine = terminal.m_currentLine;
					terminal.m_currentLine = CommandExecutor.GetFromHistory(terminal, currentLine.Substring(1, currentLine.Length - 1));
				}
				else if (terminal.m_currentLine.StartsWith('@'))
				{
					string currentLine = terminal.m_currentLine;
					terminal.m_currentLine = CommandExecutor.GetFromHistory(terminal, currentLine.Substring(1, currentLine.Length - 1));
					return false;
				}
			}
			string[] array = terminal.m_currentLine.Split(" ", StringSplitOptions.RemoveEmptyEntries);
			if (array.Length != 0)
			{
				if (array[0] == "TC")
				{
					CommandExecutor.ExecCommand(terminal, terminal.m_currentLine);
					return false;
				}
				if (!CommandExecutor.EnableModBehavior)
				{
					return true;
				}
				if (array[0] == "HIST")
				{
					LG_ComputerTerminalManager.WantToSendTerminalCommand(terminal.SyncID, (TERM_Command)45, terminal.m_currentLine, string.Empty, string.Empty);
					return false;
				}
				if (array[0] == "LS")
				{
					array[0] = "LIST";
					terminal.m_currentLine = string.Join(' ', array);
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TryUpdateLineForAutoComplete")]
		[HarmonyPrefix]
		public static bool ProcessTabCompletion(ref LG_ComputerTerminalCommandInterpreter __instance, string input, ref string autoCompletedLine)
		{
			bool num = CommandExecutor.TryAutoCompletion(input, ref autoCompletedLine);
			if (num)
			{
				__instance.m_terminal.m_currentLine = autoCompletedLine;
			}
			return !num;
		}

		[HarmonyPatch(typeof(ItemInLevel), "OnPlacedInLevel")]
		[HarmonyPostfix]
		private static void OnItemPlaced(ItemInLevel __instance, pPickupPlacement placement, PlayerAgent player, ItemCuller culler)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			if (!TerminalPlugin.SynchronizeItemLocations)
			{
				return;
			}
			LG_GenericTerminalItem componentInChildren = ((Component)__instance).GetComponentInChildren<LG_GenericTerminalItem>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return;
			}
			componentInChildren.SpawnNode = ((Agent)player).CourseNode;
			if (!TerminalPlugin.DebugEnabled)
			{
				return;
			}
			try
			{
				ManualLogSource logger = TerminalPlugin.Logger;
				bool flag = default(bool);
				BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(15, 4, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(player.Owner.NickName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" dropped: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(componentInChildren.TerminalItemKey);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" in ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(componentInChildren.FloorItemLocation);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Agent)player).CourseNode.m_area.m_navInfo.Suffix);
				}
				logger.LogDebug(val);
			}
			catch (Exception)
			{
				TerminalPlugin.Logger.LogError((object)"Exception thrown in OnPlacedInLevel debug...");
			}
		}
	}
	[BepInPlugin("Drummerx04.TerminalCompletionPlugin", "TerminalCompletionPlugin", "1.3.0")]
	public class TerminalPlugin : BasePlugin
	{
		public const string Guid = "Drummerx04.TerminalCompletionPlugin";

		public const string Name = "TerminalCompletionPlugin";

		public const string Version = "1.3.0";

		private static TerminalPlugin? instance;

		private readonly ConfigFile m_config;

		private readonly ConfigEntry<bool> m_itemSync;

		private readonly ConfigEntry<bool> m_debug;

		private readonly ConfigEntry<bool> m_subZoneDisplay;

		private readonly ConfigEntry<bool> m_capacityDisplay;

		public static ManualLogSource Logger => ((BasePlugin)instance).Log;

		public static bool SynchronizeItemLocations
		{
			get
			{
				return instance.m_itemSync.Value;
			}
			set
			{
				instance.m_itemSync.Value = value;
			}
		}

		public static bool DebugEnabled
		{
			get
			{
				return instance.m_debug.Value;
			}
			set
			{
				instance.m_debug.Value = value;
			}
		}

		public static bool SubZoneDisplay
		{
			get
			{
				return instance.m_subZoneDisplay.Value;
			}
			set
			{
				instance.m_subZoneDisplay.Value = value;
			}
		}

		public static bool CapacityDisplay
		{
			get
			{
				return instance.m_capacityDisplay.Value;
			}
			set
			{
				instance.m_capacityDisplay.Value = value;
			}
		}

		public TerminalPlugin()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			instance = this;
			m_config = new ConfigFile(Path.Combine(Paths.ConfigPath, "TerminalCompletionPlugin.cfg"), true);
			m_config.SettingChanged += SaveFileEvent;
			m_itemSync = m_config.Bind<bool>("Main", "SyncDropLocation", true, "When moving pingable items, their subzone does not normally update.\nThis enables the mod to update that sub zone when an item is dropped by a player.\nIf this fix causes issues or conflicts with other mods, it can be disabled here.");
			m_debug = m_config.Bind<bool>("Main", "DebugOutput", false, "Whether or not to output debugging messages");
			m_subZoneDisplay = m_config.Bind<bool>("Main", "DisplaySubZones", true, "Display the Sub-Zone (A,B,C...) along with the zone output in query commands.");
			m_capacityDisplay = m_config.Bind<bool>("Main", "DisplayCapacity", true, "Display the capacity of Resource Packs in the --ONELINE output.");
		}

		private void SaveFileEvent(object? sender, EventArgs e)
		{
			m_config.Save();
		}

		public override void Load()
		{
			Harmony.CreateAndPatchAll(typeof(Patch), "Drummerx04.TerminalCompletionPlugin");
		}
	}
}