Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of TerminalApi v1.5.6
BepInEx/plugins/TerminalApi.dll
Decompiled 2 weeks agousing 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 Microsoft.CodeAnalysis; using TMPro; using TerminalApi.Classes; using TerminalApi.Interfaces; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")] [assembly: AssemblyCompany("NotAtomicBomb")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Terminal Api for the terminal in Lethal Company")] [assembly: AssemblyFileVersion("1.5.4.0")] [assembly: AssemblyInformationalVersion("1.5.4+49f88f3d6ba1ef29c5521b9ab61acd5b90cc932d")] [assembly: AssemblyProduct("TerminalApi")] [assembly: AssemblyTitle("TerminalApi")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/NotAtomicBomb/TerminalApi")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.5.4.0")] [module: UnverifiableCode] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace TerminalApi { internal class DelayedAddTerminalKeyword : IDelayedAction { internal Action<TerminalKeyword, CommandInfo> Action { get; set; } internal CommandInfo CommandInfo { get; set; } internal TerminalKeyword Keyword { get; set; } public void Run() { Action(Keyword, CommandInfo); } } [BepInPlugin("atomic.terminalapi", "Terminal Api", "1.5.6")] 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_001b: 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 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 obj = ScriptableObject.CreateInstance<TerminalKeyword>(); obj.word = word.ToLower(); obj.isVerb = isVerb; obj.specialKeywordResult = triggeringNode; return obj; } public static TerminalKeyword CreateTerminalKeyword(string word, string displayText, bool clearPreviousText = false, string terminalEvent = "") { TerminalKeyword obj = ScriptableObject.CreateInstance<TerminalKeyword>(); obj.word = word.ToLower(); obj.isVerb = false; obj.specialKeywordResult = CreateTerminalNode(displayText, clearPreviousText, terminalEvent); return obj; } public static TerminalNode CreateTerminalNode(string displayText, bool clearPreviousText = false, string terminalEvent = "") { TerminalNode obj = ScriptableObject.CreateInstance<TerminalNode>(); obj.displayText = displayText; obj.clearPreviousText = clearPreviousText; obj.terminalEvent = terminalEvent; return obj; } 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"; if (commandInfo.Category == null) { string text3 = (commandInfo.Category = "Other"); } 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) { if ((Object)(object)keyword.specialKeywordResult == (Object)null) { ManualLogSource log = plugin.Log; if (log != null) { log.LogWarning((object)("Failed to add text to " + word + ". Does not have specialKeywordResult.")); } } else { keyword.specialKeywordResult.displayText = keyword.specialKeywordResult.displayText.Trim() + "\n" + text; } } else { ManualLogSource log2 = plugin.Log; if (log2 != null) { log2.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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown if (terminalKeyword.isVerb) { ConstructorInfo constructor = typeof(CompatibleNoun).GetConstructor(new Type[2] { typeof(TerminalKeyword), typeof(TerminalNode) }); CompatibleNoun val; if (constructor != null) { val = (CompatibleNoun)constructor.Invoke(new object[2] { noun, result }); } else { val = (CompatibleNoun)Activator.CreateInstance(typeof(CompatibleNoun)); val.noun = noun; val.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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown if (terminalKeyword.isVerb) { ConstructorInfo constructor = typeof(CompatibleNoun).GetConstructor(new Type[2] { typeof(TerminalKeyword), typeof(TerminalNode) }); CompatibleNoun val; if (constructor != null) { val = (CompatibleNoun)constructor.Invoke(new object[2] { TerminalApi.CreateTerminalKeyword(noun), result }); } else { val = (CompatibleNoun)Activator.CreateInstance(typeof(CompatibleNoun)); val.noun = TerminalApi.CreateTerminalKeyword(noun); val.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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown if (terminalKeyword.isVerb) { ConstructorInfo constructor = typeof(CompatibleNoun).GetConstructor(new Type[2] { typeof(TerminalKeyword), typeof(TerminalNode) }); CompatibleNoun val; if (constructor != null) { val = (CompatibleNoun)constructor.Invoke(new object[2] { TerminalApi.CreateTerminalKeyword(noun), TerminalApi.CreateTerminalNode(displayText) }); } else { val = (CompatibleNoun)Activator.CreateInstance(typeof(CompatibleNoun)); val.noun = TerminalApi.CreateTerminalKeyword(noun); val.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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if (terminalKeyword.isVerb) { ConstructorInfo constructor = typeof(CompatibleNoun).GetConstructor(new Type[2] { typeof(TerminalKeyword), typeof(TerminalNode) }); CompatibleNoun val; if (constructor != null) { val = (CompatibleNoun)constructor.Invoke(new object[2] { noun, TerminalApi.CreateTerminalNode(displayText, clearPreviousText) }); } else { val = (CompatibleNoun)Activator.CreateInstance(typeof(CompatibleNoun)); val.noun = noun; val.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; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "TerminalApi"; public const string PLUGIN_NAME = "TerminalApi"; public const string PLUGIN_VERSION = "1.5.4"; } } namespace TerminalApi.Interfaces { internal interface IDelayedAction { internal 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; } public string Category { get; set; } public string Description { get; set; } public TerminalNode TriggerNode { get; set; } public Func<string> DisplayTextSupplier { get; set; } } }