Replace Arguments by CommandContext

This commit is contained in:
themode 2021-03-10 06:38:51 +01:00
parent b03b35b881
commit 67b3b37813
10 changed files with 71 additions and 47 deletions

View File

@ -23,15 +23,10 @@ import java.util.HashMap;
import java.util.Map;
/**
* Class used to retrieve argument data in a {@link CommandExecutor}.
* <p>
* All id are the one specified in the {@link net.minestom.server.command.builder.arguments.Argument} constructor.
* <p>
* All methods are @{@link NotNull} in the sense that you should not have to verify their validity since if the syntax
* is called, it means that all of its arguments are correct. Be aware that trying to retrieve an argument not present
* in the syntax will result in a {@link NullPointerException}.
* @deprecated renamed to {@link CommandContext}
*/
public final class Arguments {
@Deprecated
public class Arguments {
private Map<String, Object> args = new HashMap<>();
@ -52,7 +47,7 @@ public final class Arguments {
public boolean has(@NotNull Argument<?> argument) {
return args.containsKey(argument.getId());
}
public boolean has(@NotNull String identifier) {
return args.containsKey(identifier);
}

View File

@ -282,11 +282,11 @@ public class Command {
* <p>
* Can be used if you wish to still suggest the player syntaxes but want to parse things mostly by yourself.
*
* @param sender the {@link CommandSender}
* @param arguments the UNCHECKED arguments of the command, some can be null even when unexpected
* @param command the raw UNCHECKED received command
* @param sender the {@link CommandSender}
* @param context the UNCHECKED context of the command, some can be null even when unexpected
* @param command the raw UNCHECKED received command
*/
public void globalListener(@NotNull CommandSender sender, @NotNull Arguments arguments, @NotNull String command) {
public void globalListener(@NotNull CommandSender sender, @NotNull CommandContext context, @NotNull String command) {
}
public static boolean isValidName(@NotNull Command command, @NotNull String name) {

View File

@ -0,0 +1,27 @@
package net.minestom.server.command.builder;
import net.minestom.server.command.builder.arguments.Argument;
import org.jetbrains.annotations.NotNull;
/**
* Class used to retrieve argument data in a {@link CommandExecutor}.
* <p>
* All id are the one specified in the {@link Argument} constructor.
* <p>
* All methods are @{@link NotNull} in the sense that you should not have to verify their validity since if the syntax
* is called, it means that all of its arguments are correct. Be aware that trying to retrieve an argument not present
* in the syntax will result in a {@link NullPointerException}.
*/
public class CommandContext extends Arguments {
private final String input;
public CommandContext(@NotNull String input) {
this.input = input;
}
@NotNull
public String getInput() {
return input;
}
}

View File

@ -129,7 +129,7 @@ public class CommandDispatcher {
CommandResult result = new CommandResult();
result.input = commandString;
// Find the used syntax and fill CommandResult#type and CommandResult#parsedCommand
findParsedCommand(command, args, result);
findParsedCommand(command, commandName, args, result);
// Cache result
{
@ -140,7 +140,7 @@ public class CommandDispatcher {
}
@Nullable
private ParsedCommand findParsedCommand(@NotNull Command command, @NotNull String[] args, @NotNull CommandResult result) {
private ParsedCommand findParsedCommand(@NotNull Command command, @NotNull String commandName, @NotNull String[] args, @NotNull CommandResult result) {
final boolean hasArgument = args.length > 0;
// Search for subcommand
@ -148,11 +148,13 @@ public class CommandDispatcher {
final String firstArgument = args[0];
for (Command subcommand : command.getSubcommands()) {
if (Command.isValidName(subcommand, firstArgument)) {
return findParsedCommand(subcommand, Arrays.copyOfRange(args, 1, args.length), result);
return findParsedCommand(subcommand, firstArgument, Arrays.copyOfRange(args, 1, args.length), result);
}
}
}
final String input = commandName + StringUtils.SPACE + String.join(StringUtils.SPACE, args);
ParsedCommand parsedCommand = new ParsedCommand();
parsedCommand.command = command;
@ -162,7 +164,7 @@ public class CommandDispatcher {
final CommandExecutor defaultExecutor = command.getDefaultExecutor();
if (defaultExecutor != null && !hasArgument) {
parsedCommand.executor = defaultExecutor;
parsedCommand.arguments = new Arguments();
parsedCommand.context = new CommandContext(input);
result.type = CommandResult.Type.SUCCESS;
result.parsedCommand = parsedCommand;
@ -187,16 +189,16 @@ public class CommandDispatcher {
// Check if there is at least one correct syntax
if (!validSyntaxes.isEmpty()) {
Arguments executorArgs = new Arguments();
CommandContext context = new CommandContext(input);
// Search the syntax with all perfect args
final ValidSyntaxHolder finalValidSyntax = CommandParser.findMostCorrectSyntax(validSyntaxes, executorArgs);
final ValidSyntaxHolder finalValidSyntax = CommandParser.findMostCorrectSyntax(validSyntaxes, context);
if (finalValidSyntax != null) {
// A fully correct syntax has been found, use it
final CommandSyntax syntax = finalValidSyntax.syntax;
parsedCommand.syntax = syntax;
parsedCommand.executor = syntax.getExecutor();
parsedCommand.arguments = executorArgs;
parsedCommand.context = context;
result.type = CommandResult.Type.SUCCESS;
result.parsedCommand = parsedCommand;
@ -230,7 +232,7 @@ public class CommandDispatcher {
// No syntax found
result.type = CommandResult.Type.INVALID_SYNTAX;
result.parsedCommand = ParsedCommand.withDefaultExecutor(command);
result.parsedCommand = ParsedCommand.withDefaultExecutor(command, input);
return result.parsedCommand;
}
}

View File

@ -14,9 +14,8 @@ public interface CommandExecutor {
/**
* Executes the command callback once the syntax has been called (or the default executor).
*
* @param sender the sender of the command
* @param args contains all the parsed arguments,
* the id is the one initialized when creating the argument object
* @param sender the sender of the command
* @param context the command context, used to retrieve the arguments and various other things
*/
void apply(@NotNull CommandSender sender, @NotNull Arguments args);
void apply(@NotNull CommandSender sender, @NotNull CommandContext context);
}

View File

@ -18,7 +18,7 @@ public class ParsedCommand {
protected CommandSyntax syntax;
protected CommandExecutor executor;
protected Arguments arguments;
protected CommandContext context;
// Argument Callback
protected ArgumentCallback callback;
@ -37,7 +37,7 @@ public class ParsedCommand {
@Nullable
public CommandData execute(@NotNull CommandSender source, @NotNull String commandString) {
// Global listener
command.globalListener(source, arguments, commandString);
command.globalListener(source, context, commandString);
// Command condition check
final CommandCondition condition = command.getCondition();
if (condition != null) {
@ -53,12 +53,12 @@ public class ParsedCommand {
// The executor is from a syntax
final CommandCondition commandCondition = syntax.getCommandCondition();
if (commandCondition == null || commandCondition.canUse(source, commandString)) {
arguments.retrieveDefaultValues(syntax.getDefaultValuesMap());
executor.apply(source, arguments);
context.retrieveDefaultValues(syntax.getDefaultValuesMap());
executor.apply(source, context);
}
} else {
// The executor is probably the default one
executor.apply(source, arguments);
executor.apply(source, context);
}
} else if (callback != null && argumentSyntaxException != null) {
// No syntax has been validated but the faulty argument with a callback has been found
@ -66,20 +66,20 @@ public class ParsedCommand {
callback.apply(source, argumentSyntaxException);
}
if (arguments == null) {
if (context == null) {
// Argument callbacks cannot return data
return null;
}
return arguments.getReturnData();
return context.getReturnData();
}
@NotNull
public static ParsedCommand withDefaultExecutor(@NotNull Command command) {
public static ParsedCommand withDefaultExecutor(@NotNull Command command, @NotNull String input) {
ParsedCommand parsedCommand = new ParsedCommand();
parsedCommand.command = command;
parsedCommand.executor = command.getDefaultExecutor();
parsedCommand.arguments = new Arguments();
parsedCommand.context = new CommandContext(input);
return parsedCommand;
}

View File

@ -1,6 +1,6 @@
package net.minestom.server.command.builder.arguments;
import net.minestom.server.command.builder.Arguments;
import net.minestom.server.command.builder.CommandContext;
import net.minestom.server.command.builder.NodeMaker;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.command.builder.parser.CommandParser;
@ -11,7 +11,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class ArgumentGroup extends Argument<Arguments> {
public class ArgumentGroup extends Argument<CommandContext> {
public static final int INVALID_ARGUMENTS_ERROR = 1;
@ -24,17 +24,17 @@ public class ArgumentGroup extends Argument<Arguments> {
@NotNull
@Override
public Arguments parse(@NotNull String input) throws ArgumentSyntaxException {
public CommandContext parse(@NotNull String input) throws ArgumentSyntaxException {
List<ValidSyntaxHolder> validSyntaxes = new ArrayList<>();
CommandParser.parse(null, group, input.split(StringUtils.SPACE), validSyntaxes, null);
Arguments arguments = new Arguments();
CommandParser.findMostCorrectSyntax(validSyntaxes, arguments);
CommandContext context = new CommandContext(input);
CommandParser.findMostCorrectSyntax(validSyntaxes, context);
if (validSyntaxes.isEmpty()) {
throw new ArgumentSyntaxException("Invalid arguments", input, INVALID_ARGUMENTS_ERROR);
}
return arguments;
return context;
}
@Override

View File

@ -3,6 +3,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.Command;
import net.minestom.server.command.builder.CommandContext;
import net.minestom.server.command.builder.CommandSyntax;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
@ -71,12 +72,12 @@ public class CommandParser {
* valid arguments.
*
* @param validSyntaxes the list containing all the valid syntaxes
* @param executorArgs the recipient of the argument parsed values
* @param context 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<ValidSyntaxHolder> validSyntaxes,
@NotNull Arguments executorArgs) {
@NotNull CommandContext context) {
if (validSyntaxes.isEmpty()) {
return null;
}
@ -109,7 +110,7 @@ public class CommandParser {
// Get the arguments values
if (finalSyntax != null) {
executorArgs.copy(finalArguments);
context.copy(finalArguments);
}
return finalSyntax;

View File

@ -26,7 +26,7 @@ public class TabCompleteListener {
final String text = packet.text;
{
String commandString = packet.text.replaceFirst("/", "");
String commandString = packet.text.replaceFirst(CommandManager.COMMAND_PREFIX, "");
String[] split = commandString.split(StringUtils.SPACE);
String commandName = split[0];
final CommandDispatcher commandDispatcher = MinecraftServer.getCommandManager().getDispatcher();
@ -50,7 +50,7 @@ public class TabCompleteListener {
final int inputLength = input.length();
final int commandLength = Arrays.stream(split).map(String::length).reduce(0, Integer::sum) +
StringUtils.countMatches(args, " ");
StringUtils.countMatches(args, StringUtils.SPACE);
final int trailingSpaces = !input.isEmpty() ? text.length() - text.trim().length() : 0;
final int start = commandLength - inputLength + 1 - trailingSpaces;

View File

@ -26,8 +26,8 @@ public class TestCommand extends Command {
var test3 = Integer("msg3");
addSyntax((sender, args) -> {
System.out.println("COMMAND SYNTAX");
addSyntax((sender, context) -> {
System.out.println("input: "+context.getInput());
}, test3, test1);
}