It stores useful information like the argument name and the user input
- * @param the argument type
- */
-@Data
-public class Argument {
-
- private final String name;
- @Getter(AccessLevel.NONE)
- private final T value;
- private final String input;
-
- public T value() {
- return value;
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/Command.java b/commands/src/main/java/com/wizardlybump17/wlib/command/Command.java
new file mode 100644
index 00000000..1980bd62
--- /dev/null
+++ b/commands/src/main/java/com/wizardlybump17/wlib/command/Command.java
@@ -0,0 +1,277 @@
+package com.wizardlybump17.wlib.command;
+
+import com.wizardlybump17.wlib.command.context.CommandContext;
+import com.wizardlybump17.wlib.command.exception.InputParsingException;
+import com.wizardlybump17.wlib.command.exception.InvalidInputException;
+import com.wizardlybump17.wlib.command.exception.SuggesterException;
+import com.wizardlybump17.wlib.command.executor.CommandNodeExecutor;
+import com.wizardlybump17.wlib.command.node.CommandNode;
+import com.wizardlybump17.wlib.command.node.LiteralCommandNode;
+import com.wizardlybump17.wlib.command.result.CommandResult;
+import com.wizardlybump17.wlib.command.sender.CommandSender;
+import com.wizardlybump17.wlib.command.suggestion.Suggester;
+import com.wizardlybump17.wlib.util.StringUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Stream;
+
+public class Command implements Comparable {
+
+ public static final @NotNull Comparator COMPARATOR = Comparator
+ .comparing(Command::getFullCommand);
+
+ private final @NotNull LiteralCommandNode root;
+
+ public Command(@NotNull LiteralCommandNode root) {
+ this.root = root;
+ }
+
+ public @NotNull LiteralCommandNode getRoot() {
+ return root;
+ }
+
+ public @NotNull CommandResult> execute(@NotNull CommandSender> sender, @NotNull String input) {
+ List inputList = getInputList(input);
+ return execute(sender, inputList);
+ }
+
+ @SuppressWarnings("unchecked")
+ public @NotNull CommandResult> execute(@NotNull CommandSender> sender, @NotNull List input) {
+ if (input.isEmpty())
+ return CommandResult.insufficientArguments(this);
+
+ List> arguments = new ArrayList<>();
+ List> children = List.of(root);
+
+ CommandNode> lastNode = null;
+ int lastInputIndex = 0;
+ InputParsingException lastParsingError = null;
+ InvalidInputException lastInputError = null;
+
+ inputLoop: for (int i = 0; i < input.size(); i++) {
+ String inputString = input.get(i);
+ lastInputIndex = i;
+
+ for (CommandNode> child : children) {
+ lastNode = child;
+
+ try {
+ Object result;
+ if (inputString == null) {
+ if (child.isValidInput(null))
+ result = null;
+ else
+ throw new InvalidInputException("Null inputs not accepted by " + child);
+ } else {
+ result = child.parseOrInvalid(inputString);
+ }
+
+ if (!(child instanceof LiteralCommandNode))
+ arguments.add(new CommandContext.CommandNodeArgument<>((CommandNode
- *
The type of each parameter is defined in the method that have this annotation.
- * An example for the command above:
- *
- * @Command(execution = "command <hello> world")
- * public void commandHelloWorld(GenericSender sender, String hello) {
- * System.out.println(sender.getName() + " executed the hello world command with the argument " + hello);
- * }
- *
- *
- * @return how the command must be sent to be triggered
- * @see com.wizardlybump17.wlib.command.args.reader.ArgsReader
- */
- String execution();
+ @NotNull String value();
- /**
- * @return which permission the sender must have to trigger this command
- */
- String permission() default "";
-
- /**
- *
Used when the {@link CommandSender} does not have the required {@link #permission()}.
- * @return the message to be sent when the {@link CommandSender} does not have the required {@link #permission()}
- */
- String permissionMessage() default "";
-
- /**
- * @return if the {@link #permissionMessage()} is a field in the class that have this annotation
- */
- boolean permissionMessageIsField() default false;
-
- /**
- * Sets the priority of this command. If the priority is -1, then the priority check is the same as
- *
{@code this.execution().split(" ").length}
- *
- * @return the priority of this command
- */
- int priority() default -1;
-
- /**
- * Sets the options of this command.
- * The Bukkit implementation does nothing with this
- *
- * @return the options of this command
- */
- String[] options() default {};
-
- /**
- * @return the description of this command
- */
- String description() default "";
-
- /**
- *
Used when the {@link CommandSender} is not valid for this command.
- * @return the message to be sent when the {@link CommandSender} is not valid for this command
- */
- String invalidSenderMessage() default "";
-
- /**
- * @return if the {@link #invalidSenderMessage()} is a field in the class that have this annotation
- */
- boolean invalidSenderMessageIsField() default false;
-
- /**
- * @return the type of the {@link CommandSender#getHandle()} that can execute this command
- */
- @NotNull Class> senderType() default Object.class;
+ @NotNull String permission() default "";
}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/Description.java b/commands/src/main/java/com/wizardlybump17/wlib/command/annotation/NonNullInput.java
similarity index 71%
rename from commands/src/main/java/com/wizardlybump17/wlib/command/Description.java
rename to commands/src/main/java/com/wizardlybump17/wlib/command/annotation/NonNullInput.java
index f66546fc..1060aab8 100644
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/Description.java
+++ b/commands/src/main/java/com/wizardlybump17/wlib/command/annotation/NonNullInput.java
@@ -1,4 +1,4 @@
-package com.wizardlybump17.wlib.command;
+package com.wizardlybump17.wlib.command.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -7,7 +7,5 @@
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
-public @interface Description {
-
- String value();
+public @interface NonNullInput {
}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/ArgsNode.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/ArgsNode.java
deleted file mode 100644
index 23d07d47..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/ArgsNode.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.wizardlybump17.wlib.command.args;
-
-import com.wizardlybump17.wlib.command.Argument;
-import com.wizardlybump17.wlib.command.args.reader.ArgsReader;
-import com.wizardlybump17.wlib.command.args.reader.ArgsReaderException;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Represents a node of a command argument
- */
-@Data
-@AllArgsConstructor
-public class ArgsNode {
-
- public static final Object EMPTY = new Object();
-
- @NotNull
- private final String name;
- private final boolean userInput;
- @Nullable
- private final ArgsReader> reader;
- @Nullable
- private final String description;
- private final boolean isArgument;
-
- /**
- * Parses the given input
- * @param input the input
- * @return the parsed object
- * @throws ArgsReaderException if the input is invalid
- */
- public Object parse(String input) throws ArgsReaderException {
- if (reader == null)
- return EMPTY;
-
- Object object = reader.read(input);
- if (isArgument)
- return new Argument<>(name, object, input);
-
- return object;
- }
-
- public static @NotNull ArgsNode literal(@NotNull String string) {
- return new ArgsNode(string, false, null, null, false);
- }
-
- public static @NotNull ArgsNode userInput(@NotNull String name, @NotNull ArgsReader> reader) {
- return new ArgsNode(name, true, reader, null, false);
- }
-
- public static @NotNull ArgsNode userInput(@NotNull String name, @NotNull Class> type) {
- return userInput(name, ArgsReaderRegistry.INSTANCE.getReader(type));
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/ArgsReaderRegistry.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/ArgsReaderRegistry.java
deleted file mode 100644
index 09c8f99d..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/ArgsReaderRegistry.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.wizardlybump17.wlib.command.args;
-
-import com.wizardlybump17.wlib.command.args.reader.*;
-import com.wizardlybump17.wlib.object.Registry;
-
-/**
- * A registry for the {@link ArgsReader}.
- *
The key is the {@link ArgsReader#getClass()} and the value is the {@link ArgsReader}
- */
-public class ArgsReaderRegistry extends Registry>, ArgsReader>> {
-
- public static final ArgsReaderRegistry INSTANCE = new ArgsReaderRegistry();
-
- static {
- INSTANCE.add(new StringReader());
- INSTANCE.add(new ByteReader());
- INSTANCE.add(new ByteArrayReader());
- INSTANCE.add(new ShortReader());
- INSTANCE.add(new ShortArrayReader());
- INSTANCE.add(new IntegerReader());
- INSTANCE.add(new IntegerArrayReader());
- INSTANCE.add(new FloatReader());
- INSTANCE.add(new FloatArrayReader());
- INSTANCE.add(new DoubleReader());
- INSTANCE.add(new DoubleArrayReader());
- INSTANCE.add(new BigIntegerArgsReader());
- INSTANCE.add(new BigDecimalArgsReader());
- INSTANCE.add(new UUIDReader());
- INSTANCE.add(new BooleanReader());
- INSTANCE.add(new DateReader());
- }
-
- private ArgsReaderRegistry() {
- }
-
- @SuppressWarnings("unchecked")
- public void add(ArgsReader> reader) {
- put((Class extends ArgsReader>>) reader.getClass(), reader);
- }
-
- /**
- * Gets the first reader that can read the specified type
- * @param type the type
- * @return the reader
- */
- public ArgsReader> getReader(Class> type) {
- for (ArgsReader> reader : getMap().values())
- if (reader.getTypes().contains(type))
- return reader;
- return null;
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/ArgsReaderType.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/ArgsReaderType.java
deleted file mode 100644
index 2e8fc4ca..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/ArgsReaderType.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.wizardlybump17.wlib.command.args;
-
-import com.wizardlybump17.wlib.command.args.reader.ArgsReader;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Specified the {@link ArgsReader} of the parameter
- */
-@Target(ElementType.PARAMETER)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface ArgsReaderType {
-
- /**
- * @return the class of the {@link ArgsReader} to use
- */
- Class extends ArgsReader>> value();
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ArgsReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ArgsReader.java
deleted file mode 100644
index d8a6fa5a..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ArgsReader.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-import com.wizardlybump17.wlib.command.sender.CommandSender;
-import lombok.NonNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Used to read and convert the args from string to the specified type
- * @param which type the string will be converted to
- */
-public abstract class ArgsReader {
-
- private List> typesCache;
-
- /**
- *
The type that the string will be converted to.
- *
If it is {@code null} then you should use the {@link com.wizardlybump17.wlib.command.args.ArgsReaderType} annotation on your parameter
- * @return the type that the string will be converted to
- * @deprecated Use the {@link #getTypes()} instead
- */
- @Nullable
- @Deprecated
- public abstract Class getType();
-
- /**
- * @return the types that {@code this} {@link ArgsReader} can accept in the method parameter
- */
- public @NonNull List> getTypes() {
- if (typesCache == null)
- typesCache = Collections.singletonList(getType());
- return typesCache;
- }
-
- public abstract T read(String string) throws ArgsReaderException;
-
- /**
- *
Gives the suggestions for the specified sender and current argument (optional).
- * @param sender who is executing the command
- * @param current the current argument
- * @return a {@link List} of suggestions
- */
- @NonNull
- public List<@NonNull String> autoComplete(@NonNull CommandSender> sender, @NonNull String current) {
- return Collections.emptyList();
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ArgsReaderException.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ArgsReaderException.java
deleted file mode 100644
index e24704dd..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ArgsReaderException.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-public class ArgsReaderException extends Exception {
-
- public ArgsReaderException(String message) {
- super(message);
- }
-
- public ArgsReaderException(Throwable cause) {
- super(cause);
- }
-
- public ArgsReaderException(String message, Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/BigDecimalArgsReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/BigDecimalArgsReader.java
deleted file mode 100644
index 638016ba..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/BigDecimalArgsReader.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-import java.math.BigDecimal;
-
-public class BigDecimalArgsReader extends ArgsReader {
-
- @Override
- public Class getType() {
- return BigDecimal.class;
- }
-
- @Override
- public BigDecimal read(String string) {
- try {
- return new BigDecimal(string);
- } catch (NumberFormatException e) {
- return null;
- }
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/BigIntegerArgsReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/BigIntegerArgsReader.java
deleted file mode 100644
index bf39e180..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/BigIntegerArgsReader.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-import java.math.BigInteger;
-
-public class BigIntegerArgsReader extends ArgsReader {
-
- @Override
- public Class getType() {
- return BigInteger.class;
- }
-
- @Override
- public BigInteger read(String string) {
- try {
- return new BigInteger(string);
- } catch (NumberFormatException e) {
- return null;
- }
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/BooleanReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/BooleanReader.java
deleted file mode 100644
index 539558be..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/BooleanReader.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-import com.wizardlybump17.wlib.command.sender.CommandSender;
-import lombok.NonNull;
-
-import java.util.List;
-
-public class BooleanReader extends ArgsReader {
-
- public static final @NonNull List> TYPES = List.of(boolean.class, Boolean.class);
- public static final List SUGGESTIONS = List.of("true", "false");
-
- @Override
- public Class getType() {
- return boolean.class;
- }
-
- @Override
- public @NonNull List> getTypes() {
- return TYPES;
- }
-
- @Override
- public Boolean read(String string) throws ArgsReaderException {
- if (string.equalsIgnoreCase("true"))
- return true;
- if (string.equalsIgnoreCase("false"))
- return false;
-
- return null;
- }
-
- @Override
- public @NonNull List<@NonNull String> autoComplete(@NonNull CommandSender> sender, @NonNull String current) {
- return SUGGESTIONS;
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ByteArrayReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ByteArrayReader.java
deleted file mode 100644
index ed29be28..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ByteArrayReader.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-public class ByteArrayReader extends ArgsReader {
-
- @Override
- public Class getType() {
- return byte[].class;
- }
-
- @Override
- public byte[] read(String string) throws ArgsReaderException {
- try {
- final String[] strings = string.split(" ");
-
- byte[] result = new byte[strings.length];
- for (int i = 0; i < result.length; i++)
- result[i] = Byte.parseByte(strings[i]);
- return result;
- } catch (NumberFormatException e) {
- throw new ArgsReaderException("expected a byte array in string form but got " + string);
- }
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ByteReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ByteReader.java
deleted file mode 100644
index 00c9056c..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ByteReader.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-import com.wizardlybump17.wlib.command.sender.CommandSender;
-import lombok.NonNull;
-
-import java.util.List;
-
-public class ByteReader extends ArgsReader {
-
- public static final List SUGGESTIONS = List.of("-128", "0", "127");
- public static final @NonNull List> TYPES = List.of(byte.class, Byte.class);
-
- @Override
- public Class getType() {
- return byte.class;
- }
-
- @Override
- public @NonNull List> getTypes() {
- return TYPES;
- }
-
- @Override
- public Byte read(String string) throws ArgsReaderException {
- try {
- return Byte.parseByte(string);
- } catch (NumberFormatException e) {
- return null;
- }
- }
-
- @Override
- public @NonNull List<@NonNull String> autoComplete(@NonNull CommandSender> sender, @NonNull String current) {
- return SUGGESTIONS;
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/DateReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/DateReader.java
deleted file mode 100644
index 70f576eb..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/DateReader.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-import com.github.sisyphsu.dateparser.DateParserUtils;
-import lombok.NonNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.time.format.DateTimeParseException;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Supplier;
-
-public class DateReader extends ArgsReader {
-
- //i could do a dedicated system for this, but this one is simpler and works so idc
- public static final @NonNull Map> PROVIDERS = new HashMap<>();
-
- static {
- PROVIDERS.put("now", Date::new);
- PROVIDERS.put("today", () -> getToday().getTime());
- PROVIDERS.put("yesterday", () -> {
- Calendar today = getToday();
- today.add(Calendar.DAY_OF_YEAR, -1);
- return today.getTime();
- });
- PROVIDERS.put("tomorrow", () -> {
- Calendar today = getToday();
- today.add(Calendar.DAY_OF_YEAR, 1);
- return today.getTime();
- });
- }
-
- @Override
- public @NonNull Class getType() {
- return Date.class;
- }
-
- @Override
- public @Nullable Date read(@NonNull String string) {
- Supplier provider = PROVIDERS.get(string.toLowerCase());
- if (provider != null)
- return provider.get();
-
- try {
- return DateParserUtils.parseDate(string);
- } catch (DateTimeParseException e) {
- return null; //i need to rework the command system :C
- }
- }
-
- public static @NonNull Calendar getToday() {
- Calendar calendar = Calendar.getInstance();
- calendar.set(Calendar.HOUR_OF_DAY, 0);
- calendar.set(Calendar.MINUTE, 0);
- calendar.set(Calendar.SECOND, 0);
- calendar.set(Calendar.MILLISECOND, 0);
- return calendar;
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/DoubleArrayReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/DoubleArrayReader.java
deleted file mode 100644
index 7ebd303f..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/DoubleArrayReader.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-public class DoubleArrayReader extends ArgsReader {
-
- @Override
- public Class getType() {
- return double[].class;
- }
-
- @Override
- public double[] read(String string) throws ArgsReaderException {
- try {
- final String[] strings = string.split(" ");
-
- double[] result = new double[strings.length];
- for (int i = 0; i < result.length; i++)
- result[i] = Double.parseDouble(strings[i]);
- return result;
- } catch (NumberFormatException e) {
- throw new ArgsReaderException("expected a double array in string form but got " + string);
- }
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/DoubleReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/DoubleReader.java
deleted file mode 100644
index b7c4f356..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/DoubleReader.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-import com.wizardlybump17.wlib.command.sender.CommandSender;
-import lombok.NonNull;
-
-import java.util.List;
-
-public class DoubleReader extends ArgsReader {
-
- public static final List SUGGESTIONS = List.of("1", "1.5", "10", "10.5");
- public static final @NonNull List> TYPES = List.of(double.class, Double.class);
-
- @Override
- public Class getType() {
- return double.class;
- }
-
- @Override
- public @NonNull List> getTypes() {
- return TYPES;
- }
-
- @Override
- public Double read(String string) throws ArgsReaderException {
- try {
- return Double.parseDouble(string);
- } catch (NumberFormatException e) {
- return null;
- }
- }
-
- @Override
- public @NonNull List<@NonNull String> autoComplete(@NonNull CommandSender> sender, @NonNull String current) {
- return SUGGESTIONS;
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/FloatArrayReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/FloatArrayReader.java
deleted file mode 100644
index bdb28e86..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/FloatArrayReader.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-public class FloatArrayReader extends ArgsReader {
-
- @Override
- public Class getType() {
- return float[].class;
- }
-
- @Override
- public float[] read(String string) throws ArgsReaderException {
- try {
- final String[] strings = string.split(" ");
-
- float[] result = new float[strings.length];
- for (int i = 0; i < result.length; i++)
- result[i] = Float.parseFloat(strings[i]);
- return result;
- } catch (NumberFormatException e) {
- throw new ArgsReaderException("expected a float array in string form but got " + string);
- }
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/FloatReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/FloatReader.java
deleted file mode 100644
index f90a346a..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/FloatReader.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-import com.wizardlybump17.wlib.command.sender.CommandSender;
-import lombok.NonNull;
-
-import java.util.List;
-
-public class FloatReader extends ArgsReader {
-
- public static final List SUGGESTIONS = List.of("1", "1.5", "10", "10.5");
- public static final @NonNull List> TYPES = List.of(float.class, Float.class);
-
- @Override
- public Class getType() {
- return float.class;
- }
-
- @Override
- public @NonNull List> getTypes() {
- return TYPES;
- }
-
- @Override
- public Float read(String string) throws ArgsReaderException {
- try {
- return Float.parseFloat(string);
- } catch (NumberFormatException e) {
- return null;
- }
- }
-
- @Override
- public @NonNull List<@NonNull String> autoComplete(@NonNull CommandSender> sender, @NonNull String current) {
- return SUGGESTIONS;
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/IntegerArrayReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/IntegerArrayReader.java
deleted file mode 100644
index 43f4e59e..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/IntegerArrayReader.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-public class IntegerArrayReader extends ArgsReader {
-
- @Override
- public Class getType() {
- return int[].class;
- }
-
- @Override
- public int[] read(String string) throws ArgsReaderException {
- try {
- final String[] strings = string.split(" ");
-
- int[] result = new int[strings.length];
- for (int i = 0; i < result.length; i++)
- result[i] = Integer.parseInt(strings[i]);
- return result;
- } catch (NumberFormatException e) {
- throw new ArgsReaderException("expected a int array in string form but got " + string);
- }
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/IntegerReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/IntegerReader.java
deleted file mode 100644
index 5123f358..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/IntegerReader.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-import com.wizardlybump17.wlib.command.sender.CommandSender;
-import lombok.NonNull;
-
-import java.util.List;
-
-public class IntegerReader extends ArgsReader {
-
- public static final List SUGGESTIONS = List.of("1", "10", "100");
- public static final @NonNull List> TYPES = List.of(int.class, Integer.class);
-
- @Override
- public Class getType() {
- return int.class;
- }
-
- @Override
- public @NonNull List> getTypes() {
- return TYPES;
- }
-
- @Override
- public Integer read(String string) throws ArgsReaderException {
- try {
- return Integer.parseInt(string);
- } catch (NumberFormatException e) {
- return null;
- }
- }
-
- @Override
- public @NonNull List<@NonNull String> autoComplete(@NonNull CommandSender> sender, @NonNull String current) {
- return SUGGESTIONS;
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ShortArrayReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ShortArrayReader.java
deleted file mode 100644
index 62315102..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ShortArrayReader.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-public class ShortArrayReader extends ArgsReader {
-
- @Override
- public Class getType() {
- return short[].class;
- }
-
- @Override
- public short[] read(String string) throws ArgsReaderException {
- try {
- final String[] strings = string.split(" ");
-
- short[] result = new short[strings.length];
- for (int i = 0; i < result.length; i++)
- result[i] = Short.parseShort(strings[i]);
- return result;
- } catch (NumberFormatException e) {
- throw new ArgsReaderException("expected a short array in string form but got " + string);
- }
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ShortReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ShortReader.java
deleted file mode 100644
index 14e84005..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/ShortReader.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-import com.wizardlybump17.wlib.command.sender.CommandSender;
-import lombok.NonNull;
-
-import java.util.List;
-
-public class ShortReader extends ArgsReader {
-
- public static final List SUGGESTIONS = List.of("-32768", "0", "32767");
- public static final @NonNull List> TYPES = List.of(short.class, Short.class);
-
- @Override
- public Class getType() {
- return short.class;
- }
-
- @Override
- public @NonNull List> getTypes() {
- return TYPES;
- }
-
- @Override
- public Short read(String string) throws ArgsReaderException {
- try {
- return Short.parseShort(string);
- } catch (NumberFormatException e) {
- return null;
- }
- }
-
- @Override
- public @NonNull List<@NonNull String> autoComplete(@NonNull CommandSender> sender, @NonNull String current) {
- return SUGGESTIONS;
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/StringReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/StringReader.java
deleted file mode 100644
index 93f2c9c4..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/StringReader.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-import com.wizardlybump17.wlib.command.sender.CommandSender;
-import lombok.NonNull;
-
-import java.util.List;
-
-public class StringReader extends ArgsReader {
-
- public static final List SUGGESTIONS = List.of("dummy", "text");
-
- @Override
- public Class getType() {
- return String.class;
- }
-
- @Override
- public String read(String string) {
- return string;
- }
-
- @Override
- public @NonNull List<@NonNull String> autoComplete(@NonNull CommandSender> sender, @NonNull String current) {
- return SUGGESTIONS;
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/UUIDReader.java b/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/UUIDReader.java
deleted file mode 100644
index d9f4c7db..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/args/reader/UUIDReader.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.wizardlybump17.wlib.command.args.reader;
-
-import com.wizardlybump17.wlib.command.sender.CommandSender;
-import lombok.NonNull;
-
-import java.util.List;
-import java.util.UUID;
-
-public class UUIDReader extends ArgsReader {
-
- public static final List SUGGESTIONS = List.of("00000000-0000-0000-0000-000000000000");
-
- @Override
- public Class getType() {
- return UUID.class;
- }
-
- @Override
- public UUID read(String string) throws ArgsReaderException {
- try {
- return UUID.fromString(string);
- } catch (IllegalArgumentException e) {
- return null;
- }
- }
-
- @Override
- public @NonNull List<@NonNull String> autoComplete(@NonNull CommandSender> sender, @NonNull String current) {
- return SUGGESTIONS;
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/completer/ArgumentCompleter.java b/commands/src/main/java/com/wizardlybump17/wlib/command/completer/ArgumentCompleter.java
deleted file mode 100644
index f0145c0d..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/completer/ArgumentCompleter.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.wizardlybump17.wlib.command.completer;
-
-import com.wizardlybump17.wlib.command.sender.CommandSender;
-import lombok.NonNull;
-
-import java.util.List;
-
-public interface ArgumentCompleter {
-
- @NonNull
- List complete(@NonNull CommandSender> sender, @NonNull String @NonNull [] args);
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/completer/ArgumentCompleterRegistry.java b/commands/src/main/java/com/wizardlybump17/wlib/command/completer/ArgumentCompleterRegistry.java
deleted file mode 100644
index 3758074a..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/completer/ArgumentCompleterRegistry.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.wizardlybump17.wlib.command.completer;
-
-import com.wizardlybump17.wlib.object.Registry;
-
-public class ArgumentCompleterRegistry extends Registry, ArgumentCompleter> {
-
- public static final ArgumentCompleterRegistry INSTANCE = new ArgumentCompleterRegistry();
-
- private ArgumentCompleterRegistry() {
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/context/CommandContext.java b/commands/src/main/java/com/wizardlybump17/wlib/command/context/CommandContext.java
new file mode 100644
index 00000000..82a63e15
--- /dev/null
+++ b/commands/src/main/java/com/wizardlybump17/wlib/command/context/CommandContext.java
@@ -0,0 +1,66 @@
+package com.wizardlybump17.wlib.command.context;
+
+import com.wizardlybump17.wlib.command.Command;
+import com.wizardlybump17.wlib.command.node.CommandNode;
+import com.wizardlybump17.wlib.command.sender.CommandSender;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.Unmodifiable;
+
+import java.util.*;
+
+public record CommandContext(@NotNull Command command, @NotNull CommandSender> sender, @NotNull CommandNodeArguments arguments, int lastInputIndex, @NotNull CommandNode> lastNode) {
+
+ public record CommandNodeArgument(@NotNull CommandNode node, @Nullable String input, @Nullable T data) {
+ }
+
+ public static final class CommandNodeArguments {
+
+ private final @NotNull @Unmodifiable Map> arguments;
+
+ public CommandNodeArguments(@NotNull List> arguments) {
+ Map> argumentsMap = new LinkedHashMap<>();
+ for (CommandNodeArgument> argument : arguments)
+ argumentsMap.put(argument.node().getName(), argument);
+ this.arguments = Collections.unmodifiableMap(argumentsMap);
+ }
+
+ public boolean hasArgument(@NotNull String key) {
+ return arguments.containsKey(key);
+ }
+
+ @SuppressWarnings("unchecked")
+ public @NotNull Optional> getArgument(@NotNull String key) {
+ return Optional.ofNullable((CommandNodeArgument) arguments.get(key));
+ }
+
+ @SuppressWarnings("unchecked")
+ public @NotNull Optional getArgumentData(@NotNull String key) {
+ return (Optional) getArgument(key).map(CommandNodeArgument::data);
+ }
+
+ public @NotNull @Unmodifiable Map> getArguments() {
+ return arguments;
+ }
+
+ @Override
+ public String toString() {
+ return "CommandNodeArguments{" +
+ "arguments=" + arguments +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || getClass() != o.getClass())
+ return false;
+ CommandNodeArguments arguments1 = (CommandNodeArguments) o;
+ return Objects.equals(arguments, arguments1.arguments);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(arguments);
+ }
+ }
+}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/data/AnnotationCommandData.java b/commands/src/main/java/com/wizardlybump17/wlib/command/data/AnnotationCommandData.java
deleted file mode 100644
index e45d26f0..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/data/AnnotationCommandData.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package com.wizardlybump17.wlib.command.data;
-
-import com.wizardlybump17.wlib.command.annotation.Command;
-import com.wizardlybump17.wlib.util.ReflectionUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.lang.reflect.Field;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-
-public class AnnotationCommandData extends CommandData {
-
- private final @NotNull Command annotation;
- private final @NotNull Object object;
- private final @NotNull Map fieldCache = new HashMap<>();
-
- public AnnotationCommandData(@NotNull Command annotation, @NotNull Object object) {
- this.annotation = annotation;
- this.object = object;
- }
-
- @Override
- public @NotNull String getExecution() {
- return annotation.execution();
- }
-
- @Override
- public @Nullable String getPermission() {
- String permission = annotation.permission();
- return permission.isBlank() ? super.getPermission() : permission;
- }
-
- @Override
- public @Nullable String getPermissionMessage() {
- return getMessage(annotation.permissionMessage(), annotation.permissionMessageIsField(), super.getPermissionMessage());
- }
-
- @Override
- public int getPriority() {
- int priority = annotation.priority();
- return priority == -1 ? super.getPriority() : priority;
- }
-
- @Override
- public @Nullable String getDescription() {
- String description = annotation.description();
- return description.isBlank() ? super.getDescription() : description;
- }
-
- @Override
- public @Nullable String getInvalidSenderMessage() {
- return getMessage(annotation.invalidSenderMessage(), annotation.invalidSenderMessageIsField(), super.getInvalidSenderMessage());
- }
-
- protected @Nullable String getMessage(@NotNull String message, boolean isField, @Nullable String defaultMessage) {
- if (isField) {
- return ReflectionUtil.getFieldValue(
- fieldCache.computeIfAbsent(
- message,
- $ -> ReflectionUtil.getField(message, object.getClass())
- ),
- object
- );
- }
- return message.isBlank() ? defaultMessage : message;
- }
-
- public @NotNull Command getAnnotation() {
- return annotation;
- }
-
- @Override
- public @NotNull Class> getSenderType() {
- return annotation.senderType();
- }
-
- @Override
- public boolean equals(Object object1) {
- if (object1 == null || getClass() != object1.getClass())
- return false;
- AnnotationCommandData that = (AnnotationCommandData) object1;
- return Objects.equals(annotation, that.annotation) && Objects.equals(object, that.object) && Objects.equals(fieldCache, that.fieldCache);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(annotation, object, fieldCache);
- }
-
- @Override
- public String toString() {
- return "AnnotationCommandData{" +
- "annotation=" + annotation +
- ", object=" + object +
- ", fieldCache=" + fieldCache +
- '}';
- }
-}
diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/data/CommandData.java b/commands/src/main/java/com/wizardlybump17/wlib/command/data/CommandData.java
deleted file mode 100644
index 9dd74ef5..00000000
--- a/commands/src/main/java/com/wizardlybump17/wlib/command/data/CommandData.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package com.wizardlybump17.wlib.command.data;
-
-import com.wizardlybump17.wlib.command.sender.CommandSender;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public abstract class CommandData {
-
- /**
- *
How the sender must type the command in order for it to be triggered.
- * Example:
command hello world
- * In the example above, the sender must type /command hello world, so it can be triggered.
- * To add parameters that depends on the sender input, just put the parameter between <>.
- *
- * Example:
command <hello> world
- *
The type of each parameter is defined in the method that have this annotation.
- * An example for the command above:
- *
- * @Command(execution = "command <hello> world")
- * public void commandHelloWorld(GenericSender sender, String hello) {
- * System.out.println(sender.getName() + " executed the hello world command with the argument " + hello);
- * }
- *
- *
- * @return how the command must be sent to be triggered
- * @see com.wizardlybump17.wlib.command.args.reader.ArgsReader
- */
- public abstract @NotNull String getExecution();
-
- /**
- * @return which permission the sender must have to trigger this command
- */
- public @Nullable String getPermission() {
- return null;
- }
-
- /**
- *
Used when the {@link CommandSender} does not have the required {@link #getPermission()}.
- * @return the message to be sent when the {@link CommandSender} does not have the required {@link #getPermission()}
- */
- public @Nullable String getPermissionMessage() {
- return null;
- }
-
- /**
- * @return the priority of this command
- */
- public int getPriority() {
- return getExecution().split(" ").length;
- }
-
- /**
- * @return the description of this command
- */
- public @Nullable String getDescription() {
- return null;
- }
-
- /**
- *
Used when the {@link CommandSender} is not valid for this command.