parent
2b62f9fa4d
commit
9e9a8b5d7d
@ -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<string> _history = new LinkedList<string>();
|
||||||
|
private static LinkedListNode<string>? _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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue