mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-29 04:28:21 +01:00
Command syntaxes can now contain a CommandCondition
This commit is contained in:
parent
b84bcde84d
commit
9781e380b9
@ -204,7 +204,7 @@ public final class CommandManager {
|
||||
/**
|
||||
* Gets the {@link DeclareCommandsPacket} for a specific player.
|
||||
* <p>
|
||||
* Can be used to update the {@link Player} auto-completion list.
|
||||
* Can be used to update a player auto-completion list.
|
||||
*
|
||||
* @param player the player to get the commands packet
|
||||
* @return the {@link DeclareCommandsPacket} for {@code player}
|
||||
@ -234,7 +234,7 @@ public final class CommandManager {
|
||||
final CommandCondition commandCondition = command.getCondition();
|
||||
if (commandCondition != null) {
|
||||
// Do not show command if return false
|
||||
if (!commandCondition.apply(player)) {
|
||||
if (!commandCondition.canUse(player, null)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -247,7 +247,7 @@ public final class CommandManager {
|
||||
names.add(command.getName());
|
||||
names.addAll(Arrays.asList(command.getAliases()));
|
||||
for (String name : names) {
|
||||
createCommand(nodes, cmdChildren, name, syntaxes, rootChildren);
|
||||
createCommand(player, nodes, cmdChildren, name, syntaxes, rootChildren);
|
||||
}
|
||||
|
||||
}
|
||||
@ -311,13 +311,15 @@ public final class CommandManager {
|
||||
/**
|
||||
* Adds the command's syntaxes to the nodes list.
|
||||
*
|
||||
* @param sender the potential sender of the command
|
||||
* @param nodes the nodes of the packet
|
||||
* @param cmdChildren the main root of this command
|
||||
* @param name the name of the command (or the alias)
|
||||
* @param syntaxes the syntaxes of the command
|
||||
* @param rootChildren the children of the main node (all commands name)
|
||||
*/
|
||||
private void createCommand(@NotNull List<DeclareCommandsPacket.Node> nodes,
|
||||
private void createCommand(@NotNull CommandSender sender,
|
||||
@NotNull List<DeclareCommandsPacket.Node> nodes,
|
||||
@NotNull IntList cmdChildren,
|
||||
@NotNull String name,
|
||||
@NotNull Collection<CommandSyntax> syntaxes,
|
||||
@ -334,6 +336,13 @@ public final class CommandManager {
|
||||
Map<Argument, List<DeclareCommandsPacket.Node>> storedArgumentsNodes = new HashMap<>();
|
||||
|
||||
for (CommandSyntax syntax : syntaxes) {
|
||||
final CommandCondition commandCondition = syntax.getCommandCondition();
|
||||
if (commandCondition != null && !commandCondition.canUse(sender, null)) {
|
||||
// Sender does not have the right to use this syntax, ignore it
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Represent the last nodes computed in the last iteration
|
||||
List<DeclareCommandsPacket.Node> lastNodes = null;
|
||||
|
||||
|
@ -104,16 +104,31 @@ public class Command {
|
||||
/**
|
||||
* Adds a new syntax in the command.
|
||||
* <p>
|
||||
* A syntax is simply a list of arguments
|
||||
* A syntax is simply a list of arguments.
|
||||
*
|
||||
* @param commandCondition the condition to use the syntax
|
||||
* @param executor the executor to call when the syntax is successfully received
|
||||
* @param args all the arguments of the syntax
|
||||
* @return the created {@link CommandSyntax}
|
||||
*/
|
||||
public CommandSyntax addSyntax(@Nullable CommandCondition commandCondition,
|
||||
@NotNull CommandExecutor executor,
|
||||
@NotNull Argument<?>... args) {
|
||||
final CommandSyntax syntax = new CommandSyntax(commandCondition, executor, args);
|
||||
this.syntaxes.add(syntax);
|
||||
return syntax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new syntax in the command without any condition.
|
||||
*
|
||||
* @param executor the executor to call when the syntax is successfully received
|
||||
* @param args all the arguments of the syntax
|
||||
* @return the created {@link CommandSyntax}
|
||||
* @see #addSyntax(CommandCondition, CommandExecutor, Argument[])
|
||||
*/
|
||||
public CommandSyntax addSyntax(@NotNull CommandExecutor executor, @NotNull Argument<?>... args) {
|
||||
final CommandSyntax syntax = new CommandSyntax(executor, args);
|
||||
this.syntaxes.add(syntax);
|
||||
return syntax;
|
||||
return addSyntax(null, executor, args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,6 +198,7 @@ public class CommandDispatcher {
|
||||
final CommandSyntax finalSyntax = findMostCorrectSyntax(validSyntaxes, syntaxesValues, executorArgs);
|
||||
if (finalSyntax != null) {
|
||||
// A fully correct syntax has been found, use it
|
||||
result.syntax = finalSyntax;
|
||||
result.executor = finalSyntax.getExecutor();
|
||||
result.arguments = executorArgs;
|
||||
return result;
|
||||
@ -333,6 +334,8 @@ public class CommandDispatcher {
|
||||
private Command command;
|
||||
|
||||
// Command Executor
|
||||
private CommandSyntax syntax;
|
||||
|
||||
private CommandExecutor executor;
|
||||
private Arguments arguments;
|
||||
|
||||
@ -353,17 +356,27 @@ public class CommandDispatcher {
|
||||
public void execute(@NotNull CommandSender source, @NotNull String commandString) {
|
||||
// Global listener
|
||||
command.globalListener(source, arguments, commandString);
|
||||
// Condition check
|
||||
// Command condition check
|
||||
final CommandCondition condition = command.getCondition();
|
||||
if (condition != null) {
|
||||
final boolean result = condition.apply(source);
|
||||
final boolean result = condition.canUse(source, commandString);
|
||||
if (!result)
|
||||
return;
|
||||
}
|
||||
// Condition is respected
|
||||
if (executor != null) {
|
||||
// An executor has been found
|
||||
executor.apply(source, arguments);
|
||||
|
||||
if (syntax != null) {
|
||||
// The executor is from a syntax
|
||||
final CommandCondition commandCondition = syntax.getCommandCondition();
|
||||
if (commandCondition == null || commandCondition.canUse(source, commandString)) {
|
||||
executor.apply(source, arguments);
|
||||
}
|
||||
} else {
|
||||
// The executor is probably the default one
|
||||
executor.apply(source, arguments);
|
||||
}
|
||||
} else if (callback != null) {
|
||||
// No syntax has been validated but the faulty argument with a callback has been found
|
||||
// Execute the faulty argument callback
|
||||
|
@ -1,7 +1,10 @@
|
||||
package net.minestom.server.command.builder;
|
||||
|
||||
import net.minestom.server.command.builder.arguments.Argument;
|
||||
import net.minestom.server.command.builder.condition.CommandCondition;
|
||||
import net.minestom.server.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a syntax in {@link Command}
|
||||
@ -9,22 +12,39 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public class CommandSyntax {
|
||||
|
||||
private final Argument<?>[] args;
|
||||
private CommandCondition commandCondition;
|
||||
private CommandExecutor executor;
|
||||
private final Argument<?>[] args;
|
||||
|
||||
protected CommandSyntax(@NotNull CommandExecutor commandExecutor, @NotNull Argument<?>... args) {
|
||||
protected CommandSyntax(@Nullable CommandCondition commandCondition,
|
||||
@NotNull CommandExecutor commandExecutor,
|
||||
@NotNull Argument<?>... args) {
|
||||
this.commandCondition = commandCondition;
|
||||
this.executor = commandExecutor;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the required {@link Argument} for this syntax.
|
||||
* Gets the condition to use this syntax.
|
||||
*
|
||||
* @return the required arguments
|
||||
* @return this command condition, null if none
|
||||
*/
|
||||
@NotNull
|
||||
public Argument<?>[] getArguments() {
|
||||
return args;
|
||||
@Nullable
|
||||
public CommandCondition getCommandCondition() {
|
||||
return commandCondition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the command condition of this syntax.
|
||||
* <p>
|
||||
* Be aware that changing the command condition will not automatically update players auto-completion.
|
||||
* You can create a new packet containing the changes with
|
||||
* {@link net.minestom.server.command.CommandManager#createDeclareCommandsPacket(Player)}.
|
||||
*
|
||||
* @param commandCondition the new command condition, null to remove it
|
||||
*/
|
||||
public void setCommandCondition(@Nullable CommandCondition commandCondition) {
|
||||
this.commandCondition = commandCondition;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,4 +66,14 @@ public class CommandSyntax {
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the required {@link Argument} for this syntax.
|
||||
*
|
||||
* @return the required arguments
|
||||
*/
|
||||
@NotNull
|
||||
public Argument<?>[] getArguments() {
|
||||
return args;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,10 +2,29 @@ package net.minestom.server.command.builder.condition;
|
||||
|
||||
import net.minestom.server.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Used to know if the {@link CommandSender} is allowed to run the command.
|
||||
* Used to know if the {@link CommandSender} is allowed to run the command or a specific syntax.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface CommandCondition {
|
||||
boolean apply(@NotNull CommandSender source);
|
||||
|
||||
/**
|
||||
* Called when the sender permission needs to be checked.
|
||||
* <p>
|
||||
* The first time will be during player connection in order to know
|
||||
* if the command/syntax should be displayed as tab-completion suggestion,
|
||||
* {@code commandString} will be null in this case.
|
||||
* <p>
|
||||
* Otherwise, {@code commandString} will never be null
|
||||
* but will instead be the raw command string given by the sender.
|
||||
* You should in this case warn the sender (eg by sending a message) if the condition is unsuccessful.
|
||||
*
|
||||
* @param source the sender of the command
|
||||
* @param commandString the raw command string,
|
||||
* null if the method has been called at player login
|
||||
* @return true if the sender has the right to use the command, false otherwise
|
||||
*/
|
||||
boolean canUse(@NotNull CommandSender source, @Nullable String commandString);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package demo;
|
||||
import demo.blocks.BurningTorchBlock;
|
||||
import demo.blocks.StoneBlock;
|
||||
import demo.blocks.UpdatableBlockDemo;
|
||||
import demo.commands.*;
|
||||
import demo.commands.TestCommand;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.command.CommandManager;
|
||||
import net.minestom.server.instance.block.BlockManager;
|
||||
@ -27,14 +27,14 @@ public class Main {
|
||||
blockManager.registerBlockPlacementRule(new RedstonePlacementRule());
|
||||
|
||||
CommandManager commandManager = MinecraftServer.getCommandManager();
|
||||
commandManager.register(new EntitySelectorCommand());
|
||||
commandManager.register(new TestCommand());
|
||||
/*commandManager.register(new EntitySelectorCommand());
|
||||
commandManager.register(new HealthCommand());
|
||||
commandManager.register(new SimpleCommand());
|
||||
commandManager.register(new GamemodeCommand());
|
||||
commandManager.register(new DimensionCommand());
|
||||
commandManager.register(new ShutdownCommand());
|
||||
commandManager.register(new TeleportCommand());
|
||||
commandManager.register(new TeleportCommand());*/
|
||||
|
||||
commandManager.setUnknownCommandCallback((sender, command) -> sender.sendMessage("unknown command"));
|
||||
|
||||
|
@ -172,7 +172,7 @@ public class PlayerInit {
|
||||
|
||||
player.addEventCallback(PlayerSpawnEvent.class, event -> {
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
if(event.isFirstSpawn()){
|
||||
if (event.isFirstSpawn()) {
|
||||
player.teleport(new Position(0, 64f, 0));
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ public class GamemodeCommand extends Command {
|
||||
sender.sendMessage("'" + gamemode + "' is not a valid gamemode!");
|
||||
}
|
||||
|
||||
private boolean isAllowed(CommandSender sender) {
|
||||
private boolean isAllowed(CommandSender sender, String commandString) {
|
||||
if (!sender.isPlayer()) {
|
||||
sender.sendMessage("The command is only available for player");
|
||||
return false;
|
||||
|
@ -28,7 +28,7 @@ public class HealthCommand extends Command {
|
||||
addSyntax(this::execute, arg0);
|
||||
}
|
||||
|
||||
private boolean condition(CommandSender sender) {
|
||||
private boolean condition(CommandSender sender, String commandString) {
|
||||
if (!sender.isPlayer()) {
|
||||
sender.sendMessage("The command is only available for player");
|
||||
return false;
|
||||
|
@ -17,8 +17,9 @@ public class TestCommand extends Command {
|
||||
//addSyntax(this::execute, dynamicWord);
|
||||
}
|
||||
|
||||
Argument test = ArgumentType.Word("test").from("hey");
|
||||
Argument num = ArgumentType.Integer("num");
|
||||
Argument test = ArgumentType.Word("wordT");
|
||||
Argument testt = ArgumentType.Word("wordTt");
|
||||
Argument test2 = ArgumentType.StringArray("array");
|
||||
|
||||
setDefaultExecutor((source, args) -> {
|
||||
System.out.println("DEFAULT");
|
||||
@ -31,7 +32,7 @@ public class TestCommand extends Command {
|
||||
|
||||
addSyntax((source, args) -> {
|
||||
System.out.println(2);
|
||||
}, test, num);
|
||||
}, test, test2);
|
||||
}
|
||||
|
||||
private void usage(CommandSender sender, Arguments arguments) {
|
||||
|
Loading…
Reference in New Issue
Block a user