diff --git a/ChatCommands/ChatCommands.csproj b/ChatCommands/ChatCommands.csproj
index bf69f03..b6fb8ee 100644
--- a/ChatCommands/ChatCommands.csproj
+++ b/ChatCommands/ChatCommands.csproj
@@ -1,10 +1,10 @@
1.13.0
- net452
+ net6.0
-
+
diff --git a/ChatCommands/ChatCommandsMod.cs b/ChatCommands/ChatCommandsMod.cs
index d312f3a..53a439a 100644
--- a/ChatCommands/ChatCommandsMod.cs
+++ b/ChatCommands/ChatCommandsMod.cs
@@ -20,6 +20,7 @@ public class ChatCommandsMod : Mod, ICommandHandler
private NotifyingTextWriter consoleNotifier;
private InputState inputState;
private ChatCommandsConfig modConfig;
+ private CommandInvoker commandInvoker;
private int repeatWaitPeriod = BaseWaitPeriod;
@@ -42,7 +43,7 @@ public void Handle(string input)
parts[0] = "help";
this.consoleNotifier.Notify = true;
- this.Helper.ConsoleCommands.Trigger(parts[0], parts.Skip(1).ToArray());
+ this.commandInvoker.InvokeCommand(parts[0], parts.Skip(1).ToArray());
this.consoleNotifier.Notify = false;
}
@@ -52,6 +53,7 @@ public override void Entry(IModHelper helper)
{
this.commandValidator = new CommandValidator(helper.ConsoleCommands);
this.consoleNotifier = new NotifyingTextWriter(Console.Out, this.OnLineWritten);
+ this.commandInvoker = new CommandInvoker(this.Helper, this.Monitor);
this.inputState = helper.Reflection.GetField(typeof(Game1), "input").GetValue();
diff --git a/ChatCommands/ClassReplacements/CommandChatBox.cs b/ChatCommands/ClassReplacements/CommandChatBox.cs
index d31a789..fbbffc1 100644
--- a/ChatCommands/ClassReplacements/CommandChatBox.cs
+++ b/ChatCommands/ClassReplacements/CommandChatBox.cs
@@ -8,6 +8,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Reflection;
using System.Text.RegularExpressions;
namespace ChatCommands.ClassReplacements
@@ -50,7 +51,9 @@ public CommandChatBox(IModHelper helper, ICommandHandler handler, ChatCommandsCo
this.bChoosingEmoji = helper.Reflection.GetField(this, "choosingEmoji");
Texture2D chatBoxTexture = Game1.content.Load("LooseSprites\\chatBox");
- this.chatBox.OnEnterPressed -= helper.Reflection.GetField(this, "e").GetValue();
+ Type[] onEnterDelegateParamTypes = { typeof(TextBox) };
+ MethodInfo textBoxEnterInfo = this.GetType().GetMethod("textBoxEnter", onEnterDelegateParamTypes);
+ this.chatBox.OnEnterPressed -= (TextBoxEvent)textBoxEnterInfo.CreateDelegate(typeof(TextBoxEvent), this);
this.chatBox = this.commandChatTextBox = new CommandChatTextBox(chatBoxTexture,
null, Game1.smallFont, Color.White);
Game1.keyboardDispatcher.Subscriber = this.chatBox;
diff --git a/ChatCommands/Util/CommandInvoker.cs b/ChatCommands/Util/CommandInvoker.cs
new file mode 100644
index 0000000..578dfd3
--- /dev/null
+++ b/ChatCommands/Util/CommandInvoker.cs
@@ -0,0 +1,113 @@
+using StardewModdingAPI;
+using StardewModdingAPI.Events;
+using StardewValley;
+using System;
+using System.Reflection;
+
+namespace ChatCommands.Util
+{
+ ///
+ /// Uses disgusting Reflection shenanigans to emulate the old behaviour of `ConsoleCommands.Trigger`
+ ///
+ internal class CommandInvoker
+ {
+ private object? commandManager;
+ private MethodInfo? getCommandMethod;
+ private PropertyInfo? callbackPropInfo;
+ private MethodInfo? cmdInvokeMethod;
+ private IMonitor monitor;
+
+ public CommandInvoker(IModHelper helper, IMonitor monitor)
+ {
+ this.monitor = monitor;
+ ObtainGetCommandMethod(helper);
+ }
+
+ private void ObtainGetCommandMethod(IModHelper helper)
+ {
+ FieldInfo? commandManagerFieldInfo = helper.ConsoleCommands.GetType().GetField("CommandManager", BindingFlags.NonPublic | BindingFlags.Instance);
+ if (commandManagerFieldInfo == null)
+ {
+ this.monitor.Log($"Could not obtain CommandManager field info", LogLevel.Error);
+ return;
+ }
+ //this.monitor.Log($"CommandManager has type {commandManagerFieldInfo.FieldType.FullName}", LogLevel.Debug);
+
+ this.commandManager = commandManagerFieldInfo.GetValue(helper.ConsoleCommands);
+ if (this.commandManager == null)
+ {
+ this.monitor.Log("Could not obtain ConsoleCommands object", LogLevel.Error);
+ return;
+ }
+ //this.monitor.Log("Obtained ConsoleCommands object", LogLevel.Debug);
+
+ this.getCommandMethod = commandManager.GetType().GetMethod("Get");
+ if (this.getCommandMethod == null)
+ {
+ this.monitor.Log("Could not obtain ConsoleCommands.Get method", LogLevel.Error);
+ return;
+ }
+ //this.monitor.Log("Obtained ConsoleCommands.Get MethodInfo", LogLevel.Debug);
+
+ Type commandType = this.getCommandMethod.ReturnType;
+ //this.monitor.Log($"Command type is {commandType.AssemblyQualifiedName}", LogLevel.Debug);
+
+ PropertyInfo[] propertyInfos = commandType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
+ foreach (PropertyInfo propertyInfo in propertyInfos)
+ {
+ if (propertyInfo.Name == "Callback")
+ {
+ this.callbackPropInfo = propertyInfo;
+ }
+ }
+
+ if (this.callbackPropInfo == null)
+ {
+ this.monitor.Log($"Could not obtain Command.Callback PropertyInfo", LogLevel.Error);
+ return;
+ }
+ //this.monitor.Log("Obtained Command.Callback PropertyInfo", LogLevel.Debug);
+ //this.monitor.Log($"Command.Callback type is {this.callbackPropInfo.PropertyType}", LogLevel.Debug);
+
+ this.cmdInvokeMethod = this.callbackPropInfo.PropertyType.GetMethod("Invoke");
+ if (this.cmdInvokeMethod == null)
+ {
+ this.monitor.Log($"Could not obtain Action.Invoke MethodInfo", LogLevel.Error);
+ return;
+ }
+ //this.monitor.Log("Obtained Action.Invoke MethodInfo", LogLevel.Debug);
+ }
+
+ ///
+ /// Invokes the requested console command.
+ ///
+ /// The command name.
+ /// The command aarguments.
+ /// Returns whether the command was actually triggered; We may not have found the `CommandManager` properly, or the requested command may not exist.
+ public bool InvokeCommand(string name, string[] args)
+ {
+ object[] getArguments = { name };
+ object? command = this.getCommandMethod?.Invoke(this.commandManager, getArguments);
+ if (command == null)
+ {
+ this.monitor.Log($"Could not obtain `{name}` command", LogLevel.Error);
+ return false;
+ }
+
+ object? callback = this.callbackPropInfo?.GetValue(command);
+ if (callback == null)
+ {
+ this.monitor.Log($"Could not obtain Callback value", LogLevel.Error);
+ return false;
+ }
+ //this.monitor.Log($"Obtained callback for command `{name}`, calling with args `{args}`", LogLevel.Debug);
+
+ if (this.cmdInvokeMethod == null)
+ return false;
+
+ object[] callbackArgs = { name, args };
+ this.cmdInvokeMethod.Invoke(callback, callbackArgs);
+ return true;
+ }
+ }
+}
diff --git a/ChatCommands/manifest.json b/ChatCommands/manifest.json
index 608cae4..1c544e9 100644
--- a/ChatCommands/manifest.json
+++ b/ChatCommands/manifest.json
@@ -1,10 +1,10 @@
{
"Name": "Chat Commands",
"Author": "Cat",
- "Version": "1.15.2",
- "Description": "Lets you run SMAPI commands from the chat window!",
+ "Version": "1.15.3",
+ "Description": "Lets you run SMAPI commands from the chat window! Updated for SV 1.6 by Lino5000",
"UniqueID": "cat.chatcommands",
"EntryDll": "ChatCommands.dll",
- "MinimumApiVersion": "3.0.0",
+ "MinimumApiVersion": "4.0.0",
"UpdateKeys": [ "Nexus:2092" ]
}