From 36d548ff355039394ff0d29adf4f0b19b818a448 Mon Sep 17 00:00:00 2001 From: themode Date: Wed, 17 Mar 2021 01:52:55 +0100 Subject: [PATCH] Improve redirection match --- .../server/command/CommandManager.java | 34 +++++++++---------- .../builder/arguments/ArgumentCommand.java | 2 ++ .../command/builder/parser/CommandParser.java | 11 +++--- .../server/listener/TabCompleteListener.java | 4 ++- src/test/java/demo/commands/TestCommand.java | 2 +- 5 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/main/java/net/minestom/server/command/CommandManager.java b/src/main/java/net/minestom/server/command/CommandManager.java index cdd97275c..1e8f8e411 100644 --- a/src/main/java/net/minestom/server/command/CommandManager.java +++ b/src/main/java/net/minestom/server/command/CommandManager.java @@ -315,7 +315,7 @@ public final class CommandManager { nodes.add(rootNode); Map commandIdentityMap = new IdentityHashMap<>(); - Map, DeclareCommandsPacket.Node[]> argumentIdentityMap = new IdentityHashMap<>(); + Map, Integer> argumentIdentityMap = new IdentityHashMap<>(); List> nodeRequests = new ArrayList<>(); @@ -338,25 +338,18 @@ public final class CommandManager { } final ArgumentQueryResult queryResult = CommandParser.findEligibleArgument(commandQueryResult.command, - commandQueryResult.args, input, true, argument -> true); + commandQueryResult.args, input, false, true, syntax -> true, argument -> true); if (queryResult == null) { // Invalid argument, return command node (default to root) - int commandNode = commandIdentityMap.getOrDefault(commandQueryResult.command, 0); + final int commandNode = commandIdentityMap.getOrDefault(commandQueryResult.command, 0); request.retrieve(commandNode); continue; } // Retrieve argument node - Argument argument = queryResult.argument; - DeclareCommandsPacket.Node[] argNodes = argumentIdentityMap.get(argument); - for (DeclareCommandsPacket.Node argNode : argNodes) { - final int node = nodes.indexOf(argNode); - request.retrieve(node); - break; - } - - // Unexpected issue, redirect to root - //request.retrieve(0); + final Argument argument = queryResult.argument; + final int argumentNode = argumentIdentityMap.getOrDefault(argument, 0); + request.retrieve(argumentNode); } // Pair @@ -417,7 +410,7 @@ public final class CommandManager { List nodes, IntList rootChildren, Map commandIdentityMap, - Map, DeclareCommandsPacket.Node[]> argumentIdentityMap, + Map, Integer> argumentIdentityMap, List> nodeRequests) { // Check if player should see this command final CommandCondition commandCondition = command.getCondition(); @@ -480,7 +473,7 @@ public final class CommandManager { @NotNull String name, @NotNull Collection syntaxes, @NotNull IntList rootChildren, - @NotNull Map, DeclareCommandsPacket.Node[]> argumentIdentityMap, + @NotNull Map, Integer> argumentIdentityMap, @NotNull List> nodeRequests) { DeclareCommandsPacket.Node literalNode = createMainNode(name, syntaxes.isEmpty()); @@ -592,8 +585,15 @@ public final class CommandManager { syntaxesArguments.add(arguments); } - storedArgumentsNodes.forEach((argument, nodes1) -> - argumentIdentityMap.put(argument, nodes1.get(nodes1.size() - 2))); + storedArgumentsNodes.forEach((argument, argNodes) -> { + int value = 0; + for (DeclareCommandsPacket.Node[] n1 : argNodes) { + for (DeclareCommandsPacket.Node n2 : n1) { + value = nodes.indexOf(n2); + } + } + argumentIdentityMap.put(argument, value); + }); literalNode.children = ArrayUtils.toArray(cmdChildren); return literalNode; diff --git a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentCommand.java b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentCommand.java index 66743f76e..c2d90c5ae 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentCommand.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentCommand.java @@ -1,5 +1,6 @@ package net.minestom.server.command.builder.arguments; +import com.google.common.annotations.Beta; import net.minestom.server.MinecraftServer; import net.minestom.server.command.builder.CommandDispatcher; import net.minestom.server.command.builder.CommandResult; @@ -68,6 +69,7 @@ public class ArgumentCommand extends Argument { return shortcut; } + @Beta public ArgumentCommand setShortcut(@NotNull String shortcut) { this.shortcut = shortcut; return this; 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 8f1fc12ab..fb8cfe713 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 @@ -13,7 +13,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; -import java.util.function.Function; +import java.util.function.Predicate; public class CommandParser { @@ -165,13 +165,15 @@ public class CommandParser { @Nullable public static ArgumentQueryResult findEligibleArgument(@NotNull Command command, String[] args, String commandString, - boolean trailingSpace, Function, Boolean> eligibilityFunction) { + boolean trailingSpace, boolean forceCorrect, + Predicate syntaxPredicate, + Predicate> argumentPredicate) { final Collection syntaxes = command.getSyntaxes(); Int2ObjectRBTreeMap suggestions = new Int2ObjectRBTreeMap<>(Collections.reverseOrder()); for (CommandSyntax syntax : syntaxes) { - if (!syntax.hasSuggestion()) { + if (!syntaxPredicate.test(syntax)) { continue; } @@ -202,7 +204,8 @@ public class CommandParser { } // Save result - if (eligibilityFunction.apply(argument)) { + if ((!forceCorrect || argumentResult.correct) && + argumentPredicate.test(argument)) { ArgumentQueryResult queryResult = new ArgumentQueryResult(); queryResult.syntax = syntax; queryResult.argument = argument; diff --git a/src/main/java/net/minestom/server/listener/TabCompleteListener.java b/src/main/java/net/minestom/server/listener/TabCompleteListener.java index 4a9db88b1..73e95dc91 100644 --- a/src/main/java/net/minestom/server/listener/TabCompleteListener.java +++ b/src/main/java/net/minestom/server/listener/TabCompleteListener.java @@ -1,6 +1,7 @@ package net.minestom.server.listener; import net.minestom.server.command.CommandManager; +import net.minestom.server.command.builder.CommandSyntax; import net.minestom.server.command.builder.arguments.Argument; import net.minestom.server.command.builder.parser.ArgumentQueryResult; import net.minestom.server.command.builder.parser.CommandParser; @@ -32,7 +33,8 @@ public class TabCompleteListener { } final ArgumentQueryResult queryResult = CommandParser.findEligibleArgument(commandQueryResult.command, - commandQueryResult.args, commandString, text.endsWith(StringUtils.SPACE), Argument::hasSuggestion); + commandQueryResult.args, commandString, text.endsWith(StringUtils.SPACE), false, + CommandSyntax::hasSuggestion, Argument::hasSuggestion); if (queryResult == null) { // Suggestible argument not found return; diff --git a/src/test/java/demo/commands/TestCommand.java b/src/test/java/demo/commands/TestCommand.java index 09879e5be..de7c3b936 100644 --- a/src/test/java/demo/commands/TestCommand.java +++ b/src/test/java/demo/commands/TestCommand.java @@ -28,7 +28,7 @@ public class TestCommand extends Command { addSyntax((sender, context) -> { System.out.println("cmd syntax"); - }, Literal("debug"), Command("cmd").setShortcut("testcmd test a")); + }, Literal("debug"), Command("cmd").setShortcut("testcmd test")); }