From beda43b7d67e29a73aa89d7fdeedd571e70d17ec Mon Sep 17 00:00:00 2001 From: Mazen Date: Thu, 18 May 2023 11:29:12 +0300 Subject: [PATCH] v1.0.7 is ready --- bungee/build.gradle | 2 +- common/build.gradle | 3 +- .../annotations/AnnotationParser.java | 65 ++++++++++++++----- .../annotations/base/CommandsGroup.java | 14 ++++ .../mqzn/commands/test/TestBootstrap.java | 50 ++------------ .../annotations/TestAnnotatedCommand.java | 36 ++++++++++ jcord/build.gradle | 2 +- spigot/build.gradle | 4 +- velocity/build.gradle | 2 +- 9 files changed, 109 insertions(+), 69 deletions(-) create mode 100644 common/src/main/java/io/github/mqzn/commands/annotations/base/CommandsGroup.java diff --git a/bungee/build.gradle b/bungee/build.gradle index ca0c2a5..5faf08c 100644 --- a/bungee/build.gradle +++ b/bungee/build.gradle @@ -6,7 +6,7 @@ plugins { } group 'io.github.mqzn' -version '1.0.6' +version '1.0.7' repositories { mavenCentral() diff --git a/common/build.gradle b/common/build.gradle index 4e6a50c..a010e19 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -22,7 +22,6 @@ version '1.0.6' repositories { mavenCentral() - maven { url 'https://jitpack.io' } } dependencies { @@ -33,11 +32,11 @@ dependencies { testImplementation 'org.jetbrains:annotations:23.0.0' testImplementation "net.kyori:adventure-api:4.13.1" + compileOnly 'org.jetbrains:annotations:24.0.1' compileOnly "net.kyori:adventure-api:4.13.1" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - compileOnly 'com.github.Revxrsal:asm-invoke-util:1.0' } java { diff --git a/common/src/main/java/io/github/mqzn/commands/annotations/AnnotationParser.java b/common/src/main/java/io/github/mqzn/commands/annotations/AnnotationParser.java index 6ae65ac..cc0fc6e 100644 --- a/common/src/main/java/io/github/mqzn/commands/annotations/AnnotationParser.java +++ b/common/src/main/java/io/github/mqzn/commands/annotations/AnnotationParser.java @@ -20,9 +20,6 @@ import io.github.mqzn.commands.utilities.Pair; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import revxrsal.asm.BoundMethodCaller; -import revxrsal.asm.MethodCaller; - import java.lang.annotation.Annotation; import java.lang.reflect.*; import java.util.Arrays; @@ -31,7 +28,6 @@ public final class AnnotationParser { - @NotNull public final static String SUB_COMMAND_EXECUTE_METHOD = "execute"; @@ -58,7 +54,39 @@ public AnnotationParser(@NotNull CommandManager manager) { @SuppressWarnings("unchecked") public , C, CO> void parse(CO annotatedCommand) { - if (!checkAnnotation(annotatedCommand)) return; + //load nested classes + if(annotatedCommand.getClass().isAnnotationPresent(CommandsGroup.class)) { + for (Class innerClass : annotatedCommand.getClass().getDeclaredClasses()) { + boolean isStatic = Modifier.isStatic(innerClass.getModifiers()); + if(!isStatic) { + throw new IllegalStateException( + String.format("Found a member class `%s` which is NOT static", + innerClass.getName()) + ); + } + try { + Constructor constructor = innerClass.getConstructor(); + if (!constructor.canAccess(null)) { + constructor.setAccessible(true); + } + var innerClassObject = constructor.newInstance(); + parse(innerClassObject); + } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | + InvocationTargetException e) { + throw new RuntimeException(e); + } + + } + } + + + if (!checkAnnotation(annotatedCommand)) { + throw new IllegalStateException( + String.format("Failed to load command class `%s`, the class is NOT annotated with `@Command`", + annotatedCommand.getClass().getName()) + ); + } + Command cmdAnnotation = annotatedCommand.getClass().getAnnotation(Command.class); assert cmdAnnotation != null; @@ -105,10 +133,9 @@ public , C, CO> void parse(CO annotatedCommand) { if (method.getParameters().length == 1 && method.isAnnotationPresent(Default.class)) { //default Execution - builder.defaultExecutor((sender, context) -> { - BoundMethodCaller caller = MethodCaller.wrap(method).bindTo(annotatedCommand); - caller.call(sender); - }); + builder + .defaultExecutor( + (sender, context) -> invokeMethod(annotatedCommand,method,sender)); } continue; @@ -138,8 +165,7 @@ public , C, CO> void parse(CO annotatedCommand) { .flags(flags) .execute((sender, context) -> { Object[] valuesToUse = readValues(method, sender, context); - BoundMethodCaller caller = MethodCaller.wrap(method).bindTo(annotatedCommand); - caller.call(valuesToUse); + invokeMethod(annotatedCommand, method, valuesToUse); }); builder.syntax(syntaxBuilder.build()); @@ -232,10 +258,9 @@ private SubCommandBuilder loadSubCommandBuilder(Command cmd, "has some redundant parameters although it needs only 1 parameter for the command sender", defaultExecutionMethod.getName())); } - subBuilder = subBuilder.defaultExecution((sender, context) -> { - BoundMethodCaller caller = MethodCaller.wrap(defaultExecutionMethod).bindTo(subCommandInstance); - caller.call(sender); - }); + subBuilder = subBuilder + .defaultExecution( + (sender, context) -> invokeMethod(subCommandInstance, defaultExecutionMethod, sender)); } Method executeMethod = Arrays.stream(subClass.getDeclaredMethods()) @@ -270,8 +295,7 @@ private SubCommandBuilder loadSubCommandBuilder(Command cmd, subBuilder = subBuilder.execute((sender, context) -> { Object[] valuesToUse = readValues(executeMethod, sender, context); - BoundMethodCaller caller = MethodCaller.wrap(executeMethod).bindTo(subCommandInstance); - caller.call(valuesToUse); + invokeMethod(subCommandInstance,executeMethod, valuesToUse); }); } @@ -788,6 +812,13 @@ private String annotationNotPresent(Class subClass, Class void invokeMethod(T instance, Method method, Object... objects) { + try { + method.invoke(instance,objects); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } private record ResolvedSubCommandMethod(Argument[] arguments, Argument[] actualArguments, diff --git a/common/src/main/java/io/github/mqzn/commands/annotations/base/CommandsGroup.java b/common/src/main/java/io/github/mqzn/commands/annotations/base/CommandsGroup.java new file mode 100644 index 0000000..5f3d7c7 --- /dev/null +++ b/common/src/main/java/io/github/mqzn/commands/annotations/base/CommandsGroup.java @@ -0,0 +1,14 @@ +package io.github.mqzn.commands.annotations.base; + +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.TYPE) +public @interface CommandsGroup { + + + +} diff --git a/common/src/test/java/io/github/mqzn/commands/test/TestBootstrap.java b/common/src/test/java/io/github/mqzn/commands/test/TestBootstrap.java index 55ed723..1214e8f 100644 --- a/common/src/test/java/io/github/mqzn/commands/test/TestBootstrap.java +++ b/common/src/test/java/io/github/mqzn/commands/test/TestBootstrap.java @@ -3,10 +3,9 @@ import io.github.mqzn.commands.annotations.AnnotationParser; import io.github.mqzn.commands.test.annotations.TestAnnotatedCommand; import org.jetbrains.annotations.TestOnly; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import java.util.Objects; - @TestOnly public final class TestBootstrap { @@ -23,53 +22,16 @@ public TestBootstrap() { @Test public void firstTest() { - - - /*var sub1 = SubCommandBuilder.genericBuilder(ClientSender.class,"test","sub1") - .argument(Argument.word("username")) - .children("sub2") - .execute((sender, context)-> { - System.out.println("Executing context for sub1 !"); - }) - .defaultExecution((sender, context)-> { - System.out.println("Default sub1 execution"); - }) - .build(); - - - var sub2 = SubCommandBuilder.genericBuilder(ClientSender.class,"test","sub2") - .argument(Argument.integer("num")) - .parent("sub1") - .children("sub3") - .execute((sender, context)-> { - System.out.println("Executing context for sub2 !"); - }) - .build(); - - var sub3 = SubCommandBuilder.genericBuilder(ClientSender.class,"test","sub3") - .argument(Argument.word("address")) - .parent("sub2") - .execute((sender, context)-> { - System.out.println("Executing context for sub3 !"); - }) - .build(); - - var cmd = Command.builder(commandManager, "test") - .syntax(sub1, sub2, sub3) - .build(); - - commandManager.registerCommand(cmd);*/ + parser.parse(new TestAnnotatedCommand()); - // /test sub1 String[] args = new String[]{ - "sub1", - "first", - "2", - "third" }; - commandManager.executeCommand(Objects.requireNonNull(commandManager.getCommand("testa")), sender, args); + var cmd = commandManager.getCommand("testinner2"); + Assertions.assertNotNull(cmd); + + commandManager.executeCommand(cmd, sender, args); } diff --git a/common/src/test/java/io/github/mqzn/commands/test/annotations/TestAnnotatedCommand.java b/common/src/test/java/io/github/mqzn/commands/test/annotations/TestAnnotatedCommand.java index dfa5af6..7d7be77 100644 --- a/common/src/test/java/io/github/mqzn/commands/test/annotations/TestAnnotatedCommand.java +++ b/common/src/test/java/io/github/mqzn/commands/test/annotations/TestAnnotatedCommand.java @@ -1,8 +1,12 @@ package io.github.mqzn.commands.test.annotations; import io.github.mqzn.commands.annotations.base.Command; +import io.github.mqzn.commands.annotations.base.CommandsGroup; +import io.github.mqzn.commands.annotations.base.Default; import io.github.mqzn.commands.annotations.subcommands.SubCommand; +import io.github.mqzn.commands.test.ClientSender; +@CommandsGroup @Command(name = "testa") @SubCommand(value = TestSub1.class) //@SubCommand(value = TestSub2.class) @@ -11,5 +15,37 @@ //@SubCommand(value = TestRoot2.class) public class TestAnnotatedCommand { + + @CommandsGroup + @Command(name = "testinner1") + public static class TestInnerCommand { + + @Default + public void exec(ClientSender sender) { + System.out.println("Executing default for " + this.getClass().getSimpleName()); + } + + @CommandsGroup + @Command(name = "testinner2") + public static class TestInner2Command { + + @Default + public void exec(ClientSender sender) { + System.out.println("Executing default for " + this.getClass().getSimpleName()); + } + + @Command(name = "testinner3") + public static class TestInner3Command { + + @Default + public void exec(ClientSender sender) { + System.out.println("Executing default for " + this.getClass().getSimpleName()); + } + } + + } + + } + } diff --git a/jcord/build.gradle b/jcord/build.gradle index 7e3b4fb..2029bde 100644 --- a/jcord/build.gradle +++ b/jcord/build.gradle @@ -6,7 +6,7 @@ plugins { } group 'io.github.mqzn' -version '1.0.6' +version '1.0.7' repositories { mavenCentral() diff --git a/spigot/build.gradle b/spigot/build.gradle index 879cbab..e2520d2 100644 --- a/spigot/build.gradle +++ b/spigot/build.gradle @@ -6,7 +6,7 @@ plugins { } group 'io.github.mqzn' -version '1.0.6' +version '1.0.7' repositories { mavenCentral() @@ -27,8 +27,6 @@ dependencies { compileOnly "net.kyori:adventure-api:4.13.1" compileOnly "net.kyori:adventure-platform-bukkit:4.3.0" - - implementation 'com.github.Revxrsal:asm-invoke-util:1.0' } def targetJavaVersion = 17 diff --git a/velocity/build.gradle b/velocity/build.gradle index 0865a3f..aa8cfc1 100644 --- a/velocity/build.gradle +++ b/velocity/build.gradle @@ -6,7 +6,7 @@ plugins { } group 'io.github.mqzn' -version '1.0.6' +version '1.0.7' repositories { mavenCentral()