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