Added suggestion support for subcommands

This commit is contained in:
themode 2021-03-10 19:14:24 +01:00
parent 67b3b37813
commit eb56324e8b
6 changed files with 90 additions and 25 deletions

View File

@ -14,7 +14,10 @@ import org.jetbrains.annotations.Nullable;
* {@link #onWrite(CommandSender, String)} and return the possible completions to suggest.
* <p>
* Please be sure to check {@link net.minestom.server.command.builder.Command} as it is likely to be better for your use case.
*
* @deprecated use {@link net.minestom.server.command.builder.Command} instead
*/
@Deprecated
public interface CommandProcessor {
/**

View File

@ -7,6 +7,7 @@ import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.command.builder.parser.CommandParser;
import net.minestom.server.command.builder.parser.CommandQueryResult;
import net.minestom.server.command.builder.parser.CommandSuggestionHolder;
import net.minestom.server.command.builder.parser.ValidSyntaxHolder;
import org.apache.commons.lang3.StringUtils;
@ -117,15 +118,17 @@ public class CommandDispatcher {
final String[] parts = commandString.split(StringUtils.SPACE);
final String commandName = parts[0];
final Command command = findCommand(commandName);
// Check if the command exists
if (command == null) {
return CommandResult.of(CommandResult.Type.UNKNOWN, commandName);
}
String[] args = new String[parts.length - 1];
System.arraycopy(parts, 1, args, 0, args.length);
final CommandQueryResult commandQueryResult = CommandParser.findCommand(commandName, args);
// Check if the command exists
if (commandQueryResult == null) {
return CommandResult.of(CommandResult.Type.UNKNOWN, commandName);
}
final Command command = commandQueryResult.command;
args = commandQueryResult.args;
CommandResult result = new CommandResult();
result.input = commandString;
// Find the used syntax and fill CommandResult#type and CommandResult#parsedCommand

View File

@ -1,6 +1,8 @@
package net.minestom.server.command.builder.parser;
import it.unimi.dsi.fastutil.ints.Int2ObjectRBTreeMap;
import net.minestom.server.MinecraftServer;
import net.minestom.server.command.CommandManager;
import net.minestom.server.command.builder.Arguments;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.CommandContext;
@ -15,6 +17,38 @@ import java.util.*;
public class CommandParser {
private static final CommandManager COMMAND_MANAGER = MinecraftServer.getCommandManager();
@Nullable
public static CommandQueryResult findCommand(@NotNull String commandName, @NotNull String[] args) {
Command command = COMMAND_MANAGER.getDispatcher().findCommand(commandName);
if (command == null) {
return null;
}
CommandQueryResult commandQueryResult = new CommandQueryResult();
commandQueryResult.command = command;
commandQueryResult.commandName = commandName;
commandQueryResult.args = args;
boolean correct;
do {
correct = false;
if (commandQueryResult.args.length > 0) {
final String firstArgument = commandQueryResult.args[0];
for (Command subcommand : command.getSubcommands()) {
correct = Command.isValidName(subcommand, firstArgument);
commandQueryResult.command = subcommand;
commandQueryResult.commandName = firstArgument;
commandQueryResult.args = Arrays.copyOfRange(args, 1, args.length);
}
}
} while (correct);
return commandQueryResult;
}
public static void parse(@Nullable CommandSyntax syntax, @NotNull Argument<?>[] commandArguments, @NotNull String[] inputArguments,
@Nullable List<ValidSyntaxHolder> validSyntaxes,
@Nullable Int2ObjectRBTreeMap<CommandSuggestionHolder> syntaxesSuggestions) {

View File

@ -0,0 +1,9 @@
package net.minestom.server.command.builder.parser;
import net.minestom.server.command.builder.Command;
public class CommandQueryResult {
public Command command;
public String commandName;
public String[] args;
}

View File

@ -4,10 +4,10 @@ import net.minestom.server.MinecraftServer;
import net.minestom.server.command.CommandManager;
import net.minestom.server.command.CommandProcessor;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.CommandDispatcher;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.parser.ArgumentQueryResult;
import net.minestom.server.command.builder.parser.CommandParser;
import net.minestom.server.command.builder.parser.CommandQueryResult;
import net.minestom.server.command.builder.suggestion.Suggestion;
import net.minestom.server.command.builder.suggestion.SuggestionCallback;
import net.minestom.server.entity.Player;
@ -29,16 +29,21 @@ public class TabCompleteListener {
String commandString = packet.text.replaceFirst(CommandManager.COMMAND_PREFIX, "");
String[] split = commandString.split(StringUtils.SPACE);
String commandName = split[0];
final CommandDispatcher commandDispatcher = MinecraftServer.getCommandManager().getDispatcher();
final Command command = commandDispatcher.findCommand(commandName);
String args = commandString.replaceFirst(commandName, "");
String[] argsSplit = new String[split.length - 1];
System.arraycopy(split, 1, argsSplit, 0, argsSplit.length);
final ArgumentQueryResult queryResult = CommandParser.findSuggestibleArgument(command, argsSplit, text);
final CommandQueryResult commandQueryResult = CommandParser.findCommand(commandName, argsSplit);
if (commandQueryResult == null) {
System.out.println("COMMAND NOT FOUND");
return;
}
final ArgumentQueryResult queryResult = CommandParser.findSuggestibleArgument(commandQueryResult.command,
commandQueryResult.args, text);
if (queryResult == null) {
System.out.println("STOP");
System.out.println("QUERY NOT FOUND");
return;
}

View File

@ -6,6 +6,7 @@ import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.Arguments;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.suggestion.SuggestionEntry;
import org.jetbrains.annotations.NotNull;
import static net.minestom.server.command.builder.arguments.ArgumentType.*;
@ -15,23 +16,33 @@ public class TestCommand extends Command {
super("testcmd");
setDefaultExecutor(this::usage);
var test1 = Word("msg").setSuggestionCallback((suggestion, input) -> {
suggestion.addEntry(new SuggestionEntry("sug1", ColoredText.of(ChatColor.RED, "Hover")));
suggestion.addEntry(new SuggestionEntry("sug2"));
});
var test2 = Word("msg2").setSuggestionCallback((suggestion, input) -> {
suggestion.addEntry(new SuggestionEntry(input, ColoredText.of(ChatColor.BRIGHT_GREEN, "GHRTEG")));
});
var test3 = Integer("msg3");
addSyntax((sender, context) -> {
System.out.println("input: "+context.getInput());
}, test3, test1);
addSubcommand(new Sub());
}
private void usage(CommandSender sender, Arguments arguments) {
sender.sendMessage("Incorrect usage");
}
private static class Sub extends Command{
public Sub() {
super("sub");
var test1 = Word("msg").setSuggestionCallback((suggestion, input) -> {
suggestion.addEntry(new SuggestionEntry("sug1", ColoredText.of(ChatColor.RED, "Hover")));
suggestion.addEntry(new SuggestionEntry("sug2"));
});
var test2 = Word("msg2").setSuggestionCallback((suggestion, input) -> {
suggestion.addEntry(new SuggestionEntry(input, ColoredText.of(ChatColor.BRIGHT_GREEN, "GHRTEG")));
});
var test3 = Integer("msg3");
addSyntax((sender, context) -> {
System.out.println("input: "+context.getInput());
}, test3, test1);
}
}
}