Organization and Optimization - CommandExecutors

Discussion in 'Plugin Development' started by travja, Aug 2, 2014.

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

    travja

    I've been looking to organize and optimize my plugins, part of this would include having a core command that either redirects or uses methods to slim down the space needed in each class and make things a little easier to look at. Basically, I was wondering if it would be possible to use the getCommand(String)#setExecutor to redirect commands to another class or if I'd have to just use an external method in another class. Either way, or if you have better ones, I'd be glad to hear your input. Thanks guys :D
     
  2. Offline

    Pizza371

    travja
    I'm not sure what you mean, but ofcourse you can use implement CommandExecutor in differenty classes, register the same way.
    Annotation based commands handlers are really good for static commands.
     
  3. Offline

    Dragonphase

    travja

    CommandExecutors are a great way of managing your plugin's commands, especially if you have more than one command. You could create a CommandExecutor like so:

    Code:java
    1. import org.apache.commons.lang.StringUtils;
    2. import org.bukkit.Bukkit;
    3. import org.bukkit.command.Command;
    4. import org.bukkit.command.CommandExecutor;
    5. import org.bukkit.command.CommandSender;
    6. import org.bukkit.entity.Player;
    7.  
    8. import org.bukkit.plugin.Plugin;
    9.  
    10. public class TellCommandExecutor implements CommandExecutor{
    11. private Plugin plugin;
    12.  
    13. public TellCommandExecutor(Plugin instance){
    14. plugin = instance;
    15. }
    16.  
    17. @Override
    18. public boolean onCommand(CommandSender sender, Command cmd, String command, String[] args) {
    19.  
    20. if (args.length < 1){
    21. handleBaseCommand(sender);
    22. return true;
    23. }
    24.  
    25. handleTell(sender, args);
    26.  
    27. return false;
    28. }
    29.  
    30. private void handleBaseCommand(CommandSender sender){
    31. sender.sendMessage("You issued the command without any arguments.");
    32. }
    33.  
    34. private void handleTell(CommandSender sender, String[] args){
    35. if (args.length < 1){
    36. sender.sendMessage("You have to write a message to send to the player.");
    37. return;
    38. }
    39.  
    40. handleTell(sender, Bukkit.getPlayer(args[0]), StringUtils.join(args, " "));
    41. }
    42.  
    43. private void handleTell(CommandSender sender, Player player, String message){
    44. sender.sendMessage(sender instanceof Player ? ((Player)sender).getName() : "Console" + ": " + message);
    45. player.sendMessage(sender instanceof Player ? ((Player)sender).getName() : "Console" + ": " + message);
    46. }
    47. }


    This is only a basic example of how I would use a CommandExecutor for a "/tell" command, which will whisper private messages to people. Don't forget to set the command's executor in your onEnable method:

    Code:java
    1. getCommand("tell").setExecutor(new TellCommandExecutor(this));
     
  4. Offline

    travja

    I'm sorry, I should have been more clear on what I was asking. For sub commands. If I were to use setExecutor in a command executor, redirecting to another for use of a sub command. Is that a good way to go or would it just be better to implement various methods for all my sub command stuff. /mycommand sub - /mycommand sub2 - etc.
     
  5. Offline

    Dragonphase

    travja

    setExecutor will only work for commands that have been declared in your plugin.yml file. You could redirect your subCommands to a class designed to handle them however.
     
  6. Offline

    travja

    Dragonphase After running some tests, I have to redirect it, and then have the player run the command again by just building the command. But it appears to put the server into an infinite loop, causing the server to crash. I suppose I'll just have to do methods to handle everything.
     
  7. Offline

    fireblast709

    travja use a CommandExecutor to get the subcommand, and let that delegate execution to another method/class
     
  8. Offline

    travja

  9. Offline

    Skye

    travja You only need a command executor for the top-level command so that Bukkit knows what to run when the command registered in the plugin.yml is passed. From there, you can check the arguments passed for the sub-commands.

    How you structure your sub-commands is up to you, but you could have them implement CommandExecutor if you want to be able to switch them to top-level commands quickly. If you look here, you can see a good example of building your own sub-command structure.
     
Thread Status:
Not open for further replies.

Share This Page