From d27200397f79414a7705a03eb34004a01c5e8d09 Mon Sep 17 00:00:00 2001 From: Revxrsal Date: Sat, 21 Sep 2024 23:11:36 +0300 Subject: [PATCH] implement granular un-registration for bukkit --- .../bukkit/hooks/BukkitCommandHooks.java | 26 ++++++++++++++++++- .../list/AnnotationListFromMap.java | 1 - .../commands/node/CommandRegistry.java | 22 +++++++++++++++- .../node/parser/BaseCommandRegistry.java | 9 +++++++ 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/bukkit/src/main/java/revxrsal/commands/bukkit/hooks/BukkitCommandHooks.java b/bukkit/src/main/java/revxrsal/commands/bukkit/hooks/BukkitCommandHooks.java index 7dca2c1a..b604c342 100644 --- a/bukkit/src/main/java/revxrsal/commands/bukkit/hooks/BukkitCommandHooks.java +++ b/bukkit/src/main/java/revxrsal/commands/bukkit/hooks/BukkitCommandHooks.java @@ -23,6 +23,7 @@ */ package revxrsal.commands.bukkit.hooks; +import org.bukkit.Bukkit; import org.bukkit.command.PluginCommand; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; @@ -33,12 +34,14 @@ import revxrsal.commands.command.ExecutableCommand; import revxrsal.commands.hook.CancelHandle; import revxrsal.commands.hook.CommandRegisteredHook; +import revxrsal.commands.hook.CommandUnregisteredHook; import java.util.HashSet; import java.util.Objects; import java.util.Set; -public final class BukkitCommandHooks implements CommandRegisteredHook { +public final class BukkitCommandHooks implements CommandRegisteredHook, + CommandUnregisteredHook { private final Set registeredRootNames = new HashSet<>(); @@ -70,4 +73,25 @@ public void onRegistered(@NotNull ExecutableCommand command, @NotNull CancelH cmd.setUsage(command.usage()); } } + + @Override public void onUnregistered(@NotNull ExecutableCommand command, @NotNull CancelHandle cancelHandle) { + String label = command.firstNode().name(); + String fallbackPrefix = fallbackPrefix(command); + PluginCommand cmd = Bukkit.getServer().getPluginCommand(fallbackPrefix + ':' + label); + // check there's no other '/fallback_prefix:label' command. if so, unregister. + if (!command.lamp().registry().any(c -> c != command && c.firstNode().name().equals(label) && fallbackPrefix(c).equals(fallbackPrefix))) + if (cmd != null) + PluginCommands.unregister(cmd, plugin); + + // check there's no other '/label' command. if so, unregister. + if (!command.lamp().registry().any(c -> c != command && c.firstNode().name().equals(label))) { + cmd = plugin.getCommand(label); + if (cmd != null) + PluginCommands.unregister(cmd, plugin); + } + } + + private @NotNull String fallbackPrefix(@NotNull ExecutableCommand command) { + return command.annotations().mapOr(FallbackPrefix.class, FallbackPrefix::value, defaultFallbackPrefix); + } } diff --git a/common/src/main/java/revxrsal/commands/annotation/list/AnnotationListFromMap.java b/common/src/main/java/revxrsal/commands/annotation/list/AnnotationListFromMap.java index 5d51dd55..125cf0cc 100644 --- a/common/src/main/java/revxrsal/commands/annotation/list/AnnotationListFromMap.java +++ b/common/src/main/java/revxrsal/commands/annotation/list/AnnotationListFromMap.java @@ -156,7 +156,6 @@ public boolean contains(@NotNull Class type) { } if (element instanceof Method method) { distributeAnnotations(annotations, method, replacers); - System.out.println(annotations); } return new AnnotationListFromMap(annotations); } diff --git a/common/src/main/java/revxrsal/commands/node/CommandRegistry.java b/common/src/main/java/revxrsal/commands/node/CommandRegistry.java index 94f6c477..a82ee3ff 100644 --- a/common/src/main/java/revxrsal/commands/node/CommandRegistry.java +++ b/common/src/main/java/revxrsal/commands/node/CommandRegistry.java @@ -23,6 +23,7 @@ */ package revxrsal.commands.node; +import org.jetbrains.annotations.CheckReturnValue; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.UnmodifiableView; @@ -103,7 +104,26 @@ default void execute(@NotNull A actor, @NotNull String input) { * * @param matches Criteria to test for */ - void unregisterIf(@NotNull Predicate> matches); + void unregisterIf(@NotNull Predicate<@NotNull ExecutableCommand> matches); + + /** + * Tests whether any of the registered commands matches the + * given predicate + * + * @param matches Criteria to test for + * @return if any command matches the predicate + */ + boolean any(@NotNull Predicate<@NotNull ExecutableCommand> matches); + + /** + * Returns a new list of all commands that match the + * given predicate + * + * @param filterPredicate Criteria to test for + * @return a list of all commands that match the predicate + */ + @NotNull @CheckReturnValue @Contract("_ -> new") + List> filter(@NotNull Predicate<@NotNull ExecutableCommand> filterPredicate); /** * Returns an immutable iterator of all entries in this registry. diff --git a/common/src/main/java/revxrsal/commands/node/parser/BaseCommandRegistry.java b/common/src/main/java/revxrsal/commands/node/parser/BaseCommandRegistry.java index 6be3bd78..0389026a 100644 --- a/common/src/main/java/revxrsal/commands/node/parser/BaseCommandRegistry.java +++ b/common/src/main/java/revxrsal/commands/node/parser/BaseCommandRegistry.java @@ -193,6 +193,15 @@ public void execute(@NotNull A actor, @NotNull StringStream input) { children.remove(execution); } + @Override public boolean any(@NotNull Predicate<@NotNull ExecutableCommand> matches) { + return revxrsal.commands.util.Collections.any(children, matches); + } + + @Override + public @NotNull List> filter(@NotNull Predicate<@NotNull ExecutableCommand> filterPredicate) { + return revxrsal.commands.util.Collections.filter(children, filterPredicate); + } + @Override public void unregisterIf(@NotNull Predicate> matches) { children.removeIf(matches); }