Decompiled source of ExitCommand v1.3.0

BepInEx/plugins/TerminalExit.dll

Decompiled 6 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using TerminalApi;
using TerminalApi.Classes;
using TerminalApi.Interfaces;
using UnityEngine;
using UnityEngine.SceneManagement;

[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.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("TerminalExit")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TerminalExit")]
[assembly: AssemblyTitle("TerminalExit")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace TerminalApi
{
	internal class DelayedAddTerminalKeyword : IDelayedAction
	{
		internal Action<TerminalKeyword, CommandInfo> Action { get; set; }

		internal CommandInfo CommandInfo { get; set; } = null;


		internal TerminalKeyword Keyword { get; set; }

		public void Run()
		{
			Action(Keyword, CommandInfo);
		}
	}
	[BepInPlugin("atomic.terminalapi", "Terminal Api", "1.5.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ConfigEntry<bool> configEnableLogs;

		public ManualLogSource Log;

		internal void SetupConfig()
		{
			configEnableLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "enableLogs", true, "Whether or not to display logs pertaining to TerminalAPI. Will still log that the mod has loaded.");
		}

		private void Awake()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			SetupConfig();
			object obj = this;
			obj = (object)((!configEnableLogs.Value) ? ((ManualLogSource)null) : new ManualLogSource("Terminal Api"));
			((Plugin)obj).Log = (ManualLogSource)obj;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin atomic.terminalapi is loaded!");
			if (Log != null)
			{
				Logger.Sources.Add((ILogSource)(object)Log);
			}
			TerminalApi.plugin = this;
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
		}
	}
	public static class TerminalApi
	{
		public static Plugin plugin;

		internal static List<IDelayedAction> QueuedDelayedActions = new List<IDelayedAction>();

		internal static List<CommandInfo> CommandInfos = new List<CommandInfo>();

		public static Terminal Terminal { get; internal set; }

		public static List<TerminalNode> SpecialNodes => Terminal.terminalNodes.specialNodes;

		public static string CurrentText => Terminal.currentText;

		public static TMP_InputField ScreenText => Terminal.screenText;

		public static bool IsInGame()
		{
			try
			{
				return Terminal != null;
			}
			catch (NullReferenceException)
			{
				return false;
			}
		}

		public static void AddCommand(string commandWord, string displayText, string verbWord = null, bool clearPreviousText = true)
		{
			commandWord = commandWord.ToLower();
			TerminalKeyword val = CreateTerminalKeyword(commandWord);
			TerminalNode val2 = CreateTerminalNode(displayText, clearPreviousText);
			if (verbWord != null)
			{
				verbWord = verbWord.ToLower();
				TerminalKeyword terminalKeyword = CreateTerminalKeyword(verbWord, isVerb: true);
				AddTerminalKeyword(val.defaultVerb = terminalKeyword.AddCompatibleNoun(val, val2));
				AddTerminalKeyword(val);
			}
			else
			{
				val.specialKeywordResult = val2;
				AddTerminalKeyword(val);
			}
		}

		public static void AddCommand(string commandWord, CommandInfo commandInfo, string verbWord = null, bool clearPreviousText = true)
		{
			commandWord = commandWord.ToLower();
			TerminalKeyword val = CreateTerminalKeyword(commandWord);
			TerminalNode val3 = (commandInfo.TriggerNode = CreateTerminalNode("", clearPreviousText));
			if (verbWord != null)
			{
				verbWord = verbWord.ToLower();
				TerminalKeyword terminalKeyword = CreateTerminalKeyword(verbWord, isVerb: true);
				AddTerminalKeyword(val.defaultVerb = terminalKeyword.AddCompatibleNoun(val, val3));
				AddTerminalKeyword(val, commandInfo);
			}
			else
			{
				val.specialKeywordResult = val3;
				AddTerminalKeyword(val, commandInfo);
			}
		}

		public static TerminalKeyword CreateTerminalKeyword(string word, bool isVerb = false, TerminalNode triggeringNode = null)
		{
			TerminalKeyword val = ScriptableObject.CreateInstance<TerminalKeyword>();
			val.word = word.ToLower();
			val.isVerb = isVerb;
			val.specialKeywordResult = triggeringNode;
			return val;
		}

		public static TerminalKeyword CreateTerminalKeyword(string word, string displayText, bool clearPreviousText = false, string terminalEvent = "")
		{
			TerminalKeyword val = ScriptableObject.CreateInstance<TerminalKeyword>();
			val.word = word.ToLower();
			val.isVerb = false;
			val.specialKeywordResult = CreateTerminalNode(displayText, clearPreviousText, terminalEvent);
			return val;
		}

		public static TerminalNode CreateTerminalNode(string displayText, bool clearPreviousText = false, string terminalEvent = "")
		{
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			val.displayText = displayText;
			val.clearPreviousText = clearPreviousText;
			val.terminalEvent = terminalEvent;
			return val;
		}

		public static void AddTerminalKeyword(TerminalKeyword terminalKeyword)
		{
			if (IsInGame())
			{
				if (GetKeyword(terminalKeyword.word) == null)
				{
					Terminal.terminalNodes.allKeywords = Terminal.terminalNodes.allKeywords.Add(terminalKeyword);
					ManualLogSource log = plugin.Log;
					if (log != null)
					{
						log.LogMessage((object)("Added " + terminalKeyword.word + " keyword to terminal keywords."));
					}
				}
				else
				{
					ManualLogSource log2 = plugin.Log;
					if (log2 != null)
					{
						log2.LogWarning((object)("Failed to add " + terminalKeyword.word + " keyword. Already exists."));
					}
				}
			}
			else
			{
				ManualLogSource log3 = plugin.Log;
				if (log3 != null)
				{
					log3.LogMessage((object)("Not in game, waiting to be in game to add " + terminalKeyword.word + " keyword."));
				}
				Action<TerminalKeyword, CommandInfo> action = AddTerminalKeyword;
				DelayedAddTerminalKeyword item = new DelayedAddTerminalKeyword
				{
					Action = action,
					Keyword = terminalKeyword
				};
				QueuedDelayedActions.Add(item);
			}
		}

		public static void AddTerminalKeyword(TerminalKeyword terminalKeyword, CommandInfo commandInfo = null)
		{
			if (IsInGame())
			{
				if (GetKeyword(terminalKeyword.word) == null)
				{
					if (commandInfo?.DisplayTextSupplier != null)
					{
						if (commandInfo?.TriggerNode == null)
						{
							commandInfo.TriggerNode = terminalKeyword.specialKeywordResult;
						}
						CommandInfos.Add(commandInfo);
					}
					if (commandInfo != null)
					{
						((Object)terminalKeyword).name = commandInfo.Title ?? (terminalKeyword.word.Substring(0, 1).ToUpper() + terminalKeyword.word.Substring(1));
						string text = "\n>" + ((Object)terminalKeyword).name.ToUpper() + "\n" + commandInfo.Description + "\n\n";
						NodeAppendLine(commandInfo.Category, text);
					}
					Terminal.terminalNodes.allKeywords = Terminal.terminalNodes.allKeywords.Add(terminalKeyword);
					ManualLogSource log = plugin.Log;
					if (log != null)
					{
						log.LogMessage((object)("Added " + terminalKeyword.word + " keyword to terminal keywords."));
					}
				}
				else
				{
					ManualLogSource log2 = plugin.Log;
					if (log2 != null)
					{
						log2.LogWarning((object)("Failed to add " + terminalKeyword.word + " keyword. Already exists."));
					}
				}
			}
			else
			{
				ManualLogSource log3 = plugin.Log;
				if (log3 != null)
				{
					log3.LogMessage((object)("Not in game, waiting to be in game to add " + terminalKeyword.word + " keyword."));
				}
				Action<TerminalKeyword, CommandInfo> action = AddTerminalKeyword;
				DelayedAddTerminalKeyword item = new DelayedAddTerminalKeyword
				{
					Action = action,
					Keyword = terminalKeyword,
					CommandInfo = commandInfo
				};
				QueuedDelayedActions.Add(item);
			}
		}

		public static void NodeAppendLine(string word, string text)
		{
			if (!IsInGame())
			{
				return;
			}
			TerminalKeyword keyword = GetKeyword(word.ToLower());
			if ((Object)(object)keyword != (Object)null)
			{
				keyword.specialKeywordResult.displayText = keyword.specialKeywordResult.displayText.Trim() + "\n" + text;
				return;
			}
			ManualLogSource log = plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)("Failed to add text to " + word + ". Does not exist."));
			}
		}

		public static TerminalKeyword GetKeyword(string keyword)
		{
			if (IsInGame())
			{
				return ((IEnumerable<TerminalKeyword>)Terminal.terminalNodes.allKeywords).FirstOrDefault((Func<TerminalKeyword, bool>)((TerminalKeyword Kw) => Kw.word == keyword));
			}
			return null;
		}

		public static void UpdateKeyword(TerminalKeyword keyword)
		{
			if (!IsInGame())
			{
				return;
			}
			for (int i = 0; i < Terminal.terminalNodes.allKeywords.Length; i++)
			{
				if (Terminal.terminalNodes.allKeywords[i].word == keyword.word)
				{
					Terminal.terminalNodes.allKeywords[i] = keyword;
					return;
				}
			}
			ManualLogSource log = plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)("Failed to update " + keyword.word + ". Was not found in keywords."));
			}
		}

		public static void DeleteKeyword(string word)
		{
			if (!IsInGame())
			{
				return;
			}
			for (int i = 0; i < Terminal.terminalNodes.allKeywords.Length; i++)
			{
				if (Terminal.terminalNodes.allKeywords[i].word == word.ToLower())
				{
					int newSize = Terminal.terminalNodes.allKeywords.Length - 1;
					for (int j = i + 1; j < Terminal.terminalNodes.allKeywords.Length; j++)
					{
						Terminal.terminalNodes.allKeywords[j - 1] = Terminal.terminalNodes.allKeywords[j];
					}
					Array.Resize(ref Terminal.terminalNodes.allKeywords, newSize);
					ManualLogSource log = plugin.Log;
					if (log != null)
					{
						log.LogMessage((object)(word + " was deleted successfully."));
					}
					return;
				}
			}
			ManualLogSource log2 = plugin.Log;
			if (log2 != null)
			{
				log2.LogWarning((object)("Failed to delete " + word + ". Was not found in keywords."));
			}
		}

		public static void UpdateKeywordCompatibleNoun(TerminalKeyword verbKeyword, string noun, TerminalNode newTriggerNode)
		{
			if (!IsInGame() || !verbKeyword.isVerb)
			{
				return;
			}
			for (int i = 0; i < verbKeyword.compatibleNouns.Length; i++)
			{
				CompatibleNoun val = verbKeyword.compatibleNouns[i];
				if (val.noun.word == noun)
				{
					val.result = newTriggerNode;
					UpdateKeyword(verbKeyword);
					return;
				}
			}
			ManualLogSource log = plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)$"WARNING: No noun found for {verbKeyword}");
			}
		}

		public static void UpdateKeywordCompatibleNoun(string verbWord, string noun, TerminalNode newTriggerNode)
		{
			if (!IsInGame())
			{
				return;
			}
			TerminalKeyword keyword = GetKeyword(verbWord);
			if (!keyword.isVerb || verbWord == null)
			{
				return;
			}
			for (int i = 0; i < keyword.compatibleNouns.Length; i++)
			{
				CompatibleNoun val = keyword.compatibleNouns[i];
				if (val.noun.word == noun)
				{
					val.result = newTriggerNode;
					UpdateKeyword(keyword);
					return;
				}
			}
			ManualLogSource log = plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)$"WARNING: No noun found for {keyword}");
			}
		}

		public static void UpdateKeywordCompatibleNoun(TerminalKeyword verbKeyword, string noun, string newDisplayText)
		{
			if (!IsInGame() || !verbKeyword.isVerb)
			{
				return;
			}
			for (int i = 0; i < verbKeyword.compatibleNouns.Length; i++)
			{
				CompatibleNoun val = verbKeyword.compatibleNouns[i];
				if (val.noun.word == noun)
				{
					val.result.displayText = newDisplayText;
					UpdateKeyword(verbKeyword);
					return;
				}
			}
			ManualLogSource log = plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)$"WARNING: No noun found for {verbKeyword}");
			}
		}

		public static void UpdateKeywordCompatibleNoun(string verbWord, string noun, string newDisplayText)
		{
			if (!IsInGame())
			{
				return;
			}
			TerminalKeyword keyword = GetKeyword(verbWord);
			if (!keyword.isVerb)
			{
				return;
			}
			for (int i = 0; i < keyword.compatibleNouns.Length; i++)
			{
				CompatibleNoun val = keyword.compatibleNouns[i];
				if (val.noun.word == noun)
				{
					val.result.displayText = newDisplayText;
					UpdateKeyword(keyword);
					return;
				}
			}
			ManualLogSource log = plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)$"WARNING: No noun found for {keyword}");
			}
		}

		public static void AddCompatibleNoun(TerminalKeyword verbKeyword, string noun, string displayText, bool clearPreviousText = false)
		{
			if (IsInGame())
			{
				TerminalKeyword keyword = GetKeyword(noun);
				verbKeyword = verbKeyword.AddCompatibleNoun(keyword, displayText, clearPreviousText);
				UpdateKeyword(verbKeyword);
			}
		}

		public static void AddCompatibleNoun(TerminalKeyword verbKeyword, string noun, TerminalNode triggerNode)
		{
			if (IsInGame())
			{
				TerminalKeyword keyword = GetKeyword(noun);
				verbKeyword = verbKeyword.AddCompatibleNoun(keyword, triggerNode);
				UpdateKeyword(verbKeyword);
			}
		}

		public static void AddCompatibleNoun(string verbWord, string noun, TerminalNode triggerNode)
		{
			if (!IsInGame())
			{
				return;
			}
			TerminalKeyword keyword = GetKeyword(verbWord);
			TerminalKeyword keyword2 = GetKeyword(noun);
			if ((Object)(object)keyword == (Object)null)
			{
				ManualLogSource log = plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"The verb given does not exist.");
				}
			}
			else
			{
				keyword = keyword.AddCompatibleNoun(keyword2, triggerNode);
				UpdateKeyword(keyword);
			}
		}

		public static void AddCompatibleNoun(string verbWord, string noun, string displayText, bool clearPreviousText = false)
		{
			if (!IsInGame())
			{
				return;
			}
			TerminalKeyword keyword = GetKeyword(verbWord);
			TerminalKeyword keyword2 = GetKeyword(noun);
			if ((Object)(object)keyword == (Object)null)
			{
				ManualLogSource log = plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"The verb given does not exist.");
				}
			}
			else
			{
				keyword = keyword.AddCompatibleNoun(keyword2, displayText, clearPreviousText);
				UpdateKeyword(keyword);
			}
		}

		public static string GetTerminalInput()
		{
			if (IsInGame())
			{
				return CurrentText.Substring(CurrentText.Length - Terminal.textAdded);
			}
			return "";
		}

		public static void SetTerminalInput(string terminalInput)
		{
			Terminal.TextChanged(CurrentText.Substring(0, CurrentText.Length - Terminal.textAdded) + terminalInput);
			ScreenText.text = CurrentText;
			Terminal.textAdded = terminalInput.Length;
		}
	}
	public static class TerminalExtenstionMethods
	{
		public static TerminalKeyword AddCompatibleNoun(this TerminalKeyword terminalKeyword, TerminalKeyword noun, TerminalNode result)
		{
			//IL_000c: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if (terminalKeyword.isVerb)
			{
				CompatibleNoun val = new CompatibleNoun
				{
					noun = noun,
					result = result
				};
				if (terminalKeyword.compatibleNouns == null)
				{
					terminalKeyword.compatibleNouns = (CompatibleNoun[])(object)new CompatibleNoun[1] { val };
				}
				else
				{
					terminalKeyword.compatibleNouns = terminalKeyword.compatibleNouns.Add(val);
				}
				return terminalKeyword;
			}
			return null;
		}

		public static TerminalKeyword AddCompatibleNoun(this TerminalKeyword terminalKeyword, string noun, TerminalNode result)
		{
			//IL_000c: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			if (terminalKeyword.isVerb)
			{
				CompatibleNoun val = new CompatibleNoun
				{
					noun = TerminalApi.CreateTerminalKeyword(noun),
					result = result
				};
				if (terminalKeyword.compatibleNouns == null)
				{
					terminalKeyword.compatibleNouns = (CompatibleNoun[])(object)new CompatibleNoun[1] { val };
				}
				else
				{
					terminalKeyword.compatibleNouns = terminalKeyword.compatibleNouns.Add(val);
				}
				return terminalKeyword;
			}
			return null;
		}

		public static TerminalKeyword AddCompatibleNoun(this TerminalKeyword terminalKeyword, string noun, string displayText)
		{
			//IL_000c: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			if (terminalKeyword.isVerb)
			{
				CompatibleNoun val = new CompatibleNoun
				{
					noun = TerminalApi.CreateTerminalKeyword(noun),
					result = TerminalApi.CreateTerminalNode(displayText)
				};
				if (terminalKeyword.compatibleNouns == null)
				{
					terminalKeyword.compatibleNouns = (CompatibleNoun[])(object)new CompatibleNoun[1] { val };
				}
				else
				{
					terminalKeyword.compatibleNouns = terminalKeyword.compatibleNouns.Add(val);
				}
				return terminalKeyword;
			}
			return null;
		}

		public static TerminalKeyword AddCompatibleNoun(this TerminalKeyword terminalKeyword, TerminalKeyword noun, string displayText, bool clearPreviousText = false)
		{
			//IL_000c: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			if (terminalKeyword.isVerb)
			{
				CompatibleNoun val = new CompatibleNoun
				{
					noun = noun,
					result = TerminalApi.CreateTerminalNode(displayText, clearPreviousText)
				};
				if (terminalKeyword.compatibleNouns == null)
				{
					terminalKeyword.compatibleNouns = (CompatibleNoun[])(object)new CompatibleNoun[1] { val };
				}
				else
				{
					terminalKeyword.compatibleNouns = terminalKeyword.compatibleNouns.Add(val);
				}
				return terminalKeyword;
			}
			return null;
		}

		internal static T[] Add<T>(this T[] array, T newItem)
		{
			int num = array.Length + 1;
			Array.Resize(ref array, num);
			array[num - 1] = newItem;
			return array;
		}
	}
}
namespace TerminalApi.Interfaces
{
	internal interface IDelayedAction
	{
		void Run();
	}
}
namespace TerminalApi.Events
{
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyPatch(typeof(Terminal))]
	public static class Events
	{
		public class TerminalEventArgs : EventArgs
		{
			public Terminal Terminal { get; set; }
		}

		public delegate void TerminalEventHandler(object sender, TerminalEventArgs e);

		public class TerminalParseSentenceEventArgs : TerminalEventArgs
		{
			public TerminalNode ReturnedNode { get; set; }

			public string SubmittedText { get; set; }
		}

		public delegate void TerminalParseSentenceEventHandler(object sender, TerminalParseSentenceEventArgs e);

		public class TerminalTextChangedEventArgs : TerminalEventArgs
		{
			public string NewText;

			public string CurrentInputText;
		}

		public delegate void TerminalTextChangedEventHandler(object sender, TerminalTextChangedEventArgs e);

		public static event TerminalEventHandler TerminalAwake;

		public static event TerminalEventHandler TerminalWaking;

		public static event TerminalEventHandler TerminalStarted;

		public static event TerminalEventHandler TerminalStarting;

		public static event TerminalEventHandler TerminalBeginUsing;

		public static event TerminalEventHandler TerminalBeganUsing;

		public static event TerminalEventHandler TerminalExited;

		public static event TerminalParseSentenceEventHandler TerminalParsedSentence;

		public static event TerminalTextChangedEventHandler TerminalTextChanged;

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void Awake(ref Terminal __instance)
		{
			TerminalApi.Terminal = __instance;
			if (TerminalApi.QueuedDelayedActions.Count > 0)
			{
				ManualLogSource log = TerminalApi.plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)"In game, applying any changes now.");
				}
				foreach (IDelayedAction queuedDelayedAction in TerminalApi.QueuedDelayedActions)
				{
					queuedDelayedAction.Run();
				}
				TerminalApi.QueuedDelayedActions.Clear();
			}
			Events.TerminalAwake?.Invoke(__instance, new TerminalEventArgs
			{
				Terminal = __instance
			});
		}

		[HarmonyPatch("BeginUsingTerminal")]
		[HarmonyPostfix]
		public static void BeganUsing(ref Terminal __instance)
		{
			Events.TerminalBeganUsing?.Invoke(__instance, new TerminalEventArgs
			{
				Terminal = __instance
			});
		}

		[HarmonyPatch("QuitTerminal")]
		[HarmonyPostfix]
		public static void OnQuitTerminal(ref Terminal __instance)
		{
			Events.TerminalExited?.Invoke(__instance, new TerminalEventArgs
			{
				Terminal = __instance
			});
		}

		[HarmonyPatch("BeginUsingTerminal")]
		[HarmonyPrefix]
		public static void OnBeginUsing(ref Terminal __instance)
		{
			Events.TerminalBeginUsing?.Invoke(__instance, new TerminalEventArgs
			{
				Terminal = __instance
			});
		}

		[HarmonyPatch("ParsePlayerSentence")]
		[HarmonyPostfix]
		public static void ParsePlayerSentence(ref Terminal __instance, TerminalNode __result)
		{
			CommandInfo commandInfo = TerminalApi.CommandInfos.FirstOrDefault((CommandInfo cI) => (Object)(object)cI.TriggerNode == (Object)(object)__result);
			if (commandInfo != null)
			{
				__result.displayText = commandInfo?.DisplayTextSupplier();
			}
			string submittedText = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded);
			Events.TerminalParsedSentence?.Invoke(__instance, new TerminalParseSentenceEventArgs
			{
				Terminal = __instance,
				SubmittedText = submittedText,
				ReturnedNode = __result
			});
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void Started(ref Terminal __instance)
		{
			Events.TerminalStarted?.Invoke(__instance, new TerminalEventArgs
			{
				Terminal = __instance
			});
		}

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		public static void Starting(ref Terminal __instance)
		{
			Events.TerminalStarting?.Invoke(__instance, new TerminalEventArgs
			{
				Terminal = __instance
			});
		}

		[HarmonyPatch("TextChanged")]
		[HarmonyPostfix]
		public static void OnTextChanged(ref Terminal __instance, string newText)
		{
			string currentInputText = "";
			if (newText.Trim().Length >= __instance.textAdded)
			{
				currentInputText = newText.Substring(newText.Length - __instance.textAdded);
			}
			Events.TerminalTextChanged?.Invoke(__instance, new TerminalTextChangedEventArgs
			{
				Terminal = __instance,
				NewText = newText,
				CurrentInputText = currentInputText
			});
		}

		[HarmonyPatch("Awake")]
		[HarmonyPrefix]
		public static void Waking(ref Terminal __instance)
		{
			Events.TerminalWaking?.Invoke(__instance, new TerminalEventArgs
			{
				Terminal = __instance
			});
		}
	}
}
namespace TerminalApi.Classes
{
	public class CommandInfo
	{
		public string Title { get; set; } = null;


		public string Category { get; set; }

		public string Description { get; set; }

		public TerminalNode TriggerNode { get; set; }

		public Func<string> DisplayTextSupplier { get; set; }
	}
}
namespace TerminalExit
{
	[BepInPlugin("TerminalExit", "TerminalExit", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public static ManualLogSource logger;

		public void Awake()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin TerminalExit is loaded!");
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (Utils.IsIngame())
			{
				global::TerminalApi.TerminalApi.AddCommand("exit", new CommandInfo
				{
					DisplayTextSupplier = delegate
					{
						Object.FindObjectOfType<Terminal>().QuitTerminal();
						return "exit\n\n";
					},
					Category = "Other"
				});
			}
		}
	}
	internal class Utils
	{
		public static bool IsIngame()
		{
			if ((Object)(object)GameObject.Find("Environment") != (Object)null)
			{
				return true;
			}
			return false;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "TerminalExit";

		public const string PLUGIN_NAME = "TerminalExit";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}