mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-19 06:32:03 +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.
|
* Gets the {@link DeclareCommandsPacket} for a specific player.
|
||||||
* <p>
|
* <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
|
* @param player the player to get the commands packet
|
||||||
* @return the {@link DeclareCommandsPacket} for {@code player}
|
* @return the {@link DeclareCommandsPacket} for {@code player}
|
||||||
@ -234,7 +234,7 @@ public final class CommandManager {
|
|||||||
final CommandCondition commandCondition = command.getCondition();
|
final CommandCondition commandCondition = command.getCondition();
|
||||||
if (commandCondition != null) {
|
if (commandCondition != null) {
|
||||||
// Do not show command if return false
|
// Do not show command if return false
|
||||||
if (!commandCondition.apply(player)) {
|
if (!commandCondition.canUse(player, null)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -247,7 +247,7 @@ public final class CommandManager {
|
|||||||
names.add(command.getName());
|
names.add(command.getName());
|
||||||
names.addAll(Arrays.asList(command.getAliases()));
|
names.addAll(Arrays.asList(command.getAliases()));
|
||||||
for (String name : names) {
|
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.
|
* 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 nodes the nodes of the packet
|
||||||
* @param cmdChildren the main root of this command
|
* @param cmdChildren the main root of this command
|
||||||
* @param name the name of the command (or the alias)
|
* @param name the name of the command (or the alias)
|
||||||
* @param syntaxes the syntaxes of the command
|
* @param syntaxes the syntaxes of the command
|
||||||
* @param rootChildren the children of the main node (all commands name)
|
* @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 IntList cmdChildren,
|
||||||
@NotNull String name,
|
@NotNull String name,
|
||||||
@NotNull Collection<CommandSyntax> syntaxes,
|
@NotNull Collection<CommandSyntax> syntaxes,
|
||||||
@ -334,6 +336,13 @@ public final class CommandManager {
|
|||||||
Map<Argument, List<DeclareCommandsPacket.Node>> storedArgumentsNodes = new HashMap<>();
|
Map<Argument, List<DeclareCommandsPacket.Node>> storedArgumentsNodes = new HashMap<>();
|
||||||
|
|
||||||
for (CommandSyntax syntax : syntaxes) {
|
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
|
// Represent the last nodes computed in the last iteration
|
||||||
List<DeclareCommandsPacket.Node> lastNodes = null;
|
List<DeclareCommandsPacket.Node> lastNodes = null;
|
||||||
|
|
||||||
|
@ -104,16 +104,31 @@ public class Command {
|
|||||||
/**
|
/**
|
||||||
* Adds a new syntax in the command.
|
* Adds a new syntax in the command.
|
||||||
* <p>
|
* <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 executor the executor to call when the syntax is successfully received
|
||||||
* @param args all the arguments of the syntax
|
* @param args all the arguments of the syntax
|
||||||
* @return the created {@link CommandSyntax}
|
* @return the created {@link CommandSyntax}
|
||||||
|
* @see #addSyntax(CommandCondition, CommandExecutor, Argument[])
|
||||||
*/
|
*/
|
||||||
public CommandSyntax addSyntax(@NotNull CommandExecutor executor, @NotNull Argument<?>... args) {
|
public CommandSyntax addSyntax(@NotNull CommandExecutor executor, @NotNull Argument<?>... args) {
|
||||||
final CommandSyntax syntax = new CommandSyntax(executor, args);
|
return addSyntax(null, executor, args);
|
||||||
this.syntaxes.add(syntax);
|
|
||||||
return syntax;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -198,6 +198,7 @@ public class CommandDispatcher {
|
|||||||
final CommandSyntax finalSyntax = findMostCorrectSyntax(validSyntaxes, syntaxesValues, executorArgs);
|
final CommandSyntax finalSyntax = findMostCorrectSyntax(validSyntaxes, syntaxesValues, executorArgs);
|
||||||
if (finalSyntax != null) {
|
if (finalSyntax != null) {
|
||||||
// A fully correct syntax has been found, use it
|
// A fully correct syntax has been found, use it
|
||||||
|
result.syntax = finalSyntax;
|
||||||
result.executor = finalSyntax.getExecutor();
|
result.executor = finalSyntax.getExecutor();
|
||||||
result.arguments = executorArgs;
|
result.arguments = executorArgs;
|
||||||
return result;
|
return result;
|
||||||
@ -333,6 +334,8 @@ public class CommandDispatcher {
|
|||||||
private Command command;
|
private Command command;
|
||||||
|
|
||||||
// Command Executor
|
// Command Executor
|
||||||
|
private CommandSyntax syntax;
|
||||||
|
|
||||||
private CommandExecutor executor;
|
private CommandExecutor executor;
|
||||||
private Arguments arguments;
|
private Arguments arguments;
|
||||||
|
|
||||||
@ -353,17 +356,27 @@ public class CommandDispatcher {
|
|||||||
public void execute(@NotNull CommandSender source, @NotNull String commandString) {
|
public void execute(@NotNull CommandSender source, @NotNull String commandString) {
|
||||||
// Global listener
|
// Global listener
|
||||||
command.globalListener(source, arguments, commandString);
|
command.globalListener(source, arguments, commandString);
|
||||||
// Condition check
|
// Command condition check
|
||||||
final CommandCondition condition = command.getCondition();
|
final CommandCondition condition = command.getCondition();
|
||||||
if (condition != null) {
|
if (condition != null) {
|
||||||
final boolean result = condition.apply(source);
|
final boolean result = condition.canUse(source, commandString);
|
||||||
if (!result)
|
if (!result)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Condition is respected
|
// Condition is respected
|
||||||
if (executor != null) {
|
if (executor != null) {
|
||||||
// An executor has been found
|
// 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) {
|
} else if (callback != null) {
|
||||||
// No syntax has been validated but the faulty argument with a callback has been found
|
// No syntax has been validated but the faulty argument with a callback has been found
|
||||||
// Execute the faulty argument callback
|
// Execute the faulty argument callback
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package net.minestom.server.command.builder;
|
package net.minestom.server.command.builder;
|
||||||
|
|
||||||
import net.minestom.server.command.builder.arguments.Argument;
|
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.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a syntax in {@link Command}
|
* Represents a syntax in {@link Command}
|
||||||
@ -9,22 +12,39 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
*/
|
*/
|
||||||
public class CommandSyntax {
|
public class CommandSyntax {
|
||||||
|
|
||||||
private final Argument<?>[] args;
|
private CommandCondition commandCondition;
|
||||||
private CommandExecutor executor;
|
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.executor = commandExecutor;
|
||||||
this.args = args;
|
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
|
@Nullable
|
||||||
public Argument<?>[] getArguments() {
|
public CommandCondition getCommandCondition() {
|
||||||
return args;
|
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;
|
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 net.minestom.server.command.CommandSender;
|
||||||
import org.jetbrains.annotations.NotNull;
|
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 {
|
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.BurningTorchBlock;
|
||||||
import demo.blocks.StoneBlock;
|
import demo.blocks.StoneBlock;
|
||||||
import demo.blocks.UpdatableBlockDemo;
|
import demo.blocks.UpdatableBlockDemo;
|
||||||
import demo.commands.*;
|
import demo.commands.TestCommand;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.command.CommandManager;
|
import net.minestom.server.command.CommandManager;
|
||||||
import net.minestom.server.instance.block.BlockManager;
|
import net.minestom.server.instance.block.BlockManager;
|
||||||
@ -27,14 +27,14 @@ public class Main {
|
|||||||
blockManager.registerBlockPlacementRule(new RedstonePlacementRule());
|
blockManager.registerBlockPlacementRule(new RedstonePlacementRule());
|
||||||
|
|
||||||
CommandManager commandManager = MinecraftServer.getCommandManager();
|
CommandManager commandManager = MinecraftServer.getCommandManager();
|
||||||
commandManager.register(new EntitySelectorCommand());
|
|
||||||
commandManager.register(new TestCommand());
|
commandManager.register(new TestCommand());
|
||||||
|
/*commandManager.register(new EntitySelectorCommand());
|
||||||
commandManager.register(new HealthCommand());
|
commandManager.register(new HealthCommand());
|
||||||
commandManager.register(new SimpleCommand());
|
commandManager.register(new SimpleCommand());
|
||||||
commandManager.register(new GamemodeCommand());
|
commandManager.register(new GamemodeCommand());
|
||||||
commandManager.register(new DimensionCommand());
|
commandManager.register(new DimensionCommand());
|
||||||
commandManager.register(new ShutdownCommand());
|
commandManager.register(new ShutdownCommand());
|
||||||
commandManager.register(new TeleportCommand());
|
commandManager.register(new TeleportCommand());*/
|
||||||
|
|
||||||
commandManager.setUnknownCommandCallback((sender, command) -> sender.sendMessage("unknown command"));
|
commandManager.setUnknownCommandCallback((sender, command) -> sender.sendMessage("unknown command"));
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ public class PlayerInit {
|
|||||||
|
|
||||||
player.addEventCallback(PlayerSpawnEvent.class, event -> {
|
player.addEventCallback(PlayerSpawnEvent.class, event -> {
|
||||||
player.setGameMode(GameMode.SURVIVAL);
|
player.setGameMode(GameMode.SURVIVAL);
|
||||||
if(event.isFirstSpawn()){
|
if (event.isFirstSpawn()) {
|
||||||
player.teleport(new Position(0, 64f, 0));
|
player.teleport(new Position(0, 64f, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ public class GamemodeCommand extends Command {
|
|||||||
sender.sendMessage("'" + gamemode + "' is not a valid gamemode!");
|
sender.sendMessage("'" + gamemode + "' is not a valid gamemode!");
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAllowed(CommandSender sender) {
|
private boolean isAllowed(CommandSender sender, String commandString) {
|
||||||
if (!sender.isPlayer()) {
|
if (!sender.isPlayer()) {
|
||||||
sender.sendMessage("The command is only available for player");
|
sender.sendMessage("The command is only available for player");
|
||||||
return false;
|
return false;
|
||||||
|
@ -28,7 +28,7 @@ public class HealthCommand extends Command {
|
|||||||
addSyntax(this::execute, arg0);
|
addSyntax(this::execute, arg0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean condition(CommandSender sender) {
|
private boolean condition(CommandSender sender, String commandString) {
|
||||||
if (!sender.isPlayer()) {
|
if (!sender.isPlayer()) {
|
||||||
sender.sendMessage("The command is only available for player");
|
sender.sendMessage("The command is only available for player");
|
||||||
return false;
|
return false;
|
||||||
|
@ -17,8 +17,9 @@ public class TestCommand extends Command {
|
|||||||
//addSyntax(this::execute, dynamicWord);
|
//addSyntax(this::execute, dynamicWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
Argument test = ArgumentType.Word("test").from("hey");
|
Argument test = ArgumentType.Word("wordT");
|
||||||
Argument num = ArgumentType.Integer("num");
|
Argument testt = ArgumentType.Word("wordTt");
|
||||||
|
Argument test2 = ArgumentType.StringArray("array");
|
||||||
|
|
||||||
setDefaultExecutor((source, args) -> {
|
setDefaultExecutor((source, args) -> {
|
||||||
System.out.println("DEFAULT");
|
System.out.println("DEFAULT");
|
||||||
@ -31,7 +32,7 @@ public class TestCommand extends Command {
|
|||||||
|
|
||||||
addSyntax((source, args) -> {
|
addSyntax((source, args) -> {
|
||||||
System.out.println(2);
|
System.out.println(2);
|
||||||
}, test, num);
|
}, test, test2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void usage(CommandSender sender, Arguments arguments) {
|
private void usage(CommandSender sender, Arguments arguments) {
|
||||||
|
Loading…
Reference in New Issue
Block a user