mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-06 00:17:58 +01:00
Added dynamic arguments for Command (allow for server tab completion)
This commit is contained in:
parent
baccc36ed7
commit
aecf0f427a
@ -1,6 +1,5 @@
|
|||||||
package fr.themode.demo.commands;
|
package fr.themode.demo.commands;
|
||||||
|
|
||||||
import net.minestom.server.chat.ColoredText;
|
|
||||||
import net.minestom.server.command.CommandSender;
|
import net.minestom.server.command.CommandSender;
|
||||||
import net.minestom.server.command.builder.Arguments;
|
import net.minestom.server.command.builder.Arguments;
|
||||||
import net.minestom.server.command.builder.Command;
|
import net.minestom.server.command.builder.Command;
|
||||||
@ -8,49 +7,32 @@ import net.minestom.server.command.builder.arguments.Argument;
|
|||||||
import net.minestom.server.command.builder.arguments.ArgumentType;
|
import net.minestom.server.command.builder.arguments.ArgumentType;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class TestCommand extends Command {
|
public class TestCommand extends Command {
|
||||||
|
|
||||||
public TestCommand() {
|
public TestCommand() {
|
||||||
super("msg");
|
super("testcmd");
|
||||||
setDefaultExecutor(this::usage);
|
setDefaultExecutor(this::usage);
|
||||||
|
|
||||||
Argument player = ArgumentType.Word("player");
|
Argument dynamicWord = ArgumentType.DynamicWord("test");
|
||||||
Argument message = ArgumentType.StringArray("array");
|
|
||||||
|
|
||||||
addSyntax(this::execute, player, message);
|
addSyntax(this::execute, dynamicWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void usage(CommandSender sender, Arguments arguments) {
|
private void usage(CommandSender sender, Arguments arguments) {
|
||||||
sender.sendMessage("Usage: /whisper <player> <message>");
|
sender.sendMessage("Incorrect usage");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void execute(CommandSender sender, Arguments arguments) {
|
private void execute(CommandSender sender, Arguments arguments) {
|
||||||
Player player = (Player) sender;
|
final String word = arguments.getWord("test");
|
||||||
String targetName = arguments.getWord("player");
|
sender.sendMessage("word: " + word);
|
||||||
String[] Message = arguments.getStringArray("array");
|
|
||||||
Optional<Player> target = player.getInstance().getPlayers().stream().filter(p -> p.getUsername().equalsIgnoreCase(targetName)).findFirst();
|
|
||||||
if (target.isPresent()) {
|
|
||||||
if (target.get() == player) {
|
|
||||||
player.sendMessage("You cannot message yourself");
|
|
||||||
} else {
|
|
||||||
String message = "";
|
|
||||||
for (int i = 0; i < Message.length; i++) {
|
|
||||||
if (i != 0) {
|
|
||||||
message = message + " ";
|
|
||||||
}
|
|
||||||
message = message + Message[i];
|
|
||||||
}
|
|
||||||
player.sendMessage("You -> " + targetName + ": " + message);
|
|
||||||
target.get().sendMessage(player.getUsername() + " -> You: " + message);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
player.sendMessage(ColoredText.ofFormat("{@argument.player.unknown}"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAllowed(Player player) {
|
private boolean isAllowed(Player player) {
|
||||||
return true; // TODO: permissions
|
return true; // TODO: permissions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] onDynamicWrite(String text) {
|
||||||
|
return new String[]{"test1", "test2"};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,16 @@ public class CommandManager {
|
|||||||
this.dispatcher.register(command);
|
this.dispatcher.register(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the command register by {@link #register(Command)}
|
||||||
|
*
|
||||||
|
* @param commandName the command name
|
||||||
|
* @return the command associated with the name, null if not any
|
||||||
|
*/
|
||||||
|
public Command getCommand(String commandName) {
|
||||||
|
return dispatcher.findCommand(commandName);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a simple command without auto-completion
|
* Register a simple command without auto-completion
|
||||||
*
|
*
|
||||||
@ -353,12 +363,12 @@ public class CommandManager {
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
if (argument instanceof ArgumentBoolean) {
|
if (argument instanceof ArgumentBoolean) {
|
||||||
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, false);
|
||||||
|
|
||||||
argumentNode.parser = "brigadier:bool";
|
argumentNode.parser = "brigadier:bool";
|
||||||
argumentNode.properties = packetWriter -> packetWriter.writeByte((byte) 0);
|
argumentNode.properties = packetWriter -> packetWriter.writeByte((byte) 0);
|
||||||
} else if (argument instanceof ArgumentDouble) {
|
} else if (argument instanceof ArgumentDouble) {
|
||||||
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, false);
|
||||||
|
|
||||||
ArgumentDouble argumentDouble = (ArgumentDouble) argument;
|
ArgumentDouble argumentDouble = (ArgumentDouble) argument;
|
||||||
argumentNode.parser = "brigadier:double";
|
argumentNode.parser = "brigadier:double";
|
||||||
@ -370,7 +380,7 @@ public class CommandManager {
|
|||||||
packetWriter.writeDouble(argumentDouble.getMax());
|
packetWriter.writeDouble(argumentDouble.getMax());
|
||||||
};
|
};
|
||||||
} else if (argument instanceof ArgumentFloat) {
|
} else if (argument instanceof ArgumentFloat) {
|
||||||
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, false);
|
||||||
|
|
||||||
ArgumentFloat argumentFloat = (ArgumentFloat) argument;
|
ArgumentFloat argumentFloat = (ArgumentFloat) argument;
|
||||||
argumentNode.parser = "brigadier:float";
|
argumentNode.parser = "brigadier:float";
|
||||||
@ -382,7 +392,7 @@ public class CommandManager {
|
|||||||
packetWriter.writeFloat(argumentFloat.getMax());
|
packetWriter.writeFloat(argumentFloat.getMax());
|
||||||
};
|
};
|
||||||
} else if (argument instanceof ArgumentInteger) {
|
} else if (argument instanceof ArgumentInteger) {
|
||||||
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, false);
|
||||||
|
|
||||||
ArgumentInteger argumentInteger = (ArgumentInteger) argument;
|
ArgumentInteger argumentInteger = (ArgumentInteger) argument;
|
||||||
argumentNode.parser = "brigadier:integer";
|
argumentNode.parser = "brigadier:integer";
|
||||||
@ -418,50 +428,67 @@ public class CommandManager {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Can be any word, add only one argument node
|
// Can be any word, add only one argument node
|
||||||
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, false);
|
||||||
wordConsumer.accept(argumentNode);
|
wordConsumer.accept(argumentNode);
|
||||||
}
|
}
|
||||||
|
} else if (argument instanceof ArgumentDynamicWord) {
|
||||||
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, true);
|
||||||
|
|
||||||
|
argumentNode.parser = "brigadier:string";
|
||||||
|
argumentNode.properties = packetWriter -> {
|
||||||
|
packetWriter.writeVarInt(0); // Single word
|
||||||
|
};
|
||||||
|
argumentNode.suggestionsType = "minecraft:ask_server";
|
||||||
|
|
||||||
} else if (argument instanceof ArgumentString) {
|
} else if (argument instanceof ArgumentString) {
|
||||||
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, false);
|
||||||
|
|
||||||
argumentNode.parser = "brigadier:string";
|
argumentNode.parser = "brigadier:string";
|
||||||
argumentNode.properties = packetWriter -> {
|
argumentNode.properties = packetWriter -> {
|
||||||
packetWriter.writeVarInt(1); // Quotable phrase
|
packetWriter.writeVarInt(1); // Quotable phrase
|
||||||
};
|
};
|
||||||
} else if (argument instanceof ArgumentStringArray) {
|
} else if (argument instanceof ArgumentStringArray) {
|
||||||
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, false);
|
||||||
|
|
||||||
argumentNode.parser = "brigadier:string";
|
argumentNode.parser = "brigadier:string";
|
||||||
argumentNode.properties = packetWriter -> {
|
argumentNode.properties = packetWriter -> {
|
||||||
packetWriter.writeVarInt(2); // Greedy phrase
|
packetWriter.writeVarInt(2); // Greedy phrase
|
||||||
};
|
};
|
||||||
|
} else if (argument instanceof ArgumentDynamicStringArray) {
|
||||||
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, true);
|
||||||
|
|
||||||
|
argumentNode.parser = "brigadier:string";
|
||||||
|
argumentNode.properties = packetWriter -> {
|
||||||
|
packetWriter.writeVarInt(2); // Greedy phrase
|
||||||
|
};
|
||||||
|
argumentNode.suggestionsType = "minecraft:ask_server";
|
||||||
} else if (argument instanceof ArgumentColor) {
|
} else if (argument instanceof ArgumentColor) {
|
||||||
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, false);
|
||||||
argumentNode.parser = "minecraft:color";
|
argumentNode.parser = "minecraft:color";
|
||||||
} else if (argument instanceof ArgumentTime) {
|
} else if (argument instanceof ArgumentTime) {
|
||||||
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, false);
|
||||||
argumentNode.parser = "minecraft:time";
|
argumentNode.parser = "minecraft:time";
|
||||||
} else if (argument instanceof ArgumentEnchantment) {
|
} else if (argument instanceof ArgumentEnchantment) {
|
||||||
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, false);
|
||||||
argumentNode.parser = "minecraft:item_enchantment";
|
argumentNode.parser = "minecraft:item_enchantment";
|
||||||
} else if (argument instanceof ArgumentParticle) {
|
} else if (argument instanceof ArgumentParticle) {
|
||||||
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, false);
|
||||||
argumentNode.parser = "minecraft:particle";
|
argumentNode.parser = "minecraft:particle";
|
||||||
} else if (argument instanceof ArgumentPotion) {
|
} else if (argument instanceof ArgumentPotion) {
|
||||||
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, false);
|
||||||
argumentNode.parser = "minecraft:mob_effect";
|
argumentNode.parser = "minecraft:mob_effect";
|
||||||
} else if (argument instanceof ArgumentEntityType) {
|
} else if (argument instanceof ArgumentEntityType) {
|
||||||
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, false);
|
||||||
argumentNode.parser = "minecraft:entity_summon";
|
argumentNode.parser = "minecraft:entity_summon";
|
||||||
} else if (argument instanceof ArgumentIntRange) {
|
} else if (argument instanceof ArgumentIntRange) {
|
||||||
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, false);
|
||||||
argumentNode.parser = "minecraft:int_range";
|
argumentNode.parser = "minecraft:int_range";
|
||||||
} else if (argument instanceof ArgumentFloatRange) {
|
} else if (argument instanceof ArgumentFloatRange) {
|
||||||
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, false);
|
||||||
argumentNode.parser = "minecraft:float_range";
|
argumentNode.parser = "minecraft:float_range";
|
||||||
} else if (argument instanceof ArgumentEntities) {
|
} else if (argument instanceof ArgumentEntities) {
|
||||||
ArgumentEntities argumentEntities = (ArgumentEntities) argument;
|
ArgumentEntities argumentEntities = (ArgumentEntities) argument;
|
||||||
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable);
|
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(nodes, argument, executable, false);
|
||||||
argumentNode.parser = "minecraft:entity";
|
argumentNode.parser = "minecraft:entity";
|
||||||
argumentNode.properties = packetWriter -> {
|
argumentNode.properties = packetWriter -> {
|
||||||
byte mask = 0;
|
byte mask = 0;
|
||||||
@ -496,11 +523,11 @@ public class CommandManager {
|
|||||||
* @return the created {@link DeclareCommandsPacket.Node}
|
* @return the created {@link DeclareCommandsPacket.Node}
|
||||||
*/
|
*/
|
||||||
private DeclareCommandsPacket.Node simpleArgumentNode(List<DeclareCommandsPacket.Node> nodes,
|
private DeclareCommandsPacket.Node simpleArgumentNode(List<DeclareCommandsPacket.Node> nodes,
|
||||||
Argument<?> argument, boolean executable) {
|
Argument<?> argument, boolean executable, boolean suggestion) {
|
||||||
DeclareCommandsPacket.Node argumentNode = new DeclareCommandsPacket.Node();
|
DeclareCommandsPacket.Node argumentNode = new DeclareCommandsPacket.Node();
|
||||||
nodes.add(argumentNode);
|
nodes.add(argumentNode);
|
||||||
|
|
||||||
argumentNode.flags = getFlag(NodeType.ARGUMENT, executable, false, false);
|
argumentNode.flags = getFlag(NodeType.ARGUMENT, executable, false, suggestion);
|
||||||
argumentNode.name = argument.getId();
|
argumentNode.name = argument.getId();
|
||||||
|
|
||||||
return argumentNode;
|
return argumentNode;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package net.minestom.server.command.builder;
|
package net.minestom.server.command.builder;
|
||||||
|
|
||||||
import net.minestom.server.command.builder.arguments.Argument;
|
import net.minestom.server.command.builder.arguments.Argument;
|
||||||
|
import net.minestom.server.command.builder.arguments.ArgumentDynamicStringArray;
|
||||||
|
import net.minestom.server.command.builder.arguments.ArgumentDynamicWord;
|
||||||
import net.minestom.server.command.builder.condition.CommandCondition;
|
import net.minestom.server.command.builder.condition.CommandCondition;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -123,4 +125,16 @@ public class Command {
|
|||||||
public Collection<CommandSyntax> getSyntaxes() {
|
public Collection<CommandSyntax> getSyntaxes() {
|
||||||
return syntaxes;
|
return syntaxes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow for tab auto completion, this is called everytime the player press a key in the chat
|
||||||
|
* when in a dynamic argument ({@link ArgumentDynamicWord} & {@link ArgumentDynamicStringArray})
|
||||||
|
*
|
||||||
|
* @param text the whole player text
|
||||||
|
* @return the array containing all the suggestion for the current arg (split " ")
|
||||||
|
*/
|
||||||
|
public String[] onDynamicWrite(String text) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,9 @@ public class CommandDispatcher {
|
|||||||
private Set<Command> commands = new HashSet<>();
|
private Set<Command> commands = new HashSet<>();
|
||||||
|
|
||||||
public void register(Command command) {
|
public void register(Command command) {
|
||||||
this.commandMap.put(command.getName(), command);
|
this.commandMap.put(command.getName().toLowerCase(), command);
|
||||||
for (String alias : command.getAliases()) {
|
for (String alias : command.getAliases()) {
|
||||||
this.commandMap.put(alias, command);
|
this.commandMap.put(alias.toLowerCase(), command);
|
||||||
}
|
}
|
||||||
this.commands.add(command);
|
this.commands.add(command);
|
||||||
}
|
}
|
||||||
@ -54,7 +54,14 @@ public class CommandDispatcher {
|
|||||||
return Collections.unmodifiableSet(commands);
|
return Collections.unmodifiableSet(commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Command findCommand(String commandName) {
|
/**
|
||||||
|
* Get the command class associated with its name
|
||||||
|
*
|
||||||
|
* @param commandName the command name
|
||||||
|
* @return the {@link Command} associated with the name, null if not any
|
||||||
|
*/
|
||||||
|
public Command findCommand(String commandName) {
|
||||||
|
commandName = commandName.toLowerCase();
|
||||||
return commandMap.containsKey(commandName) ? commandMap.get(commandName) : null;
|
return commandMap.containsKey(commandName) ? commandMap.get(commandName) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package net.minestom.server.command.builder.arguments;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class ArgumentDynamicStringArray extends Argument<String[]> {
|
||||||
|
|
||||||
|
public ArgumentDynamicStringArray(String id) {
|
||||||
|
super(id, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCorrectionResult(String value) {
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] parse(String value) {
|
||||||
|
return value.split(Pattern.quote(" "));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getConditionResult(String[] value) {
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package net.minestom.server.command.builder.arguments;
|
||||||
|
|
||||||
|
public class ArgumentDynamicWord extends Argument<String> {
|
||||||
|
|
||||||
|
public ArgumentDynamicWord(String id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCorrectionResult(String value) {
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String parse(String value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getConditionResult(String value) {
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
@ -43,10 +43,18 @@ public class ArgumentType {
|
|||||||
return new ArgumentWord(id);
|
return new ArgumentWord(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ArgumentDynamicWord DynamicWord(String id) {
|
||||||
|
return new ArgumentDynamicWord(id);
|
||||||
|
}
|
||||||
|
|
||||||
public static ArgumentStringArray StringArray(String id) {
|
public static ArgumentStringArray StringArray(String id) {
|
||||||
return new ArgumentStringArray(id);
|
return new ArgumentStringArray(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ArgumentDynamicStringArray DynamicStringArray(String id) {
|
||||||
|
return new ArgumentDynamicStringArray(id);
|
||||||
|
}
|
||||||
|
|
||||||
// Minecraft specific
|
// Minecraft specific
|
||||||
|
|
||||||
public static ArgumentColor Color(String id) {
|
public static ArgumentColor Color(String id) {
|
||||||
|
@ -21,7 +21,7 @@ public class ArgumentWord extends Argument<String> {
|
|||||||
if (value.contains(" "))
|
if (value.contains(" "))
|
||||||
return SPACE_ERROR;
|
return SPACE_ERROR;
|
||||||
|
|
||||||
return Argument.SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -37,7 +37,7 @@ public class ArgumentWord extends Argument<String> {
|
|||||||
if (restrictions != null && restrictions.length > 0) {
|
if (restrictions != null && restrictions.length > 0) {
|
||||||
for (String r : restrictions) {
|
for (String r : restrictions) {
|
||||||
if (value.equalsIgnoreCase(r))
|
if (value.equalsIgnoreCase(r))
|
||||||
return Argument.SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
if (!findRestriction)
|
if (!findRestriction)
|
||||||
return RESTRICTION_ERROR;
|
return RESTRICTION_ERROR;
|
||||||
|
@ -3,6 +3,7 @@ package net.minestom.server.listener;
|
|||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.command.CommandManager;
|
import net.minestom.server.command.CommandManager;
|
||||||
import net.minestom.server.command.CommandProcessor;
|
import net.minestom.server.command.CommandProcessor;
|
||||||
|
import net.minestom.server.command.builder.Command;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.network.packet.client.play.ClientTabCompletePacket;
|
import net.minestom.server.network.packet.client.play.ClientTabCompletePacket;
|
||||||
import net.minestom.server.network.packet.server.play.TabCompletePacket;
|
import net.minestom.server.network.packet.server.play.TabCompletePacket;
|
||||||
@ -23,22 +24,41 @@ public class TabCompleteListener {
|
|||||||
// Tab complete for CommandProcessor
|
// Tab complete for CommandProcessor
|
||||||
final CommandProcessor commandProcessor = COMMAND_MANAGER.getCommandProcessor(commandName);
|
final CommandProcessor commandProcessor = COMMAND_MANAGER.getCommandProcessor(commandName);
|
||||||
if (commandProcessor != null) {
|
if (commandProcessor != null) {
|
||||||
|
final int start = findStart(text, split);
|
||||||
|
final String[] matches = commandProcessor.onWrite(text);
|
||||||
|
if (matches != null && matches.length > 0) {
|
||||||
|
sendTabCompletePacket(packet.transactionId, start, matches, player);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Tab complete for Command
|
||||||
|
final Command command = COMMAND_MANAGER.getCommand(commandName);
|
||||||
|
if (command != null) {
|
||||||
|
final int start = findStart(text, split);
|
||||||
|
final String[] matches = command.onDynamicWrite(text);
|
||||||
|
if (matches != null && matches.length > 0) {
|
||||||
|
sendTabCompletePacket(packet.transactionId, start, matches, player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int findStart(String text, String[] split) {
|
||||||
final boolean endSpace = text.endsWith(" ");
|
final boolean endSpace = text.endsWith(" ");
|
||||||
|
|
||||||
int start;
|
int start;
|
||||||
|
|
||||||
if (endSpace) {
|
if (endSpace) {
|
||||||
start = text.length();
|
start = text.length();
|
||||||
} else {
|
} else {
|
||||||
final String lastArg = split[split.length - 1];
|
final String lastArg = split[split.length - 1];
|
||||||
start = text.indexOf(lastArg);
|
start = text.lastIndexOf(lastArg);
|
||||||
|
}
|
||||||
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String[] matches = commandProcessor.onWrite(text);
|
private static void sendTabCompletePacket(int transactionId, int start, String[] matches, Player player) {
|
||||||
|
|
||||||
if (matches != null && matches.length > 0) {
|
|
||||||
TabCompletePacket tabCompletePacket = new TabCompletePacket();
|
TabCompletePacket tabCompletePacket = new TabCompletePacket();
|
||||||
tabCompletePacket.transactionId = packet.transactionId;
|
tabCompletePacket.transactionId = transactionId;
|
||||||
tabCompletePacket.start = start;
|
tabCompletePacket.start = start;
|
||||||
tabCompletePacket.length = 20;
|
tabCompletePacket.length = 20;
|
||||||
|
|
||||||
@ -53,12 +73,6 @@ public class TabCompleteListener {
|
|||||||
|
|
||||||
player.getPlayerConnection().sendPacket(tabCompletePacket);
|
player.getPlayerConnection().sendPacket(tabCompletePacket);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// TODO tab complete for Command (TabArgument)
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user