Resource (ACF - BETA) Annotation Command Framework

Discussion in 'Spigot Plugin Development' started by Aikar, Apr 19, 2017.

  1. ... I think i'll stick with chaining based command builders.

    While this looks quite nifty (especially with minidigger adding brigadier support!) I honestly think that using too much annotations can make the code more difficult to read, maintain and refactor. But everyone got their own preferences I guess?

    I also am of the firm belief that wrapping arguments with a class which can extract double/long/int/byte/short are the way to go for argument handling (alongside a simple way to register "unwrappers" which can be accessed by class references.) I mean something like a WrappedStringArg#getInt signature. Annotations work really well to define defaulting values though - a great idea!
     
  2. Would it be possible to make an initial command? (Don't think I'm using the right words)
    For Example:

    /random - Display a list of uses of the command
     
  3. Just don't define it for no arguments and the help will take care of the rest
     
  4. Alright, thank you.
     
  5. simpleauthority

    Supporter

    i.e.

    Code (Java):
    @CommandAlias("random")
    class RandomCommand extends BaseCommand {
      @Default @CatchUnknown
      void doRandom(CommandSender sender) {
        // they did /random plain or with arguments that we couldn't understand
      }
    }
     
  6. For the @CommandCompletion is it possible to create your own values? so like @players shows all players then like if I wanted to do @<something> it lists stuff on tab
     
  7. MiniDigger

    Supporter

    Yes, you can register command completions in your command handler.
     
  8. Alright, thanks. Do you have any examples?
     
  9. Is there a way to use this in your plugin without having to shadow it? Or is there a way to only shadow this library (I'm using Gradle)

    Code (Text):
    buildscript {
        repositories {
            jcenter()
        }

        dependencies {
            classpath "com.github.jengelman.gradle.plugins:shadow:2.0.2"
        }
    }


    plugins {
        id 'net.ltgt.apt' version '0.10'
    }
    apply plugin: "com.github.johnrengelman.shadow"
    apply plugin: 'java'

    group = pluginGroup
    version = pluginVersion

    sourceCompatibility = 1.8
    targetCompatibility = 1.8


    repositories {
        mavenCentral()
        maven {
            name = 'spigotmc-repo'
            url = 'https://hub.spigotmc.org/nexus/content/groups/public/'
        }
        maven {
            name = 'sonatype'
            url = 'https://oss.sonatype.org/content/groups/public/'
        }
        flatDir {
            dirs './/Spigot'
        }
        maven {
            url "http://repo.extendedclip.com/content/repositories/placeholderapi/"
        }
        maven {
            url = "https://repo.aikar.co/content/groups/aikar/"
        }
        maven {
            url = "https://hub.spigotmc.org/nexus/content/groups/public/"
        }
    }

    compileJava {
        options.compilerArgs += ["-parameters"]
        options.fork = true
        options.forkOptions.executable = 'javac'
    }

    dependencies {
        testCompile group: 'junit', name: 'junit', version: '4.12'
        compileOnly 'org.projectlombok:lombok:1.18.0'
        compile 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT'
        apt "org.projectlombok:lombok:1.18.0"
        compileOnly name: 'Factions'
        compileOnly name: 'worldguard'
        compileOnly name: 'worldedit'
        compileOnly name: 'spigot'
        compileOnly name: 'TacoSpigot'
        compileOnly 'me.clip:placeholderapi:2.9.2'
        compile "co.aikar:acf-core:0.5.0-SNAPSHOT"
        compile "co.aikar:acf-bukkit:0.5.0-SNAPSHOT"
    }

    shadowJar {
        relocate 'co.aikar.commands', 'net.splodgebox.cosmic.acf'
    }

    import org.apache.tools.ant.filters.ReplaceTokens

    processResources {
        from(sourceSets.main.resources.srcDirs) {
            filter ReplaceTokens, tokens: [version: version]
        }
    }

    build.dependsOn shadowJar
    Issue is I'm using other plugins so when i shadow this library it shadows all of them creating a jar with the size of 4.5mb
     
  10. electronicboy

    IRC Staff

    You're shading in spigot API which is ~4.5MB, ACF sits at a meer 267K when shaded
     
  11. How do I avoid shading spigotAPI?
     
  12. electronicboy

    IRC Staff

    use compileOnly instead of compile on libraries you don't want to shade into your jar
     
  13. Okay thanks lemme try that
     
  14. Seeing as you were already helped, I'd also love to point out ways to improve that build while also working as a bump ^^

    For one, shadow 4.0.3 is out, secondly, you already use the plugins block so why do this?
    Look at the first block here: https://imperceptiblethoughts.com/shadow/getting-started/#getting-started
    You could move this to the plugins block with just `id 'java'`
    `sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8`
    JavaVersion has existed for a long time, and it's guaranteed to work in the future, hence why it's also better to use for this
     
    • Friendly Friendly x 1
  15. Ah thank you. I just converted from maven to gradle so i had no clue what i was doing
     
    • Friendly Friendly x 1
  16. [​IMG]
    Does anyone know why people are getting this issue.
     
  17. Is it possible to get something like @Default command with arguments?

    I tried this code:
    upload_2019-1-24_21-19-12.png

    However that won't work because default commands can't have arguments.
    When I change @Default to @CatchUnknown it even runs the default command when I write /skin2 set. I'd like it to show the help for set subcommand tho...

    How would I do that?
     
  18. simpleauthority

    Supporter

    Yes. You make a subclass base command.
    Code (Java):
    @CommandAlias("outer")
    @CommandPermission("some.permission.outer")
    public class OuterCommand extends BaseCommand {
      @Default
      @CatchUnknown
      public void onNoArguments(CommandSender sender, CommandHelp help) {
        help.showHelp(); // help for /outer
      }
     
      @Subcommand("inner")
      @CommandPermission("some.permission.outer.inner")
      public class InnerCommand extends BaseCommand {
        @Default
        @CatchUnknown
        public void onNoArguments(CommandSender sender, CommandHelp help) {
          help.showHelp(); // help for /outer inner
        }

        @Subcommand("manualargs|margs")
        public void onManualArgs(CommandSender sender, String[] args) {
          // here you can use args as a normal array
        }
      }
    }