diff --git a/src/main/java/net/minestom/server/command/builder/Arguments.java b/src/main/java/net/minestom/server/command/builder/Arguments.java index eca62ea4c..3b8498632 100644 --- a/src/main/java/net/minestom/server/command/builder/Arguments.java +++ b/src/main/java/net/minestom/server/command/builder/Arguments.java @@ -272,11 +272,16 @@ public final class Arguments { this.returnData = returnData; } - protected void setArg(@NotNull String id, Object value) { + @NotNull + public Map getMap() { + return args; + } + + public void setArg(@NotNull String id, Object value) { this.args.put(id, value); } - protected void copy(@NotNull Arguments arguments) { + public void copy(@NotNull Arguments arguments) { this.args = arguments.args; } diff --git a/src/main/java/net/minestom/server/command/builder/CommandDispatcher.java b/src/main/java/net/minestom/server/command/builder/CommandDispatcher.java index 72bdcd63e..1a2b86a61 100644 --- a/src/main/java/net/minestom/server/command/builder/CommandDispatcher.java +++ b/src/main/java/net/minestom/server/command/builder/CommandDispatcher.java @@ -162,11 +162,13 @@ public class CommandDispatcher { if (!validSyntaxes.isEmpty()) { Arguments executorArgs = new Arguments(); // Search the syntax with all perfect args - final CommandSyntax finalSyntax = findMostCorrectSyntax(validSyntaxes, executorArgs); - if (finalSyntax != null) { + final ValidSyntaxHolder finalValidSyntax = CommandParser.findMostCorrectSyntax(validSyntaxes, executorArgs); + if (finalValidSyntax != null) { // A fully correct syntax has been found, use it - parsedCommand.syntax = finalSyntax; - parsedCommand.executor = finalSyntax.getExecutor(); + final CommandSyntax syntax = finalValidSyntax.syntax; + + parsedCommand.syntax = syntax; + parsedCommand.executor = syntax.getExecutor(); parsedCommand.arguments = executorArgs; return parsedCommand; } @@ -197,52 +199,4 @@ public class CommandDispatcher { // No syntax found return null; } - - /** - * Retrieves from the valid syntax map the arguments condition result and get the one with the most - * valid arguments. - * - * @param validSyntaxes the list containing all the valid syntaxes - * @param executorArgs the recipient of the argument parsed values - * @return the command syntax with all of its arguments correct and with the most arguments count, null if not any - */ - @Nullable - private CommandSyntax findMostCorrectSyntax(@NotNull List validSyntaxes, - @NotNull Arguments executorArgs) { - CommandSyntax finalSyntax = null; - int maxArguments = 0; - Arguments finalArguments = null; - - for (ValidSyntaxHolder validSyntaxHolder : validSyntaxes) { - final CommandSyntax syntax = validSyntaxHolder.syntax; - - final Argument[] arguments = syntax.getArguments(); - final int argumentsCount = arguments.length; - final Map, Object> argsValues = validSyntaxHolder.argumentsValue; - - final int argsSize = argsValues.size(); - - if (argsSize > maxArguments) { - finalSyntax = syntax; - maxArguments = argsSize; - - // Fill arguments map - Arguments syntaxValues = new Arguments(); - for (Map.Entry, Object> entry : argsValues.entrySet()) { - final Argument argument = entry.getKey(); - final Object argumentValue = entry.getValue(); - - syntaxValues.setArg(argument.getId(), argumentValue); - } - finalArguments = syntaxValues; - } - } - - // Get the arguments values - if (finalSyntax != null) { - executorArgs.copy(finalArguments); - } - - return finalSyntax; - } } diff --git a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentGroup.java b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentGroup.java new file mode 100644 index 000000000..f245eb2d2 --- /dev/null +++ b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentGroup.java @@ -0,0 +1,44 @@ +package net.minestom.server.command.builder.arguments; + +import net.minestom.server.command.builder.Arguments; +import net.minestom.server.command.builder.NodeMaker; +import net.minestom.server.command.builder.exception.ArgumentSyntaxException; +import net.minestom.server.command.builder.parser.CommandParser; +import net.minestom.server.command.builder.parser.ValidSyntaxHolder; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public class ArgumentGroup extends Argument { + + public static final int INVALID_ARGUMENTS_ERROR = 1; + + private final Argument[] group; + + public ArgumentGroup(@NotNull String id, @NotNull Argument... group) { + super(id, true, false); + this.group = group; + } + + @NotNull + @Override + public Arguments parse(@NotNull String input) throws ArgumentSyntaxException { + List validSyntaxes = new ArrayList<>(); + CommandParser.parse(null, group, input.split(StringUtils.SPACE), validSyntaxes, null); + + Arguments arguments = new Arguments(); + CommandParser.findMostCorrectSyntax(validSyntaxes, arguments); + if (validSyntaxes.isEmpty()) { + throw new ArgumentSyntaxException("Invalid arguments", input, INVALID_ARGUMENTS_ERROR); + } + + return arguments; + } + + @Override + public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) { + // TODO + } +} diff --git a/src/main/java/net/minestom/server/command/builder/parser/CommandParser.java b/src/main/java/net/minestom/server/command/builder/parser/CommandParser.java index 7e15aa099..84061bf78 100644 --- a/src/main/java/net/minestom/server/command/builder/parser/CommandParser.java +++ b/src/main/java/net/minestom/server/command/builder/parser/CommandParser.java @@ -1,6 +1,7 @@ package net.minestom.server.command.builder.parser; import it.unimi.dsi.fastutil.ints.Int2ObjectRBTreeMap; +import net.minestom.server.command.builder.Arguments; import net.minestom.server.command.builder.CommandSyntax; import net.minestom.server.command.builder.arguments.Argument; import net.minestom.server.command.builder.exception.ArgumentSyntaxException; @@ -14,7 +15,7 @@ import java.util.Map; public class CommandParser { - public static void parse(@NotNull CommandSyntax syntax, @NotNull Argument[] commandArguments, @NotNull String[] inputArguments, + public static void parse(@Nullable CommandSyntax syntax, @NotNull Argument[] commandArguments, @NotNull String[] inputArguments, @Nullable List validSyntaxes, @Nullable Int2ObjectRBTreeMap syntaxesSuggestions) { final Map, Object> argsValues = new HashMap<>(); @@ -125,4 +126,53 @@ public class CommandParser { } } + /** + * Retrieves from the valid syntax map the arguments condition result and get the one with the most + * valid arguments. + * + * @param validSyntaxes the list containing all the valid syntaxes + * @param executorArgs the recipient of the argument parsed values + * @return the command syntax with all of its arguments correct and with the most arguments count, null if not any + */ + @Nullable + public static ValidSyntaxHolder findMostCorrectSyntax(@NotNull List validSyntaxes, + @NotNull Arguments executorArgs) { + if (validSyntaxes.isEmpty()) { + return null; + } + + ValidSyntaxHolder finalSyntax = null; + int maxArguments = 0; + Arguments finalArguments = null; + + for (ValidSyntaxHolder validSyntaxHolder : validSyntaxes) { + final Map, Object> argsValues = validSyntaxHolder.argumentsValue; + + final int argsSize = argsValues.size(); + + // Check if the syntax has more valid arguments + if (argsSize > maxArguments) { + finalSyntax = validSyntaxHolder; + maxArguments = argsSize; + + // Fill arguments map + Arguments syntaxValues = new Arguments(); + for (Map.Entry, Object> entry : argsValues.entrySet()) { + final Argument argument = entry.getKey(); + final Object argumentValue = entry.getValue(); + + syntaxValues.setArg(argument.getId(), argumentValue); + } + finalArguments = syntaxValues; + } + } + + // Get the arguments values + if (finalSyntax != null) { + executorArgs.copy(finalArguments); + } + + return finalSyntax; + } + }