[Lib] Dynamic CommandAPI

Discussion in 'Resources' started by Not2EXceL, Dec 21, 2013.

Thread Status:
Not open for further replies.
  1. Offline


    This is a CommandAPI that I developed so that I can avoid having to statically register any command whether using reflection and a CommandExecutor, or simply putting the commands into my plugin.yml. This is a purely annotation based API. The functionality to statically add commands is there, I just have not implemented any ways that are easy for a user to do so.

    How to use:
    Using this CommandAPI is super simple, and only requires 3 lines to register the commands, and obviously the commands themselves.

    First in either your onEnable() or onLoad() you're going to want to do this:
    2. CommandManager commandManager = new CommandManager(this); //this == plugin instance
    3. commandManager.registerCommands(); //registers commands from anywhere in the plugin jar
    4. commandManager.registerHelp(); //registers a generated helptopic to bukkit
    5. //so the /help PluginName displays our plugin's registered commands

    Example commands to be registered: Here are some test commands to display how commands should be written to allow registration. CommandListener is a required interface for any class you wish commands to be registered from. This is to allow shrinkage of classes searched for commands, and increase registration time.
    2. public class TestCommand implements CommandListener //CommandListener is required
    3. {
    4. /*
    5.   command is the only required field for the annotation
    7.   The base command is not required. If not created, a default one will be generated and will direct to the usage
    8.   upon command use
    9.   */
    10. @CommandHandler(command = "test")
    11. public static void testingCommand(CommandInfo info)
    12. {
    13. info.getSender().sendMessage("Test worked");
    14. }
    16. /*
    17.   Sub commands can go as deep as you wish
    18.   ie. test -> sub1 -> ... -> sub15
    19.   */
    20. @CommandHandler(command = "test.test2.test3", permission = "test.test2", noPermission = "LOL no permissions",
    21. aliases = {"2", "testing"}, usage = "/test test2 test3 <player>",
    22. description = "Testing out all of the CommandHandler's attribute values")
    23. public void testingCommand3(CommandInfo info)
    24. {
    25. info.getSender().sendMessage("Test3 worked");
    26. }
    27. }

    Source Code:
    Finally the source code is on github. Its opensource and GPLv2 license.
    Adding in Maven would have taken much longer if not for xTrollxDudex
    Thanks for those links.

    The repository:
    2. <repository>
    3. <id>CommandAPI</id>
    4. <url>[url]https://github.com/Not2EXceL/CommandAPI_Builds/raw/master</url>[/url]
    5. <snapshots>
    6. <enabled>true</enabled>
    7. <updatePolicy>always</updatePolicy>
    8. </snapshots>
    9. </repository>

    The dependency:
    2. <dependency>
    3. <groupId>com.not2excel.api</groupId>
    4. <artifactId>CommandAPI</artifactId>
    5. <version>LATEST</version>
    6. <type>jar</type>
    7. <scope>compile</scope>
    8. </dependency>

    idk, suggest anything?

    Added Maven support to the project.
    Updated recursion to fix bug with sub commands below sub-2.
    Now properly displays help when displaying usage for sub commands
    Generates empty(default) sub commands if you don't create an annotation for them.
    Initial release.

    Finally: Please leave any comments, suggestions, and/or bugs you may find while using this CommandAPI.
  2. Offline


    I think it would be cool if you set it on Maven :)
  3. Offline


    PunKeel I'll look into maven as I haven't used it before.

    To do; fix a bug with registering commands that don't have a proper parent. And subs deeper than 2.
  4. Offline


    Thanks :)

    PS: TODO to come: and subs not providing a proper sub parent ? :D
  5. Offline


    PunKeel the recursion works for searching for the deepest parent. But I forgot to account for parents that don't exist and generate an empty parent for them so the command works. Eg. /test color set and /test color remove. But the subcommand color doesn't exist. Its something I missed last night when I was running tests.I caught it this morning but I can't fix it till I get off work
  6. Offline


    Wait WHAT. You haven't used maven before? Gosh... For a guy like you, this wasn't what I was expecting :p
    glen3b likes this.
  7. Offline


    xTrollxDudex I use ant for builds mainly. Never used maven since most of my projects are completed solely by me. So I never saw the point in learning it if I could do it with an ide or batch
  8. Offline


  9. Offline


    xTrollxDudex thanks for the links but I'll probably just read off mavens docs. I haven't even looked at them once.
    jimuskin likes this.
  10. Does this do anything that isn't possible using the usual Bukkit API?
    (you know... plugin.yml and things like that)
  11. Does this work with tab?
  12. Offline


    MinecraftShamrock I'm not sure what you mean by that?

    BlockCat And [​IMG]
    it shows up if you push tab, but I may add in a tabcompleter thing later. Right now have to fix two bugs, but being sick is slowing progress down a lot
  13. Registering commands and making tab auto completion, adding permissions and aliases are features that you dont need this API for. Bukkit supports that too.
  14. Offline


    Had an update. Fixed the bug I was talking about previously.

    The whole point of this api, was to avoid manual or static registration of commands to Bukkit's CommandMap, or using plugin.yml. This provides a simple and dynamic way of command and sub command registration. There are 4 other resources that deal with commands that I know of. MondoCommand(which was created solely for sub commands, both statically and dynamically), AbstractCommand(which allowed you to avoid having to put a command into plugin.yml), and Annotated based command lib(which is similar to mine in terms of using only annotations to register commands and sub commands, but different), and Desht's AbstractCommand is one made for when he creates anything but small plugins.

    If all you're going to do is bash on how this can all be done with Bukkit already, please just leave.
  15. Offline


    Not within 24 hours but this isn't a bump lol.

    Updated the repo. Added Maven to the project. Updated the OP to include that info.
  16. Offline


    Not2EXceL hey :)
    Do you use Eclipse IDE? If so please continue reading
    you see, im a bit slow, so I need help importing this into a project.
    can you give me a quick way to do this? Do i download it as zip from githib?

    btw do I have permission to use this in privAte and public bukkut plugins? Thanks
  17. Offline


    Pizza371 You could dl the src from the github, or you could just use Maven to auto add it as a dependency.

    ot: I'll be pushing an update in a bit that fixes a problem that I intentionally put in. (by accident:oops:)
  18. Offline


    Hey Not2EXceL,

    I've been trying to use your Command API but it appears that arguments are not being passed in correctly - the first two arguments are being ignored.

    I notice that you can use the system you mentioned in the original post, but that doesn't look like it allows 'unknown' arguments

    1. @CommandHandler
    2. (
    3. command = "makearena",
    4. permission = "br.makearena",
    5. usage = "/makearena <name>",
    6. aliases = {"createarena", "genarena"},
    7. description = "Start creation of arena",
    8. noPermission = "Permission denied"
    9. )
    10. public static void makeArenaCommand(CommandInfo info)
    11. {
    12. info.getSender().sendMessage(info.getArgs() + "");
    13. //code
    14. }

    Will always return an empty array when typing /makearena test, but if you type /makearena test test test, the arguments contain just a single "test".
  19. Offline


    My bad. I'll find it tonight after work.
  20. Offline


    I looked at the repo and there is a fix in there. I've tested it and it does not work.

    It appears I was mistaken on the number of args you need to enter, though. You just have to enter 2 args for the latter to be passed through.
  21. Offline


    Bart no that was one bug I thought was the issue. I just tested it fast right before work. I don't get home for another 2 hours so I can take a better look. Its with the 3rd arg it only gets sent
  22. Offline


    Hi and thank you for your work.
    I have some problems with your ClassEnumerator and i think it's because i use 'relocation' i my pom.xml's plugin section for maven-shade-plugin.

    I will try to explain and sorry for my bad language.
    This is for example how i relocate shaded package included to not interfer with a lib that another plugin shaded too:

    I take the example of this lombok relocation and now this is the kind of problem encountered with your reflection ClassEnumerator:

    1. [03:25:26 ERROR]: Error occurred while enabling BooTreasure v0.5 (Is it up to date?)
    2. java.lang.NoClassDefFoundError: org/shortrip/boozaa/plugins/lombok/com/sun/tools/javac/tree/TreeScanner
    3. at java.lang.ClassLoader.defineClass1(Native Method) ~[?:1.7.0_45]
    4. at java.lang.ClassLoader.defineClass(ClassLoader.java:800) ~[?:1.7.0_45]
    5. at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[?:1.7.0_45]
    6. at java.net.URLClassLoader.defineClass(URLClassLoader.java:449) ~[?:1.7.0_45]
    7. at java.net.URLClassLoader.access$100(URLClassLoader.java:71) ~[?:1.7.0_45]
    8. at java.net.URLClassLoader$1.run(URLClassLoader.java:361) ~[?:1.7.0_45]
    9. at java.net.URLClassLoader$1.run(URLClassLoader.java:355) ~[?:1.7.0_45]
    10. at java.security.AccessController.doPrivileged(Native Method) ~[?:1.7.0_45]
    11. at java.net.URLClassLoader.findClass(URLClassLoader.java:354) ~[?:1.7.0_45]
    12. at org.bukkit.plugin.java.PluginClassLoader.findClass0(PluginClassLoader.java:80) ~[spigot-1.7.2-R0.3-SNAPSHOT.jar:git-Spigot-1223]
    13. at org.bukkit.plugin.java.JavaPluginLoader.getClassByName0(JavaPluginLoader.java:300) ~[spigot-1.7.2-R0.3-SNAPSHOT.jar:git-Spigot-1223]
    14. at org.bukkit.plugin.java.PluginClassLoader.findClass0(PluginClassLoader.java:76) ~[spigot-1.7.2-R0.3-SNAPSHOT.jar:git-Spigot-1223]
    15. at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:53) ~[spigot-1.7.2-R0.3-SNAPSHOT.jar:git-Spigot-1223]
    16. at java.lang.ClassLoader.loadClass(ClassLoader.java:425) ~[?:1.7.0_45]
    17. at java.lang.ClassLoader.loadClass(ClassLoader.java:412) ~[?:1.7.0_45]
    18. at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ~[?:1.7.0_45]
    19. at com.not2excel.api.reflection.ClassEnumerator.getClassesFromJar(ClassEnumerator.java:184) ~[?:?]
    20. at com.not2excel.api.reflection.ClassEnumerator.getClassesFromLocation(ClassEnumerator.java:100) ~[?:?]
    21. at com.not2excel.api.reflection.ClassEnumerator.getClassesFromThisJar(ClassEnumerator.java:156) ~[?:?]
    22. at com.not2excel.api.command.CommandManager.registerCommands(CommandManager.java:72) ~[?:?]
    23. at org.shortrip.boozaa.plugins.bootreasure.BooTreasure.onEnable(BooTreasure.java:141) ~[?:?]
    24. at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:218) ~[spigot-1.7.2-R0.3-SNAPSHOT.jar:git-Spigot-1223]
    25. at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:457) [spigot-1.7.2-R0.3-SNAPSHOT.jar:git-Spigot-1223]
    26. at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:385) [spigot-1.7.2-R0.3-SNAPSHOT.jar:git-Spigot-1223]
    27. at org.bukkit.craftbukkit.v1_7_R1.CraftServer.loadPlugin(CraftServer.java:302) [spigot-1.7.2-R0.3-SNAPSHOT.jar:git-Spigot-1223]
    28. at org.bukkit.craftbukkit.v1_7_R1.CraftServer.enablePlugins(CraftServer.java:284) [spigot-1.7.2-R0.3-SNAPSHOT.jar:git-Spigot-1223]
    29. at net.minecraft.server.v1_7_R1.MinecraftServer.m(MinecraftServer.java:348) [spigot-1.7.2-R0.3-SNAPSHOT.jar:git-Spigot-1223]
    30. at net.minecraft.server.v1_7_R1.MinecraftServer.g(MinecraftServer.java:325) [spigot-1.7.2-R0.3-SNAPSHOT.jar:git-Spigot-1223]
    31. at net.minecraft.server.v1_7_R1.MinecraftServer.a(MinecraftServer.java:281) [spigot-1.7.2-R0.3-SNAPSHOT.jar:git-Spigot-1223]
    32. at net.minecraft.server.v1_7_R1.DedicatedServer.init(DedicatedServer.java:186) [spigot-1.7.2-R0.3-SNAPSHOT.jar:git-Spigot-1223]
    33. at net.minecraft.server.v1_7_R1.MinecraftServer.run(MinecraftServer.java:430) [spigot-1.7.2-R0.3-SNAPSHOT.jar:git-Spigot-1223]
    34. at net.minecraft.server.v1_7_R1.ThreadServerApplication.run(SourceFile:617) [spigot-1.7.2-R0.3-SNAPSHOT.jar:git-Spigot-1223]
    35. Caused by: java.lang.ClassNotFoundException: org.shortrip.boozaa.plugins.lombok.com.sun.tools.javac.tree.TreeScanner

    Sorry if this appear because of my own fault, i try to understand what happens and thought that perhaps you'll can help me.

    The error is a ClassNotFoundException because this Class is not in package of course. I search on my side.

    solved by not shaded lombok.jar, probably a bad idea to do that but it was just to see if others shaded lib don't throw errors. I shade also Cron4J library without errors on CommandAPI side Commands aren't working for the moment but i search why.
  23. Offline


    boozaa commands work for me other than the args bug that Bart mentioned. I'll take a look at your post and situation further after I fix the args bug
  24. Offline


    Any progress? I'm looking forward to using this! :)
  25. Offline


    Yeah I'm working on it atm, just busy with New Years family stuff.
  26. Offline


  27. Offline


    Double post but bump? Any updates?
  28. Offline


    I've been busy with a paid plugin project as well. But I found and fixed the bug. I'll be pushing an update to fix it later tonight.
    I facepalmed and mis-did a for loop when sorting the arguments for quotes, currently its disabled till I write a better method.
  29. Offline


    Awesome. Mind pushing it? EDIT: Whoops, didn't see your message about pushing it later.
  30. Offline


    Bart I pushed an update, I dont think I missed or removed anything by accident, but I'll double check the repo in a sec

    And fixed the quotes method
Thread Status:
Not open for further replies.

Share This Page