From 793561e0cb7944990b43af68d7d60e752eafba8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noel=20N=C3=A9meth?= Date: Sat, 2 Jul 2022 05:39:39 +0200 Subject: [PATCH] Simplify command graph generation (#1200) --- .../src/main/java/net/minestom/demo/Main.java | 2 + .../demo/commands/ExecuteCommand.java | 14 + .../demo/commands/RedirectTestCommand.java | 18 + .../server/command/CommandManager.java | 310 ++---------------- .../minestom/server/command/GraphBuilder.java | 108 ++++++ .../net/minestom/server/command/Node.java | 88 +++++ .../server/command/builder/NodeMaker.java | 123 ------- .../command/builder/arguments/Argument.java | 43 +-- .../builder/arguments/ArgumentBoolean.java | 10 +- .../builder/arguments/ArgumentCommand.java | 20 +- .../builder/arguments/ArgumentEnum.java | 22 +- .../builder/arguments/ArgumentGroup.java | 12 +- .../builder/arguments/ArgumentLiteral.java | 11 +- .../builder/arguments/ArgumentLoop.java | 26 +- .../builder/arguments/ArgumentString.java | 15 +- .../arguments/ArgumentStringArray.java | 15 +- .../builder/arguments/ArgumentType.java | 5 +- .../builder/arguments/ArgumentWord.java | 37 +-- .../minecraft/ArgumentBlockState.java | 9 +- .../arguments/minecraft/ArgumentColor.java | 9 +- .../minecraft/ArgumentComponent.java | 10 +- .../arguments/minecraft/ArgumentEntity.java | 16 +- .../minecraft/ArgumentFloatRange.java | 7 +- .../arguments/minecraft/ArgumentIntRange.java | 7 +- .../minecraft/ArgumentItemStack.java | 9 +- .../minecraft/ArgumentNbtCompoundTag.java | 9 +- .../arguments/minecraft/ArgumentNbtTag.java | 9 +- .../arguments/minecraft/ArgumentRange.java | 15 +- .../minecraft/ArgumentResourceLocation.java | 9 +- .../arguments/minecraft/ArgumentTime.java | 9 +- .../arguments/minecraft/ArgumentUUID.java | 9 +- .../registry/ArgumentEnchantment.java | 13 +- .../registry/ArgumentEntityType.java | 17 +- .../minecraft/registry/ArgumentParticle.java | 13 +- .../registry/ArgumentPotionEffect.java | 13 +- .../arguments/number/ArgumentNumber.java | 14 +- .../ArgumentRelativeBlockPosition.java | 9 +- .../relative/ArgumentRelativeVec2.java | 9 +- .../relative/ArgumentRelativeVec3.java | 9 +- .../server/command/CommandManagerTest.java | 41 +-- 40 files changed, 404 insertions(+), 740 deletions(-) create mode 100644 demo/src/main/java/net/minestom/demo/commands/ExecuteCommand.java create mode 100644 demo/src/main/java/net/minestom/demo/commands/RedirectTestCommand.java create mode 100644 src/main/java/net/minestom/server/command/GraphBuilder.java create mode 100644 src/main/java/net/minestom/server/command/Node.java delete mode 100644 src/main/java/net/minestom/server/command/builder/NodeMaker.java diff --git a/demo/src/main/java/net/minestom/demo/Main.java b/demo/src/main/java/net/minestom/demo/Main.java index c776db29e..4030fd3d7 100644 --- a/demo/src/main/java/net/minestom/demo/Main.java +++ b/demo/src/main/java/net/minestom/demo/Main.java @@ -52,6 +52,8 @@ public class Main { commandManager.register(new AutoViewCommand()); commandManager.register(new SaveCommand()); commandManager.register(new GamemodeCommand()); + commandManager.register(new ExecuteCommand()); + commandManager.register(new RedirectTestCommand()); commandManager.setUnknownCommandCallback((sender, command) -> sender.sendMessage(Component.text("Unknown command", NamedTextColor.RED))); diff --git a/demo/src/main/java/net/minestom/demo/commands/ExecuteCommand.java b/demo/src/main/java/net/minestom/demo/commands/ExecuteCommand.java new file mode 100644 index 000000000..d48c36e0d --- /dev/null +++ b/demo/src/main/java/net/minestom/demo/commands/ExecuteCommand.java @@ -0,0 +1,14 @@ +package net.minestom.demo.commands; + +import net.minestom.server.command.builder.Command; +import net.minestom.server.command.builder.arguments.ArgumentCommand; + +public class ExecuteCommand extends Command { + + public ExecuteCommand() { + super("execute"); + ArgumentCommand run = new ArgumentCommand("run"); + + addSyntax(((sender, context) -> {}), run); + } +} diff --git a/demo/src/main/java/net/minestom/demo/commands/RedirectTestCommand.java b/demo/src/main/java/net/minestom/demo/commands/RedirectTestCommand.java new file mode 100644 index 000000000..c187ac903 --- /dev/null +++ b/demo/src/main/java/net/minestom/demo/commands/RedirectTestCommand.java @@ -0,0 +1,18 @@ +package net.minestom.demo.commands; + +import net.minestom.server.command.builder.Command; +import net.minestom.server.command.builder.arguments.ArgumentLiteral; +import net.minestom.server.command.builder.arguments.ArgumentLoop; + +public class RedirectTestCommand extends Command { + public RedirectTestCommand() { + super("redirect"); + + final ArgumentLiteral a = new ArgumentLiteral("a"); + final ArgumentLiteral b = new ArgumentLiteral("b"); + final ArgumentLiteral c = new ArgumentLiteral("c"); + final ArgumentLiteral d = new ArgumentLiteral("d"); + + addSyntax(((sender, context) -> {}), new ArgumentLoop<>("test", a,b,c,d)); + } +} diff --git a/src/main/java/net/minestom/server/command/CommandManager.java b/src/main/java/net/minestom/server/command/CommandManager.java index cb7c2db71..6c6ffac09 100644 --- a/src/main/java/net/minestom/server/command/CommandManager.java +++ b/src/main/java/net/minestom/server/command/CommandManager.java @@ -1,27 +1,20 @@ package net.minestom.server.command; -import it.unimi.dsi.fastutil.Pair; -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntList; -import net.minestom.server.command.builder.*; +import net.minestom.server.command.builder.Command; +import net.minestom.server.command.builder.CommandDispatcher; +import net.minestom.server.command.builder.CommandResult; +import net.minestom.server.command.builder.CommandSyntax; import net.minestom.server.command.builder.arguments.Argument; -import net.minestom.server.command.builder.arguments.minecraft.SuggestionType; import net.minestom.server.command.builder.condition.CommandCondition; -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.entity.Player; import net.minestom.server.event.EventDispatcher; import net.minestom.server.event.player.PlayerCommandEvent; import net.minestom.server.network.packet.server.play.DeclareCommandsPacket; -import net.minestom.server.utils.ArrayUtils; import net.minestom.server.utils.callback.CommandCallback; import net.minestom.server.utils.validate.Check; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; - /** * Manager used to register {@link Command commands}. *

@@ -167,282 +160,43 @@ public final class CommandManager { * @return the {@link DeclareCommandsPacket} for {@code player} */ public @NotNull DeclareCommandsPacket createDeclareCommandsPacket(@NotNull Player player) { - return buildPacket(player); - } + final GraphBuilder factory = new GraphBuilder(); - /** - * Builds the {@link DeclareCommandsPacket} for a {@link Player}. - * - * @param player the player to build the packet for - * @return the commands packet for the specific player - */ - private @NotNull DeclareCommandsPacket buildPacket(@NotNull Player player) { - List nodes = new ArrayList<>(); - // Contains the children of the main node (all commands name) - IntList rootChildren = new IntArrayList(); + for (Command command : this.dispatcher.getCommands()) { + // Check if user can use the command + final CommandCondition condition = command.getCondition(); + if (condition != null && !condition.canUse(player, null)) continue; - // Root node - DeclareCommandsPacket.Node rootNode = new DeclareCommandsPacket.Node(); - rootNode.flags = 0; - nodes.add(rootNode); + // Add command to the graph + // Create the command's root node + final Node cmdNode = factory.createLiteralNode(command.getName(), true, + command.getDefaultExecutor() != null, command.getAliases(), null); - Map commandIdentityMap = new IdentityHashMap<>(); - Map, Integer> argumentIdentityMap = new IdentityHashMap<>(); - - List> nodeRequests = new ArrayList<>(); - - // Brigadier-like commands - for (Command command : dispatcher.getCommands()) { - final int commandNodeIndex = serializeCommand(player, command, nodes, rootChildren, commandIdentityMap, argumentIdentityMap, nodeRequests); - commandIdentityMap.put(command, commandNodeIndex); - } - - // Answer to all node requests - for (Pair pair : nodeRequests) { - String input = pair.left(); - NodeMaker.Request request = pair.right(); - - final CommandQueryResult commandQueryResult = CommandParser.findCommand(dispatcher, input); - if (commandQueryResult == null) { - // Invalid command, return root node - request.retrieve(0); - continue; - } - - final ArgumentQueryResult queryResult = CommandParser.findEligibleArgument(commandQueryResult.command(), - commandQueryResult.args(), input, false, true, syntax -> true, argument -> true); - if (queryResult == null) { - // Invalid argument, return command node (default to root) - final int commandNode = commandIdentityMap.getOrDefault(commandQueryResult.command(), 0); - request.retrieve(commandNode); - continue; - } - - // Retrieve argument node - final int argumentNode = argumentIdentityMap.getOrDefault(queryResult.argument(), 0); - request.retrieve(argumentNode); - } - // Add root node children - rootNode.children = rootChildren.toIntArray(); - return new DeclareCommandsPacket(nodes, 0); - } - - private int serializeCommand(CommandSender sender, Command command, - List nodes, - IntList rootChildren, - Map commandIdentityMap, - Map, Integer> argumentIdentityMap, - List> nodeRequests) { - // Check if player should see this command - final CommandCondition commandCondition = command.getCondition(); - if (commandCondition != null) { - // Do not show command if return false - if (!commandCondition.canUse(sender, null)) { - return -1; - } - } - - // The main root of this command - IntList cmdChildren = new IntArrayList(); - final Collection syntaxes = command.getSyntaxes(); - - // Create command for main name - final DeclareCommandsPacket.Node mainNode = createCommandNodes(sender, nodes, cmdChildren, - command.getName(), syntaxes, rootChildren, argumentIdentityMap, nodeRequests); - final int mainNodeIndex = nodes.indexOf(mainNode); - - // Serialize all the subcommands - for (Command subcommand : command.getSubcommands()) { - final int subNodeIndex = serializeCommand(sender, subcommand, nodes, cmdChildren, commandIdentityMap, argumentIdentityMap, nodeRequests); - if (subNodeIndex != -1) { - mainNode.children = ArrayUtils.concatenateIntArrays(mainNode.children, new int[]{subNodeIndex}); - commandIdentityMap.put(subcommand, subNodeIndex); - } - } - - // Use redirection to hook aliases with the command - final String[] aliases = command.getAliases(); - if (aliases != null) { - for (String alias : aliases) { - DeclareCommandsPacket.Node aliasNode = new DeclareCommandsPacket.Node(); - aliasNode.flags = DeclareCommandsPacket.getFlag(DeclareCommandsPacket.NodeType.LITERAL, - false, true, false); - aliasNode.name = alias; - aliasNode.redirectedNode = mainNodeIndex; - - addCommandNameNode(aliasNode, rootChildren, nodes); - } - } - - return mainNodeIndex; - } - - /** - * 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 cmdChildren the main root of this command - * @param name the name of the command (or the alias) - * @param syntaxes the syntaxes of the command - * @param rootChildren the children of the main node (all commands name) - * @return The index of the main node for alias redirection - */ - private DeclareCommandsPacket.Node createCommandNodes(@NotNull CommandSender sender, - @NotNull List nodes, - @NotNull IntList cmdChildren, - @NotNull String name, - @NotNull Collection syntaxes, - @NotNull IntList rootChildren, - @NotNull Map, Integer> argumentIdentityMap, - @NotNull List> nodeRequests) { - - DeclareCommandsPacket.Node literalNode = createMainNode(name, syntaxes.isEmpty()); - - final int literalNodeId = addCommandNameNode(literalNode, rootChildren, nodes); - - // Contains the arguments of the already-parsed syntaxes - Map[]> syntaxesArguments = new HashMap<>(); - // Contains the nodes of an argument - Map> storedArgumentsNodes = new HashMap<>(); - - // Sort syntaxes by argument count. Brigadier requires it. - syntaxes = syntaxes.stream().sorted(Comparator.comparingInt(o -> -o.getArguments().length)).toList(); - 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 - DeclareCommandsPacket.Node[] lastNodes = new DeclareCommandsPacket.Node[]{literalNode}; - - // Represent the children of the last node - IntList argChildren = cmdChildren; - - NodeMaker nodeMaker = new NodeMaker(lastNodes, literalNodeId); - int lastArgumentNodeIndex = nodeMaker.getNodesCount(); - - final Argument[] arguments = syntax.getArguments(); - for (int i = 0; i < arguments.length; i++) { - final Argument argument = arguments[i]; - final boolean isLast = i == arguments.length - 1; - - // Search previously parsed syntaxes to find identical part in order to create a link between those - { - // Find shared part - boolean foundSharedPart = false; - for (var entry : syntaxesArguments.entrySet()) { - final var parsedArguments = entry.getValue(); - final int index = i + 1; - if (Arrays.mismatch(arguments, 0, index, parsedArguments, 0, index) == -1) { - final Argument sharedArgument = parsedArguments[i]; - final var sharedSyntax = entry.getKey(); - final var indexed = new IndexedArgument(sharedSyntax, sharedArgument, i); - final List storedNodes = storedArgumentsNodes.get(indexed); - if (storedNodes == null) - continue; // Retrieved argument has already been redirected - - argChildren = new IntArrayList(); - lastNodes = storedNodes.get(storedNodes.size() > index ? index : i); - foundSharedPart = true; - } + // Add syntax to the command + for (CommandSyntax syntax : command.getSyntaxes()) { + boolean executable = false; + Node[] lastArgNodes = new Node[] {cmdNode}; // First arg links to cmd root + @NotNull Argument[] arguments = syntax.getArguments(); + for (int i = 0; i < arguments.length; i++) { + Argument argument = arguments[i]; + // Determine if command is executable here + if (executable && argument.getDefaultValue() == null) { + // Optional arg was followed by a non-optional + throw new RuntimeException("");//todo exception } - if (foundSharedPart) { - continue; + if (!executable && i < arguments.length-1 && arguments[i+1].getDefaultValue() != null || i+1 == arguments.length) { + executable = true; } - } - - // Process the nodes for the argument - { - argument.processNodes(nodeMaker, isLast); - - // Each node array represent a layer - final List nodesLayer = nodeMaker.getNodes(); - storedArgumentsNodes.put(new IndexedArgument(syntax, argument, i), new ArrayList<>(nodesLayer)); - for (int nodeIndex = lastArgumentNodeIndex; nodeIndex < nodesLayer.size(); nodeIndex++) { - final NodeMaker.ConfiguredNodes configuredNodes = nodeMaker.getConfiguredNodes().get(nodeIndex); - final NodeMaker.Options options = configuredNodes.getOptions(); - final DeclareCommandsPacket.Node[] argumentNodes = nodesLayer.get(nodeIndex); - - for (DeclareCommandsPacket.Node argumentNode : argumentNodes) { - final int childId = nodes.size(); - nodeMaker.getNodeIdsMap().put(argumentNode, childId); - argChildren.add(childId); - - // Enable ASK_SERVER suggestion if required - { - if (argument.hasSuggestion()) { - argumentNode.flags |= 0x10; // Suggestion flag - argumentNode.suggestionsType = SuggestionType.ASK_SERVER.getIdentifier(); - } - } - - // Append to the last node - { - final int[] children = argChildren.toIntArray(); - for (DeclareCommandsPacket.Node lastNode : lastNodes) { - lastNode.children = lastNode.children == null ? - children : - ArrayUtils.concatenateIntArrays(lastNode.children, children); - } - } - - nodes.add(argumentNode); - } - - if (options.shouldUpdateLastNode()) { - // 'previousNodes' used if the nodes options require to overwrite the parent - final DeclareCommandsPacket.Node[] previousNodes = options.getPreviousNodes(); - - lastNodes = previousNodes != null ? previousNodes : argumentNodes; - argChildren = new IntArrayList(); - } + // Append current node to previous + final Node[] argNodes = factory.createArgumentNode(argument, executable); + for (Node lastArgNode : lastArgNodes) { + lastArgNode.addChild(argNodes); } - - // Used to do not re-compute the previous arguments - lastArgumentNodeIndex = nodesLayer.size(); + lastArgNodes = argNodes; } } - - nodeRequests.addAll(nodeMaker.getNodeRequests()); - - syntaxesArguments.put(syntax, arguments); } - storedArgumentsNodes.forEach((indexedArgument, argNodes) -> { - int value = 0; - for (DeclareCommandsPacket.Node[] n1 : argNodes) { - for (DeclareCommandsPacket.Node n2 : n1) { - value = nodes.indexOf(n2); - } - } - // FIXME: add syntax for indexing - argumentIdentityMap.put(indexedArgument.argument, value); - }); - - literalNode.children = cmdChildren.toIntArray(); - return literalNode; + return factory.createCommandPacket(); } - - private @NotNull DeclareCommandsPacket.Node createMainNode(@NotNull String name, boolean executable) { - DeclareCommandsPacket.Node literalNode = new DeclareCommandsPacket.Node(); - literalNode.flags = DeclareCommandsPacket.getFlag(DeclareCommandsPacket.NodeType.LITERAL, executable, false, false); - literalNode.name = name; - - return literalNode; - } - - private int addCommandNameNode(@NotNull DeclareCommandsPacket.Node commandNode, - @NotNull IntList rootChildren, - @NotNull List nodes) { - final int node = nodes.size(); - rootChildren.add(node); - nodes.add(commandNode); - return node; - } - - private record IndexedArgument(CommandSyntax syntax, Argument argument, int index) {} - } diff --git a/src/main/java/net/minestom/server/command/GraphBuilder.java b/src/main/java/net/minestom/server/command/GraphBuilder.java new file mode 100644 index 000000000..a18cafaaa --- /dev/null +++ b/src/main/java/net/minestom/server/command/GraphBuilder.java @@ -0,0 +1,108 @@ +package net.minestom.server.command; + +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import it.unimi.dsi.fastutil.objects.ObjectSet; +import net.minestom.server.command.builder.arguments.*; +import net.minestom.server.network.packet.server.play.DeclareCommandsPacket; +import org.jetbrains.annotations.Nullable; + +import java.util.Comparator; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; +import java.util.stream.Stream; + +final class GraphBuilder { + private final AtomicInteger idSource = new AtomicInteger(); + private final ObjectSet nodes = new ObjectOpenHashSet<>(); + private final ObjectSet> redirectWaitList = new ObjectOpenHashSet<>(); + private final Node root = rootNode(); + + private Node rootNode() { + final Node rootNode = new Node(idSource.getAndIncrement()); + nodes.add(rootNode); + return rootNode; + } + + public Node createLiteralNode(String name, boolean addToRoot, boolean executable, @Nullable String[] aliases, @Nullable Integer redirectTo) { + if (aliases != null) { + final Node node = createLiteralNode(name, addToRoot, executable, null, null); + for (String alias : aliases) { + createLiteralNode(alias, addToRoot, false, null, node.getId()); + } + return node; + } else { + final Node literalNode = new Node(idSource.getAndIncrement(), name, redirectTo); + literalNode.setExecutable(executable); + nodes.add(literalNode); + if (addToRoot) root.addChild(literalNode); + return literalNode; + } + } + + public Node[] createArgumentNode(Argument argument, boolean executable) { + final Node[] nodes; + Integer overrideRedirectTarget = null; + if (argument instanceof ArgumentEnum argumentEnum) { + nodes = argumentEnum.entries().stream().map(x -> createLiteralNode(x, false, executable, null, null)).toArray(Node[]::new); + } else if (argument instanceof ArgumentGroup argumentGroup) { + nodes = argumentGroup.group().stream().map(x -> createArgumentNode(x, executable)).flatMap(Stream::of).toArray(Node[]::new); + } else if (argument instanceof ArgumentLoop argumentLoop) { + overrideRedirectTarget = idSource.get()-1; + nodes = argumentLoop.arguments().stream().map(x -> createArgumentNode(x, executable)).flatMap(Stream::of).toArray(Node[]::new); + } else { + if (argument instanceof ArgumentCommand) { + return new Node[]{createLiteralNode(argument.getId(), false, false, null, 0)}; + } + final int id = idSource.getAndIncrement(); + nodes = new Node[] {argument instanceof ArgumentLiteral ? new Node(id, argument.getId(), null) : new Node(id, argument)}; + } + for (Node node : nodes) { + node.setExecutable(executable); + this.nodes.add(node); + Integer finalOverrideRedirectTarget = overrideRedirectTarget; + if (finalOverrideRedirectTarget != null) { + redirectWaitList.add(() -> { + int target = finalOverrideRedirectTarget; + if (target != -1) { + node.setRedirectTarget(target); + return true; + } + return false; + }); + } + } + return nodes; + } + + private int tryResolveId(String[] path) { + if (path.length == 0) { + return root.getId(); + } else { + Node target = root; + for (String next : path) { + Node finalTarget = target; + final Optional result = nodes.stream().filter(finalTarget::isParentOf) + .filter(x -> x.name().equals(next)).findFirst(); + if (result.isEmpty()) { + return -1; + } else { + target = result.get(); + } + } + return target.getId(); + } + } + + private void finalizeStructure() { + redirectWaitList.removeIf(Supplier::get); + if (redirectWaitList.size() > 0) + throw new RuntimeException("Could not set redirects for all arguments! Did you provide a correct id path which doesn't rely on redirects?"); + } + + public DeclareCommandsPacket createCommandPacket() { + finalizeStructure(); + return new DeclareCommandsPacket(nodes.stream().sorted(Comparator.comparingInt(Node::getId)) + .map(Node::getPacketNode).toList(), root.getId()); + } +} diff --git a/src/main/java/net/minestom/server/command/Node.java b/src/main/java/net/minestom/server/command/Node.java new file mode 100644 index 000000000..f6b9871bb --- /dev/null +++ b/src/main/java/net/minestom/server/command/Node.java @@ -0,0 +1,88 @@ +package net.minestom.server.command; + +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntSet; +import net.minestom.server.command.builder.arguments.Argument; +import net.minestom.server.network.packet.server.play.DeclareCommandsPacket; + +final class Node { + private final int id; + private final IntSet children; + private final DeclareCommandsPacket.NodeType type; + private String name; + private Integer redirectTarget; + private Argument argument; + private boolean executable; + + Node(int id, DeclareCommandsPacket.NodeType type) { + this.id = id; + this.children = new IntOpenHashSet(); + this.type = type; + } + + Node(int id) { + this(id, DeclareCommandsPacket.NodeType.ROOT); + } + + Node(int id, String name, Integer redirectTarget) { + this(id, DeclareCommandsPacket.NodeType.LITERAL); + setName(name); + setRedirectTarget(redirectTarget); + } + + Node(int id, Argument argument) { + this(id, DeclareCommandsPacket.NodeType.ARGUMENT); + setName(argument.getId()); + this.argument = argument; + } + + public void setExecutable(boolean executable) { + this.executable = executable; + } + + public String name() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setRedirectTarget(Integer redirectTarget) { + this.redirectTarget = redirectTarget; + } + + public void addChild(Node ...nodes) { + for (Node node : nodes) { + children.add(node.id); + } + } + + public boolean isParentOf(Node node) { + return children.contains(node.getId()); + } + + public int getId() { + return id; + } + + public DeclareCommandsPacket.Node getPacketNode() { + final DeclareCommandsPacket.Node node = new DeclareCommandsPacket.Node(); + node.children = children.toIntArray(); + node.flags = DeclareCommandsPacket.getFlag(type, executable, redirectTarget != null, + type == DeclareCommandsPacket.NodeType.ARGUMENT && argument.hasSuggestion()); + node.name = name; + if (redirectTarget != null) { + node.redirectedNode = redirectTarget; + } + if (type == DeclareCommandsPacket.NodeType.ARGUMENT) { + node.properties = argument.nodeProperties(); + node.parser = argument.parser(); + if (argument.hasSuggestion()) { + //noinspection ConstantConditions + node.suggestionsType = argument.suggestionType().getIdentifier(); + } + } + return node; + } +} diff --git a/src/main/java/net/minestom/server/command/builder/NodeMaker.java b/src/main/java/net/minestom/server/command/builder/NodeMaker.java deleted file mode 100644 index bafe9e467..000000000 --- a/src/main/java/net/minestom/server/command/builder/NodeMaker.java +++ /dev/null @@ -1,123 +0,0 @@ -package net.minestom.server.command.builder; - -import it.unimi.dsi.fastutil.Pair; -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -import net.minestom.server.network.packet.server.play.DeclareCommandsPacket; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; - -public class NodeMaker { - - private final List configuredNodes = new ArrayList<>(2); - private final List nodes = new ArrayList<>(2); - private final Object2IntMap nodeIdsMap = new Object2IntOpenHashMap<>(); - - private final List> nodeRequests = new ArrayList<>(); - - public NodeMaker(@NotNull DeclareCommandsPacket.Node[] commandNodes, int id) { - addNodes(commandNodes); - for (DeclareCommandsPacket.Node node : commandNodes) { - this.nodeIdsMap.put(node, id); - } - } - - public ConfiguredNodes getLatestConfiguredNodes() { - if (configuredNodes.isEmpty()) - return null; - return configuredNodes.get(configuredNodes.size() - 1); - } - - public DeclareCommandsPacket.Node[] getLatestNodes() { - ConfiguredNodes configuredNodes = getLatestConfiguredNodes(); - return configuredNodes != null ? configuredNodes.nodes : null; - } - - public int getNodesCount() { - return nodes.size(); - } - - public void addNodes(@NotNull DeclareCommandsPacket.Node[] nodes) { - Options options = new Options(); - this.configuredNodes.add(ConfiguredNodes.of(nodes, options)); - this.nodes.add(nodes); - } - - @NotNull - public List getConfiguredNodes() { - return configuredNodes; - } - - public List getNodes() { - return nodes; - } - - @NotNull - public Object2IntMap getNodeIdsMap() { - return nodeIdsMap; - } - - public void request(String input, Request request) { - this.nodeRequests.add(Pair.of(input, request)); - } - - public List> getNodeRequests() { - return nodeRequests; - } - - public static class ConfiguredNodes { - private DeclareCommandsPacket.Node[] nodes; - private Options options; - - private static ConfiguredNodes of(DeclareCommandsPacket.Node[] nodes, Options options) { - ConfiguredNodes configuredNodes = new ConfiguredNodes(); - configuredNodes.nodes = nodes; - configuredNodes.options = options; - return configuredNodes; - } - - public DeclareCommandsPacket.Node[] getNodes() { - return nodes; - } - - public Options getOptions() { - return options; - } - } - - public static class Options { - - private boolean updateLastNode = true; - private DeclareCommandsPacket.Node[] previousNodes; - - public static Options init() { - return new Options(); - } - - public boolean shouldUpdateLastNode() { - return updateLastNode; - } - - public Options updateLastNode(boolean updateLastNode) { - this.updateLastNode = updateLastNode; - return this; - } - - public DeclareCommandsPacket.Node[] getPreviousNodes() { - return previousNodes; - } - - public Options setPreviousNodes(DeclareCommandsPacket.Node[] previousNodes) { - this.previousNodes = previousNodes; - return this; - } - } - - @FunctionalInterface - public interface Request { - void retrieve(int id); - } - -} diff --git a/src/main/java/net/minestom/server/command/builder/arguments/Argument.java b/src/main/java/net/minestom/server/command/builder/arguments/Argument.java index 254a01290..19b8e7f65 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/Argument.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/Argument.java @@ -3,10 +3,9 @@ package net.minestom.server.command.builder.arguments; import net.minestom.server.command.builder.ArgumentCallback; import net.minestom.server.command.builder.Command; import net.minestom.server.command.builder.CommandExecutor; -import net.minestom.server.command.builder.NodeMaker; +import net.minestom.server.command.builder.arguments.minecraft.SuggestionType; import net.minestom.server.command.builder.exception.ArgumentSyntaxException; import net.minestom.server.command.builder.suggestion.SuggestionCallback; -import net.minestom.server.network.packet.server.play.DeclareCommandsPacket; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,6 +34,7 @@ public abstract class Argument { private Supplier defaultValue; private SuggestionCallback suggestionCallback; + protected SuggestionType suggestionType; /** * Creates a new argument. @@ -91,30 +91,14 @@ public abstract class Argument { */ public abstract @NotNull T parse(@NotNull String input) throws ArgumentSyntaxException; - /** - * Turns the argument into a list of nodes for command dispatching. Make sure to set the Node's parser. - * - * @param nodeMaker helper object used to create and modify nodes - * @param executable true if this will be the last argument, false otherwise - */ - public abstract void processNodes(@NotNull NodeMaker nodeMaker, boolean executable); + public abstract String parser(); - /** - * Builds an argument node. - * - * @param argument the argument - * @param executable true if this will be the last argument, false otherwise - * @return the created {@link DeclareCommandsPacket.Node} - */ - @NotNull - protected static DeclareCommandsPacket.Node simpleArgumentNode(@NotNull Argument argument, - boolean executable, boolean redirect, boolean suggestion) { - DeclareCommandsPacket.Node argumentNode = new DeclareCommandsPacket.Node(); + public byte @Nullable [] nodeProperties() { + return null; + } - argumentNode.flags = DeclareCommandsPacket.getFlag(DeclareCommandsPacket.NodeType.ARGUMENT, executable, redirect, suggestion); - argumentNode.name = argument.getId(); - - return argumentNode; + public @Nullable SuggestionType suggestionType() { + return suggestionType; } /** @@ -242,6 +226,7 @@ public abstract class Argument { */ public Argument setSuggestionCallback(@NotNull SuggestionCallback suggestionCallback) { this.suggestionCallback = suggestionCallback; + this.suggestionType = SuggestionType.ASK_SERVER; return this; } @@ -251,7 +236,7 @@ public abstract class Argument { * @return If this argument has a suggestion. */ public boolean hasSuggestion() { - return suggestionCallback != null; + return suggestionType != null; } /** @@ -317,8 +302,8 @@ public abstract class Argument { } @Override - public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) { - argument.processNodes(nodeMaker, executable); + public String parser() { + return argument.parser(); } } @@ -346,8 +331,8 @@ public abstract class Argument { } @Override - public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) { - argument.processNodes(nodeMaker, executable); + public String parser() { + return argument.parser(); } } } diff --git a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentBoolean.java b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentBoolean.java index 9a76b99ae..cffac0579 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentBoolean.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentBoolean.java @@ -1,8 +1,6 @@ package 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.network.packet.server.play.DeclareCommandsPacket; import org.jetbrains.annotations.NotNull; /** @@ -30,13 +28,9 @@ public class ArgumentBoolean extends Argument { } @Override - public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) { - DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(this, executable, false, false); - argumentNode.parser = "brigadier:bool"; - - nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode}); + public String parser() { + return "brigadier:bool"; } - @Override public String toString() { return String.format("Boolean<%s>", getId()); 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 7068ffedc..dec261091 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 @@ -3,9 +3,7 @@ package net.minestom.server.command.builder.arguments; import net.minestom.server.MinecraftServer; import net.minestom.server.command.builder.CommandDispatcher; import net.minestom.server.command.builder.CommandResult; -import net.minestom.server.command.builder.NodeMaker; import net.minestom.server.command.builder.exception.ArgumentSyntaxException; -import net.minestom.server.network.packet.server.play.DeclareCommandsPacket; import net.minestom.server.utils.StringUtils; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -37,22 +35,8 @@ public class ArgumentCommand extends Argument { } @Override - public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) { - final DeclareCommandsPacket.Node[] lastNodes = nodeMaker.getLatestNodes(); - - if (!shortcut.isEmpty()) { - nodeMaker.request(shortcut, (id) -> { - for (DeclareCommandsPacket.Node node : lastNodes) { - node.flags |= 0x08; // Redirection mask - node.redirectedNode = id; - } - }); - } else { - for (DeclareCommandsPacket.Node node : lastNodes) { - node.flags |= 0x08; // Redirection mask - node.redirectedNode = 0; // Redirect to root - } - } + public String parser() { + return null; } public boolean isOnlyCorrect() { diff --git a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentEnum.java b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentEnum.java index 723842555..3ac12d8d6 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentEnum.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentEnum.java @@ -1,10 +1,10 @@ package 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.network.packet.server.play.DeclareCommandsPacket; import org.jetbrains.annotations.NotNull; +import java.util.Arrays; +import java.util.List; import java.util.Locale; import java.util.function.UnaryOperator; @@ -40,20 +40,12 @@ public class ArgumentEnum extends Argument { } @Override - public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) { - // Create a primitive array for mapping - DeclareCommandsPacket.Node[] nodes = new DeclareCommandsPacket.Node[this.values.length]; + public String parser() { + return null; + } - // Create a node for each restrictions as literal - for (int i = 0; i < nodes.length; i++) { - DeclareCommandsPacket.Node argumentNode = new DeclareCommandsPacket.Node(); - - argumentNode.flags = DeclareCommandsPacket.getFlag(DeclareCommandsPacket.NodeType.LITERAL, - executable, false, false); - argumentNode.name = this.format.formatter.apply(this.values[i].name()); - nodes[i] = argumentNode; - } - nodeMaker.addNodes(nodes); + public List entries() { + return Arrays.stream(values).map(x -> format.formatter.apply(x.name())).toList(); } public enum Format { 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 index 9d4c8f659..d598faa5e 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentGroup.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentGroup.java @@ -1,7 +1,6 @@ package 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; import net.minestom.server.command.builder.parser.ValidSyntaxHolder; @@ -38,10 +37,11 @@ public class ArgumentGroup extends Argument { } @Override - public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) { - for (int i = 0; i < group.length; i++) { - final boolean isLast = i == group.length - 1; - group[i].processNodes(nodeMaker, executable && isLast); - } + public String parser() { + return null; + } + + public List> group() { + return List.of(group); } } diff --git a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentLiteral.java b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentLiteral.java index 558e38509..ffaccf0f0 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentLiteral.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentLiteral.java @@ -1,8 +1,6 @@ package 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.network.packet.server.play.DeclareCommandsPacket; import org.jetbrains.annotations.NotNull; public class ArgumentLiteral extends Argument { @@ -23,13 +21,8 @@ public class ArgumentLiteral extends Argument { } @Override - public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) { - DeclareCommandsPacket.Node literalNode = new DeclareCommandsPacket.Node(); - literalNode.flags = DeclareCommandsPacket.getFlag(DeclareCommandsPacket.NodeType.LITERAL, - executable, false, false); - literalNode.name = getId(); - - nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{literalNode}); + public String parser() { + return null; } @Override diff --git a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentLoop.java b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentLoop.java index 5387bae0f..f16e8c907 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentLoop.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentLoop.java @@ -1,8 +1,6 @@ package 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.network.packet.server.play.DeclareCommandsPacket; import net.minestom.server.utils.StringUtils; import org.jetbrains.annotations.NotNull; @@ -58,24 +56,12 @@ public class ArgumentLoop extends Argument> { return result; } + public List> arguments() { + return arguments; + } + @Override - public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) { - DeclareCommandsPacket.Node[] latestNodes = nodeMaker.getLatestNodes(); - - for (DeclareCommandsPacket.Node latestNode : latestNodes) { - final int id = nodeMaker.getNodeIdsMap().getInt(latestNode); - - for (Argument argument : arguments) { - argument.processNodes(nodeMaker, executable); - - NodeMaker.ConfiguredNodes configuredNodes = nodeMaker.getLatestConfiguredNodes(); - // For the next loop argument to start at the same place - configuredNodes.getOptions().setPreviousNodes(latestNodes); - for (DeclareCommandsPacket.Node lastArgumentNode : configuredNodes.getNodes()) { - lastArgumentNode.flags |= 0x08; - lastArgumentNode.redirectedNode = id; - } - } - } + public String parser() { + return null; } } diff --git a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentString.java b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentString.java index f8aaed23d..cb781abb0 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentString.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentString.java @@ -1,11 +1,10 @@ package 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.network.packet.server.play.DeclareCommandsPacket; import net.minestom.server.utils.StringUtils; import net.minestom.server.utils.binary.BinaryWriter; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Argument which will take a quoted string. @@ -31,15 +30,15 @@ public class ArgumentString extends Argument { } @Override - public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) { - DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(this, executable, false, false); + public String parser() { + return "brigadier:string"; + } - argumentNode.parser = "brigadier:string"; - argumentNode.properties = BinaryWriter.makeArray(packetWriter -> { + @Override + public byte @Nullable [] nodeProperties() { + return BinaryWriter.makeArray(packetWriter -> { packetWriter.writeVarInt(1); // Quotable phrase }); - - nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode}); } /** diff --git a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentStringArray.java b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentStringArray.java index e6429a4c1..3df213102 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentStringArray.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentStringArray.java @@ -1,10 +1,9 @@ package net.minestom.server.command.builder.arguments; -import net.minestom.server.command.builder.NodeMaker; -import net.minestom.server.network.packet.server.play.DeclareCommandsPacket; import net.minestom.server.utils.StringUtils; import net.minestom.server.utils.binary.BinaryWriter; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.regex.Pattern; @@ -26,15 +25,15 @@ public class ArgumentStringArray extends Argument { } @Override - public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) { - DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(this, executable, false, false); + public String parser() { + return "brigadier:string"; + } - argumentNode.parser = "brigadier:string"; - argumentNode.properties = BinaryWriter.makeArray(packetWriter -> { + @Override + public byte @Nullable [] nodeProperties() { + return BinaryWriter.makeArray(packetWriter -> { packetWriter.writeVarInt(2); // Greedy phrase }); - - nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode}); } @Override diff --git a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentType.java b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentType.java index 011ce7f3c..0410e0193 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentType.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentType.java @@ -1,7 +1,10 @@ package net.minestom.server.command.builder.arguments; import net.minestom.server.command.builder.arguments.minecraft.*; -import net.minestom.server.command.builder.arguments.minecraft.registry.*; +import net.minestom.server.command.builder.arguments.minecraft.registry.ArgumentEnchantment; +import net.minestom.server.command.builder.arguments.minecraft.registry.ArgumentEntityType; +import net.minestom.server.command.builder.arguments.minecraft.registry.ArgumentParticle; +import net.minestom.server.command.builder.arguments.minecraft.registry.ArgumentPotionEffect; import net.minestom.server.command.builder.arguments.number.ArgumentDouble; import net.minestom.server.command.builder.arguments.number.ArgumentFloat; import net.minestom.server.command.builder.arguments.number.ArgumentInteger; diff --git a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentWord.java b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentWord.java index 91da3861e..5f7915369 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentWord.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentWord.java @@ -1,11 +1,9 @@ package 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.network.packet.server.play.DeclareCommandsPacket; +import net.minestom.server.utils.StringUtils; import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.validate.Check; -import net.minestom.server.utils.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -70,32 +68,15 @@ public class ArgumentWord extends Argument { } @Override - public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) { - if (restrictions != null) { + public String parser() { + return "brigadier:string"; + } - // Create a primitive array for mapping - DeclareCommandsPacket.Node[] nodes = new DeclareCommandsPacket.Node[this.restrictions.length]; - - // Create a node for each restrictions as literal - for (int i = 0; i < nodes.length; i++) { - DeclareCommandsPacket.Node argumentNode = new DeclareCommandsPacket.Node(); - - argumentNode.flags = DeclareCommandsPacket.getFlag(DeclareCommandsPacket.NodeType.LITERAL, - executable, false, false); - argumentNode.name = this.restrictions[i]; - nodes[i] = argumentNode; - - } - nodeMaker.addNodes(nodes); - } else { - // Can be any word, add only one argument node - DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(this, executable, false, false); - argumentNode.parser = "brigadier:string"; - argumentNode.properties = BinaryWriter.makeArray(packetWriter -> { - packetWriter.writeVarInt(0); // Single word - }); - nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode}); - } + @Override + public byte @Nullable [] nodeProperties() { + return BinaryWriter.makeArray(packetWriter -> { + packetWriter.writeVarInt(0); // Single word + }); } /** diff --git a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentBlockState.java b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentBlockState.java index c203e8b85..a4a8cc7aa 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentBlockState.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentBlockState.java @@ -1,10 +1,8 @@ package net.minestom.server.command.builder.arguments.minecraft; -import net.minestom.server.command.builder.NodeMaker; import net.minestom.server.command.builder.arguments.Argument; import net.minestom.server.command.builder.exception.ArgumentSyntaxException; import net.minestom.server.instance.block.Block; -import net.minestom.server.network.packet.server.play.DeclareCommandsPacket; import net.minestom.server.utils.block.BlockUtils; import org.jetbrains.annotations.NotNull; @@ -25,11 +23,8 @@ public class ArgumentBlockState extends Argument { } @Override - public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) { - DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(this, executable, false, false); - argumentNode.parser = "minecraft:block_state"; - - nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode}); + public String parser() { + return "minecraft:block_state"; } /** diff --git a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentColor.java b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentColor.java index dfe6e805f..7b5d6fa1c 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentColor.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentColor.java @@ -2,10 +2,8 @@ package net.minestom.server.command.builder.arguments.minecraft; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; -import net.minestom.server.command.builder.NodeMaker; import net.minestom.server.command.builder.arguments.Argument; import net.minestom.server.command.builder.exception.ArgumentSyntaxException; -import net.minestom.server.network.packet.server.play.DeclareCommandsPacket; import org.jetbrains.annotations.NotNull; /** @@ -41,11 +39,8 @@ public class ArgumentColor extends Argument