New command interface! Everything is broken!

Discussion in 'Plugin Development' started by Dinnerbone, Feb 27, 2011.

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

    Dinnerbone Bukkit Team Member

    Ok, the last part isn't true. But it got your attention.

    Commands are ugly creatures. With any given plugin, you either had an amazingly large onCommand or a custom coded command processing system to process the output of the built in command processing system. It just got crazy.

    Fortunately, I've just finished coding a simple method which should eliminate the need for either of the above.

    You can now directly access Command objects which have been preregistered for your plugin. They each have a CommandExecutor, which defaults to your plugin but you have the option to override it with a custom CommandExecutor you have created.

    Short example:
    Code:
        public void onEnable() {
            getCommand("marco").setExecutor(new CommandExecutor() {
                public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
                    sender.sendMessage("Polo");
                    return true;
                }
            });
        }
    
    plugin.yml (open)

    commands:
    marco:
    description: The popular swimming game!
    usage: /<command>


    Enjoy, and let me know any questions or comments you have :) Coming up soon, dynamic command registration!
     
  2. Offline

    Incendia

    Oh god oh god we're all gonna d-

    Oh, very nice
     
  3. Offline

    Dinnerbone Bukkit Team Member

    Updated with JavaPlugin.getCommand instead of getServer.getPluginCommand. JavaPlugin.getCommand is guaranteed to return a command which belongs to the given plugin, whereas the other is not (if there's two plugins which give /warp, the second to load would overwrite the firsts command - no longer happens with JavaPlugin.getCommand)
     
  4. Offline

    Gregory

    Every second when i run my server it says, "[SEVERE] chunk fetched was not chunk requested"
    its so annoying, please help.....
     
  5. Offline

    Dinnerbone Bukkit Team Member

  6. Offline

    ursa_arcadius

    I don't even understand
    Where is the long example? [​IMG]
     
  7. Offline

    Dinnerbone Bukkit Team Member

  8. Offline

    Plague

    aliases: field is not even present in the example, had to guess how it's done ;)
     
  9. Offline

    Amagineer

    This makes command handling so much better than nasty if trees!
    *hugs DinnerBone*
     
  10. Offline

    Dutchy

    If I understand this correctly, for each command you register in the yml, the default (that is, no need to do it manually) is this?
    Code:
            getCommand("marco").setExecutor(this);
     
  11. Offline

    Dinnerbone Bukkit Team Member

    Essentially yes. That means your plugins onCommand method handles the command.
     
  12. Offline

    DjDCH

    Dinnerbone, please, answer this question:
    I've lose the past 30 minutes to search, guess and try to figure how I'm supposedly fill this setting to put more than one aliases.
     
  13. Offline

    Dinnerbone Bukkit Team Member

    I didn't add aliases because they weren't relevant to the example. Command aliases are just a list, so whatever syntax on yml you prefer will work.
    Code:
    aliases: [marcopolo, echo, testalias]
    aliases:
     - marcopolo
     - echo
     - testalias
     
  14. Offline

    Plague

    You really should put this somewhere because I see it as the et feature of onCommand yet. Users can edit those by themselves and go around plugin conflicts and such...
     
  15. Offline

    Colecf

    Wait, how is this different from the previous system? True, it gets rid of pm.registerevent(), but there's still a huge onCommand() meathod. Is it only different because it gives you the command, player, and arguments straight up?

    I have some other questions too.
    1. Can you be more specific for the onCommand() variables? I assume command is what comes immatley after the / and args is everything after seperated by spaces, but I'm not sure. I also don't know what label is.
    2. If I'm not going to make a seperate class file for my executer, does my onCommand() have to be inside onEnable()?
     
  16. Offline

    Dutchy

    What does this do to builtin commands, such as /say ?
    If I wanted to monitor a call to /say, but still have the command execute normally, how would I do that? Is this possible?

    edit: relevant for my ServerIRC plugin, it relays server stuff to IRC, and this is a planned feature.
     
  17. Offline

    clash

    It is different because you can split up command handling code to separate classes, if desired. You can have everything done in the onCommand method as before. But this change allows commands with a lot of code and/or support methods to be split into separate classes (and source files) -- which I like.

    Also, the "label" parameter is what the player entered. It might be one of the aliases, whereas command.getName() is the name of the command registered in the plugin.yml. I generally ignore the label parameter.

    And no, if you're not making a separate class for your command handlers, you don't even need the CommandExecutor. Just continue to use the onCommand method as before. His example uses an anonymous class to illustrate how it could work. Only the simplest of commands would be implemented that way, IMO.
     
  18. Offline

    Mattie

    Just want to say-- can't wait to see how you guys make this happen. It's pretty key for a number of reasons (especially for dynamic languages). I've been fighting with how to handle this since Bukkit started. With the death of the original command events, though, it's really a tough situation to try to fake it.

    -Mattie
     
  19. Offline

    xZise

    So actually this change will break nothing and only add a new amazing feature? Nice work. Okay at the moment I have only one command, but for some plugins like Essentials this should be perfect.

    Fabian
     
  20. Offline

    nickguletskii

    Err, does that mean that the old method is removed? If not, is it deprecated? If yes, how much time do we have to upgrade?

    EDIT: Is @returns still a TODO?
     
  21. Offline

    Infernus

    It did, but you got me frightened though [​IMG]
     
  22. Offline

    ceulemans

    I'm getting a weird bug,
    Code:
    getCommand("armor").setExecutor(new InstantArmorPListener(this));
    
    it gives under the message my plugins sends the messsage:
    /armor

    EDIT: I failed with the plugin.yml :oops:
    -ceulemans
     
  23. Offline

    Hybris95

    I'm coding a chat plugin that uses commands like :
    "/1 Im speaking"
    "/2 Im speaking elsewhere"
    And these numbers are dynamically generated for each player, so should I just register each commands when they are available (that should become really complicated for nothing) or use the "PLAYER_COMMAND_PREPROCESS" event for these ?
     
  24. Offline

    crohead13

    This is a great way to structure the code. Thanks
     
  25. Offline

    GDorn

    getCommand('foo') is always returning null, even if 'foo' is in plugin.yml. Is there a more complete tutorial on this?
     
  26. Offline

    1337

    would trying to get a command that is not in the .yml return a null exception? because that is the error i am getting
     
  27. Offline

    Dinnerbone Bukkit Team Member

  28. Offline

    1337

    ok so my yml is this :
    Code:
    name: Snowball fight
    main: plugins.x1337x.bukkit.Snowballfight.Snowball
    version: 0.1
    author: (1337)
    description: Snowball fight!!!!
    commands :
    
    s :
        description: Shows the snowball commands
        usage: /<command>
    
    and im calling the s command with this :
    Code:
     public void onEnable() {
              getCommand("s").setExecutor(new Snowballcommand(this));
    }
    and the error :
    Code:
    16:43:04 [SEVERE] null loading Snowball fight v0.1 (Is it up to date?)
    java.lang.NullPointerException
            at plugins.x1337x.bukkit.Snowballfight.Snowball.onEnable(Snowball.java:4
    5)
            at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:118)
            at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader
    .java:414)
            at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManage
    r.java:187)
            at org.bukkit.craftbukkit.CraftServer.loadPlugin(CraftServer.java:83)
            at org.bukkit.craftbukkit.CraftServer.loadPlugins(CraftServer.java:61)
            at net.minecraft.server.MinecraftServer.e(MinecraftServer.java:204)
            at net.minecraft.server.MinecraftServer.a(MinecraftServer.java:191)
            at net.minecraft.server.MinecraftServer.d(MinecraftServer.java:131)
            at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:246)
            at net.minecraft.server.ThreadServerApplication.run(SourceFile:366)
    16:43:04 [INFO] Done (0.246s)! For help, type "help" or "?"
    >
     
  29. Offline

    Dinnerbone Bukkit Team Member

    Your indentation is wrong.

    Code:
    name: Snowball fight
    main: plugins.x1337x.bukkit.Snowballfight.Snowball
    version: 0.1
    author: (1337)
    description: Snowball fight!!!!
    commands:
      s:
         description: Shows the snowball commands
         usage: /<command>
    
     
  30. Offline

    1337

    thanks dinnerbone that fixed it :) thanks for the quick reply
     
Thread Status:
Not open for further replies.

Share This Page