ArgumentEnum and /horse command for demo scene

This commit is contained in:
Konstantin Shandurenko 2021-02-23 09:06:19 +03:00
parent cfc5f860e9
commit b409eadffa
4 changed files with 143 additions and 0 deletions

View File

@ -0,0 +1,64 @@
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.Locale;
import java.util.function.Consumer;
/**
* Created by k.shandurenko on 23.02.2021
*/
@SuppressWarnings("rawtypes")
public class ArgumentEnum<E extends Enum> extends Argument<E> {
public final static int NOT_ENUM_VALUE_ERROR = 1;
private final Class<E> enumClass;
private final E[] values;
public ArgumentEnum(@NotNull String id, Class<E> enumClass) {
super(id);
this.enumClass = enumClass;
this.values = enumClass.getEnumConstants();
}
@NotNull
@Override
public E parse(@NotNull String input) throws ArgumentSyntaxException {
for (E value : this.values) {
if (value.name().equalsIgnoreCase(input)) {
return value;
}
}
throw new ArgumentSyntaxException("Not a " + this.enumClass.getSimpleName() + " value", input, NOT_ENUM_VALUE_ERROR);
}
@Override
public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) {
// Add the single word properties + parser
final Consumer<DeclareCommandsPacket.Node> wordConsumer = node -> {
node.parser = "brigadier:string";
node.properties = packetWriter -> {
packetWriter.writeVarInt(0); // Single word
};
};
// Create a primitive array for mapping
DeclareCommandsPacket.Node[] nodes = new DeclareCommandsPacket.Node[this.values.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.values[i].name().toLowerCase(Locale.ROOT);
wordConsumer.accept(argumentNode);
nodes[i] = argumentNode;
}
nodeMaker.addNodes(nodes);
}
}

View File

@ -79,6 +79,11 @@ public class ArgumentType {
return new ArgumentCommand(id);
}
@SuppressWarnings("rawtypes")
public static <E extends Enum> ArgumentEnum<E> Enum(@NotNull String id, @NotNull Class<E> enumClass) {
return new ArgumentEnum<>(id, enumClass);
}
// Minecraft specific arguments
public static ArgumentColor Color(@NotNull String id) {

View File

@ -43,6 +43,7 @@ public class Main {
commandManager.register(new TitleCommand());
commandManager.register(new BookCommand());
commandManager.register(new ShootCommand());
commandManager.register(new HorseCommand());
commandManager.setUnknownCommandCallback((sender, command) -> sender.sendMessage("unknown command"));

View File

@ -0,0 +1,73 @@
package demo.commands;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.Arguments;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.arguments.ArgumentType;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.type.animal.EntityHorse;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class HorseCommand extends Command {
public HorseCommand() {
super("horse");
setCondition(this::condition);
setDefaultExecutor(this::defaultExecutor);
var babyArg = ArgumentType.Boolean("baby");
var markingArg = ArgumentType.Enum("marking", EntityHorse.Marking.class);
var colorArg = ArgumentType.Enum("color", EntityHorse.Color.class);
setArgumentCallback(this::onBabyError, babyArg);
setArgumentCallback(this::onMarkingError, markingArg);
setArgumentCallback(this::onColorError, colorArg);
addSyntax(this::onHorseCommand, babyArg, markingArg, colorArg);
}
private boolean condition(CommandSender sender, String commandString) {
if (!sender.isPlayer()) {
sender.sendMessage("The command is only available for player");
return false;
}
return true;
}
private void defaultExecutor(CommandSender sender, Arguments args) {
sender.sendMessage("Correct usage: horse [baby] [marking] [color]");
}
private void onBabyError(CommandSender sender, ArgumentSyntaxException exception) {
sender.sendMessage("SYNTAX ERROR: '" + exception.getInput() + "' should be replaced by 'true' or 'false'");
}
private void onMarkingError(CommandSender sender, ArgumentSyntaxException exception) {
String values = Stream.of(EntityHorse.Marking.values())
.map(value -> "'" + value.name().toLowerCase(Locale.ROOT) + "'")
.collect(Collectors.joining(", "));
sender.sendMessage("SYNTAX ERROR: '" + exception.getInput() + "' should be replaced by " + values + ".");
}
private void onColorError(CommandSender sender, ArgumentSyntaxException exception) {
String values = Stream.of(EntityHorse.Color.values())
.map(value -> "'" + value.name().toLowerCase(Locale.ROOT) + "'")
.collect(Collectors.joining(", "));
sender.sendMessage("SYNTAX ERROR: '" + exception.getInput() + "' should be replaced by " + values + ".");
}
private void onHorseCommand(CommandSender sender, Arguments args) {
var player = (Player) sender;
boolean baby = args.get("baby");
EntityHorse.Marking marking = args.get("marking");
EntityHorse.Color color = args.get("color");
var horse = (EntityHorse) EntityType.HORSE.createFromPosition(player.getPosition());
horse.setBaby(baby);
horse.setVariant(new EntityHorse.Variant(marking, color));
horse.setInstance(player.getInstance());
}
}