2020-04-24 03:25:58 +02:00
|
|
|
package net.minestom.server.command;
|
2020-04-05 10:15:21 +02:00
|
|
|
|
|
|
|
import fr.themode.command.Command;
|
|
|
|
import fr.themode.command.CommandDispatcher;
|
|
|
|
import fr.themode.command.CommandSyntax;
|
|
|
|
import fr.themode.command.arguments.*;
|
|
|
|
import fr.themode.command.arguments.number.ArgumentDouble;
|
|
|
|
import fr.themode.command.arguments.number.ArgumentFloat;
|
|
|
|
import fr.themode.command.arguments.number.ArgumentInteger;
|
2020-04-24 03:25:58 +02:00
|
|
|
import net.minestom.server.entity.Player;
|
|
|
|
import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
|
|
|
|
import net.minestom.server.utils.ArrayUtils;
|
2020-04-05 10:15:21 +02:00
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
public class CommandManager {
|
|
|
|
|
|
|
|
private String commandPrefix = "/";
|
|
|
|
|
|
|
|
private CommandDispatcher<Player> dispatcher = new CommandDispatcher<>();
|
|
|
|
private Map<String, CommandProcessor> commandProcessorMap = new HashMap<>();
|
|
|
|
|
|
|
|
private DeclareCommandsPacket declareCommandsPacket = new DeclareCommandsPacket();
|
|
|
|
|
|
|
|
public void register(Command<Player> command) {
|
|
|
|
this.dispatcher.register(command);
|
2020-04-05 17:46:29 +02:00
|
|
|
refreshPacket();
|
2020-04-05 10:15:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void register(CommandProcessor commandProcessor) {
|
|
|
|
this.commandProcessorMap.put(commandProcessor.getCommandName().toLowerCase(), commandProcessor);
|
2020-04-05 17:46:29 +02:00
|
|
|
refreshPacket();
|
2020-04-05 10:15:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean execute(Player source, String command) {
|
|
|
|
if (source == null)
|
|
|
|
throw new NullPointerException("Source cannot be null");
|
|
|
|
if (command == null)
|
|
|
|
throw new NullPointerException("Command string cannot be null");
|
|
|
|
|
|
|
|
try {
|
|
|
|
this.dispatcher.execute(source, command);
|
|
|
|
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(" ");
|
|
|
|
|
|
|
|
return commandProcessor.process(source, commandName, args);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getCommandPrefix() {
|
|
|
|
return commandPrefix;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setCommandPrefix(String commandPrefix) {
|
|
|
|
this.commandPrefix = commandPrefix;
|
|
|
|
}
|
|
|
|
|
|
|
|
public DeclareCommandsPacket getDeclareCommandsPacket() {
|
|
|
|
return declareCommandsPacket;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void refreshPacket() {
|
2020-04-05 17:46:29 +02:00
|
|
|
List<String> commands = new ArrayList<>();
|
|
|
|
for (Command<Player> command : dispatcher.getCommands()) {
|
|
|
|
commands.add(command.getName());
|
|
|
|
for (String alias : command.getAliases()) {
|
|
|
|
commands.add(alias);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (CommandProcessor commandProcessor : commandProcessorMap.values()) {
|
|
|
|
commands.add(commandProcessor.getCommandName());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
declareCommandsPacket.nodes = nodes.toArray(new DeclareCommandsPacket.Node[nodes.size()]);
|
|
|
|
declareCommandsPacket.rootIndex = nodes.size() - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void refreshPacket2() {
|
2020-04-05 10:15:21 +02:00
|
|
|
|
|
|
|
List<DeclareCommandsPacket.Node> nodes = new ArrayList<>();
|
|
|
|
ArrayList<Integer> rootChildren = new ArrayList<>();
|
|
|
|
|
|
|
|
for (Command<Player> command : dispatcher.getCommands()) {
|
|
|
|
ArrayList<Integer> cmdChildren = new ArrayList<>();
|
|
|
|
|
|
|
|
String name = command.getName();
|
|
|
|
|
|
|
|
DeclareCommandsPacket.Node literalNode = new DeclareCommandsPacket.Node();
|
|
|
|
literalNode.flags = 0b1;
|
|
|
|
literalNode.name = name;
|
|
|
|
|
|
|
|
rootChildren.add(nodes.size());
|
|
|
|
nodes.add(literalNode);
|
|
|
|
|
|
|
|
for (CommandSyntax syntax : command.getSyntaxes()) {
|
|
|
|
ArrayList<Integer> argChildren = cmdChildren;
|
|
|
|
|
|
|
|
for (Argument argument : syntax.getArguments()) {
|
|
|
|
|
|
|
|
DeclareCommandsPacket.Node argumentNode = toNode(argument);
|
|
|
|
|
|
|
|
argChildren.add(nodes.size());
|
|
|
|
nodes.add(argumentNode);
|
|
|
|
System.out.println("size: " + argChildren.size());
|
|
|
|
argumentNode.children = ArrayUtils.toArray(argChildren);
|
|
|
|
argChildren = new ArrayList<>();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
System.out.println("test " + cmdChildren.size() + " : " + cmdChildren.get(0));
|
|
|
|
literalNode.children = ArrayUtils.toArray(cmdChildren);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DeclareCommandsPacket.Node rootNode = new DeclareCommandsPacket.Node();
|
|
|
|
rootNode.flags = 0;
|
|
|
|
rootNode.children = ArrayUtils.toArray(rootChildren);
|
|
|
|
|
|
|
|
nodes.add(rootNode);
|
|
|
|
|
|
|
|
declareCommandsPacket.nodes = nodes.toArray(new DeclareCommandsPacket.Node[nodes.size()]);
|
|
|
|
declareCommandsPacket.rootIndex = nodes.size() - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
private DeclareCommandsPacket.Node toNode(Argument argument) {
|
|
|
|
DeclareCommandsPacket.Node argumentNode = new DeclareCommandsPacket.Node();
|
|
|
|
argumentNode.flags = 0b1010;
|
|
|
|
argumentNode.name = argument.getId();
|
|
|
|
|
|
|
|
if (argument instanceof ArgumentBoolean) {
|
|
|
|
argumentNode.parser = "brigadier:bool";
|
|
|
|
argumentNode.properties = packetWriter -> packetWriter.writeByte((byte) 0);
|
|
|
|
} else if (argument instanceof ArgumentDouble) {
|
|
|
|
ArgumentDouble argumentDouble = (ArgumentDouble) argument;
|
|
|
|
argumentNode.parser = "brigadier:double";
|
|
|
|
argumentNode.properties = packetWriter -> {
|
|
|
|
packetWriter.writeByte((byte) 0b11);
|
|
|
|
packetWriter.writeDouble(argumentDouble.min);
|
|
|
|
packetWriter.writeDouble(argumentDouble.max);
|
|
|
|
};
|
|
|
|
} else if (argument instanceof ArgumentFloat) {
|
|
|
|
ArgumentFloat argumentFloat = (ArgumentFloat) argument;
|
|
|
|
argumentNode.parser = "brigadier:float";
|
|
|
|
argumentNode.properties = packetWriter -> {
|
|
|
|
packetWriter.writeByte((byte) 0b11);
|
|
|
|
packetWriter.writeFloat(argumentFloat.min);
|
|
|
|
packetWriter.writeFloat(argumentFloat.max);
|
|
|
|
};
|
|
|
|
} else if (argument instanceof ArgumentInteger) {
|
|
|
|
ArgumentInteger argumentInteger = (ArgumentInteger) argument;
|
|
|
|
argumentNode.parser = "brigadier:integer";
|
|
|
|
argumentNode.properties = packetWriter -> {
|
|
|
|
packetWriter.writeByte((byte) 0b11);
|
|
|
|
packetWriter.writeInt(argumentInteger.min);
|
|
|
|
packetWriter.writeInt(argumentInteger.max);
|
|
|
|
};
|
|
|
|
} else if (argument instanceof ArgumentWord) {
|
|
|
|
argumentNode.parser = "brigadier:string";
|
|
|
|
argumentNode.properties = packetWriter -> {
|
|
|
|
packetWriter.writeVarInt(0); // Single word
|
|
|
|
};
|
|
|
|
} else if (argument instanceof ArgumentString) {
|
|
|
|
argumentNode.parser = "brigadier:string";
|
|
|
|
argumentNode.properties = packetWriter -> {
|
|
|
|
packetWriter.writeVarInt(1); // Quotable phrase
|
|
|
|
};
|
|
|
|
} else if (argument instanceof ArgumentStringArray) {
|
|
|
|
argumentNode.parser = "brigadier:string";
|
|
|
|
argumentNode.properties = packetWriter -> {
|
|
|
|
packetWriter.writeVarInt(2); // Greedy phrase
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return argumentNode;
|
|
|
|
}
|
|
|
|
}
|