From 9e9a8b5d7dd66f35e442e4aa094a64db03d255bb Mon Sep 17 00:00:00 2001 From: d4vid Date: Sat, 17 May 2025 22:34:39 +0200 Subject: [PATCH] Add a command history --- .../ConsoleImprovements.csproj | 9 +- .../ConsoleImprovements/manifest.jecs | 2 +- .../src/client/CommandHistoryPatch.cs | 98 +++++++++++++++++++ .../src/client/ConsoleImprovementsMod.cs | 6 ++ 4 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 ConsoleImprovements/ConsoleImprovements/src/client/CommandHistoryPatch.cs diff --git a/ConsoleImprovements/ConsoleImprovements.csproj b/ConsoleImprovements/ConsoleImprovements.csproj index bc7d9a2..3075f25 100644 --- a/ConsoleImprovements/ConsoleImprovements.csproj +++ b/ConsoleImprovements/ConsoleImprovements.csproj @@ -2,8 +2,9 @@ net8.0 - enable + disable enable + @@ -31,5 +32,11 @@ $(LogicWorldGameLocation)\Logic_World_Data\Managed\JimmysUnityUtilities.dll + + $(LogicWorldGameLocation)\Logic_World_Data\Managed\FancyInput.dll + + + $(LogicWorldGameLocation)\Logic_World_Data\Managed\Unity.TextMeshPro.dll + diff --git a/ConsoleImprovements/ConsoleImprovements/manifest.jecs b/ConsoleImprovements/ConsoleImprovements/manifest.jecs index 003cb45..23c7ca3 100644 --- a/ConsoleImprovements/ConsoleImprovements/manifest.jecs +++ b/ConsoleImprovements/ConsoleImprovements/manifest.jecs @@ -1,7 +1,7 @@ ID: D4VID_ConsoleImprovements Name: ConsoleImprovements Author: D4VID -Version: 0.1.0 +Version: 0.2.0 Priority: 0 ClientOnly: true Dependencies: diff --git a/ConsoleImprovements/ConsoleImprovements/src/client/CommandHistoryPatch.cs b/ConsoleImprovements/ConsoleImprovements/src/client/CommandHistoryPatch.cs new file mode 100644 index 0000000..e1e27a8 --- /dev/null +++ b/ConsoleImprovements/ConsoleImprovements/src/client/CommandHistoryPatch.cs @@ -0,0 +1,98 @@ +using System.Reflection; +using System.Collections.Generic; +using EccsLogicWorldAPI.Shared.AccessHelper; +using FancyInput; +using HarmonyLib; +using LogicLog; +using TMPro; +using Console = FancyPantsConsole.Console; + +namespace ConsoleImprovements.Client { + public class CommandHistoryPatch { + const int HistLength = 1000; + + private static ILogicLogger _logger = null!; + private static FieldInfo? _commandInputFieldField; + + private static LinkedList _history = new LinkedList(); + private static LinkedListNode? _command; + + public static bool Prepare(ILogicLogger logger) { + _logger = logger; + + // Get access to the rich text string inside the MessageData class + _commandInputFieldField = AccessTools.Field(typeof(Console), "CommandInputField"); + if (_commandInputFieldField == null) { + _logger.Error("Cannot get field CommandInputField of Console"); + return false; + } + + return true; + } + + public static void Inject(Harmony harmony) { + PatchUpdate(harmony); + PatchCommandSubmit(harmony); + } + + private static void PatchUpdate(Harmony harmony) { + var methodTarget = Methods.getPrivate(typeof(Console), "Update"); + var methodHook = Methods.get(typeof(CommandHistoryPatch), nameof(HookUpdate)); + harmony.Patch(methodTarget, prefix: new HarmonyMethod(methodHook)); + } + + private static void PatchCommandSubmit(Harmony harmony) { + var methodTarget = Methods.getPrivate(typeof(Console), "OnCommandInputFieldSubmit"); + var methodHook = Methods.get(typeof(CommandHistoryPatch), nameof(HookCommandSubmit)); + harmony.Patch(methodTarget, prefix: new HarmonyMethod(methodHook)); + } + + // ReSharper disable once InconsistentNaming + public static bool HookUpdate(Console __instance) { + if (RawInput.UpArrow.DownThisFrame()) { + if (_command == null) { + if (_history.Count > 0) { + _command = _history.First; + UpdateCommandTextField(__instance, _command!.Value); + } + } else if (_command.Next != null) { + _command = _command.Next; + UpdateCommandTextField(__instance, _command!.Value); + } + } + + if (RawInput.DownArrow.DownThisFrame()) { + if (_command != null) { + _command = _command.Previous; + UpdateCommandTextField(__instance, _command?.Value ?? ""); + } + } + + return true; // Resume original functionality + } + + private static void UpdateCommandTextField(Console instance, string text) { + TMP_InputField? commandInputField = _commandInputFieldField!.GetValue(instance) as TMP_InputField; + if (commandInputField == null) { + _logger.Error("Cannot get CommandInputField value"); + return; + } + + commandInputField.text = text; + } + + // ReSharper disable once InconsistentNaming + public static bool HookCommandSubmit(Console __instance, ref string line) { + // Keep the set max number of entries in the history + if (_history.Count >= HistLength) { + _history.RemoveLast(); + } + + _history.AddFirst(line); + + _command = null; // Clear the command pointer + + return true; // Resume original functionality + } + } +} \ No newline at end of file diff --git a/ConsoleImprovements/ConsoleImprovements/src/client/ConsoleImprovementsMod.cs b/ConsoleImprovements/ConsoleImprovements/src/client/ConsoleImprovementsMod.cs index bc4614c..0d6bf56 100644 --- a/ConsoleImprovements/ConsoleImprovements/src/client/ConsoleImprovementsMod.cs +++ b/ConsoleImprovements/ConsoleImprovements/src/client/ConsoleImprovementsMod.cs @@ -8,6 +8,12 @@ namespace ConsoleImprovements.Client { if (MessageCopyPatch.Prepare(Logger)) { MessageCopyPatch.Inject(harmony); + Logger.Info("Message Copy Patch Successful"); + } + + if (CommandHistoryPatch.Prepare(Logger)) { + CommandHistoryPatch.Inject(harmony); + Logger.Info("Command History Patch Successful"); } Logger.Info("ConsoleImprovements mod loaded");