From 293786854be507a0806127291285607ebdc153fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9meth=20Noel?= Date: Sun, 22 Aug 2021 08:36:02 +0200 Subject: [PATCH] Fix range parsing --- .../arguments/minecraft/ArgumentEntity.java | 4 +- .../minecraft/ArgumentFloatRange.java | 54 +-------------- .../arguments/minecraft/ArgumentIntRange.java | 64 +---------------- .../arguments/minecraft/ArgumentRange.java | 68 ++++++++++++++++++- 4 files changed, 72 insertions(+), 118 deletions(-) diff --git a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentEntity.java b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentEntity.java index fbfec065b..249707ef7 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentEntity.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentEntity.java @@ -245,7 +245,7 @@ public class ArgumentEntity extends Argument { break; case "level": try { - final IntRange level = ArgumentIntRange.staticParse(value); + final IntRange level = Argument.parse(new ArgumentIntRange(value)); entityFinder.setLevel(level); } catch (ArgumentSyntaxException e) { throw new ArgumentSyntaxException("Invalid level number", input, INVALID_ARGUMENT_VALUE); @@ -253,7 +253,7 @@ public class ArgumentEntity extends Argument { break; case "distance": try { - final IntRange distance = ArgumentIntRange.staticParse(value); + final IntRange distance = Argument.parse(new ArgumentIntRange(value)); entityFinder.setDistance(distance); } catch (ArgumentSyntaxException e) { throw new ArgumentSyntaxException("Invalid level number", input, INVALID_ARGUMENT_VALUE); diff --git a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentFloatRange.java b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentFloatRange.java index bc25f5fcf..2fc4c3d87 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentFloatRange.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentFloatRange.java @@ -1,66 +1,16 @@ package net.minestom.server.command.builder.arguments.minecraft; -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 net.minestom.server.utils.math.FloatRange; -import org.jetbrains.annotations.NotNull; - -import java.util.regex.Pattern; /** * Represents an argument which will give you an {@link FloatRange}. *

* Example: ..3, 3.., 5..10, 15 */ -public class ArgumentFloatRange extends ArgumentRange { +public class ArgumentFloatRange extends ArgumentRange { public ArgumentFloatRange(String id) { - super(id); - } - - @NotNull - @Override - public FloatRange parse(@NotNull String input) throws ArgumentSyntaxException { - try { - if (input.contains("..")) { - final int index = input.indexOf('.'); - final String[] split = input.split(Pattern.quote("..")); - - final float min; - final float max; - if (index == 0) { - // Format ..NUMBER - min = Float.MIN_VALUE; - max = Float.parseFloat(split[0]); - } else { - if (split.length == 2) { - // Format NUMBER..NUMBER - min = Float.parseFloat(split[0]); - max = Float.parseFloat(split[1]); - } else { - // Format NUMBER.. - min = Float.parseFloat(split[0]); - max = Float.MAX_VALUE; - } - } - - return new FloatRange(min, max); - } else { - final float number = Float.parseFloat(input); - return new FloatRange(number); - } - } catch (NumberFormatException e2) { - throw new ArgumentSyntaxException("Invalid number", input, FORMAT_ERROR); - } - } - - @Override - public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) { - DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(this, executable, false, false); - argumentNode.parser = "minecraft:float_range"; - - nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode}); + super(id, Float.MIN_VALUE, Float.MAX_VALUE, Float::parseFloat, "minecraft:float_range", FloatRange::new); } @Override diff --git a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentIntRange.java b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentIntRange.java index 0d88829d4..730a63769 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentIntRange.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentIntRange.java @@ -1,76 +1,16 @@ 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.network.packet.server.play.DeclareCommandsPacket; import net.minestom.server.utils.math.IntRange; -import org.jetbrains.annotations.NotNull; - -import java.util.regex.Pattern; /** * Represents an argument which will give you an {@link IntRange}. *

* Example: ..3, 3.., 5..10, 15 */ -public class ArgumentIntRange extends ArgumentRange { +public class ArgumentIntRange extends ArgumentRange { public ArgumentIntRange(String id) { - super(id); - } - - @NotNull - @Override - public IntRange parse(@NotNull String input) throws ArgumentSyntaxException { - return staticParse(input); - } - - /** - * @deprecated use {@link Argument#parse(Argument)} - */ - @Deprecated - @NotNull - public static IntRange staticParse(@NotNull String input) throws ArgumentSyntaxException { - try { - if (input.contains("..")) { - final int index = input.indexOf('.'); - final String[] split = input.split(Pattern.quote("..")); - - final int min; - final int max; - if (index == 0) { - // Format ..NUMBER - min = Integer.MIN_VALUE; - max = Integer.parseInt(split[0]); - } else { - if (split.length == 2) { - // Format NUMBER..NUMBER - min = Integer.parseInt(split[0]); - max = Integer.parseInt(split[1]); - } else { - // Format NUMBER.. - min = Integer.parseInt(split[0]); - max = Integer.MAX_VALUE; - } - } - - return new IntRange(min, max); - } else { - final int number = Integer.parseInt(input); - return new IntRange(number); - } - } catch (NumberFormatException e2) { - throw new ArgumentSyntaxException("Invalid number", input, FORMAT_ERROR); - } - } - - @Override - public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) { - DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(this, executable, false, false); - argumentNode.parser = "minecraft:int_range"; - - nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode}); + super(id, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer::parseInt, "minecraft:int_range", IntRange::new); } @Override diff --git a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentRange.java b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentRange.java index a29980bda..590fd5591 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentRange.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentRange.java @@ -1,17 +1,81 @@ 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.network.packet.server.play.DeclareCommandsPacket; +import net.minestom.server.utils.math.FloatRange; +import org.jetbrains.annotations.NotNull; + +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.regex.Pattern; /** * Abstract class used by {@link ArgumentIntRange} and {@link ArgumentFloatRange}. * * @param the type of the range */ -public abstract class ArgumentRange extends Argument { +public abstract class ArgumentRange extends Argument { public static final int FORMAT_ERROR = -1; + private final N min; + private final N max; + private final Function parser; + private final String parserName; + private final BiFunction rangeConstructor; - public ArgumentRange(String id) { + public ArgumentRange(@NotNull String id, N min, N max, Function parser, String parserName, BiFunction rangeConstructor) { super(id); + this.min = min; + this.max = max; + this.parser = parser; + this.parserName = parserName; + this.rangeConstructor = rangeConstructor; } + + @NotNull + @Override + public T parse(@NotNull String input) throws ArgumentSyntaxException { + try { + final String[] split = input.split(Pattern.quote(".."), -1); + + if (split.length == 2) { + final N min; + final N max; + if (split[0].length() == 0 && split[1].length() > 0) { + // Format ..NUMBER + min = this.min; + max = parser.apply(split[1]); + } else if (split[0].length() > 0 && split[1].length() == 0) { + // Format NUMBER.. + min = parser.apply(split[0]); + max = this.max; + } else if (split[0].length() > 0) { + // Format NUMBER..NUMBER + min = parser.apply(split[0]); + max = parser.apply(split[1]); + } else { + // Format .. + throw new ArgumentSyntaxException("Invalid range format", input, FORMAT_ERROR); + } + return rangeConstructor.apply(min, max); + } else if (split.length == 1) { + final N number = parser.apply(input); + return rangeConstructor.apply(number, number); + } + } catch (NumberFormatException e2) { + throw new ArgumentSyntaxException("Invalid number", input, FORMAT_ERROR); + } + throw new ArgumentSyntaxException("Invalid range format", input, FORMAT_ERROR); + } + + @Override + public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) { + DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(this, executable, false, false); + argumentNode.parser = parserName; + + nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode}); + } + }