From 687d1746edc55b166402bbd65ca82ba4b26fabf0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 24 Mar 2026 17:43:14 +0000 Subject: [PATCH] Fix command registration for external MCC scripts - Update Roslyn compiler LanguageVersion from CSharp9 to Latest - Implement ChatBotCommand.RegisterCommand() (was empty) - Add RegisterChatBotCommand() helper to ChatBot base class - Add automatic command cleanup in BotUnLoad via UnregisterChatBotCommands() - Fix external scripts using Handler.dispatcher (CS0176 static via instance) - Fix AutoTree.cs wrong Initialize/OnUnload signatures (CS0115) - EntityCount.cs RegisterChatBotCommand() now works with new helper Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/27fc44b8-50d8-4194-8057-019a29675d4a --- MinecraftClient/McClient.cs | 1 + MinecraftClient/Scripting/ChatBot.cs | 48 ++++++++++++++++++- .../Scripting/DynamicRun/Builder/Compiler.cs | 2 +- MinecraftClient/config/ChatBots/AutoTree.cs | 14 +++--- .../config/ChatBots/DiscordWebhook.cs | 4 +- MinecraftClient/config/ChatBots/MineCube.cs | 4 +- .../config/ChatBots/SugarCaneFarmer.cs | 4 +- 7 files changed, 62 insertions(+), 15 deletions(-) diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index a9fccdba..104ad218 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -1025,6 +1025,7 @@ namespace MinecraftClient } b.OnUnload(); + b.UnregisterChatBotCommands(); bots.RemoveAll(item => ReferenceEquals(item, b)); diff --git a/MinecraftClient/Scripting/ChatBot.cs b/MinecraftClient/Scripting/ChatBot.cs index 8b612ab8..554dc491 100644 --- a/MinecraftClient/Scripting/ChatBot.cs +++ b/MinecraftClient/Scripting/ChatBot.cs @@ -6,7 +6,9 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading; using Brigadier.NET; +using Brigadier.NET.Builder; using MinecraftClient.CommandHandler; +using MinecraftClient.CommandHandler.Patch; using MinecraftClient.Inventory; using MinecraftClient.Mapping; using static MinecraftClient.Settings; @@ -43,6 +45,7 @@ namespace MinecraftClient.Scripting private McClient? _handler = null; private ChatBot? master = null; private readonly List registeredPluginChannels = new(); + private readonly List registeredChatBotCommands = new(); private readonly Lock delayTasksLock = new(); private readonly List delayedTasks = new(); protected McClient Handler @@ -1710,6 +1713,34 @@ namespace MinecraftClient.Scripting /// Command result to display to the user public delegate string CommandRunner(string command, string[] args); + /// + /// Register a simple ChatBot command with the Brigadier dispatcher. + /// The command is automatically unregistered when the bot is unloaded. + /// + /// Name of the command (used as the literal command name) + /// Description of the command + /// Usage string for the command + /// Method to handle the command execution + protected void RegisterChatBotCommand(string cmdName, string cmdDesc, string cmdUsage, CommandRunner callback) + { + var command = new ChatBotCommand(cmdName, cmdDesc, cmdUsage, callback); + command.RegisterCommand(McClient.dispatcher); + registeredChatBotCommands.Add(cmdName); + } + + /// + /// Unregisters all commands that were registered via RegisterChatBotCommand. + /// Called automatically during bot unload. + /// + internal void UnregisterChatBotCommands() + { + foreach (var cmdName in registeredChatBotCommands) + { + McClient.dispatcher.Unregister(cmdName); + } + registeredChatBotCommands.Clear(); + } + /// /// Command class with constructor for creating command for ChatBots. /// @@ -1727,7 +1758,22 @@ namespace MinecraftClient.Scripting public override void RegisterCommand(CommandDispatcher dispatcher) { - + dispatcher.Register(l => l.Literal(_cmdName) + .Then(l => l.Argument("args", Arguments.GreedyString()) + .Executes(r => + { + string fullArgs = Arguments.GetString(r, "args"); + string result = Runner( + $"{_cmdName} {fullArgs}", + fullArgs.Split(' ', StringSplitOptions.RemoveEmptyEntries)); + return r.Source.SetAndReturn(CmdResult.Status.Done, result); + })) + .Executes(r => + { + string result = Runner(_cmdName, Array.Empty()); + return r.Source.SetAndReturn(CmdResult.Status.Done, result); + }) + ); } /// diff --git a/MinecraftClient/Scripting/DynamicRun/Builder/Compiler.cs b/MinecraftClient/Scripting/DynamicRun/Builder/Compiler.cs index 9cc1df13..a49f1127 100644 --- a/MinecraftClient/Scripting/DynamicRun/Builder/Compiler.cs +++ b/MinecraftClient/Scripting/DynamicRun/Builder/Compiler.cs @@ -49,7 +49,7 @@ namespace MinecraftClient.Scripting.DynamicRun.Builder private static CSharpCompilation GenerateCode(string sourceCode, string fileName, List additionalAssemblies) { var codeString = SourceText.From(sourceCode); - var options = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9); + var options = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest); var parsedSyntaxTree = SyntaxFactory.ParseSyntaxTree(codeString, options); diff --git a/MinecraftClient/config/ChatBots/AutoTree.cs b/MinecraftClient/config/ChatBots/AutoTree.cs index 5488d8ad..21d731b7 100644 --- a/MinecraftClient/config/ChatBots/AutoTree.cs +++ b/MinecraftClient/config/ChatBots/AutoTree.cs @@ -75,7 +75,7 @@ public class AutoTree : ChatBot } } - public override void Initialize(CommandDispatcher dispatcher) + public override void Initialize() { if (!GetTerrainEnabled()) { @@ -89,7 +89,7 @@ public class AutoTree : ChatBot } else { - dispatcher.Register(l => l.Literal("help") + McClient.dispatcher.Register(l => l.Literal("help") .Then(l => l.Literal(CommandName) .Executes(r => OnCommandHelp(r.Source, string.Empty)) .Then(l => l.Literal("set") @@ -99,7 +99,7 @@ public class AutoTree : ChatBot ) ); - dispatcher.Register(l => l.Literal(CommandName) + McClient.dispatcher.Register(l => l.Literal(CommandName) .Then(l => l.Literal("toggle") .Executes(r => { return r.Source.SetAndReturn(CmdResult.Status.Done, Toggle() ? "Now is running" : "Now is stopping"); })) .Then(l => l.Literal("set") @@ -109,17 +109,17 @@ public class AutoTree : ChatBot .Then(l => l.Argument("TreeType", Arguments.String()) .Executes(r => OnCommandType(r.Source, Arguments.GetString(r, "TreeType"))))) .Then(l => l.Literal("_help") - .Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CommandName))) + .Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName))) ); LogToConsole("Loaded."); } } - public override void OnUnload(CommandDispatcher dispatcher) + public override void OnUnload() { - dispatcher.Unregister(CommandName); - dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName); + McClient.dispatcher.Unregister(CommandName); + McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName); } private int OnCommandHelp(CmdResult r, string? cmd) diff --git a/MinecraftClient/config/ChatBots/DiscordWebhook.cs b/MinecraftClient/config/ChatBots/DiscordWebhook.cs index 892f087d..ce0e6d22 100644 --- a/MinecraftClient/config/ChatBots/DiscordWebhook.cs +++ b/MinecraftClient/config/ChatBots/DiscordWebhook.cs @@ -306,7 +306,7 @@ class DiscordWebhook : ChatBot LogToConsole("Made by Daenges.\nSpecial thanks to Crafatar for providing the beautiful avatars!"); LogToConsole("Please set a Webhook with '/dw changeurl [URL]'. For further information type '/discordwebhook help'."); - Handler.dispatcher.Register(l => l.Literal(CommandName) + McClient.dispatcher.Register(l => l.Literal(CommandName) .Then(l => l.Argument("Commands", Arguments.GreedyString()) .Executes(r => { CommandHandler(Arguments.GetString(r, "Commands").Split(' ', StringSplitOptions.TrimEntries)); @@ -317,7 +317,7 @@ class DiscordWebhook : ChatBot public override void OnUnload() { - Handler.dispatcher.Unregister(CommandName); + McClient.dispatcher.Unregister(CommandName); } public override void Update() diff --git a/MinecraftClient/config/ChatBots/MineCube.cs b/MinecraftClient/config/ChatBots/MineCube.cs index 71d760a6..1f64f0da 100644 --- a/MinecraftClient/config/ChatBots/MineCube.cs +++ b/MinecraftClient/config/ChatBots/MineCube.cs @@ -46,7 +46,7 @@ class MineCube : ChatBot LogToConsole("Mining bot created by Daenges."); - Handler.dispatcher.Register(l => l.Literal(CommandName) + McClient.dispatcher.Register(l => l.Literal(CommandName) .Then(l => l.Argument("Commands", Arguments.GreedyString()) .Executes(r => { EvaluateMineCommand(CommandName + ' ' + Arguments.GetString(r, "Commands"), Arguments.GetString(r, "Commands").Split(' ', StringSplitOptions.TrimEntries)); @@ -57,7 +57,7 @@ class MineCube : ChatBot public override void OnUnload() { - Handler.dispatcher.Unregister(CommandName); + McClient.dispatcher.Unregister(CommandName); } /// diff --git a/MinecraftClient/config/ChatBots/SugarCaneFarmer.cs b/MinecraftClient/config/ChatBots/SugarCaneFarmer.cs index 68979e4b..9b670b48 100644 --- a/MinecraftClient/config/ChatBots/SugarCaneFarmer.cs +++ b/MinecraftClient/config/ChatBots/SugarCaneFarmer.cs @@ -151,7 +151,7 @@ class SugarCaneFarmer : SugarCaneFarmerBase { LogToConsole("Sugar Cane farming bot created by Daenges."); - Handler.dispatcher.Register(l => l.Literal(CommandName) + McClient.dispatcher.Register(l => l.Literal(CommandName) .Then(l => l.Argument("Commands", Arguments.GreedyString()) .Executes(r => { CommandHandler(Arguments.GetString(r, "Commands").Split(' ', StringSplitOptions.TrimEntries)); @@ -162,7 +162,7 @@ class SugarCaneFarmer : SugarCaneFarmerBase public override void OnUnload() { - Handler.dispatcher.Unregister(CommandName); + McClient.dispatcher.Unregister(CommandName); } ///