Please disclose if any significant portion of your mod was created 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 TerminalAliases v1.1.1
TerminalAliases.dll
Decompiled 4 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("TerminalAliases")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.1.0")] [assembly: AssemblyInformationalVersion("1.1.1+37c6543cb4b656ea651197164928e3c0efe80b33")] [assembly: AssemblyProduct("TerminalAliases")] [assembly: AssemblyTitle("TerminalAliases")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.1.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.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 TerminalAliases { public class AliasManager { private readonly string _filePath; private Dictionary<string, string> _aliases = new Dictionary<string, string>(); public IReadOnlyDictionary<string, string> Aliases => _aliases; public AliasManager(string configDirectory) { _filePath = Path.Combine(configDirectory, "TerminalAliases.cfg"); Load(); } public void Load() { _aliases.Clear(); if (!File.Exists(_filePath)) { Plugin.Log.LogInfo((object)("No alias file found at " + _filePath + ", starting fresh.")); return; } try { string[] array = File.ReadAllLines(_filePath); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (string.IsNullOrEmpty(text) || text.StartsWith("#")) { continue; } int num = text.IndexOf('='); if (num > 0 && num < text.Length - 1) { string text2 = text.Substring(0, num).Trim().ToLowerInvariant(); string value = text.Substring(num + 1).Trim(); if (!string.IsNullOrEmpty(text2) && !string.IsNullOrEmpty(value)) { _aliases[text2] = value; } } } Plugin.Log.LogInfo((object)$"Loaded {_aliases.Count} alias(es) from {_filePath}"); } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to load aliases: " + ex.Message)); } } public void Save() { try { List<string> list = new List<string>(); foreach (KeyValuePair<string, string> alias in _aliases) { list.Add(alias.Key + "=" + alias.Value); } File.WriteAllLines(_filePath, list); Plugin.Log.LogDebug((object)$"Saved {_aliases.Count} alias(es) to {_filePath}"); } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to save aliases: " + ex.Message)); } } public bool Add(string alias, string command) { if (string.IsNullOrWhiteSpace(alias) || string.IsNullOrWhiteSpace(command)) { return false; } alias = alias.ToLowerInvariant(); _aliases[alias] = command; Save(); return true; } public bool Remove(string alias) { if (string.IsNullOrWhiteSpace(alias)) { return false; } alias = alias.ToLowerInvariant(); if (_aliases.Remove(alias)) { Save(); return true; } return false; } public bool TryGet(string alias, out string command) { return _aliases.TryGetValue(alias.ToLowerInvariant(), out command); } } [BepInPlugin("TerminalAliases", "TerminalAliases", "1.1.1")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log { get; private set; } internal static AliasManager AliasManager { get; private set; } internal static Harmony Harmony { get; private set; } private void Awake() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; AliasManager = new AliasManager(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath)); Harmony = new Harmony("TerminalAliases"); Harmony.PatchAll(Assembly.GetExecutingAssembly()); Log.LogInfo((object)"TerminalAliases v1.1.1 loaded."); } } public static class PluginInfo { public const string PLUGIN_GUID = "TerminalAliases"; public const string PLUGIN_NAME = "TerminalAliases"; public const string PLUGIN_VERSION = "1.1.1"; } } namespace TerminalAliases.Patches { [HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")] internal static class AliasCommandsPatch { [HarmonyPrefix] private static bool HandleAliasCommands(Terminal __instance, ref TerminalNode __result) { if (__instance.textAdded <= 0) { return true; } string text = __instance.screenText.text; int startIndex = text.Length - __instance.textAdded; string text2 = text.Substring(startIndex).Trim().ToLowerInvariant(); if (string.IsNullOrEmpty(text2)) { return true; } string[] array = text2.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length == 0) { return true; } string text3 = array[0]; if (text3 == "alias") { __result = HandleAliasCommand(array, __instance); return false; } if (text3 == "removealias") { __result = HandleRemoveAliasCommand(array, __instance); return false; } return true; } private static TerminalNode HandleAliasCommand(string[] parts, Terminal terminal) { if (parts.Length == 1) { IReadOnlyDictionary<string, string> aliases = Plugin.AliasManager.Aliases; if (aliases.Count == 0) { return CreateNode("No aliases defined.\n\nUse 'alias [name] [command]' to create one.\n\n"); } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Defined aliases:"); stringBuilder.AppendLine(); foreach (KeyValuePair<string, string> item in aliases) { stringBuilder.AppendLine(" " + item.Key + " = " + item.Value); } stringBuilder.AppendLine(); return CreateNode(stringBuilder.ToString()); } if (parts.Length == 2) { return CreateNode("Usage: alias [name] [command]\n\nExample: alias vm view monitor\n\n"); } string text = parts[1]; string text2 = string.Join(" ", parts, 2, parts.Length - 2); if (Plugin.AliasManager.Add(text, text2)) { return CreateNode("Alias '" + text + "' set to '" + text2 + "'\n\n"); } return CreateNode("Failed to add alias.\n\n"); } private static TerminalNode HandleRemoveAliasCommand(string[] parts, Terminal terminal) { if (parts.Length < 2) { return CreateNode("Usage: removealias [name]\n\n"); } string text = parts[1]; if (Plugin.AliasManager.Remove(text)) { return CreateNode("Alias '" + text + "' removed.\n\n"); } return CreateNode("Alias '" + text + "' not found.\n\n"); } private static TerminalNode CreateNode(string text) { TerminalNode obj = ScriptableObject.CreateInstance<TerminalNode>(); obj.displayText = text; obj.clearPreviousText = true; return obj; } } [HarmonyPatch(typeof(Terminal))] internal static class TerminalInputPatch { private static readonly string[] ConfirmKeywords = new string[3] { "confirm", "yes", "y" }; private static FieldInfo? _modifyingTextField; private static FieldInfo ModifyingTextField => _modifyingTextField ?? (_modifyingTextField = typeof(Terminal).GetField("modifyingText", BindingFlags.Instance | BindingFlags.NonPublic)); [HarmonyPatch("Update")] [HarmonyPostfix] private static void HandleCtrlEnter(Terminal __instance) { if (__instance.terminalInUse) { Keyboard current = Keyboard.current; if (current != null && (((ButtonControl)current.leftCtrlKey).isPressed || ((ButtonControl)current.rightCtrlKey).isPressed) && ((ButtonControl)current.enterKey).wasPressedThisFrame) { ((MonoBehaviour)__instance).StartCoroutine(SubmitAndConfirm(__instance)); } } } private static IEnumerator SubmitAndConfirm(Terminal terminal) { terminal.OnSubmit(); yield return (object)new WaitForEndOfFrame(); yield return null; if (!terminal.terminalInUse) { yield break; } TerminalNode currentNode = terminal.currentNode; if ((Object)(object)currentNode == (Object)null || currentNode.terminalOptions == null || currentNode.terminalOptions.Length == 0) { yield break; } CompatibleNoun[] terminalOptions = currentNode.terminalOptions; foreach (CompatibleNoun val in terminalOptions) { if ((Object)(object)val.noun == (Object)null) { continue; } string word = val.noun.word; if (word == null) { continue; } string text = word.ToLowerInvariant(); string[] confirmKeywords = ConfirmKeywords; foreach (string text2 in confirmKeywords) { if (text == text2) { TypeAndSubmit(terminal, word); Plugin.Log.LogDebug((object)("Auto-confirmed via Ctrl+Enter (keyword: " + word + ").")); yield break; } } } } private static void TypeAndSubmit(Terminal terminal, string text) { bool flag = (bool)ModifyingTextField.GetValue(terminal); ModifyingTextField.SetValue(terminal, true); terminal.screenText.text = terminal.screenText.text.Substring(0, terminal.screenText.text.Length - terminal.textAdded); TMP_InputField screenText = terminal.screenText; screenText.text += text; terminal.textAdded = text.Length; ModifyingTextField.SetValue(terminal, flag); terminal.OnSubmit(); } } [HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")] internal static class TerminalPatch { private static FieldInfo? _modifyingTextField; private const int MaxChainDepth = 10; private static FieldInfo ModifyingTextField => _modifyingTextField ?? (_modifyingTextField = typeof(Terminal).GetField("modifyingText", BindingFlags.Instance | BindingFlags.NonPublic)); [HarmonyPrefix] private static void ExpandAliases(Terminal __instance) { if (__instance.textAdded <= 0) { return; } string text = __instance.screenText.text; int num = text.Length - __instance.textAdded; string text2 = text.Substring(num); if (!string.IsNullOrWhiteSpace(text2)) { string text3 = ExpandInput(text2); if (!(text3 == text2)) { bool flag = (bool)ModifyingTextField.GetValue(__instance); ModifyingTextField.SetValue(__instance, true); int num2 = text3.Length - text2.Length; __instance.screenText.text = text.Substring(0, num) + text3; __instance.textAdded += num2; ModifyingTextField.SetValue(__instance, flag); Plugin.Log.LogDebug((object)("Expanded: '" + text2.Trim() + "' -> '" + text3.Trim() + "'")); } } } private static string ExpandInput(string input) { IReadOnlyDictionary<string, string> aliases = Plugin.AliasManager.Aliases; if (aliases.Count == 0) { return input; } string text = input; for (int i = 0; i < 10; i++) { string[] array = text.Split(new char[1] { ' ' }, StringSplitOptions.None); bool flag = false; for (int j = 0; j < array.Length; j++) { string text2 = array[j]; string key = text2.ToLowerInvariant(); if (aliases.TryGetValue(key, out var value)) { array[j] = PreserveCase(text2, value); flag = true; } } if (!flag) { break; } text = string.Join(" ", array); } return text; } private static string PreserveCase(string original, string replacement) { if (string.IsNullOrEmpty(original) || string.IsNullOrEmpty(replacement)) { return replacement; } if (original == original.ToUpperInvariant()) { return replacement.ToUpperInvariant(); } if (char.IsUpper(original[0])) { StringBuilder stringBuilder = new StringBuilder(replacement.Length); stringBuilder.Append(char.ToUpperInvariant(replacement[0])); if (replacement.Length > 1) { stringBuilder.Append(replacement.Substring(1)); } return stringBuilder.ToString(); } return replacement; } } }