diff --git a/src/main/java/carpet/fakes/CommandDispatcherInterface.java b/src/main/java/carpet/fakes/CommandDispatcherInterface.java new file mode 100644 index 00000000..473b638a --- /dev/null +++ b/src/main/java/carpet/fakes/CommandDispatcherInterface.java @@ -0,0 +1,5 @@ +package carpet.fakes; + +public interface CommandDispatcherInterface { + void carpet$unregister(String node); +} diff --git a/src/main/java/carpet/fakes/CommandNodeInterface.java b/src/main/java/carpet/fakes/CommandNodeInterface.java new file mode 100644 index 00000000..9401dfb4 --- /dev/null +++ b/src/main/java/carpet/fakes/CommandNodeInterface.java @@ -0,0 +1,5 @@ +package carpet.fakes; + +public interface CommandNodeInterface { + void carpet$removeChild(String name); +} diff --git a/src/main/java/carpet/mixins/CommandDispatcher_scarpetCommandsMixin.java b/src/main/java/carpet/mixins/CommandDispatcher_scarpetCommandsMixin.java new file mode 100644 index 00000000..d97e74ea --- /dev/null +++ b/src/main/java/carpet/mixins/CommandDispatcher_scarpetCommandsMixin.java @@ -0,0 +1,22 @@ +package carpet.mixins; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.tree.RootCommandNode; + +import carpet.fakes.CommandDispatcherInterface; +import carpet.fakes.CommandNodeInterface; + +@Mixin(CommandDispatcher.class) +public class CommandDispatcher_scarpetCommandsMixin implements CommandDispatcherInterface { + @Shadow @Final + private RootCommandNode root; + + @Override + public void carpet$unregister(String node) { + ((CommandNodeInterface)this.root).carpet$removeChild(node); + } +} diff --git a/src/main/java/carpet/mixins/CommandNode_scarpetCommandsMixin.java b/src/main/java/carpet/mixins/CommandNode_scarpetCommandsMixin.java new file mode 100644 index 00000000..8e4fb593 --- /dev/null +++ b/src/main/java/carpet/mixins/CommandNode_scarpetCommandsMixin.java @@ -0,0 +1,30 @@ +package carpet.mixins; + +import java.util.Map; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import com.mojang.brigadier.tree.ArgumentCommandNode; +import com.mojang.brigadier.tree.CommandNode; +import com.mojang.brigadier.tree.LiteralCommandNode; + +import carpet.fakes.CommandNodeInterface; + +@Mixin(CommandNode.class) +public class CommandNode_scarpetCommandsMixin implements CommandNodeInterface { + @Shadow @Final + private Map> children; + @Shadow @Final + private Map> literals; + @Shadow @Final + private Map> arguments; + + @Override + public void carpet$removeChild(String name) { + this.children.remove(name); + this.literals.remove(name); + this.arguments.remove(name); + } +} diff --git a/src/main/java/carpet/script/CarpetScriptHost.java b/src/main/java/carpet/script/CarpetScriptHost.java index b549d86d..75f60c5c 100644 --- a/src/main/java/carpet/script/CarpetScriptHost.java +++ b/src/main/java/carpet/script/CarpetScriptHost.java @@ -192,7 +192,7 @@ public class CarpetScriptHost extends ScriptHost String hostName = main.name(); Predicate configValidator = getCommandConfigPermissions(); LiteralArgumentBuilder command = literal(hostName). - requires((player) -> CarpetServer.scriptServer.modules.containsKey(hostName) && useValidator.test(player) && configValidator.test(player)); + requires((player) -> useValidator.test(player) && configValidator.test(player)); for (Pair,FunctionArgument> commandData : entries) { command = this.addPathToCommand(command, commandData.getKey(), commandData.getValue()); @@ -472,7 +472,7 @@ public class CarpetScriptHost extends ScriptHost } String hostName = getName(); LiteralArgumentBuilder command = literal(hostName). - requires((player) -> scriptServer().modules.containsKey(hostName) && commandValidator.test(player) && configValidator.test(player)). + requires((player) -> commandValidator.test(player) && configValidator.test(player)). executes( (c) -> { CarpetScriptHost targetHost = scriptServer().modules.get(hostName).retrieveOwnForExecution(c.getSource()); @@ -505,7 +505,7 @@ public class CarpetScriptHost extends ScriptHost { command = command. then(literal(function). - requires((player) -> scriptServer().modules.containsKey(hostName) && scriptServer().modules.get(hostName).getFunction(function) != null). + requires((player) -> scriptServer().modules.get(hostName).getFunction(function) != null). executes((c) -> { CarpetScriptHost targetHost = scriptServer().modules.get(hostName).retrieveOwnForExecution(c.getSource()); Value response = targetHost.handleCommandLegacy(c.getSource(),function, null, ""); diff --git a/src/main/java/carpet/script/CarpetScriptServer.java b/src/main/java/carpet/script/CarpetScriptServer.java index 2de5fd4a..e2d2f140 100644 --- a/src/main/java/carpet/script/CarpetScriptServer.java +++ b/src/main/java/carpet/script/CarpetScriptServer.java @@ -1,6 +1,7 @@ package carpet.script; import carpet.CarpetSettings; +import carpet.fakes.CommandDispatcherInterface; import carpet.script.annotation.AnnotationParser; import carpet.script.api.Auxiliary; import carpet.script.api.BlockIterators; @@ -343,6 +344,7 @@ public class CarpetScriptServer extends ScriptServer events.removeAllHostEvents(modules.get(name)); modules.get(name).onClose(); modules.remove(name); + ((CommandDispatcherInterface)server.getCommands().getDispatcher()).carpet$unregister(name); if (!isRuleApp) unloadableModules.remove(name); CommandHelper.notifyPlayersCommandsChanged(server); if (notifySource) Messenger.m(source, "gi Removed "+name+" app"); diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index 3fd7fb06..2ab99cc4 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -155,6 +155,8 @@ "PersistentEntitySectionManager_scarpetMixin", "ReloadCommand_reloadAppsMixin", "SystemReport_addScarpetAppsMixin", + "CommandNode_scarpetCommandsMixin", + "CommandDispatcher_scarpetCommandsMixin", "RecipeManager_scarpetMixin", "Ingredient_scarpetMixin",