SubCommand - wysohn/GeneralLib GitHub Wiki

SubCommand

This is an abstract class which help developers to make organized commands.

To make a command, you make your own command class and let it implement SubCommand class.

public class Kick extends SubCommand{
        
}

And like any other classes, you will need to initialize SubCommand with its constructor. Simply call super() constructor to do so.

public class Kick extends SubCommand{
    public Kick(PluginBase base, String permission){
        super(base, permission,
            MyPluginLanguage.Command_Kick_Description,
            new MyPluginLanguage[]{
                MyPluginLanguage.Command_Kick_Usage1,
            },
            1,
            "kick",
            "k", "kc", "kk");
            
    }
}

And again, let go through one by one

Arg0 -- The first argument will be a little bit ambiguous if you have no idea what polymorphism is. If you don't know what is that, think about what we did when we have created the 'main' class. Didn't we 'extends' PluginBase? If some class 'extends' something, it can be stored in the parent type variable. In this case, the first argument is expecting PluginBase, you also can put any class that 'extends' PluginBase. In our case, MyPlugin; right? But we are going to use the input value from the constructor as we will instanciate the commands in our 'main' class.

Main class would look like this:

public class MyPlugin extends PluginBase{
    public MyPlugin(){
        super(new MyPluginConfig(), "mymaincommand", "myadminpermission")
    }

    @Override
    public void preEnable(){
        //TODO initialize your commands, languages, managers, and APISupports
        initLanguages();
        initCommands();
    }

    private void initLanguages(){
        for(Language lang : MyPluginLanguage.values())
            this.lang.registerLanguage(lang);
    }

    private void initCommands(){
        this.executor.addCommand(new Kick(this, "myplugin.some.permission"));
    }

}

arg1 -- The second parameter is obviously just permission to use the command. However, it can be null if you want this command to be used by anyone.

arg2 -- This is the description. Just like I explained in arg0 part, any class that 'implements' can be stored in the parent type interface. In our case, it's Language, and as you did in MyPluginLanguage enum, it implements Language interface. Therefore, you can pass any enum value of MyPluginLangue into this part.

arg3 -- This is the usage show up below the description. This is an array, so you have to create an array in order to make it work. It accepts array of Language.

arg4 -- This is number of arguments. The example set this value to 1, which means it will accept only one parameter for the SubCommand. For example, any command that has more or less than the argument /mmc kick somename, it will be refused and show description and usage instead. /mmc kick or /mmc kick test test for example.

And if you want to have a command that accepts variable amount of parameters, simply set this to -1. Setting this to -1 means you will handle the arguments manually. In this case, you have to check the args.length yourself and return appropriate return value. If you return false, it indicates that the command doesn't fulfill the required arguments; therefore; let the plugin to print out description and usage instead.

Functionality

And most of all, we've just made a command with all the detailed descriptions, but how are we gonna 'do somthing' when a player enter the command? To do so, you have three methods can be overriden as your need.

public class Kick extends SubCommand{
    public Kick(PluginBase base, String permission){
        super(base, permission,
            MyPluginLanguage.Command_Kick_Description,
            new MyPluginLanguage[]{
                MyPluginLanguage.Command_Kick_Usage1,
            },
            1,
            "kick",
            "k", "kc", "kk");
            
    }
    
    @Override
    protected boolean excuteConsole(CommandSender sender, String[] args){
    }

    @Override
    protected boolean excuteOp(Player sender, String[] args){
    }

    @Override
    protected boolean executeUser(Player sender, String[] args){
    }
}

Now we have three methods that can be implemented as your need. If you don't want to allow such command to be executed from the unwanted command source, you just take out the method you don't want to support. The parent class already implemented the method and will show the message 'Not allowed to execute from XX' to the command source.

ExecuteConsole

This is the method invoked when a command was executed by console. So you can safely assume that you have no Player object to deal with in this case.

ExecuteOp

This is the method invoked when a command was executed by a player with OP. Usually, I just call executeUser() method internally, so you don't have to write exact same thing in two different methods. So unless you have some special things to do with OPs, just forward it like this:

@Override
public boolean executeOp(Player op, String[] args){
    return executeUser(op, args);
}

ExecuteUser

This is the method invoked when a command was executed by any player (well except one with OP). This is probably where you are gonna put most of the codes for.

Just a friendly reminder that the 'args' array's length varies depends on the parameter you used in the constructor. If you put a number bigger or equal to 0, the length will be exact match. However, if you set argument parameter in constructor to be '-1,' you will need to check the length like I said above.