Commands Reborn v1.1

Discussion in 'Resources' started by Jaker232, Dec 25, 2011.

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

    Jaker232

    My old command tutorial which has tooken notice, has broke down and is incompatible with recent builds. In this thread, I will rewrite the entire tutorial from scratch, and a step by step method of creating them. Let's run down to the basics. For this, I will execute a command using another class.

    1 - Setting up the command
    First, you'll want to bring up plugin.yml in any notepad program (Eclipse and NetBeans has one built in, just drag the file into the window tabs where the classes are). Now, you'll want to write in this plugin.yml some required stuff. For this tutorial, I'll use a kick command.
    Code:
    kick:
        description: Kicks a player
        permission: example.kick
        usage: /kick [player] <reason>
    
    For this, you can remove '<reason>' because it's optional, the sender does not have to include it. I will explain what each field means. description describes what the command is used for, give it a short statement. permission is optional, but you can add it. usage is the syntax to execute it when the following is made. The one without the brackets and arrows are not required as well. If you want, alias can give it one alias, meaning short version. If you want more aliases, replace alias with aliases. Both of them must be covered with straight brackets '[]'. Here is an example of one with aliases.
    Code:
    kick:
        description: Kicks a player
        permission: example.kick
        aliases: [remove, rm]
        usage: /kick [player] <reason>
    
    You'll have to find it optionally. Now in the main class, you want to add this to your onEnable() method.
    Code:java
    1.  
    2. getCommand("kick").setExecutor(new KickCommand(this));
    3.  

    Change the 'kick' to the name of the command you started the block with in plugin.yml. Create the class KickCommand with the interface CommandExecutor with a constructor leading to the main class. For this onCommand already implemented for you when you made the class, modify it to make it look like this.
    Code:java
    1.  
    2. public boolean onCommand(CommandSender sender, Command cmd, String cmdLabel, String[] args) {
    3. return false;
    4. }
    5.  

    The only thing you have to change are args0, args1, args2, and args3 in the method constructor or arguments. Now, we need to create a universal Player variable inside the onCommand.
    Code:java
    1.  
    2. Player player = (Player) sender;
    3.  

    You now are ready to move on.
    2 - Creating the grounds
    So we have set up our command, registered it in plugin.yml, gave it a class executor in the main class. Now we need to write in our command class stuff to make it actually work. Write inside your onCommand this code.
    Code:java
    1.  
    2. if(cmdLabel.equalsIgnoreCase("kick")) {
    3. }
    4.  

    It will get the command name and see if it matches kick, if you make it 'equals("kick")', it will only look for '/kick' not '/KiCk'. 'equalsIgnoreCase("kick")' will ignore case-sensitive keys, but read it as lowercase, which is very efficient and recommended to use incase a person's caps lock key is on or stuck. Because I have defined one required field to kick someone, I will add an argument checking. The argument checking is NOT required. You do not need it.
    Code:java
    1.  
    2. if(args.length == 1) {
    3. }
    4.  

    To check for permissions using Bukkit's API, do this.
    Code:java
    1.  
    2. if(player.hasPermission("example.kick")) {
    3. }
    4.  

    If you are finding the player's name, create a variable called.
    Code:java
    1.  
    2. String pname = (args[0]);
    3. Player toKick = Bukkit.getPlayer(pname);
    4.  

    If you want to compact it, here's the code.
    Compacted (open)

    Code:java
    1.  
    2. Player toKick = Bukkit.getPlayer(args[0]);
    3.  


    Now that we have catched the arguments, it's time to make fun of the player! We need to kick them.
    Code:java
    1.  
    2. toKick.kickPlayer("Kicked by" + player.getDisplayName());
    3.  

    Now we need to tell the sender that they have been kicked.
    Code:java
    1.  
    2. player.sendMessage(toKick.toString() + " has been kicked!");
    3.  

    Now we need to return it that the player has sucessfully executed the command.
    Code:java
    1.  
    2. return true;
    3.  

    Congrats! You have made your first (or not) command that kicks the player in argument 1 (bukkit reads it as argument 0, which can be confusing).
    3 - Credits
    First, I want to thank everyone for reading my best command tutorial, and giving support and feedback on it. I have never gotten so much credit and feedback ever on my tutorials previously. I want to also thank the old @chernobyl360 for crediting me for his ModSiren plugin, which he now is gone (probably dead due to his Bukkit status and signature) and left his plugin to die. I'll never forget him and his ModSiren plugin.
    I also want to thank @Coryf88 for listing my old command tutorial in the directory (he should replace the old directory to the tutorial with the new one here) as well.
    There is also a bonus if you want to add the reason why you want to kick that player. Here is the source.
    BONUS - Reasoning to kick
    Write a new argument length checking line like this.
    Code:java
    1.  
    2. if(args.length == 2) {
    3. }
    4.  

    Now we want to recopy the variables. I will use the compact method.
    Code:java
    1.  
    2. Player toKick = Bukkit.getPlayer(args[0]);
    3.  

    Now we want to add the reasoning.
    Code:java
    1.  
    2. String reason = (args[1]);
    3.  

    Now we want to kick him and send the player that the kicked has been kicked for 'reason' and return true.
    Code:java
    1.  
    2. toKick.kickPlayer(reason);
    3. player.sendMessage(toKick.toString() + " has been kicked. (reason: " + reason.toString + ").");
    4. return true;
    5.  

    You are done. Take a little time to celebrate on what you just have learned.
     
    xxMatthewo likes this.
  2. Offline

    Mr_H4mm3r

  3. Offline

    NuclearW

    A few things: In the plugin.yml for command usage it is suggested one uses "<command>" instead of the actual name of the command, as that usage line is printed on a return false from the command, and using <command> allows CraftBukkit to change the name of the command to whatever alias was used.

    Furthermore, unless one has more than one command in a CommandExecutor, the checking of the command's name is not needed.

    Another suggestion you might want to put in there is checking for a console command, you can do that with: if(!(sender instanceof Player)) { ... }

    Just some stuff to think about, otherwise an alright tutorial.
     
    heisan213 likes this.
  4. Offline

    Jaker232

    Alright. I'll try to improve my code.
     
  5. Offline

    DrAgonmoray

    @Jaker232

    I'll be honest, I actually learned something here. Good job. :)
     
  6. Offline

    Jaker232

    I did a good fix. The commands from the other one didn't work, so did v1.0.

    Please update your plugins to be with the tutorial.
     
  7. Offline

    hatstand

    The kick command will not work with the aliases, as you check against the command label, instead of the command name. One word for a reason is generally insufficient, so merging together all the arguments after the first (the player's name) would work better in that respect. You should be checking that the arguments the command was passed are valid - Checking that the arguments even exist, instead of assuming they do, is a good idea, unless you're into throwing exceptions.

    Edit: And you appear to have missed what NuclearW mentioned about plugin.yml
     
  8. Offline

    ThatBox

    Using reason as args[1] is kind of bad due to only can be one word :/
     
  9. Offline

    tips48

    You still need to check if sender is instanceof player before casting...And what ThatBox said. Try using a string builder and combining all the other arguments to get the full reason.
     
    ThatBox likes this.
  10. Offline

    MeneXia

    tips48 Something like this?
    Code:java
    1.  
    2. if (cmd.getName().equalsIgnoreCase("server")) {
    3. if (args.length == 0) {
    4. player.sendMessage(ChatColor.RED + "Message expected after /server");
    5. }
    6. if (args.length >= 1) {
    7. StringBuilder sb = new StringBuilder();
    8. for (int a=0; a<args.length; a++) {
    9. sb.append(args[a] + " ");
    10. }
    11. player.getServer().broadcastMessage(ChatColor.LIGHT_PURPLE + "[Server] " + sb);
    12. }
    13.  


    EDIT: I tried fixing the formatting for so long.
     
  11. Offline

    tips48

    Try that
     
  12. Offline

    TopGear93

    how would i cancell a command if an integer is bigger then the other?

    Code:
            if(depth > maxed){
                player.sendMessage("too deep!");
     
  13. Offline

    MeneXia

    tips48 Wouldn't you also have to get the first argument as well? it's logical to start the loop using an int a=0.
    Otherwise, added the "return true."
    Code:java
    1.  
    2. if (args.length >= 1) {
    3. StringBuilder sb = new StringBuilder();
    4. for (int a=0; a<args.length; a++) {
    5. sb.append(args[a] + " ");
    6. }
    7. player.getServer().broadcastMessage(ChatColor.LIGHT_PURPLE + "[Server] " + sb);
    8. }
    9.  


    TopGear93
    I'm assuming somewhere in your code you're comparing an integer argument with another initalized variable. You can continue what you're doing, just add a return true or false.
    Code:java
    1. if(depth > maxed){
    2. player.sendMessage("too deep!");
    3. return true; // or similarly, return false;
    4. }
     
  14. Offline

    tips48

    MeneXia
    Shit yea, was just typing an argument why not then I remembered the main command (/server) isn't included in args. Derp!
     
  15. Offline

    desht

    StringBuilder is good, but Joiner is even better :)
    Code:java
    1.  
    2. String sb = Joiner.on(" ").join(args);
    3.  

    One line of code instead of four, and the trailing space is gone too.
    (Joiner comes from the Google Collections Library, which is included with Bukkit).
     
  16. Offline

    MeneXia

    desht Cool! I'll get back to you once I work out how to use it, thanks.
     
Thread Status:
Not open for further replies.

Share This Page