Solved Command not recognized?

Discussion in 'Plugin Development' started by Duskite, May 26, 2013.

  1. I am relatively new to java(and modding), so bear with me. I am trying to create a plugin named Medic! (without ! in most instances as for some reason nothing likes that) and I am working on a revive command right now. The command is /mrev and it only recognizes it like that, not with a player like I want it to (ex /mrev Duskite to revive Duskite).

    Here is my main class -
    Code (Text):
    1. package;
    3. import java.util.logging.Logger;
    5. import org.bukkit.plugin.PluginDescriptionFile;
    6. import org.bukkit.plugin.PluginManager;
    7. import;
    9. public class main extends JavaPlugin{
    10.     public Logger logger = Logger.getLogger("Minecraft");
    11.     public static main plugin;
    13.     @Override
    14.     public void onDisable() {
    15.         PluginDescriptionFile pdfFile = this.getDescription();
    16. +  " Has Been Disabled!");
    17.     }
    19.     @SuppressWarnings("unused")
    20.     @Override
    21.     public void onEnable() {
    22.         PluginDescriptionFile pdfFile = this.getDescription();
    23. + " Version " + pdfFile.getVersion() + " Has Been Enabled!");
    24.         PluginManager pm = getServer().getPluginManager();
    25.     }
    26. }
    And here is the class supposed to take over for the revive command(I have one for extinguish commands and one for heal commands too, just not started on them) -
    Code (Text):
    1. package;
    3. import org.bukkit.Bukkit;
    4. import org.bukkit.ChatColor;
    5. import org.bukkit.Location;
    6. import org.bukkit.command.Command;
    7. import org.bukkit.command.CommandExecutor;
    8. import org.bukkit.command.CommandSender;
    9. import org.bukkit.entity.Player;
    11. public class revive implements CommandExecutor{
    12.     @SuppressWarnings("unused")
    13.     private main plugin;
    15.     public revive(main plugin){
    16.         this.plugin = plugin;
    17.     }
    19.     @SuppressWarnings("unused")
    20.     @Override
    21.     public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
    23.         if(cmd.getName().equalsIgnoreCase("mrevive")){
    24.             if(!(sender instanceof Player)){
    25.                 return true;
    26.             }
    28.             Player p = (Player) sender;
    30.             if(args[0].length() == 1) {
    31.                 p.sendMessage(ChatColor.RED + "You need more arguements than that.");
    32.             }
    33.             if(args[0].length() == 2 && p.hasPermission("medic.revive")) {
    34.                 Player player = Bukkit.getServer().getPlayer(args[1]);
    36.                 if(player == null || !player.isOnline()){
    37.                     p.sendMessage(ChatColor.RED + "" + player + " is not online.");
    38.                 }
    40.                 if(!player.isDead()){
    41.                     p.sendMessage(ChatColor.RED + "The player " + player + " is not dead.");
    42.                 }
    43.                 Location playerlc = player.getLocation();
    45.                 player.setHealth(20);
    46.                 player.sendMessage(ChatColor.GREEN + "Player " + p + " has revived you.");
    47.             }
    48.         }
    49.         return false;
    50.     }
    51. }
    And my plugin.yml -
    Code (Text):
    1. name: Medic
    2. version: 0.1.0
    3. description: Plugin to allow for medics.
    4. author: Duskite
    6. main:
    8. commands:
    9.   mrevive:
    10.     decription: Revives players where they stand.
    11.     aliases: mrev OR
    12.     permission: medic.revive
    13.     usage: Systax error, did you mean /mrev PlayerName?
    I don;t get any messages of errors from the actual command class, only from the plugin.yml lines. It seems like there is nothing linking the main to the revive class, but as I am still a total noob, I have no idea for sure. If more information about the errors is needed, I will provide.
  2. This line will set "mref OR" as an alias for the command. If you want to define more than one, put them in square brackets, like so:
    [mrev, secondAlias, thirdAlias]
    Additionally, you should do a check in your onCommand to see if the label equals the command or the alias.

    EDIT: Also, do what this guy said. \/ Missed that entirely.
  3. Duskite
    Hey! I see you aren't setting the executor of your command... Well in addition to having them defined under your commands: node in your plugin.yml, you need to set the executor for them.

    1. @Override
    2. public void onEnable() {
    3. PluginDescriptionFile pdfFile = this.getDescription();
    4. + " Version " + pdfFile.getVersion() + " Has Been Enabled!");
    5. PluginManager pm = getServer().getPluginManager();
    6. registerCommands();
    7. }
    9. private void registerCommands() {
    10. getCommand("mrev").setExecutor(new revive(this));
    11. }
  4. Also get rid of the + " Version " + pdfFile.getVersion() + " Has Been Enabled!");
    It is not needed! Bukkit automatically does this for you.
  5. Unless he wants the version in it... Bukkit doesn't log a message with the name and the version, so it's not bad if he wants the version
  6. JUST started my server and found this line from one of my plugins. I know that I did not log this line.
    01:30:12 [INFO] [Zephyrus] Enabling Zephyrus v0.4.1
    It says the name and the version.
  7. Hmm you're absolutely right! Odd how I forgot (it's been all the code over testing time I've been doing)
    Minnymin3 likes this.
  8. I actually do have a 01:30:12 [INFO] [Zephyrus] Zephyrus v0.4.1 by minnymin3 Enabled! cuz I have a bunch of stuff that does stuff in onEnable and ya it hooks into other plugins
  9. I kinda want that in case I decide to do something with it later, but thanks for that info.

    As for that, I never knew about that, so I will go test that right away.

    Edit: Every command (/mrev and /mrevive) returned null, when they should send errors that there wasn't enough arguments. I added the return true; to every ending in the class, so I don't know what is null right now.
  10. args.length not args[0].length?
  11. Thanks, but now I see it requires two names, when I just wanted it to specify the player to revive. Gotta figure this one out now. At least this provides experience to learn and hopefully never make these stupid mistakes again.
  12. So far, it seems to be working, other than the fact that when a mistake is made, both the plugin.yml and my code yells at the player. I am trying to get rid of the plugin.yml, and instead changed the error message to
    Code (Text):
    1. @SuppressWarnings("unused")
    2.     @Override
    3.     public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
    5.         if(cmd.getName().equalsIgnoreCase("mrevive") || cmd.getName().equalsIgnoreCase("mrev")){
    6.             if(!(sender instanceof Player)){
    7.                 return true;
    8.             }
    9.             String command = (String) cmd.getName();
    10.             Player p = (Player) sender;
    12.             if(args.length == 0) {
    13.                 p.sendMessage(ChatColor.RED + "You need more arguements than that, did you mean /" + command + " Player?");
    14.             }
    (This being the revive command code up until the first false)
    I am trying to make the code recognize whether the player typed /mrev or /mrevive and then change the error presented to them so it is less confusing. However, in the message (the command part) it just typed mrevive, no matter if the player typed mrev or mrevive. It makes no sense to me, as I set the string to be similar to the if statement that checks for mrev or mrevive. (And yes, the mrev is part of the aliases in the plugin.yml, so it should recognize both.)
  13. Still don't know what is wrong with this latest error (post above).
  14. Wait, what? Please structure your question. Put the things you want in points, put the errors you get in points. Otherwise for me, it's just tl;dr
  15. Okay then:

    - Player types /mrev, instead of returning "You need more arguements, try /(whichever alias they used) player", it types "... try /mrevive player"

    - I want it to recognize what alias was used, and use it inside the error notice, to show the player it was a correct alias.

    This is the piece of code I have to recognize what they typed,
    Code (Text):
    1. String command = (String) cmd.getName();
    2.             Player p = (Player) sender;
    taking the cmd.getName(); from the if that recognizes a command, thinking it would output the same string for my command string.
    Code (Text):
    1. if(cmd.getName().equalsIgnoreCase("mrevive") || cmd.getName().equalsIgnoreCase("mrev")){
    colony88 likes this.
  16. If you want it to recognize which command was sent, don't do "if it's this command or this command move on and do this-" because it won't seperate the execution of code per command it'll just do the code within the if statement for both commands.

    1. if(cmd.getName().equalsIgnoreCase("mrev") {
    2. // do some more checks then the end result
    3. } else if(cmd.getName().equalsIgnoreCase("mrevive") {
    4. // do some more checks then the end result
    5. }
  17. Was kinda hoping to only change the response if the arguments are wrong, duplicating the code just to change one word seems a bit.. much? I don't know if that's the only way, though it seems like there should be an easier way.
  18. It's not a bit much, considering you want to check for two different commands. Having the same execution code would make having two commands useless and at that point you're wanting an alias.

    If you want command aliases go to your plugin.yml, under where you specified your command add:
    2. aliases: my_alias
    3. # OR for multiple
    4. aliases: [my_alias, my_second_alias, my_third_alias]
  19. I have it there, it's just I wanted the code to detect what is typed so as the response
    p.sendMessage(ChatColor.RED + "You need more arguements than that, did you mean /" + command + " Player?");
    would detect what alias was used, and use it to confirm the player had, in fact, used a correct alias but it was used wrong.
  20. You can alternatively use label instead of command.getName() as it will detect aliases the way you want I believe.
    1. if(label.equalsIgnoreCase("mrev") {
    2. // do some more checks then the end result
    3. } else if(label.equalsIgnoreCase("mrevive") {
    4. // do some more checks then the end result
    5. }

    You can then send messages using:
    2. p.sendMessage(ChatColor.RED + "You need more arguments than that, did you mean /" + label + " player?");

    It will correctly send the used alias the player sent.
  21. Thank you! Now, to figure out how to respawn a player on command...
  22. Duskite
    When a player dies, get their location, and put it into a map or wherever you want to store their death location. Then when a player revives someone, it gives them X health and teleports them to their death location. Now, you can get more creative with animations, sounds, reagents and possibly giving them all items or only certain items back when revived. Good luck!
  23. Been trying that, giving them health 20 and teleporting them to their previous location, but it just gets them stuck in the respawn menu, with the respawn button not working. Now, my tester was across the ocean, so latency might be bugging it up. I'll try again with someone close to me.

    The code that that deals with it is:
    Code (Text):
    1. @Override
    2.     public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
    4.         if(cmd.getName().equalsIgnoreCase("mrevive") || cmd.getName().equalsIgnoreCase("mrev")){
    5.             if(!(sender instanceof Player)){
    6.                 return true;
    7.             }
    8.             Player p = (Player) sender;
    10.             if(args.length == 0) {
    11.                 p.sendMessage(ChatColor.RED + "You need more arguements than that, did you mean /" + label + " Player?");
    12.             }
    13.             if(args.length == 1 && p.hasPermission("medic.revive")) {
    14.                 Player player = Bukkit.getServer().getPlayer(args[0]);
    16.                 if(player == null || !player.isOnline()){
    17.                     p.sendMessage(ChatColor.RED + "" + player + " is not online.");
    18.                     return true;
    19.                 }
    21.                 else if(!player.isDead()){
    22.                     p.sendMessage(ChatColor.RED + "The player " + player + " is not dead.");
    23.                     return true;
    24.                 }
    26.                 else{
    27.                     Location playerlc = player.getLocation();
    28.                   player.setHealth(20);
    29.                     player.teleport(playerlc);
    30.                     player.sendMessage(ChatColor.GREEN + "Player " + p + " has revived you.");
    31.                   return true;
    32.               }
    33.             }
    34.         }
    35.         return false;
    36.     }
    Way down at the last else.
  24. As you see in the else if right about that, it checks if player is not dead and if they aren't, it produces a message.
  25. Duskite
    Okay well first you want to check if the player is dead:
    2. if(player.isDead()) {
    3. // force spawn them
    4. } else {
    5. // else simply teleport them and do all the other stuff
    6. }

    A post from this thread shown by fireblast709 on how to use packet #205 to force respawn a player (I believe).
    1. @EventHandler
    2. public void onDeath(PlayerDeathEvent e)
    3. {
    4. String tv = Bukkit.getVersion();
    5. int index = tv.indexOf("(MC: ")+5;
    6. int end = tv.indexOf(")", index);
    7. String version = tv.substring(index, end);
    8. try
    9. {
    10. Class packet = Class.forName("net.minecraft.server.v"+version.replace(".", "_") +".Packet205ClientCommand");
    11. Object name = packet.getConstructor(new Class[0]).newInstance(new Object[0]);
    12. Field a = packet.getDeclaredField("a");
    13. a.setAccessible(true);
    14. a.set(name, 1);
    15. Object nmsPlayer = Class.forName("org.bukkit.craftbukkit.v"+version.replace(".", "_")+".entity.CraftPlayer").getMethod("getHandle", new Class[0]).invoke(e.getEntity(), new Object[0]);
    16. Field con = Class.forName("net.minecraft.server.v"+version.replace(".", "_") +".EntityPlayer").getDeclaredField("playerConnection");
    17. con.setAccessible(true);
    18. Object handle = con.get(nmsPlayer);
    19. packet.getDeclaredMethod("handle", Class.forName("net.minecraft.server.v"+version.replace(".", "_") +".Connection")).invoke(name, handle);
    20. }
    21. catch(Exception ex)
    22. {
    23. ex.printStackTrace();
    24. }
    25. }
    Duskite likes this.
  26. This is just going to be if they're dead, so I think I weeded out the players who arn't dead so this will only run on a dead player, someone who isn't respawned yet. I will check out that thread.

Share This Page