+ * Of course, {@link SubCommand}s can be added and "stacked". For example, the following command class:
+ *
{@code
+ * @literal @Command(name = "mycommand", aliases = {"alias1"}, description = "My command description")
+ * public class TestCommand {
+ * @literal @Main
+ * private static void mainCommandMethod() {
+ * // do things here
+ * }
+ *
+ * @literal @SubCommand(name = "subcommand", aliases = {"subalias1"}, description = "My subcommand description")
+ * private static class SubCommandClass {
+ * @literal @Main
+ * private static void subCommandMethod() {
+ * // do things here
+ * }
+ *
+ * @literal @SubCommand(name = "subsubcommand", aliases = {"subsubalias1"}, description = "My subsubcommand description")
+ * private static class SubSubCommandClass {
+ * @literal @Main
+ * private static void subSubCommandMethod() {
+ * // do things here
+ * }
+ * }
+ * }
+ * }
+ * }
+ *
+ *
+ * To register commands, either extend {@link CommandHelper} and run {@link CommandHelper#preload()} (which does nothing,
+ * just makes loading look nicer lol), or use {@link CommandManager#registerCommand(Object)}.
+ *
+ *
+ * Note: if you're viewing this in IntelliJ or just see the @literal tag everywhere, please ignore that.
+ *
+ *
+ * @see cc.polyfrost.oneconfig.test.TestCommand
+ * @see Main
+ * @see CommandManager
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+public @interface Command {
+ /**
+ * The name of the command.
+ *
+ * @return The name of the command.
+ */
+ String value();
+
+ /**
+ * The aliases of the command.
+ *
+ * @return The aliases of the command.
+ */
+ String[] aliases() default {};
+
+ /**
+ * The description of the command.
+ *
+ * @return The description of the command.
+ */
+ String description() default "";
+
+ /**
+ * Whether the command generates a help command.
+ */
+ boolean helpCommand() default true;
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Greedy.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Greedy.java
new file mode 100644
index 0000000..31c948d
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Greedy.java
@@ -0,0 +1,20 @@
+package cc.polyfrost.oneconfig.utils.commands.annotations;
+
+import cc.polyfrost.oneconfig.utils.commands.arguments.Arguments;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates that the specific parameter should capture all remaining arguments and itself
+ * Can only be used on the last parameter, and only works with {@link cc.polyfrost.oneconfig.utils.commands.arguments.StringParser} by default.
+ *
+ * @see cc.polyfrost.oneconfig.utils.commands.arguments.StringParser#parse(Arguments)
+ * @see Command
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface Greedy {
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Main.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Main.java
new file mode 100644
index 0000000..3c105c7
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Main.java
@@ -0,0 +1,20 @@
+package cc.polyfrost.oneconfig.utils.commands.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a method as the main method of a command.
+ *
+ * @see Command
+ * @see SubCommand
+ * @see cc.polyfrost.oneconfig.utils.commands.CommandManager
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface Main {
+ String description() default "";
+ int priority() default 1000;
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Name.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Name.java
new file mode 100644
index 0000000..ef178a0
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Name.java
@@ -0,0 +1,22 @@
+package cc.polyfrost.oneconfig.utils.commands.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks the name of a parameter.
+ *
+ * @see Main
+ * @see Command
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface Name {
+ /**
+ * The name of the parameter.
+ * @return The name of the parameter.
+ */
+ String value();
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Optional.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Optional.java
new file mode 100644
index 0000000..4dbe8b5
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Optional.java
@@ -0,0 +1,12 @@
+package cc.polyfrost.oneconfig.utils.commands.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface Optional {
+
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/SubCommand.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/SubCommand.java
new file mode 100644
index 0000000..b1cf035
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/SubCommand.java
@@ -0,0 +1,34 @@
+package cc.polyfrost.oneconfig.utils.commands.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a class as a subcommand. Can be stacked together.
+ *
+ * @see Command
+ * @see cc.polyfrost.oneconfig.utils.commands.CommandManager
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+public @interface SubCommand {
+ /**
+ * The name of the command.
+ * @return The name of the command.
+ */
+ String value();
+
+ /**
+ * The aliases of the command.
+ * @return The aliases of the command.
+ */
+ String[] aliases() default {};
+
+ /**
+ * The description of the command.
+ * @return The description of the command.
+ */
+ String description() default "";
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/ArgumentParser.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/ArgumentParser.java
new file mode 100644
index 0000000..d9d51b0
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/ArgumentParser.java
@@ -0,0 +1,12 @@
+package cc.polyfrost.oneconfig.utils.commands.arguments;
+
+import com.google.common.reflect.TypeToken;
+import org.jetbrains.annotations.Nullable;
+
+@SuppressWarnings("unstable")
+public abstract class ArgumentParser {
+ private final TypeToken type = new TypeToken(getClass()) {};
+ public final Class> typeClass = type.getRawType();
+ @Nullable
+ public abstract T parse(Arguments arguments);
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/Arguments.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/Arguments.java
new file mode 100644
index 0000000..74a0840
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/Arguments.java
@@ -0,0 +1,33 @@
+package cc.polyfrost.oneconfig.utils.commands.arguments;
+
+public class Arguments {
+ private int position = 0;
+ public final String[] args;
+ public final boolean greedy;
+
+ public Arguments(String[] args, boolean greedy) {
+ this.args = args;
+ this.greedy = greedy;
+ }
+
+ public String poll() {
+ ++position;
+ return args[position - 1];
+ }
+
+ public String peek() {
+ if (hasNext()) {
+ return args[position];
+ } else {
+ return null;
+ }
+ }
+
+ public boolean hasNext() {
+ return position < args.length;
+ }
+
+ public int getPosition() {
+ return position;
+ }
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/BooleanParser.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/BooleanParser.java
new file mode 100644
index 0000000..dfdca2d
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/BooleanParser.java
@@ -0,0 +1,11 @@
+package cc.polyfrost.oneconfig.utils.commands.arguments;
+
+import org.jetbrains.annotations.Nullable;
+
+public class BooleanParser extends ArgumentParser {
+
+ @Override
+ public @Nullable Boolean parse(Arguments arguments) {
+ return Boolean.parseBoolean(arguments.poll());
+ }
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/DoubleParser.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/DoubleParser.java
new file mode 100644
index 0000000..8c85849
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/DoubleParser.java
@@ -0,0 +1,10 @@
+package cc.polyfrost.oneconfig.utils.commands.arguments;
+
+import org.jetbrains.annotations.Nullable;
+
+public class DoubleParser extends ArgumentParser {
+ @Override
+ public @Nullable Double parse(Arguments arguments) {
+ return Double.parseDouble(arguments.poll());
+ }
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/FloatParser.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/FloatParser.java
new file mode 100644
index 0000000..7053fcb
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/FloatParser.java
@@ -0,0 +1,11 @@
+package cc.polyfrost.oneconfig.utils.commands.arguments;
+
+import org.jetbrains.annotations.Nullable;
+
+public class FloatParser extends ArgumentParser {
+
+ @Override
+ public @Nullable Float parse(Arguments arguments) {
+ return Float.parseFloat(arguments.poll());
+ }
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/IntegerParser.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/IntegerParser.java
new file mode 100644
index 0000000..6910d4b
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/IntegerParser.java
@@ -0,0 +1,8 @@
+package cc.polyfrost.oneconfig.utils.commands.arguments;
+
+public class IntegerParser extends ArgumentParser {
+ @Override
+ public Integer parse(Arguments arguments) {
+ return Integer.parseInt(arguments.poll());
+ }
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/StringParser.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/StringParser.java
new file mode 100644
index 0000000..6a34722
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/arguments/StringParser.java
@@ -0,0 +1,18 @@
+package cc.polyfrost.oneconfig.utils.commands.arguments;
+
+public class StringParser extends ArgumentParser {
+
+ @Override
+ public String parse(Arguments arguments) {
+ if (arguments.greedy) {
+ StringBuilder builder = new StringBuilder();
+ while (arguments.hasNext()) {
+ String arg = arguments.poll();
+ builder.append(arg).append(" ");
+ }
+ return builder.toString().trim();
+ } else {
+ return arguments.poll();
+ }
+ }
+}
--
cgit