Solved Plugin prints command as message

Discussion in 'Plugin Development' started by blue1, Jan 21, 2016.

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

    blue1

    I looked in the forums and couldn't find anyone else who had this problem. I know it must be something I've overlooked, but I can't figure it out. When I type a command, it does execute the command. However, it also prints out the command as a player message.
    My Main class looks like this:

    Code:
    package me.blue1.main;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.event.Listener;
    import org.bukkit.plugin.java.JavaPlugin;
    
    import me.blue1.rides.Pig;
    
    public final class Main extends JavaPlugin implements Listener{
    
    
      public void onEnable(){
        Bukkit.getConsoleSender().sendMessage(ChatColor.GREEN + "Rides has been enabled!");
        getServer().getPluginManager().registerEvents(this, this);
        getCommand("pig").setExecutor(new Pig());
      }
    
      public void onDisable(){
          Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "Rides has been disabled.");
      }
    
    }
    My Listener class looks like this:

    Code:
    package me.blue1.main;
    
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerInteractEntityEvent;
    
    public class PlayerListener implements Listener{
        public PlayerListener(Main main){
           
        }
        @EventHandler
        public void onRide(PlayerInteractEntityEvent e){
            e.getRightClicked().setPassenger(e.getPlayer());
        }
       
    }
    
    My Pig command class is as follows:

    Code:
    package me.blue1.rides;
    
    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.EntityType;
    import org.bukkit.entity.LivingEntity;
    import org.bukkit.entity.Player;
    
    public class Pig implements CommandExecutor {
    
    
    @SuppressWarnings("deprecation")
    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
        Player p = (Player)sender;
        Location loc = p.getLocation();
        LivingEntity pig = loc.getWorld().spawnCreature(loc, EntityType.PIG);
       
        if (commandLabel.equalsIgnoreCase("pig")){
            spawnCreature(loc, pig);
            p.sendMessage(ChatColor.BOLD+"You have spawned a pig");
        }
        return false;
      }
    
    private void spawnCreature(Location loc, LivingEntity pig) {
       
    }
    }
    Sorry if it's just some stupid mistake I made. I just really can't seem to find it.
     
  2. Offline

    teej107

    return true in the onCommand method. This means that the command was successfully ran unlike returning false
     
    blue1 likes this.
  3. Offline

    blue1

    Thanks so much! Figured it was something simple but apparently my brain was a little sleep-deprived. Works fine now. :)
     
  4. Offline

    Zombie_Striker

    Don't blind cast! What if the console sends this command? Then your whole plugin will break. Check if sender is an instanceof Player first before casting.
    1. I thought CommandExecutor does not have a commandLabel.
    2. Don't use command label, instead, use cmd.getName() when getting the command (works with aliases)
    3. You don't even need to check! The executor is only set for "pig", so only when the "pig" command is sent will that bit of code ever be read
    No need to log your plugins, bukkit does this for you.
     
  5. Offline

    blue1

    The plugins I write are only for myself and my own plugin, so I have no worries about it being sent through the console. Thanks for pointing that out though.
    As for the Command Label, it works just fine as is. This isn't the final plugin, it's a small piece of it to demonstrate what was relevant to my problem. And I personally just like seeing the little red letters when the plugin disables. :p
     
  6. Offline

    ShowbizLocket61

    /pig spawns a pig at your location. I have no idea why someone would execute it from console.

    Plus, the whole plugin would break? What? The whole point of an exception is that it prevents your plugin from being broken.

    Code:
    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
    Yes, it does indeed have a commandLabel.
     
  7. Offline

    Zombie_Striker

    It's not about "why", it about that the fact you can. If you want to be a compitant programmer, you have to make sure there is no way for a error to be thrown.

    Yeah, I say "your whole plugin will break" because "there going to be an error in the console" does not normally get people to fix the problem.

    My mistake then, but even still, he should use cmd.getName() instead.
     
  8. Offline

    ShowbizLocket61

    Are these people not averse to being spammed by a horde of formidable error messages?
     
  9. Offline

    Zombie_Striker

    Still not the point. If you wish to have any future as a programmer, you should get use to making sure there is no way for an event to happen.

    Again, also not the point. It is convention to use cmd.getName() because this also works with aliases. The only reason why they do not remove CommandLabel is because it would break most plugins (since most plugins use it, but they should not).
     
  10. Offline

    mythbusterma

    I'm sorry? Since when is that the point of an exception? The point of an exception is to pass error handling up the stack to prevent your code from being left in a broken state.

    ClassCastException is a RuntimeException. You should always program around RuntimeExceptions in Java. There is absolutely no reason to let them happen unless you're incredibly lazy.

    No properly written program should be dumping stack traces just because I did something "unexpected."
     
    teej107 likes this.
  11. Offline

    ShowbizLocket61

    @mythbusterma
    Nowhere did I say that exceptions should be ignored, and nowhere did I say that one shouldn't avoid them

    All I was doing was correcting Zombie_Striker's statement that the whole plugin would break.
     
    WolfMage1 and mythbusterma like this.
  12. Offline

    blue1

    This is not about being a competent programmer, and this is not about making money selling plugins. I didn't ask you to proofread my plugin, just to show me what I did wrong that caused my error. You came in after the issue was fixed, and to be honest I don't know why. If you have a way to make the fix better or more sure, have at telling me, but I'd prefer if you didn't tell me every little thing I have done wrong. I only looked at my first line of code 3 months ago, so I think I'm doing ok at teaching myself.
    Sorry if that sounded rude.
     
    ShowbizLocket61 likes this.
  13. Offline

    teej107

    I do agree with @Zombie_Striker. Some of us are very passionate about programming and hate it when we see code that can be easily improved.
    And since you are 3 months in on programming, I advise you listen to the suggestions and ask questions on why.

    EDIT: Oh and if this is solved, please mark the thread as solved.
     
    Konato_K likes this.
  14. Offline

    ShowbizLocket61

    @blue1
    Yes, threads get a bit off topic here. I agree with you for the most part, but it's sometimes the small things that will trip you up.
    [​IMG]
    I'll give you a tip, though; if you want to post on these forums, try not to take anything personally.
     
    Konato_K, WolfMage1 and mythbusterma like this.
  15. Offline

    blue1

    I realize that often the smallest things can lead to the biggest consequences. But for now, I am still learning as I only have early mornings and late evenings to do so. I'm not all that experienced.

    This issue is not yet solved, as I came across the same problem, and this time there was nothing I knew to do that would fix it. I checked the plugin.yml, perfect. I checked the Main, perfect. All of the music classes are fine except for three. I'll post the code here. What happens, is I will type /mmellohi and it will return what I typed.


    Code:
    package me.blue1.skyemusic.cmds;
    
    import org.bukkit.ChatColor;
    import org.bukkit.Effect;
    import org.bukkit.Material;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    
    import me.blue1.skyemusic.Main;
    
    public class MMellohi implements CommandExecutor {
       
        public MMellohi(Main main) {
           
        }
    
        @SuppressWarnings("deprecation")
        public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
            Player p = (Player) sender;
            String prefix = new String(ChatColor.GRAY+"["+ChatColor.DARK_AQUA+"Music"+ChatColor.GRAY+"] ");
            if(commandLabel.equalsIgnoreCase("mmellohi")){
                p.sendMessage(prefix+ChatColor.GOLD+"You have selected music disc Mellohi");
                p.playEffect(p.getLocation(), Effect.RECORD_PLAY, Material.RECORD_7.getId());
            }
           
            return true;
        }
    }
    
    This class works flawlessly though:


    Code:
    package me.blue1.skyemusic.cmds;
    
    import org.bukkit.ChatColor;
    import org.bukkit.Effect;
    import org.bukkit.Material;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    
    import me.blue1.skyemusic.Main;
    
    public class MFar implements CommandExecutor {
       
        public MFar(Main main) {
           
        }
    
        @SuppressWarnings("deprecation")
        public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
            Player p = (Player) sender;
            String prefix = new String(ChatColor.GRAY+"["+ChatColor.DARK_AQUA+"Music"+ChatColor.GRAY+"] ");
            if(commandLabel.equalsIgnoreCase("mfar")){
                p.sendMessage(prefix+ChatColor.GOLD+"You have selected music disc Far");
                p.playEffect(p.getLocation(), Effect.RECORD_PLAY, Material.RECORD_5.getId());
            }
           
            return true;
        }
    }
    
    If anyone can see what is causing this, please let me know. I really am clueless on these things.
     
  16. Online

    timtower Administrator Administrator Moderator

    @blue1 Did you register the first class as commandexecutor?
     
  17. Offline

    WolfMage1

    To be fair, no matter how much you try people will always try and succeed in breaking a plugin.
    You just made my day a very happy one <3
     
    Last edited: Jan 27, 2016
    ShowbizLocket61 likes this.
  18. Offline

    Zombie_Striker

    @WolfMage1
    The post is you want to make it difficult for those types of people. You would be making too easy if you blindly cast objects.
     
  19. Offline

    blue1

    TBH I don't think I know what you mean by registering it as CommandExecutor. I have it implementing it. My main class is as follows:

    Code:
    package me.blue1.skyemusic;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.plugin.java.JavaPlugin;
    
    import me.blue1.skyemusic.cmds.M13;
    import me.blue1.skyemusic.cmds.MBlocks;
    import me.blue1.skyemusic.cmds.MCat;
    import me.blue1.skyemusic.cmds.MChirp;
    import me.blue1.skyemusic.cmds.MFar;
    import me.blue1.skyemusic.cmds.MMall;
    import me.blue1.skyemusic.cmds.MMellohi;
    import me.blue1.skyemusic.cmds.MStal;
    import me.blue1.skyemusic.cmds.MStrad;
    import me.blue1.skyemusic.cmds.MWard;
    
    public class Main extends JavaPlugin{
        @Override
        public void onEnable(){
            Bukkit.getConsoleSender().sendMessage(ChatColor.GREEN+"Music has been Enabled successfully");
            getCommand("m13").setExecutor(new M13(this));
            getCommand("mblocks").setExecutor(new MBlocks(this));
            getCommand("mcat").setExecutor(new MCat(this));
            getCommand("mchirp").setExecutor(new MChirp(this));
            getCommand("mfar").setExecutor(new MFar(this));
            getCommand("mmall").setExecutor(new MMall(this));
            getCommand("mellohi").setExecutor(new MMellohi(this));
            getCommand("mstal").setExecutor(new MStal(this));
            getCommand("mstrad").setExecutor(new MStrad(this));
            getCommand("mward").setExecutor(new MWard(this));
        }
        @Override
        public void onDisable(){
           
        }
    }
    
    All but MMellohi, MStrad, and MWard work. They all three have the same problem.
     
  20. Offline

    Zombie_Striker

    @blue1
    1. If you don't need main's instance in the commandexecutor classes, then you might as well remove those constructors.
    2. If each class takes care of one command only, then you don't need to check which command it is. It will only trigger onCommand if the command sent is the one you are testing for.
    3. The onDisabled does nothing. Remove it.
    4. Again, DON'T BLIND CAST! Check if sender is an instanceof Player before casting.
     
    Konato_K likes this.
  21. Offline

    blue1

    I removed the main instance, and the onDisable. Sometimes I like to send a message when it disables, which is why I had it there to begin with. But thanks for pointing that out.
    I don't know any other way to make the commands run than specifying each in the Main class. Can you tell me how else to do it? Here's what it looks like now.
    Code:
    package me.blue1.skyemusic;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.plugin.java.JavaPlugin;
    
    import me.blue1.skyemusic.cmds.M13;
    import me.blue1.skyemusic.cmds.MBlocks;
    import me.blue1.skyemusic.cmds.MCat;
    import me.blue1.skyemusic.cmds.MChirp;
    import me.blue1.skyemusic.cmds.MFar;
    import me.blue1.skyemusic.cmds.MMall;
    import me.blue1.skyemusic.cmds.MMellohi;
    import me.blue1.skyemusic.cmds.MStal;
    import me.blue1.skyemusic.cmds.MStrad;
    import me.blue1.skyemusic.cmds.MWard;
    
    public class Main extends JavaPlugin{
        @Override
        public void onEnable(){
            Bukkit.getConsoleSender().sendMessage(ChatColor.GREEN+"Music has been Enabled successfully");
            getCommand("m13").setExecutor(new M13());
            getCommand("mblocks").setExecutor(new MBlocks());
            getCommand("mcat").setExecutor(new MCat());
            getCommand("mchirp").setExecutor(new MChirp());
            getCommand("mfar").setExecutor(new MFar());
            getCommand("mmall").setExecutor(new MMall());
            getCommand("mellohi").setExecutor(new MMellohi());
            getCommand("mstal").setExecutor(new MStal());
            getCommand("mstrad").setExecutor(new MStrad());
            getCommand("MWard").setExecutor(new MWard());
        }
    }
    
    I'm not very well acquainted with instanceof yet, could you show me what to change in the class?
    Code:
    package me.blue1.skyemusic.cmds;
    
    import org.bukkit.ChatColor;
    import org.bukkit.Effect;
    import org.bukkit.Material;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    
    public class MMellohi implements CommandExecutor {
    
        @SuppressWarnings("deprecation")
        public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
            Player p = (Player) sender;
            String prefix = new String(ChatColor.GRAY+"["+ChatColor.DARK_AQUA+"Music"+ChatColor.GRAY+"] ");
            if(commandLabel.equalsIgnoreCase("mmellohi")){
                p.sendMessage(prefix+ChatColor.GOLD+"You have selected music disc Mellohi");
                p.playEffect(p.getLocation(), Effect.RECORD_PLAY, Material.RECORD_7.getId());
            }
           
            return true;
        }
    }
    
     
  22. Offline

    Zombie_Striker

    @blue1
    Code:
    if(sender istanceof Player)
    //The sender is a player.
    
    That's not what I meant. I meant you should remove this line.
     
  23. Offline

    blue1

    Ooooh, I see what you mean xD sorry for my ignorance. I will try this. :)

    EDIT: But if I remove that line... how can I possibly specify the command? Does the line in the Main class do that on it's own?

    EDIT2: I see, that works nicely. :) But still, on several classes it does not run the command. It only types it out. Can you help with this?

    The command classes, by the way, are copy/pastes of each other. The only difference is the id of the music discs.
     
    Last edited by a moderator: Jan 27, 2016
  24. Offline

    blue1

    bump? Anyone? Still need to know why it is printing out my command without executing it.
     
  25. Offline

    mcdorli

    Why do you have different commands for different songs? Hav you ever heard of arguments?
    You regoster the mellohi command, not the mmelohi im the maim class. Always search for typos with commands.
     
  26. Offline

    blue1

    I don't know how to use the arguments to make subcommands. I just started teaching myself Java a couple months ago. If you could give a basic example, that would be great!
    And thanks for pointing that out with the mellohi! It works now, seemingly flawlessly. I guess programming at night doesn't pay off all the time. :p Again, thanks so much for pointing that out. I'll be more careful next time.
     
  27. Offline

    Zombie_Striker

    @blue1
    Args control all the arguments the command has (E.G. /command arg[0] arg[1] arg[2]). Use something like the following to test for an args:
    Code:
    if(cmd.getName.equals("m")){
     if(args[0].equalsIgnoreCase("mellohi"))
      //Test for /m mellohi
     }
    }
    Note this means that you can condense all those classes into one. Just register the command "m", and test for all the arguments in that one class.
     
  28. Offline

    mcdorli

    Omg, you forgot to checm for length. How could ypu

    Neced forget to check the mength of an array, before using it. It can lead to indexoutofboundsexception
     
    Zombie_Striker likes this.
  29. Offline

    Konato_K

    No, exceptions in Java can terminate the execution of any application if they are not handled, the reason why the server doesn't break it's because the section that calls the command has a try-catch and will catch any exception being thrown from a command and print it to the console, otherwise they whole server could break.

    I don't see why CommandLabel should be removed, it's used for aliases, removing it would be removing the alias feature, which is really useful.
     
  30. Offline

    blue1

    My "commandLabel" shown above is a String variable. I could have named it anything I wanted.
     
Thread Status:
Not open for further replies.

Share This Page