diff --git a/api/src/main/java/com/velocitypowered/api/command/CommandManager.java b/api/src/main/java/com/velocitypowered/api/command/CommandManager.java index 5ece4e7d6..6cf90a791 100644 --- a/api/src/main/java/com/velocitypowered/api/command/CommandManager.java +++ b/api/src/main/java/com/velocitypowered/api/command/CommandManager.java @@ -10,6 +10,7 @@ package com.velocitypowered.api.command; import com.velocitypowered.api.event.command.CommandExecuteEvent; import java.util.Collection; import java.util.concurrent.CompletableFuture; +import java.util.function.Predicate; import org.checkerframework.checker.nullness.qual.Nullable; /** @@ -126,4 +127,15 @@ public interface CommandManager { * @return true if the alias is registered; false otherwise */ boolean hasCommand(String alias); + + /** + * Returns whether the given alias is registered on this manager + * and can be used by the given {@link CommandSource}. + * See {@link com.mojang.brigadier.builder.ArgumentBuilder#requires(Predicate)} + * + * @param alias the command alias to check + * @param source the command source + * @return true if the alias is registered and usable; false otherwise + */ + boolean hasCommand(String alias, CommandSource source); } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/command/VelocityCommandManager.java b/proxy/src/main/java/com/velocitypowered/proxy/command/VelocityCommandManager.java index b92c4f500..a4fab9321 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/command/VelocityCommandManager.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/command/VelocityCommandManager.java @@ -347,8 +347,19 @@ public class VelocityCommandManager implements CommandManager { @Override public boolean hasCommand(final String alias) { + return getCommand(alias) != null; + } + + @Override + public boolean hasCommand(String alias, CommandSource source) { + Preconditions.checkNotNull(source, "source"); + CommandNode command = getCommand(alias); + return command != null && command.canUse(source); + } + + CommandNode getCommand(final String alias) { Preconditions.checkNotNull(alias, "alias"); - return dispatcher.getRoot().getChild(alias.toLowerCase(Locale.ENGLISH)) != null; + return dispatcher.getRoot().getChild(alias.toLowerCase(Locale.ENGLISH)); } @VisibleForTesting // this constitutes unsafe publication diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java index ef769b168..f5e6e880f 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java @@ -630,7 +630,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler { } String commandLabel = command.substring(0, commandEndPosition); - if (!server.getCommandManager().hasCommand(commandLabel)) { + if (!server.getCommandManager().hasCommand(commandLabel, player)) { if (player.getProtocolVersion().lessThan(ProtocolVersion.MINECRAFT_1_13)) { // Outstanding tab completes are recorded for use with 1.12 clients and below to provide // additional tab completion support.