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 new file mode 100644 index 000000000..7ce558006 --- /dev/null +++ b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentBlockState.java @@ -0,0 +1,74 @@ +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 org.jetbrains.annotations.NotNull; + +public class ArgumentBlockState extends Argument { + + public static final int NO_BLOCK = 1; + public static final int INVALID_BLOCK = 2; + + public ArgumentBlockState(@NotNull String id) { + super(id); + } + + @Override + public @NotNull Block parse(@NotNull String input) throws ArgumentSyntaxException { + final int nbtIndex = input.indexOf("["); + if (nbtIndex == 0) + throw new ArgumentSyntaxException("No block type", input, NO_BLOCK); + + if (nbtIndex == -1) { + // Only block name + final Block block = Block.fromNamespaceId(input); + if (block == null) + throw new ArgumentSyntaxException("Invalid block type", input, INVALID_BLOCK); + return block; + } else { + // Block state + final String blockName = input.substring(0, nbtIndex); + Block block = Block.fromNamespaceId(blockName); + if (block == null) + throw new ArgumentSyntaxException("Invalid block type", input, INVALID_BLOCK); + + // Compute properties + final String propertiesString = input.substring(nbtIndex + 1, input.length() - 1); + StringBuilder keyBuilder = new StringBuilder(); + StringBuilder valueBuilder = new StringBuilder(); + StringBuilder builder = keyBuilder; + for (int i = 0; i < propertiesString.length(); i++) { + final char c = propertiesString.charAt(i); + if (c == '=') { + // Switch to value builder + builder = valueBuilder; + } else if (c == ',') { + // Append current text + block = block.withProperty(keyBuilder.toString(), valueBuilder.toString()); + keyBuilder = new StringBuilder(); + valueBuilder = new StringBuilder(); + builder = keyBuilder; + } else if (c != ' ') { + builder.append(c); + } + } + return block.withProperty(keyBuilder.toString(), valueBuilder.toString()); + } + } + + @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}); + } + + @Override + public String toString() { + return String.format("BlockState<%s>", getId()); + } +} diff --git a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/registry/ArgumentBlockState.java b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/registry/ArgumentBlockState.java deleted file mode 100644 index 52de26a20..000000000 --- a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/registry/ArgumentBlockState.java +++ /dev/null @@ -1,31 +0,0 @@ -package net.minestom.server.command.builder.arguments.minecraft.registry; - -import net.minestom.server.command.builder.NodeMaker; -import net.minestom.server.instance.block.Block; -import net.minestom.server.network.packet.server.play.DeclareCommandsPacket; -import org.jetbrains.annotations.NotNull; - -public class ArgumentBlockState extends ArgumentRegistry { - - public ArgumentBlockState(@NotNull String id) { - super(id); - } - - @Override - public Block getRegistry(@NotNull String value) { - return Block.fromNamespaceId(value); - } - - @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}); - } - - @Override - public String toString() { - return String.format("BlockState<%s>", getId()); - } -} diff --git a/src/test/java/demo/commands/TestCommand.java b/src/test/java/demo/commands/TestCommand.java index e70172049..15bfa1f9f 100644 --- a/src/test/java/demo/commands/TestCommand.java +++ b/src/test/java/demo/commands/TestCommand.java @@ -4,6 +4,7 @@ import net.kyori.adventure.text.Component; import net.minestom.server.command.CommandSender; import net.minestom.server.command.builder.Command; import net.minestom.server.command.builder.CommandContext; +import net.minestom.server.command.builder.arguments.ArgumentType; public class TestCommand extends Command { @@ -11,7 +12,10 @@ public class TestCommand extends Command { super("testcmd"); setDefaultExecutor(this::usage); - addSyntax((sender, context) -> System.out.println("executed"), "test Get integer"); + var block = ArgumentType.BlockState("block"); + block.setCallback((sender, exception) -> exception.printStackTrace()); + + addSyntax((sender, context) -> System.out.println("executed"), block); } private void usage(CommandSender sender, CommandContext context) {