Add initial brigadier support (implements #77) (#153)

Co-authored-by: Aikar <aikar@aikar.co>
This commit is contained in:
MiniDigger
2020-08-14 02:40:06 +02:00
committed by GitHub
parent a8b69370ae
commit 9452873d13
17 changed files with 519 additions and 17 deletions
+10 -7
View File
@@ -7,20 +7,22 @@
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="acf-sponge" />
<module name="acf" />
<module name="acf-example" />
<module name="example-plugin" />
<module name="acf-brigadier" />
<module name="acf-paper" />
<module name="acf-jda" />
<module name="acf-core" />
<module name="acf-velocity" />
<module name="acf-bukkit" />
<module name="acf-bungee" />
<module name="acf-core" />
<module name="acf-example" />
<module name="acf-jda" />
<module name="acf-paper" />
<module name="acf-sponge" />
<module name="acf-velocity" />
<module name="example-plugin" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
<module name="acf" target="1.8" />
<module name="acf-brigadier" target="1.8" />
<module name="acf-bukkit" target="1.8" />
<module name="acf-bungee" target="1.8" />
<module name="acf-core" target="1.8" />
@@ -36,6 +38,7 @@
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="acf-brigadier" options="-parameters" />
<module name="acf-bukkit" options="-parameters" />
<module name="acf-bungee" options="-parameters" />
<module name="acf-core" options="-parameters" />
+2
View File
@@ -2,6 +2,8 @@
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/brigadier" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/brigadier/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/bukkit" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/bukkit/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/bungee" charset="UTF-8" />
+1
View File
@@ -35,6 +35,7 @@
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
<option name="myAdditionalJavadocTags" value="" />
</inspection_tool>
<inspection_tool class="MissingJSR305" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="SameParameterValue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" />
+74
View File
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
~
~ Permission is hereby granted, free of charge, to any person obtaining
~ a copy of this software and associated documentation files (the
~ "Software"), to deal in the Software without restriction, including
~ without limitation the rights to use, copy, modify, merge, publish,
~ distribute, sublicense, and/or sell copies of the Software, and to
~ permit persons to whom the Software is furnished to do so, subject to
~ the following conditions:
~
~ The above copyright notice and this permission notice shall be
~ included in all copies or substantial portions of the Software.
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
~ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
~ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
~ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
~ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
~ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
~ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>co.aikar</groupId>
<artifactId>acf-parent</artifactId>
<version><!--VERSION-->0.5.0-SNAPSHOT<!--VERSION--></version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>acf-brigadier</artifactId>
<version><!--VERSION-->0.5.0-SNAPSHOT<!--VERSION--></version>
<name>ACF (Brigadier)</name>
<repositories>
<repository>
<id>mojang-repo</id>
<url>https://libraries.minecraft.net/</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>co.aikar</groupId>
<artifactId>acf-core</artifactId>
<version><!--VERSION-->0.5.0-SNAPSHOT<!--VERSION--></version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>brigadier</artifactId>
<version>1.0.17</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,164 @@
package co.aikar.commands;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.BoolArgumentType;
import com.mojang.brigadier.arguments.DoubleArgumentType;
import com.mojang.brigadier.arguments.FloatArgumentType;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.suggestion.SuggestionProvider;
import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
/**
* Handles registering of commands into brigadier
*
* @param <S>
* @author MiniDigger
* @deprecated Unstable API
*/
@Deprecated
@UnstableAPI
public class ACFBrigadierManager<S> {
protected final CommandManager<?, ?, ?, ?, ?, ?> manager;
private final Map<Class<?>, ArgumentType<?>> arguments = new HashMap<>();
/**
* Constructs a new brigadier manager, utilizing the currently active command manager
*
* @param manager
*/
ACFBrigadierManager(CommandManager<?, ?, ?, ?, ?, ?> manager) {
manager.verifyUnstableAPI("brigadier");
this.manager = manager;
// TODO support stuff like min max via brigadier?
registerArgument(String.class, StringArgumentType.word());
registerArgument(float.class, FloatArgumentType.floatArg());
registerArgument(Float.class, FloatArgumentType.floatArg());
registerArgument(double.class, DoubleArgumentType.doubleArg());
registerArgument(Double.class, DoubleArgumentType.doubleArg());
registerArgument(boolean.class, BoolArgumentType.bool());
registerArgument(Boolean.class, BoolArgumentType.bool());
registerArgument(int.class, IntegerArgumentType.integer());
registerArgument(Integer.class, IntegerArgumentType.integer());
// We use integer for long due to Bungee bug, plus should really be considered same on client
registerArgument(long.class, IntegerArgumentType.integer());
registerArgument(Long.class, IntegerArgumentType.integer());
}
<T> void registerArgument(Class<T> clazz, ArgumentType<?> type) {
arguments.put(clazz, type);
}
ArgumentType<Object> getArgumentTypeByClazz(CommandParameter param) {
if (param.consumesRest) {
//noinspection unchecked
return (ArgumentType<Object>) (ArgumentType<?>) StringArgumentType.greedyString();
}
//noinspection unchecked
return (ArgumentType<Object>) arguments.getOrDefault(param.getType(), StringArgumentType.string());
}
/**
* Registers the given RootCommand into the given brigadir command node, utilizing the provided suggestion provider, executor and permission predicate.<br>
* <p>
* It recreates the root command node!
*/
LiteralCommandNode<S> register(RootCommand rootCommand,
LiteralCommandNode<S> root,
SuggestionProvider<S> suggestionProvider,
Command<S> executor,
BiPredicate<RootCommand, S> permCheckerRoot,
BiPredicate<RegisteredCommand, S> permCheckerSub) {
// recreate root to get rid of bukkits default arg
LiteralArgumentBuilder<S> rootBuilder = LiteralArgumentBuilder.<S>literal(root.getLiteral())
.requires(sender -> permCheckerRoot.test(rootCommand, sender));
root = rootBuilder.build();
boolean isForwardingCommand = rootCommand.getDefCommand() instanceof ForwardingCommand;
for (Map.Entry<String, RegisteredCommand> subCommand : rootCommand.getSubCommands().entries()) {
if ((BaseCommand.isSpecialSubcommand(subCommand.getKey()) && !isForwardingCommand) || (!subCommand.getKey().equals("help") && subCommand.getValue().prefSubCommand.equals("help"))) {
// don't register stuff like __catchunknown and don't help command aliases
continue;
}
// handle sub sub commands
String commandName = subCommand.getKey();
CommandNode<S> currentParent = root;
CommandNode<S> subCommandNode;
Predicate<S> subPermChecker = sender -> permCheckerSub.test(subCommand.getValue(), sender);
if (!isForwardingCommand) {
if (commandName.contains(" ")) {
String[] split = ACFPatterns.SPACE.split(commandName);
for (int i = 0; i < split.length - 1; i++) {
if (currentParent.getChild(split[i]) == null) {
LiteralCommandNode<S> sub = LiteralArgumentBuilder.<S>literal(split[i])
.requires(subPermChecker).build();
currentParent.addChild(sub);
currentParent = sub;
} else {
currentParent = currentParent.getChild(split[i]);
}
}
commandName = split[split.length - 1];
}
subCommandNode = currentParent.getChild(commandName);
if (subCommandNode == null) {
LiteralArgumentBuilder<S> argumentBuilder = LiteralArgumentBuilder.<S>literal(commandName)
.requires(subPermChecker);
// if we have no params, this command is actually executable
if (subCommand.getValue().consumeInputResolvers == 0) {
argumentBuilder.executes(executor);
}
subCommandNode = argumentBuilder.build();
}
} else {
subCommandNode = root;
}
CommandNode<S> paramNode = subCommandNode;
CommandParameter[] parameters = subCommand.getValue().parameters;
for (int i = 0; i < parameters.length; i++) {
CommandParameter param = parameters[i];
CommandParameter nextParam = param.getNextParam();
if (param.isCommandIssuer() || (param.canExecuteWithoutInput() && nextParam != null && !nextParam.canExecuteWithoutInput())) {
continue;
}
RequiredArgumentBuilder<S, Object> builder = RequiredArgumentBuilder
.<S, Object>argument(param.getName(), getArgumentTypeByClazz(param))
.suggests(suggestionProvider)
.requires(sender -> permCheckerSub.test(subCommand.getValue(), sender));
if (nextParam != null && nextParam.canExecuteWithoutInput()) {
builder.executes(executor);
}
CommandNode<S> subSubCommand = builder.build();
paramNode.addChild(subSubCommand);
paramNode = subSubCommand;
}
if (!isForwardingCommand) {
currentParent.addChild(subCommandNode);
}
}
return root;
}
}
@@ -662,7 +662,7 @@ public abstract class BaseCommand {
String argString = ApacheCommonsLangUtil.join(args, " ").toLowerCase(Locale.ENGLISH);
for (Map.Entry<String, RegisteredCommand> entry : subCommands.entries()) {
final String key = entry.getKey();
if (key.startsWith(argString) && !CATCHUNKNOWN.equals(key) && !DEFAULT.equals(key)) {
if (key.startsWith(argString) && !isSpecialSubcommand(key)) {
final RegisteredCommand value = entry.getValue();
if (!value.hasPermission(issuer) || value.isPrivate) {
continue;
@@ -675,6 +675,10 @@ public abstract class BaseCommand {
return new ArrayList<>(cmds);
}
static boolean isSpecialSubcommand(String key) {
return CATCHUNKNOWN.equals(key) || DEFAULT.equals(key);
}
/**
* Complete a command properly per issuer and input.
*
@@ -839,4 +843,8 @@ public abstract class BaseCommand {
registeredCommands.addAll(this.subCommands.values());
return registeredCommands;
}
protected SetMultimap<String, RegisteredCommand> getSubCommands() {
return subCommands;
}
}
@@ -66,9 +66,13 @@ public class CommandParameter<CEC extends CommandExecutionContext<CEC, ? extends
private boolean canConsumeInput;
private boolean optionalResolver;
boolean consumesRest;
private boolean isLast;
private boolean isOptionalInput;
private CommandParameter<CEC> nextParam;
public CommandParameter(RegisteredCommand<CEC> command, Parameter param, int paramIndex, boolean isLast) {
this.parameter = param;
this.isLast = isLast;
this.type = param.getType();
this.name = param.getName(); // do we care for an annotation to supply name?
this.manager = command.manager;
@@ -99,10 +103,12 @@ public class CommandParameter<CEC extends CommandExecutionContext<CEC, ? extends
this.values = annotations.getAnnotationValues(param, Values.class, Annotations.REPLACEMENTS | Annotations.NO_EMPTY);
this.syntax = null;
this.isOptionalInput = !requiresInput && canConsumeInput;
if (!commandIssuer) {
this.syntax = annotations.getAnnotationValue(param, Syntax.class);
if (syntax == null) {
if (!requiresInput && canConsumeInput) {
if (isOptionalInput) {
this.syntax = "[" + name + "]";
} else if (requiresInput) {
this.syntax = "<" + name + ">";
@@ -184,6 +190,10 @@ public class CommandParameter<CEC extends CommandExecutionContext<CEC, ? extends
this.resolver = resolver;
}
public boolean isOptionalInput() {
return isOptionalInput;
}
public boolean isOptional() {
return optional;
}
@@ -275,4 +285,20 @@ public class CommandParameter<CEC extends CommandExecutionContext<CEC, ? extends
public Set<String> getRequiredPermissions() {
return permissions;
}
public void setNextParam(CommandParameter<CEC> nextParam) {
this.nextParam = nextParam;
}
public CommandParameter<CEC> getNextParam() {
return nextParam;
}
public boolean canExecuteWithoutInput() {
return (!canConsumeInput || isOptionalInput()) && (nextParam == null || nextParam.canExecuteWithoutInput());
}
public boolean isLast() {
return isLast;
}
}
@@ -23,8 +23,6 @@
package co.aikar.commands;
import co.aikar.commands.apachecommonslang.ApacheCommonsLangUtil;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -84,7 +84,7 @@ public class RegisteredCommand<CEC extends CommandExecutionContext<CEC, ? extend
this.manager = this.scope.manager;
final Annotations annotations = this.manager.getAnnotations();
if (BaseCommand.CATCHUNKNOWN.equals(prefSubCommand) || BaseCommand.DEFAULT.equals(prefSubCommand)) {
if (BaseCommand.isSpecialSubcommand(prefSubCommand)) {
prefSubCommand = "";
command = command.trim();
}
@@ -110,8 +110,13 @@ public class RegisteredCommand<CEC extends CommandExecutionContext<CEC, ? extend
int optionalResolvers = 0;
StringBuilder syntaxBuilder = new StringBuilder(64);
CommandParameter<CEC> previousParam = null;
for (int i = 0; i < parameters.length; i++) {
CommandParameter<CEC> parameter = this.parameters[i] = new CommandParameter<>(this, parameters[i], i, i == parameters.length - 1);
if (previousParam != null) {
previousParam.setNextParam(parameter);
}
previousParam = parameter;
if (!parameter.isCommandIssuer()) {
if (!parameter.requiresInput()) {
optionalResolvers++;
@@ -247,9 +252,9 @@ public class RegisteredCommand<CEC extends CommandExecutionContext<CEC, ? extend
} else if (allowOptional && parameter.isOptional()) {
Object value;
if (!parameter.isOptionalResolver() || !this.manager.hasPermission(sender, parameterPermissions)) {
value = null;
value = null;
} else {
value = resolver.getContext(context);
value = resolver.getContext(context);
}
if (value == null && parameter.getClass().isPrimitive()) {
+1 -1
View File
@@ -111,7 +111,7 @@
<dependency>
<groupId>com.destroystokyo.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.13.2-R0.1-SNAPSHOT</version>
<version>1.15.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -23,10 +23,11 @@
package co.aikar.acfexample;
import co.aikar.commands.PaperCommandManager;
import co.aikar.commands.ConditionFailedException;
import co.aikar.commands.MessageKeys;
import co.aikar.commands.MessageType;
import co.aikar.commands.PaperBrigadierManager;
import co.aikar.commands.PaperCommandManager;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.Arrays;
@@ -46,6 +47,9 @@ public final class ACFExample extends JavaPlugin {
// 1: Create Command Manager for your respective platform
commandManager = new PaperCommandManager(this);
// enable brigadier integration for paper servers
commandManager.enableUnstableAPI("brigadier");
// optional: enable unstable api to use help
commandManager.enableUnstableAPI("help");
@@ -109,6 +113,12 @@ public final class ACFExample extends JavaPlugin {
getLogger().warning("Error occurred while executing command " + command.getName());
return false; // mark as unhandeled, sender will see default message
});
// test command for brigadier
commandManager.getCommandCompletions().registerAsyncCompletion("someobject", c ->
Arrays.asList("1", "2", "3", "4", "5")
);
commandManager.registerCommand(new BrigadierTest());
}
// Typical Bukkit Plugin Scaffolding
@@ -0,0 +1,92 @@
package co.aikar.acfexample;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.CommandHelp;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Default;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Flags;
import co.aikar.commands.annotation.HelpCommand;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Single;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandAlias("brigadiertest")
public class BrigadierTest extends BaseCommand {
@Subcommand("hello")
@Syntax("<player>")
@CommandCompletion("@players")
@Description("Says hello to a player")
public static void onHello(Player player, @Flags("other") Player arg) {
player.sendMessage("You said hello to " + arg.getDisplayName());
}
@Default
@HelpCommand
public static void onHelp(CommandSender sender, CommandHelp help) {
help.showHelp();
}
@Subcommand("test|test2")
@Description("Says hello to a player")
@CommandCompletion("true|false @range:20 @range:1-5 @range:20-30 test|test2|foo|bar true|false")
public static void onTest(CommandSender sender, boolean booleanParam, float floatParam, double doubleParam, int integerParam, String stringParam, @Optional Boolean test2) {
sender.sendMessage("You said: " + booleanParam + " - " + floatParam + " - " + doubleParam + " - " + integerParam + " - " + stringParam + " - " + test2 + "!");
}
@Subcommand("custom")
@Description("Try custom completions")
@Syntax("<syntaxTest>")
@CommandCompletion("@someobject")
public static void onCustom(Player player, SomeObject object) {
player.sendMessage("You said: " + object);
}
@Subcommand("dummy admin")
@CommandPermission("dummy")
public static void onPerm(Player player) {
player.sendMessage("You shall pass");
}
@Subcommand("sub3")
public static void sub3(Player player, String wooo) {
player.sendMessage("Wooo " + wooo);
}
@Subcommand("sub sub")
public static void onSubSub(Player player, String wooo) {
player.sendMessage("Wooo " + wooo);
}
@Subcommand("sub2")
public static void onSub2(Player player) {
player.sendMessage("Sub2");
}
@Subcommand("sub2 sub")
public static void onSub2Sub(Player player, String test) {
player.sendMessage("Sub2 sub " + test);
}
@Subcommand("find|where")
@CommandPermission("hyperverse.find")
@CommandAlias("hvf|hvfind")
@CommandCompletion("@players")
public void findPlayer(final CommandSender sender, final String player) { /* stub */ }
@Subcommand("greedy")
public void onGreedy(Player player, String greedyString) {
player.sendMessage(greedyString);
}
@Subcommand("notgreedy")
public void notGreedy(Player player, @Single String notGreedy) {
player.sendMessage(notGreedy);
}
}
+19 -1
View File
@@ -46,10 +46,28 @@
<version><!--VERSION-->0.5.0-SNAPSHOT<!--VERSION--></version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>co.aikar</groupId>
<artifactId>acf-brigadier</artifactId>
<version><!--VERSION-->0.5.0-SNAPSHOT<!--VERSION--></version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.destroystokyo.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<version>1.15.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.destroystokyo.paper</groupId>
<artifactId>paper-mojangapi</artifactId>
<version>1.15.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.destroystokyo.paper</groupId>
<artifactId>paper-mojangapi</artifactId>
<version>1.15.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
@@ -51,6 +51,10 @@ class PaperAsyncTabCompleteHandler implements Listener {
if (false) throw new CommandCompletions.SyncCompletionRequired(); // fake compiler due to SneakyThrows
List<String> completions = getCompletions(buffer, event.getCompletions(), event.getSender(), true);
if (completions != null) {
// if we have no completion data, client will display an error, lets just send a space instead (https://bugs.mojang.com/browse/MC-165562)
if (completions.size() == 1 && completions.get(0).equals("")) {
completions.set(0, " ");
}
event.setCompletions(completions);
event.setHandled(true);
}
@@ -0,0 +1,78 @@
/*
* Copyright (c) 2016-2020 Daniel Ennis (Aikar) - MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package co.aikar.commands;
import com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource;
import com.destroystokyo.paper.event.brigadier.CommandRegisteredEvent;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
/**
* Handles registering of commands into brigadier
*
* @author MiniDigger
* @deprecated Unstable API
*/
@Deprecated
@UnstableAPI
public class PaperBrigadierManager implements Listener {
private final PaperCommandManager manager;
private final ACFBrigadierManager<BukkitBrigadierCommandSource> brigadierManager;
public PaperBrigadierManager(Plugin plugin, PaperCommandManager manager) {
manager.verifyUnstableAPI("brigadier");
manager.log(LogLevel.INFO, "Enabled Brigadier Support!");
this.manager = manager;
this.brigadierManager = new ACFBrigadierManager<>(manager);
Bukkit.getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void onCommandRegister(CommandRegisteredEvent<BukkitBrigadierCommandSource> event) {
RootCommand acfCommand = manager.getRootCommand(event.getCommandLabel());
if (acfCommand != null) {
event.setLiteral(brigadierManager.register(
acfCommand,
event.getLiteral(),
event.getBrigadierCommand(),
event.getBrigadierCommand(),
this::checkPermRoot,
this::checkPermSub
));
}
}
private boolean checkPermSub(RegisteredCommand registeredCommand, BukkitBrigadierCommandSource sender) {
return registeredCommand.hasPermission(manager.getCommandIssuer(sender.getBukkitSender()));
}
private boolean checkPermRoot(RootCommand rootCommand, BukkitBrigadierCommandSource sender) {
return rootCommand.hasAnyPermission(manager.getCommandIssuer(sender.getBukkitSender()));
}
}
@@ -28,6 +28,8 @@ import org.bukkit.plugin.Plugin;
@SuppressWarnings("WeakerAccess")
public class PaperCommandManager extends BukkitCommandManager {
private boolean brigadierAvailable;
// If we get anything Paper specific
public PaperCommandManager(Plugin plugin) {
super(plugin);
@@ -37,6 +39,21 @@ public class PaperCommandManager extends BukkitCommandManager {
} catch (ClassNotFoundException ignored) {
// Ignored
}
try {
Class.forName("com.destroystokyo.paper.event.brigadier.CommandRegisteredEvent");
brigadierAvailable = true;
} catch (ClassNotFoundException ignored) {
// Ignored
}
}
@Override
public void enableUnstableAPI(String api) {
super.enableUnstableAPI(api);
if ("brigadier".equals(api) && brigadierAvailable) {
new PaperBrigadierManager(plugin, this);
}
}
@Override
+2
View File
@@ -197,11 +197,13 @@
<modules>
<module>core</module>
<module>brigadier</module>
<module>bukkit</module>
<module>paper</module>
<module>bungee</module>
<module>sponge</module>
<module>jda</module>
<module>velocity</module>
<module>example</module>
</modules>
</project>