2020-04-24 03:25:58 +02:00
|
|
|
package net.minestom.server.command;
|
2020-04-05 10:15:21 +02:00
|
|
|
|
2020-07-10 16:37:18 +02:00
|
|
|
import net.minestom.server.command.builder.Command;
|
|
|
|
import net.minestom.server.command.builder.CommandDispatcher;
|
|
|
|
import net.minestom.server.command.builder.CommandSyntax;
|
|
|
|
import net.minestom.server.command.builder.arguments.*;
|
2020-07-10 22:50:05 +02:00
|
|
|
import net.minestom.server.command.builder.arguments.minecraft.ArgumentColor;
|
|
|
|
import net.minestom.server.command.builder.arguments.minecraft.ArgumentTime;
|
|
|
|
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.ArgumentPotion;
|
2020-07-10 16:37:18 +02:00
|
|
|
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;
|
2020-07-10 22:50:05 +02:00
|
|
|
import net.minestom.server.command.builder.arguments.number.ArgumentNumber;
|
2020-07-10 18:12:29 +02:00
|
|
|
import net.minestom.server.command.builder.condition.CommandCondition;
|
2020-04-24 03:25:58 +02:00
|
|
|
import net.minestom.server.entity.Player;
|
2020-05-07 15:46:21 +02:00
|
|
|
import net.minestom.server.event.player.PlayerCommandEvent;
|
2020-04-24 03:25:58 +02:00
|
|
|
import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
|
|
|
|
import net.minestom.server.utils.ArrayUtils;
|
2020-05-23 04:20:01 +02:00
|
|
|
import net.minestom.server.utils.validate.Check;
|
2020-04-05 10:15:21 +02:00
|
|
|
|
2020-06-21 14:01:03 +02:00
|
|
|
import java.util.*;
|
2020-07-10 22:50:05 +02:00
|
|
|
import java.util.function.Consumer;
|
2020-04-05 10:15:21 +02:00
|
|
|
|
|
|
|
public class CommandManager {
|
|
|
|
|
2020-07-01 21:03:53 +02:00
|
|
|
private boolean running;
|
2020-04-05 10:15:21 +02:00
|
|
|
private String commandPrefix = "/";
|
|
|
|
|
2020-06-21 14:01:03 +02:00
|
|
|
private ConsoleSender consoleSender = new ConsoleSender();
|
|
|
|
|
|
|
|
private CommandDispatcher<CommandSender> dispatcher = new CommandDispatcher<>();
|
2020-04-05 10:15:21 +02:00
|
|
|
private Map<String, CommandProcessor> commandProcessorMap = new HashMap<>();
|
|
|
|
|
2020-06-21 14:01:03 +02:00
|
|
|
public CommandManager() {
|
2020-07-01 21:03:53 +02:00
|
|
|
running = true;
|
2020-06-21 14:01:03 +02:00
|
|
|
// Setup console thread
|
2020-07-01 21:03:53 +02:00
|
|
|
Thread consoleThread = new Thread(() -> {
|
2020-06-21 14:01:03 +02:00
|
|
|
Scanner scanner = new Scanner(System.in);
|
2020-07-01 21:03:53 +02:00
|
|
|
while (running) {
|
2020-07-10 16:37:18 +02:00
|
|
|
if (scanner.hasNext()) {
|
2020-07-01 21:03:53 +02:00
|
|
|
String command = scanner.nextLine();
|
|
|
|
if (!command.startsWith(commandPrefix))
|
|
|
|
continue;
|
|
|
|
command = command.replaceFirst(commandPrefix, "");
|
|
|
|
execute(consoleSender, command);
|
|
|
|
}
|
2020-06-21 14:01:03 +02:00
|
|
|
}
|
2020-07-01 21:03:53 +02:00
|
|
|
}, "ConsoleCommand-Thread");
|
|
|
|
consoleThread.setDaemon(true);
|
|
|
|
consoleThread.start();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void stopConsoleThread() {
|
|
|
|
running = false;
|
2020-06-21 14:01:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void register(Command<CommandSender> command) {
|
2020-04-05 10:15:21 +02:00
|
|
|
this.dispatcher.register(command);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void register(CommandProcessor commandProcessor) {
|
|
|
|
this.commandProcessorMap.put(commandProcessor.getCommandName().toLowerCase(), commandProcessor);
|
|
|
|
}
|
|
|
|
|
2020-06-21 14:01:03 +02:00
|
|
|
public boolean execute(CommandSender sender, String command) {
|
|
|
|
Check.notNull(sender, "Source cannot be null");
|
2020-05-23 04:20:01 +02:00
|
|
|
Check.notNull(command, "Command string cannot be null");
|
2020-04-05 10:15:21 +02:00
|
|
|
|
2020-06-21 14:01:03 +02:00
|
|
|
if (sender instanceof Player) {
|
|
|
|
Player player = (Player) sender;
|
2020-04-29 19:23:47 +02:00
|
|
|
|
2020-06-21 14:01:03 +02:00
|
|
|
PlayerCommandEvent playerCommandEvent = new PlayerCommandEvent(player, command);
|
|
|
|
player.callEvent(PlayerCommandEvent.class, playerCommandEvent);
|
2020-04-29 19:23:47 +02:00
|
|
|
|
2020-06-21 14:01:03 +02:00
|
|
|
if (playerCommandEvent.isCancelled())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
command = playerCommandEvent.getCommand();
|
|
|
|
}
|
2020-04-29 19:23:47 +02:00
|
|
|
|
2020-04-05 10:15:21 +02:00
|
|
|
try {
|
2020-06-21 14:01:03 +02:00
|
|
|
this.dispatcher.execute(sender, command);
|
2020-04-05 10:15:21 +02:00
|
|
|
return true;
|
|
|
|
} catch (NullPointerException e) {
|
|
|
|
String[] splitted = command.split(" ");
|
|
|
|
String commandName = splitted[0];
|
|
|
|
CommandProcessor commandProcessor = commandProcessorMap.get(commandName.toLowerCase());
|
|
|
|
if (commandProcessor == null)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
String[] args = command.substring(command.indexOf(" ") + 1).split(" ");
|
|
|
|
|
2020-06-21 14:01:03 +02:00
|
|
|
return commandProcessor.process(sender, commandName, args);
|
2020-04-05 10:15:21 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getCommandPrefix() {
|
|
|
|
return commandPrefix;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setCommandPrefix(String commandPrefix) {
|
|
|
|
this.commandPrefix = commandPrefix;
|
|
|
|
}
|
|
|
|
|
2020-06-21 14:01:03 +02:00
|
|
|
public ConsoleSender getConsoleSender() {
|
|
|
|
return consoleSender;
|
|
|
|
}
|
|
|
|
|
2020-04-26 06:34:08 +02:00
|
|
|
public DeclareCommandsPacket createDeclareCommandsPacket(Player player) {
|
2020-07-10 18:12:29 +02:00
|
|
|
return buildPacket(player);
|
2020-04-05 10:15:21 +02:00
|
|
|
}
|
|
|
|
|
2020-07-10 16:37:18 +02:00
|
|
|
/*private DeclareCommandsPacket buildPacket(Player player) {
|
2020-04-26 06:34:08 +02:00
|
|
|
DeclareCommandsPacket declareCommandsPacket = new DeclareCommandsPacket();
|
|
|
|
|
2020-04-05 17:46:29 +02:00
|
|
|
List<String> commands = new ArrayList<>();
|
2020-06-21 14:01:03 +02:00
|
|
|
for (Command<CommandSender> command : dispatcher.getCommands()) {
|
2020-04-26 06:34:08 +02:00
|
|
|
CommandCondition<Player> commandCondition = command.getCondition();
|
|
|
|
if (commandCondition != null) {
|
|
|
|
// Do not show command if return false
|
|
|
|
if (!commandCondition.apply(player)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2020-04-05 17:46:29 +02:00
|
|
|
commands.add(command.getName());
|
|
|
|
for (String alias : command.getAliases()) {
|
|
|
|
commands.add(alias);
|
|
|
|
}
|
|
|
|
}
|
2020-04-26 06:34:08 +02:00
|
|
|
|
2020-04-05 17:46:29 +02:00
|
|
|
for (CommandProcessor commandProcessor : commandProcessorMap.values()) {
|
2020-04-26 06:34:08 +02:00
|
|
|
// Do not show command if return false
|
|
|
|
if (!commandProcessor.hasAccess(player))
|
|
|
|
continue;
|
|
|
|
|
2020-04-05 17:46:29 +02:00
|
|
|
commands.add(commandProcessor.getCommandName());
|
2020-04-25 23:51:45 +02:00
|
|
|
String[] aliases = commandProcessor.getAliases();
|
|
|
|
if (aliases == null || aliases.length == 0)
|
|
|
|
continue;
|
|
|
|
for (String alias : aliases) {
|
|
|
|
commands.add(alias);
|
|
|
|
}
|
2020-04-05 17:46:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
List<DeclareCommandsPacket.Node> nodes = new ArrayList<>();
|
|
|
|
ArrayList<Integer> rootChildren = new ArrayList<>();
|
|
|
|
|
|
|
|
DeclareCommandsPacket.Node argNode = new DeclareCommandsPacket.Node();
|
|
|
|
argNode.flags = 0b10;
|
|
|
|
argNode.name = "arg";
|
|
|
|
argNode.parser = "brigadier:string";
|
|
|
|
argNode.properties = packetWriter -> {
|
|
|
|
packetWriter.writeVarInt(0);
|
|
|
|
};
|
|
|
|
int argOffset = nodes.size();
|
|
|
|
nodes.add(argNode);
|
|
|
|
argNode.children = new int[]{argOffset};
|
|
|
|
|
|
|
|
for (String commandName : commands) {
|
|
|
|
|
|
|
|
DeclareCommandsPacket.Node literalNode = new DeclareCommandsPacket.Node();
|
|
|
|
literalNode.flags = 0b1;
|
|
|
|
literalNode.name = commandName;
|
|
|
|
literalNode.children = new int[]{argOffset};
|
|
|
|
|
|
|
|
rootChildren.add(nodes.size());
|
|
|
|
nodes.add(literalNode);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
DeclareCommandsPacket.Node rootNode = new DeclareCommandsPacket.Node();
|
|
|
|
rootNode.flags = 0;
|
|
|
|
rootNode.children = ArrayUtils.toArray(rootChildren);
|
|
|
|
|
|
|
|
nodes.add(rootNode);
|
|
|
|
|
2020-05-25 12:25:39 +02:00
|
|
|
declareCommandsPacket.nodes = nodes.toArray(new DeclareCommandsPacket.Node[0]);
|
2020-04-05 17:46:29 +02:00
|
|
|
declareCommandsPacket.rootIndex = nodes.size() - 1;
|
2020-04-26 06:34:08 +02:00
|
|
|
|
|
|
|
return declareCommandsPacket;
|
2020-07-10 16:37:18 +02:00
|
|
|
}*/
|
2020-04-05 17:46:29 +02:00
|
|
|
|
2020-07-10 18:12:29 +02:00
|
|
|
private DeclareCommandsPacket buildPacket(Player player) {
|
2020-07-10 16:37:18 +02:00
|
|
|
DeclareCommandsPacket declareCommandsPacket = new DeclareCommandsPacket();
|
2020-04-05 10:15:21 +02:00
|
|
|
|
|
|
|
List<DeclareCommandsPacket.Node> nodes = new ArrayList<>();
|
2020-07-10 18:12:29 +02:00
|
|
|
// Contains the children of the main node (all commands name)
|
2020-04-05 10:15:21 +02:00
|
|
|
ArrayList<Integer> rootChildren = new ArrayList<>();
|
|
|
|
|
2020-07-10 16:37:18 +02:00
|
|
|
for (Command<CommandSender> command : dispatcher.getCommands()) {
|
2020-07-10 18:12:29 +02:00
|
|
|
// Check if player should see this command
|
|
|
|
CommandCondition<Player> commandCondition = command.getCondition();
|
|
|
|
if (commandCondition != null) {
|
|
|
|
// Do not show command if return false
|
|
|
|
if (!commandCondition.apply(player)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// The main root of this command
|
2020-04-05 10:15:21 +02:00
|
|
|
ArrayList<Integer> cmdChildren = new ArrayList<>();
|
2020-07-10 18:12:29 +02:00
|
|
|
Collection<CommandSyntax> syntaxes = command.getSyntaxes();
|
|
|
|
|
|
|
|
List<String> names = new ArrayList<>();
|
|
|
|
names.add(command.getName());
|
|
|
|
for (String alias : command.getAliases()) {
|
|
|
|
names.add(alias);
|
|
|
|
}
|
|
|
|
for (String name : names) {
|
|
|
|
createCommand(nodes, cmdChildren, name, syntaxes, rootChildren);
|
|
|
|
}
|
2020-04-05 10:15:21 +02:00
|
|
|
|
2020-07-10 18:12:29 +02:00
|
|
|
}
|
2020-07-10 22:50:05 +02:00
|
|
|
|
2020-07-10 18:12:29 +02:00
|
|
|
final List<String> simpleCommands = new ArrayList<>();
|
|
|
|
for (CommandProcessor commandProcessor : commandProcessorMap.values()) {
|
|
|
|
// Do not show command if return false
|
|
|
|
if (!commandProcessor.hasAccess(player))
|
|
|
|
continue;
|
2020-04-05 10:15:21 +02:00
|
|
|
|
2020-07-10 18:12:29 +02:00
|
|
|
simpleCommands.add(commandProcessor.getCommandName());
|
|
|
|
String[] aliases = commandProcessor.getAliases();
|
|
|
|
if (aliases == null || aliases.length == 0)
|
|
|
|
continue;
|
|
|
|
for (String alias : aliases) {
|
|
|
|
simpleCommands.add(alias);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (String simpleCommand : simpleCommands) {
|
|
|
|
// TODO server suggestion
|
2020-04-05 10:15:21 +02:00
|
|
|
DeclareCommandsPacket.Node literalNode = new DeclareCommandsPacket.Node();
|
2020-07-10 18:12:29 +02:00
|
|
|
literalNode.flags = getFlag(NodeType.LITERAL, true, false, false);
|
|
|
|
literalNode.name = simpleCommand;
|
|
|
|
literalNode.children = new int[0];
|
|
|
|
//literalNode.suggestionsType = "minecraft:ask_server";
|
2020-04-05 10:15:21 +02:00
|
|
|
|
|
|
|
rootChildren.add(nodes.size());
|
|
|
|
nodes.add(literalNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
DeclareCommandsPacket.Node rootNode = new DeclareCommandsPacket.Node();
|
|
|
|
rootNode.flags = 0;
|
|
|
|
rootNode.children = ArrayUtils.toArray(rootChildren);
|
|
|
|
|
|
|
|
nodes.add(rootNode);
|
|
|
|
|
2020-05-25 12:25:39 +02:00
|
|
|
declareCommandsPacket.nodes = nodes.toArray(new DeclareCommandsPacket.Node[0]);
|
2020-04-05 10:15:21 +02:00
|
|
|
declareCommandsPacket.rootIndex = nodes.size() - 1;
|
2020-07-10 16:37:18 +02:00
|
|
|
|
|
|
|
return declareCommandsPacket;
|
2020-04-05 10:15:21 +02:00
|
|
|
}
|
|
|
|
|
2020-07-10 18:12:29 +02:00
|
|
|
private void createCommand(List<DeclareCommandsPacket.Node> nodes, ArrayList<Integer> cmdChildren, String name, Collection<CommandSyntax> syntaxes, ArrayList<Integer> rootChildren) {
|
|
|
|
|
|
|
|
DeclareCommandsPacket.Node literalNode = createMainNode(name, syntaxes.isEmpty());
|
|
|
|
|
|
|
|
rootChildren.add(nodes.size());
|
|
|
|
nodes.add(literalNode);
|
|
|
|
|
|
|
|
for (CommandSyntax syntax : syntaxes) {
|
|
|
|
// Represent the last nodes computed in the last iteration
|
|
|
|
List<DeclareCommandsPacket.Node> lastNodes = null;
|
|
|
|
|
|
|
|
// Represent the children of the last node
|
|
|
|
ArrayList<Integer> argChildren = null;
|
|
|
|
|
|
|
|
final Argument[] arguments = syntax.getArguments();
|
|
|
|
for (int i = 0; i < arguments.length; i++) {
|
|
|
|
final Argument argument = arguments[i];
|
|
|
|
final boolean isFirst = i == 0;
|
|
|
|
final boolean isLast = i == arguments.length - 1;
|
|
|
|
|
|
|
|
|
|
|
|
List<DeclareCommandsPacket.Node> argumentNodes = toNodes(argument, isLast);
|
|
|
|
for (DeclareCommandsPacket.Node node : argumentNodes) {
|
|
|
|
final int childId = nodes.size();
|
|
|
|
|
|
|
|
if (isFirst) {
|
|
|
|
// Add to main command child
|
|
|
|
cmdChildren.add(childId);
|
|
|
|
} else {
|
|
|
|
// Add to previous argument children
|
|
|
|
argChildren.add(childId);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lastNodes != null) {
|
|
|
|
int[] children = ArrayUtils.toArray(argChildren);
|
|
|
|
lastNodes.forEach(n -> n.children = children);
|
|
|
|
}
|
|
|
|
|
|
|
|
nodes.add(node);
|
|
|
|
}
|
|
|
|
|
|
|
|
//System.out.println("debug: " + argument.getId() + " : " + isFirst + " : " + isLast);
|
|
|
|
//System.out.println("debug2: " + i);
|
|
|
|
//System.out.println("size: " + (argChildren != null ? argChildren.size() : "NULL"));
|
|
|
|
|
|
|
|
if (isLast) {
|
|
|
|
// Last argument doesn't have children
|
|
|
|
int[] children = new int[0];
|
|
|
|
argumentNodes.forEach(node -> node.children = children);
|
|
|
|
} else {
|
|
|
|
// Create children list which will be filled during next iteration
|
|
|
|
argChildren = new ArrayList<>();
|
|
|
|
lastNodes = argumentNodes;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
int[] children = ArrayUtils.toArray(cmdChildren);
|
|
|
|
//System.out.println("test " + children.length + " : " + children[0]);
|
|
|
|
literalNode.children = children;
|
|
|
|
if (children.length > 0) {
|
|
|
|
literalNode.redirectedNode = children[0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private DeclareCommandsPacket.Node createMainNode(String name, boolean executable) {
|
|
|
|
DeclareCommandsPacket.Node literalNode = new DeclareCommandsPacket.Node();
|
|
|
|
literalNode.flags = getFlag(NodeType.LITERAL, executable, false, false);
|
|
|
|
literalNode.name = name;
|
|
|
|
|
|
|
|
return literalNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
private List<DeclareCommandsPacket.Node> toNodes(Argument argument, boolean executable) {
|
|
|
|
List<DeclareCommandsPacket.Node> nodes = new ArrayList<>();
|
2020-04-05 10:15:21 +02:00
|
|
|
|
2020-07-10 22:50:05 +02:00
|
|
|
/*DeclareCommandsPacket.Node testNode = simpleArgumentNode(nodes, argument, executable);
|
|
|
|
testNode.parser = "minecraft:entity_summon";
|
|
|
|
|
|
|
|
if (true) {
|
|
|
|
return nodes;
|
|
|
|
}*/
|
|
|
|
|
2020-04-05 10:15:21 +02:00
|
|
|
if (argument instanceof ArgumentBoolean) {
|
2020-07-10 18:12:29 +02:00
|
|
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
|
|
|
|
2020-04-05 10:15:21 +02:00
|
|
|
argumentNode.parser = "brigadier:bool";
|
|
|
|
argumentNode.properties = packetWriter -> packetWriter.writeByte((byte) 0);
|
|
|
|
} else if (argument instanceof ArgumentDouble) {
|
2020-07-10 18:12:29 +02:00
|
|
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
|
|
|
|
2020-04-05 10:15:21 +02:00
|
|
|
ArgumentDouble argumentDouble = (ArgumentDouble) argument;
|
|
|
|
argumentNode.parser = "brigadier:double";
|
|
|
|
argumentNode.properties = packetWriter -> {
|
2020-07-10 22:50:05 +02:00
|
|
|
packetWriter.writeByte(getNumberProperties(argumentDouble));
|
|
|
|
if (argumentDouble.hasMin())
|
|
|
|
packetWriter.writeDouble(argumentDouble.getMin());
|
|
|
|
if (argumentDouble.hasMax())
|
|
|
|
packetWriter.writeDouble(argumentDouble.getMax());
|
2020-04-05 10:15:21 +02:00
|
|
|
};
|
|
|
|
} else if (argument instanceof ArgumentFloat) {
|
2020-07-10 18:12:29 +02:00
|
|
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
|
|
|
|
2020-04-05 10:15:21 +02:00
|
|
|
ArgumentFloat argumentFloat = (ArgumentFloat) argument;
|
|
|
|
argumentNode.parser = "brigadier:float";
|
|
|
|
argumentNode.properties = packetWriter -> {
|
2020-07-10 22:50:05 +02:00
|
|
|
packetWriter.writeByte(getNumberProperties(argumentFloat));
|
|
|
|
if (argumentFloat.hasMin())
|
|
|
|
packetWriter.writeFloat(argumentFloat.getMin());
|
|
|
|
if (argumentFloat.hasMax())
|
|
|
|
packetWriter.writeFloat(argumentFloat.getMax());
|
2020-04-05 10:15:21 +02:00
|
|
|
};
|
|
|
|
} else if (argument instanceof ArgumentInteger) {
|
2020-07-10 18:12:29 +02:00
|
|
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
|
|
|
|
2020-04-05 10:15:21 +02:00
|
|
|
ArgumentInteger argumentInteger = (ArgumentInteger) argument;
|
|
|
|
argumentNode.parser = "brigadier:integer";
|
|
|
|
argumentNode.properties = packetWriter -> {
|
2020-07-10 22:50:05 +02:00
|
|
|
packetWriter.writeByte(getNumberProperties(argumentInteger));
|
|
|
|
if (argumentInteger.hasMin())
|
|
|
|
packetWriter.writeInt(argumentInteger.getMin());
|
|
|
|
if (argumentInteger.hasMax())
|
|
|
|
packetWriter.writeInt(argumentInteger.getMax());
|
2020-04-05 10:15:21 +02:00
|
|
|
};
|
|
|
|
} else if (argument instanceof ArgumentWord) {
|
2020-07-10 18:12:29 +02:00
|
|
|
|
|
|
|
ArgumentWord argumentWord = (ArgumentWord) argument;
|
|
|
|
|
2020-07-10 22:50:05 +02:00
|
|
|
// Add the single word properties + parser
|
|
|
|
final Consumer<DeclareCommandsPacket.Node> wordConsumer = node -> {
|
|
|
|
node.parser = "brigadier:string";
|
|
|
|
node.properties = packetWriter -> {
|
|
|
|
packetWriter.writeVarInt(0); // Single word
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2020-07-10 18:12:29 +02:00
|
|
|
final boolean hasRestriction = argumentWord.hasRestrictions();
|
|
|
|
if (hasRestriction) {
|
2020-07-10 22:50:05 +02:00
|
|
|
// Create a node for each restrictions as literal
|
2020-07-10 18:12:29 +02:00
|
|
|
for (String restrictionWord : argumentWord.getRestrictions()) {
|
|
|
|
DeclareCommandsPacket.Node argumentNode = new DeclareCommandsPacket.Node();
|
|
|
|
nodes.add(argumentNode);
|
|
|
|
|
|
|
|
argumentNode.flags = getFlag(NodeType.LITERAL, executable, false, false);
|
|
|
|
argumentNode.name = restrictionWord;
|
2020-07-10 22:50:05 +02:00
|
|
|
wordConsumer.accept(argumentNode);
|
2020-07-10 18:12:29 +02:00
|
|
|
}
|
|
|
|
} else {
|
2020-07-10 22:50:05 +02:00
|
|
|
// Can be any word, add only one argument node
|
2020-07-10 18:12:29 +02:00
|
|
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
2020-07-10 22:50:05 +02:00
|
|
|
wordConsumer.accept(argumentNode);
|
2020-07-10 18:12:29 +02:00
|
|
|
}
|
2020-04-05 10:15:21 +02:00
|
|
|
} else if (argument instanceof ArgumentString) {
|
2020-07-10 18:12:29 +02:00
|
|
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
|
|
|
|
2020-04-05 10:15:21 +02:00
|
|
|
argumentNode.parser = "brigadier:string";
|
|
|
|
argumentNode.properties = packetWriter -> {
|
|
|
|
packetWriter.writeVarInt(1); // Quotable phrase
|
|
|
|
};
|
|
|
|
} else if (argument instanceof ArgumentStringArray) {
|
2020-07-10 18:12:29 +02:00
|
|
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
|
|
|
|
2020-04-05 10:15:21 +02:00
|
|
|
argumentNode.parser = "brigadier:string";
|
|
|
|
argumentNode.properties = packetWriter -> {
|
|
|
|
packetWriter.writeVarInt(2); // Greedy phrase
|
|
|
|
};
|
2020-07-10 22:50:05 +02:00
|
|
|
} else if (argument instanceof ArgumentColor) {
|
|
|
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
|
|
|
argumentNode.parser = "minecraft:color";
|
|
|
|
} else if (argument instanceof ArgumentTime) {
|
|
|
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
|
|
|
argumentNode.parser = "minecraft:time";
|
|
|
|
} else if (argument instanceof ArgumentEnchantment) {
|
|
|
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
|
|
|
argumentNode.parser = "minecraft:item_enchantment";
|
|
|
|
} else if (argument instanceof ArgumentParticle) {
|
|
|
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
|
|
|
argumentNode.parser = "minecraft:particle";
|
|
|
|
} else if (argument instanceof ArgumentPotion) {
|
|
|
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
|
|
|
argumentNode.parser = "minecraft:mob_effect";
|
|
|
|
} else if (argument instanceof ArgumentEntityType) {
|
|
|
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
|
|
|
argumentNode.parser = "minecraft:entity_summon";
|
2020-04-05 10:15:21 +02:00
|
|
|
}
|
|
|
|
|
2020-07-10 18:12:29 +02:00
|
|
|
return nodes;
|
|
|
|
}
|
|
|
|
|
2020-07-10 22:50:05 +02:00
|
|
|
private byte getNumberProperties(ArgumentNumber argumentNumber) {
|
|
|
|
byte result = 0;
|
|
|
|
if (argumentNumber.hasMin())
|
|
|
|
result += 1;
|
|
|
|
if (argumentNumber.hasMax())
|
|
|
|
result += 2;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2020-07-10 18:12:29 +02:00
|
|
|
private DeclareCommandsPacket.Node simpleArgumentNode(List<DeclareCommandsPacket.Node> nodes,
|
|
|
|
Argument argument, boolean executable) {
|
|
|
|
DeclareCommandsPacket.Node argumentNode = new DeclareCommandsPacket.Node();
|
|
|
|
nodes.add(argumentNode);
|
|
|
|
|
|
|
|
argumentNode.flags = getFlag(NodeType.ARGUMENT, executable, false, false);
|
|
|
|
argumentNode.name = argument.getId();
|
|
|
|
|
2020-04-05 10:15:21 +02:00
|
|
|
return argumentNode;
|
2020-07-10 16:37:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private byte getFlag(NodeType type, boolean executable, boolean redirect, boolean suggestionType) {
|
|
|
|
byte result = (byte) type.mask;
|
|
|
|
|
|
|
|
if (executable) {
|
|
|
|
result |= 0x4;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (redirect) {
|
|
|
|
result |= 0x8;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (suggestionType) {
|
2020-07-10 18:12:29 +02:00
|
|
|
result |= 0x10;
|
2020-07-10 16:37:18 +02:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
private enum NodeType {
|
|
|
|
ROOT(0), LITERAL(0b1), ARGUMENT(0b10), NONE(0x11);
|
|
|
|
|
|
|
|
private int mask;
|
|
|
|
|
|
|
|
NodeType(int mask) {
|
|
|
|
this.mask = mask;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2020-04-05 10:15:21 +02:00
|
|
|
}
|