feat(bukkit/paper): add root command deletion support (#371)
This commit is contained in:
parent
17491c17c7
commit
2572b73c4b
10 changed files with 177 additions and 18 deletions
|
|
@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Annotations: Annotation string processors ([#353](https://github.com/Incendo/cloud/pull/353))
|
- Annotations: Annotation string processors ([#353](https://github.com/Incendo/cloud/pull/353))
|
||||||
- Annotations: `@CommandContainer` annotation processing ([#364](https://github.com/Incendo/cloud/pull/364))
|
- Annotations: `@CommandContainer` annotation processing ([#364](https://github.com/Incendo/cloud/pull/364))
|
||||||
- Annotations: `@CommandMethod` annotation processing for compile-time validation ([#365](https://github.com/Incendo/cloud/pull/365))
|
- Annotations: `@CommandMethod` annotation processing for compile-time validation ([#365](https://github.com/Incendo/cloud/pull/365))
|
||||||
|
- Add root command deletion support (core/pircbotx/javacord/jda/bukkit/paper) ([#369](https://github.com/Incendo/cloud/pull/369),
|
||||||
|
[#371](https://github.com/Incendo/cloud/pull/371))
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Core: Fix missing caption registration for the regex caption ([#351](https://github.com/Incendo/cloud/pull/351))
|
- Core: Fix missing caption registration for the regex caption ([#351](https://github.com/Incendo/cloud/pull/351))
|
||||||
|
|
|
||||||
|
|
@ -439,7 +439,8 @@ public abstract class CommandManager<C> {
|
||||||
// Mark the command for deletion.
|
// Mark the command for deletion.
|
||||||
final CommandTree.Node<@Nullable CommandArgument<C, ?>> node = this.commandTree.getNamedNode(rootCommand);
|
final CommandTree.Node<@Nullable CommandArgument<C, ?>> node = this.commandTree.getNamedNode(rootCommand);
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
throw new IllegalArgumentException(String.format("No root command named '%s' exists", rootCommand));
|
// If the node doesn't exist, we don't really need to delete it...
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The registration handler gets to act before we destruct the command.
|
// The registration handler gets to act before we destruct the command.
|
||||||
|
|
|
||||||
|
|
@ -963,15 +963,11 @@ public final class CommandTree<C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean removeNode(final @NonNull Node<@Nullable CommandArgument<C, ?>> node) {
|
private boolean removeNode(final @NonNull Node<@Nullable CommandArgument<C, ?>> node) {
|
||||||
if (node.isLeaf()) {
|
|
||||||
if (this.getRootNodes().contains(node)) {
|
if (this.getRootNodes().contains(node)) {
|
||||||
this.internalTree.removeChild(node);
|
this.internalTree.removeChild(node);
|
||||||
} else {
|
} else {
|
||||||
return node.getParent().removeChild(node);
|
return node.getParent().removeChild(node);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
throw new IllegalStateException(String.format("Cannot delete intermediate node '%s'", node));
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,13 +37,16 @@ import cloud.commandframework.permission.CommandPermission;
|
||||||
import cloud.commandframework.permission.Permission;
|
import cloud.commandframework.permission.Permission;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.concurrent.CompletionException;
|
import java.util.concurrent.CompletionException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import org.apiguardian.api.API;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.PluginIdentifiableCommand;
|
import org.bukkit.command.PluginIdentifiableCommand;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
final class BukkitCommand<C> extends org.bukkit.command.Command implements PluginIdentifiableCommand {
|
final class BukkitCommand<C> extends org.bukkit.command.Command implements PluginIdentifiableCommand {
|
||||||
|
|
||||||
|
|
@ -58,6 +61,8 @@ final class BukkitCommand<C> extends org.bukkit.command.Command implements Plugi
|
||||||
private final BukkitCommandManager<C> manager;
|
private final BukkitCommandManager<C> manager;
|
||||||
private final Command<C> cloudCommand;
|
private final Command<C> cloudCommand;
|
||||||
|
|
||||||
|
private boolean disabled;
|
||||||
|
|
||||||
BukkitCommand(
|
BukkitCommand(
|
||||||
final @NonNull String label,
|
final @NonNull String label,
|
||||||
final @NonNull List<@NonNull String> aliases,
|
final @NonNull List<@NonNull String> aliases,
|
||||||
|
|
@ -77,6 +82,7 @@ final class BukkitCommand<C> extends org.bukkit.command.Command implements Plugi
|
||||||
if (this.command.getOwningCommand() != null) {
|
if (this.command.getOwningCommand() != null) {
|
||||||
this.setPermission(this.command.getOwningCommand().getCommandPermission().toString());
|
this.setPermission(this.command.getOwningCommand().getCommandPermission().toString());
|
||||||
}
|
}
|
||||||
|
this.disabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -191,22 +197,38 @@ final class BukkitCommand<C> extends org.bukkit.command.Command implements Plugi
|
||||||
@Override
|
@Override
|
||||||
public @NonNull String getUsage() {
|
public @NonNull String getUsage() {
|
||||||
return this.manager.getCommandSyntaxFormatter().apply(
|
return this.manager.getCommandSyntaxFormatter().apply(
|
||||||
Collections.singletonList(this.namedNode().getValue()),
|
Collections.singletonList(Objects.requireNonNull(this.namedNode().getValue())),
|
||||||
this.namedNode()
|
this.namedNode()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean testPermissionSilent(final @NonNull CommandSender target) {
|
public boolean testPermissionSilent(final @NonNull CommandSender target) {
|
||||||
final CommandPermission permission = (CommandPermission) this.namedNode()
|
final CommandTree.Node<CommandArgument<C, ?>> node = this.namedNode();
|
||||||
|
if (this.disabled || node == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final CommandPermission permission = (CommandPermission) node
|
||||||
.getNodeMeta()
|
.getNodeMeta()
|
||||||
.getOrDefault("permission", Permission.empty());
|
.getOrDefault("permission", Permission.empty());
|
||||||
|
|
||||||
return this.manager.hasPermission(this.manager.getCommandSenderMapper().apply(target), permission);
|
return this.manager.hasPermission(this.manager.getCommandSenderMapper().apply(target), permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CommandTree.Node<CommandArgument<C, ?>> namedNode() {
|
@API(status = API.Status.INTERNAL, since = "1.7.0")
|
||||||
return this.manager.getCommandTree().getNamedNode(this.command.getName());
|
void disable() {
|
||||||
|
this.disabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRegistered() {
|
||||||
|
// This allows us to prevent the command from showing
|
||||||
|
// in Bukkit help topics.
|
||||||
|
return !this.disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CommandTree.@Nullable Node<CommandArgument<C, ?>> namedNode() {
|
||||||
|
return this.manager.getCommandTree().getNamedNode(this.command.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,7 @@ public class BukkitCommandManager<C> extends CommandManager<C> implements Brigad
|
||||||
|
|
||||||
/* Register capabilities */
|
/* Register capabilities */
|
||||||
CloudBukkitCapabilities.CAPABLE.forEach(this::registerCapability);
|
CloudBukkitCapabilities.CAPABLE.forEach(this::registerCapability);
|
||||||
|
this.registerCapability(CloudCapability.StandardCapabilities.ROOT_COMMAND_DELETION);
|
||||||
|
|
||||||
/* Register Bukkit Preprocessor */
|
/* Register Bukkit Preprocessor */
|
||||||
this.registerCommandPreProcessor(new BukkitCommandPreprocessor<>(this));
|
this.registerCommandPreProcessor(new BukkitCommandPreprocessor<>(this));
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,12 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
import org.apiguardian.api.API;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.CommandMap;
|
import org.bukkit.command.CommandMap;
|
||||||
import org.bukkit.command.PluginIdentifiableCommand;
|
import org.bukkit.command.PluginIdentifiableCommand;
|
||||||
import org.bukkit.command.SimpleCommandMap;
|
import org.bukkit.command.SimpleCommandMap;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.help.GenericCommandHelpTopic;
|
import org.bukkit.help.GenericCommandHelpTopic;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
|
@ -53,7 +55,7 @@ public class BukkitPluginRegistrationHandler<C> implements CommandRegistrationHa
|
||||||
private BukkitCommandManager<C> bukkitCommandManager;
|
private BukkitCommandManager<C> bukkitCommandManager;
|
||||||
private CommandMap commandMap;
|
private CommandMap commandMap;
|
||||||
|
|
||||||
BukkitPluginRegistrationHandler() {
|
protected BukkitPluginRegistrationHandler() {
|
||||||
}
|
}
|
||||||
|
|
||||||
final void initialize(final @NonNull BukkitCommandManager<C> bukkitCommandManager) throws Exception {
|
final void initialize(final @NonNull BukkitCommandManager<C> bukkitCommandManager) throws Exception {
|
||||||
|
|
@ -93,7 +95,7 @@ public class BukkitPluginRegistrationHandler<C> implements CommandRegistrationHa
|
||||||
|
|
||||||
if (this.bukkitCommandManager.getSetting(CommandManager.ManagerSettings.OVERRIDE_EXISTING_COMMANDS)) {
|
if (this.bukkitCommandManager.getSetting(CommandManager.ManagerSettings.OVERRIDE_EXISTING_COMMANDS)) {
|
||||||
this.bukkitCommands.remove(label);
|
this.bukkitCommands.remove(label);
|
||||||
aliases.forEach(alias -> this.bukkitCommands.remove(alias));
|
aliases.forEach(this.bukkitCommands::remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Set<String> newAliases = new HashSet<>();
|
final Set<String> newAliases = new HashSet<>();
|
||||||
|
|
@ -126,6 +128,46 @@ public class BukkitPluginRegistrationHandler<C> implements CommandRegistrationHa
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public final void unregisterRootCommand(
|
||||||
|
final @NonNull StaticArgument<?> rootCommand
|
||||||
|
) {
|
||||||
|
final org.bukkit.command.Command registeredCommand = this.registeredCommands.get(rootCommand);
|
||||||
|
if (registeredCommand == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
((BukkitCommand<C>) registeredCommand).disable();
|
||||||
|
|
||||||
|
final List<String> aliases = new ArrayList<>(rootCommand.getAlternativeAliases());
|
||||||
|
final Set<String> registeredAliases = new HashSet<>();
|
||||||
|
|
||||||
|
for (final String alias : aliases) {
|
||||||
|
registeredAliases.add(this.getNamespacedLabel(alias));
|
||||||
|
if (this.bukkitCommandOrAliasExists(alias)) {
|
||||||
|
registeredAliases.add(alias);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.bukkitCommandExists(rootCommand.getName())) {
|
||||||
|
registeredAliases.add(rootCommand.getName());
|
||||||
|
}
|
||||||
|
registeredAliases.add(this.getNamespacedLabel(rootCommand.getName()));
|
||||||
|
|
||||||
|
this.bukkitCommands.remove(rootCommand.getName());
|
||||||
|
this.bukkitCommands.remove(this.getNamespacedLabel(rootCommand.getName()));
|
||||||
|
|
||||||
|
this.recognizedAliases.removeAll(registeredAliases);
|
||||||
|
if (this.bukkitCommandManager.getSplitAliases()) {
|
||||||
|
registeredAliases.forEach(this::unregisterExternal);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.registeredCommands.remove(rootCommand);
|
||||||
|
|
||||||
|
// Once the command has been unregistered, we need to refresh the command list for all online players.
|
||||||
|
Bukkit.getOnlinePlayers().forEach(Player::updateCommands);
|
||||||
|
}
|
||||||
|
|
||||||
private @NonNull String getNamespacedLabel(final @NonNull String label) {
|
private @NonNull String getNamespacedLabel(final @NonNull String label) {
|
||||||
return String.format("%s:%s", this.bukkitCommandManager.getOwningPlugin().getName(), label).toLowerCase();
|
return String.format("%s:%s", this.bukkitCommandManager.getOwningPlugin().getName(), label).toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
@ -147,6 +189,10 @@ public class BukkitPluginRegistrationHandler<C> implements CommandRegistrationHa
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@API(status = API.Status.STABLE, since = "1.7.0")
|
||||||
|
protected void unregisterExternal(final @NonNull String label) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if a command exists in the Bukkit command map, is not an alias, and is not owned by us.
|
* Returns true if a command exists in the Bukkit command map, is not an alias, and is not owned by us.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerLoginEvent;
|
import org.bukkit.event.player.PlayerLoginEvent;
|
||||||
|
import org.bukkit.event.server.PluginDisableEvent;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -47,4 +48,10 @@ final class CloudBukkitListener<C> implements Listener {
|
||||||
this.bukkitCommandManager.lockIfBrigadierCapable();
|
this.bukkitCommandManager.lockIfBrigadierCapable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
void onPluginDisable(final @NonNull PluginDisableEvent event) {
|
||||||
|
if (event.getPlugin().equals(this.bukkitCommandManager.getOwningPlugin())) {
|
||||||
|
this.bukkitCommandManager.rootCommands().forEach(this.bukkitCommandManager::deleteRootCommand);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,11 @@ import cloud.commandframework.bukkit.internal.BukkitBackwardsBrigadierSenderMapp
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
import com.mojang.brigadier.tree.CommandNode;
|
import com.mojang.brigadier.tree.CommandNode;
|
||||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||||
|
import com.mojang.brigadier.tree.RootCommandNode;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import me.lucko.commodore.Commodore;
|
import me.lucko.commodore.Commodore;
|
||||||
import me.lucko.commodore.CommodoreProvider;
|
import me.lucko.commodore.CommodoreProvider;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
|
@ -74,6 +78,11 @@ class CloudCommodoreManager<C> extends BukkitPluginRegistrationHandler<C> {
|
||||||
this.registerWithCommodore(label, (Command<C>) command);
|
this.registerWithCommodore(label, (Command<C>) command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void unregisterExternal(final @NonNull String label) {
|
||||||
|
this.unregisterWithCommodore(label);
|
||||||
|
}
|
||||||
|
|
||||||
protected @NonNull CloudBrigadierManager brigadierManager() {
|
protected @NonNull CloudBrigadierManager brigadierManager() {
|
||||||
return this.brigadierManager;
|
return this.brigadierManager;
|
||||||
}
|
}
|
||||||
|
|
@ -84,6 +93,11 @@ class CloudCommodoreManager<C> extends BukkitPluginRegistrationHandler<C> {
|
||||||
) {
|
) {
|
||||||
final LiteralCommandNode<?> literalCommandNode = this.brigadierManager
|
final LiteralCommandNode<?> literalCommandNode = this.brigadierManager
|
||||||
.createLiteralCommandNode(label, command, (o, p) -> {
|
.createLiteralCommandNode(label, command, (o, p) -> {
|
||||||
|
// We need to check that the command still exists...
|
||||||
|
if (this.commandManager.getCommandTree().getNamedNode(label) == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
final CommandSender sender = this.commodore.getBukkitSender(o);
|
final CommandSender sender = this.commodore.getBukkitSender(o);
|
||||||
return this.commandManager.hasPermission(this.commandManager.getCommandSenderMapper().apply(sender), p);
|
return this.commandManager.hasPermission(this.commandManager.getCommandSenderMapper().apply(sender), p);
|
||||||
}, false, o -> 1);
|
}, false, o -> 1);
|
||||||
|
|
@ -95,6 +109,35 @@ class CloudCommodoreManager<C> extends BukkitPluginRegistrationHandler<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void unregisterWithCommodore(
|
||||||
|
final @NonNull String label
|
||||||
|
) {
|
||||||
|
final CommandNode node = this.commodore.getDispatcher().findNode(Collections.singletonList(label));
|
||||||
|
if (node == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Class<? extends Commodore> commodoreImpl = (Class<? extends Commodore>) Class.forName("me.lucko.commodore.CommodoreImpl");
|
||||||
|
|
||||||
|
final Method removeChild = commodoreImpl.getDeclaredMethod("removeChild", RootCommandNode.class, String.class);
|
||||||
|
removeChild.setAccessible(true);
|
||||||
|
|
||||||
|
removeChild.invoke(
|
||||||
|
null /* static method */,
|
||||||
|
this.commodore.getDispatcher().getRoot(),
|
||||||
|
node.getName()
|
||||||
|
);
|
||||||
|
|
||||||
|
final Field registeredNodes = commodoreImpl.getDeclaredField("registeredNodes");
|
||||||
|
registeredNodes.setAccessible(true);
|
||||||
|
|
||||||
|
((List<LiteralCommandNode<?>>) registeredNodes.get(this.commodore)).remove(node);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new RuntimeException(String.format("Failed to unregister command '%s' with commodore", label), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void mergeChildren(@Nullable final CommandNode<?> existingNode, @Nullable final CommandNode<?> node) {
|
private void mergeChildren(@Nullable final CommandNode<?> existingNode, @Nullable final CommandNode<?> node) {
|
||||||
for (final CommandNode child : node.getChildren()) {
|
for (final CommandNode child : node.getChildren()) {
|
||||||
final CommandNode<?> existingChild = existingNode.getChild(child.getName());
|
final CommandNode<?> existingChild = existingNode.getChild(child.getName());
|
||||||
|
|
|
||||||
|
|
@ -79,16 +79,24 @@ class PaperBrigadierListener<C> implements Listener {
|
||||||
|
|
||||||
final CommandTree<C> commandTree = this.paperCommandManager.getCommandTree();
|
final CommandTree<C> commandTree = this.paperCommandManager.getCommandTree();
|
||||||
|
|
||||||
String label = event.getCommandLabel();
|
final String label;
|
||||||
if (label.contains(":")) {
|
if (event.getCommandLabel().contains(":")) {
|
||||||
label = label.split(Pattern.quote(":"))[1];
|
label = event.getCommandLabel().split(Pattern.quote(":"))[1];
|
||||||
|
} else {
|
||||||
|
label = event.getCommandLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
final CommandTree.Node<CommandArgument<C, ?>> node = commandTree.getNamedNode(label);
|
final CommandTree.Node<CommandArgument<C, ?>> node = commandTree.getNamedNode(label);
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final BiPredicate<BukkitBrigadierCommandSource, CommandPermission> permissionChecker = (s, p) -> {
|
final BiPredicate<BukkitBrigadierCommandSource, CommandPermission> permissionChecker = (s, p) -> {
|
||||||
|
// We need to check that the command still exists...
|
||||||
|
if (commandTree.getNamedNode(label) == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
final C sender = this.paperCommandManager.getCommandSenderMapper().apply(s.getBukkitSender());
|
final C sender = this.paperCommandManager.getCommandSenderMapper().apply(s.getBukkitSender());
|
||||||
return this.paperCommandManager.hasPermission(sender, p);
|
return this.paperCommandManager.hasPermission(sender, p);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import cloud.commandframework.annotations.Confirmation;
|
||||||
import cloud.commandframework.annotations.Flag;
|
import cloud.commandframework.annotations.Flag;
|
||||||
import cloud.commandframework.annotations.Regex;
|
import cloud.commandframework.annotations.Regex;
|
||||||
import cloud.commandframework.annotations.specifier.Greedy;
|
import cloud.commandframework.annotations.specifier.Greedy;
|
||||||
|
import cloud.commandframework.annotations.suggestions.Suggestions;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ParserParameters;
|
import cloud.commandframework.arguments.parser.ParserParameters;
|
||||||
import cloud.commandframework.arguments.parser.StandardParameters;
|
import cloud.commandframework.arguments.parser.StandardParameters;
|
||||||
|
|
@ -51,6 +52,7 @@ import cloud.commandframework.bukkit.parsers.WorldArgument;
|
||||||
import cloud.commandframework.bukkit.parsers.selector.SingleEntitySelectorArgument;
|
import cloud.commandframework.bukkit.parsers.selector.SingleEntitySelectorArgument;
|
||||||
import cloud.commandframework.captions.Caption;
|
import cloud.commandframework.captions.Caption;
|
||||||
import cloud.commandframework.captions.SimpleCaptionRegistry;
|
import cloud.commandframework.captions.SimpleCaptionRegistry;
|
||||||
|
import cloud.commandframework.context.CommandContext;
|
||||||
import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator;
|
import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator;
|
||||||
import cloud.commandframework.execution.CommandExecutionCoordinator;
|
import cloud.commandframework.execution.CommandExecutionCoordinator;
|
||||||
import cloud.commandframework.extra.confirmation.CommandConfirmationManager;
|
import cloud.commandframework.extra.confirmation.CommandConfirmationManager;
|
||||||
|
|
@ -71,6 +73,7 @@ import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
@ -454,7 +457,7 @@ public final class ExamplePlugin extends JavaPlugin {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@CommandMethod("example help [query]")
|
@CommandMethod("example|e|ex help [query]")
|
||||||
@CommandDescription("Help menu")
|
@CommandDescription("Help menu")
|
||||||
public void commandHelp(
|
public void commandHelp(
|
||||||
final @NonNull CommandSender sender,
|
final @NonNull CommandSender sender,
|
||||||
|
|
@ -528,6 +531,36 @@ public final class ExamplePlugin extends JavaPlugin {
|
||||||
.execute(() -> sender.sendMessage("You have been teleported!"));
|
.execute(() -> sender.sendMessage("You have been teleported!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@CommandMethod("removeall")
|
||||||
|
public void removeAll(
|
||||||
|
final @NonNull CommandSender sender
|
||||||
|
) {
|
||||||
|
this.manager.rootCommands().forEach(this.manager::deleteRootCommand);
|
||||||
|
sender.sendMessage("All root commands have been deleted :)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@CommandMethod("removesingle <command>")
|
||||||
|
public void removeSingle(
|
||||||
|
final @NonNull CommandSender sender,
|
||||||
|
final @Argument(value = "command", suggestions = "commands") String command
|
||||||
|
) {
|
||||||
|
this.manager.deleteRootCommand(command);
|
||||||
|
sender.sendMessage("Deleted the root command :)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suggestions("commands")
|
||||||
|
public List<String> commands(
|
||||||
|
final @NonNull CommandContext<CommandSender> context,
|
||||||
|
final @NonNull String input
|
||||||
|
) {
|
||||||
|
return new ArrayList<>(this.manager.rootCommands());
|
||||||
|
}
|
||||||
|
|
||||||
|
@CommandMethod("disableme")
|
||||||
|
public void disableMe() {
|
||||||
|
this.getServer().getPluginManager().disablePlugin(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command must have the given game mode
|
* Command must have the given game mode
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue