onCommand Method Not Returning True

Discussion in 'Plugin Development' started by KingOfTheEast01, May 22, 2017.

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

    KingOfTheEast01

    Hey guys! My name is Lucas, and I'm having trouble getting my onCommand method to return true. I know it's not doing so, as when I execute the command in-game, the server returns the message "/choose <tribe>", which is the specified usage in my plugin.yml. I deleted the usage wondering what would happen, but then the command wouldn't return any response, so I'm wondering if any of you could help me out here.

    My plugin is structured with two packages called me.CallMeFilms.TZ, which holds TZFront, my main class, and me.CallMeFilms.TZ.Cmds, which holds Choose, my command executor class.

    Here are the files:

    TZFront:

    Code:
    package me.CallMeFilms.TZ;
    
    import org.bukkit.plugin.java.JavaPlugin;
    
    import me.CallMeFilms.TZ.Cmds.Choose;
    
    public class TZFront extends JavaPlugin{
      
        public void onEnable() {
            this.getCommand("choose").setExecutor(new Choose());
            this.getConfig().options().copyDefaults(true);
            this.saveDefaultConfig();
        }
    
    }
    
    and Choose:

    Code:
    package me.CallMeFilms.TZ.Cmds;
    
    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    
    import me.CallMeFilms.TZ.TZFront;
    
    public class Choose implements CommandExecutor{
      
        TZFront front = new TZFront();
        public boolean isBeingChecked = false;
      
        @Override
        public boolean onCommand(CommandSender sndr, Command cmd, String label, String[] args) {
            if(label.equalsIgnoreCase("choose")) {
                if(!(sndr instanceof Player)) {
                    sndr.sendMessage("Sorry, but that command can not be executed by console personnel. Please try again in-game.");
                } else {
                    Player player = (Player) sndr;
                    player.sendMessage("Test 3");
                    player.sendMessage("Test 4");
                    switch(args.length) {
                    case 0:
                        player.sendMessage(ChatColor.RED + "Usage: /choose <tribe>");
                        break;
                    case 1:
                        for(int i = 0; i <= front.getConfig().getStringList("Tribes").size(); i++) {
                            if(args[0] == front.getConfig().getStringList("Tribes").get(i)) {
                                this.isBeingChecked = true;
                            } else {
                                player.sendMessage(ChatColor.GRAY + "[" + ChatColor.YELLOW + ChatColor.BOLD + "Tribe" + ChatColor.GOLD + ChatColor.BOLD + "z" + ChatColor.GRAY + "] " + ChatColor.WHITE + ChatColor.BOLD + ">> " + ChatColor.RED + args[0] + "is not an existing tribe.");
                            }
                        }
                        break;
                    default:
                        player.sendMessage(ChatColor.GRAY + "[" + ChatColor.YELLOW + ChatColor.BOLD + "Tribe" + ChatColor.GOLD + ChatColor.BOLD + "z" + ChatColor.GRAY + "] " + ChatColor.WHITE + ChatColor.BOLD + ">> " + ChatColor.RED + "Too many arguments.");
                    }
                }
                return true;
            } else {
                return false;
            }
        }
    }
    P.S. I know something is wrong with this and it may be obvious. I come here for help and constructive criticism, so please don't ridicule me for my mistakes. I'm not the most advanced coder out there.

    Thanks! :D
    -Lucas (KingOfTheEast01/CallMeFilms)
     
    Last edited: May 22, 2017
  2. Offline

    Coww

    @KingOfTheEast01 The 'label' parameter in the onCommand is alias of the command that was used. Do you use an alias (for example just /c) to execute the command? The label.equals("choose") is the only line that can cause the usage to be printed out.
    You only have the choose command inside your 'Choose' class, right? So there's basically no reason to have that if statement there.


    (not related to your usage being printed issue) Further down in your code (case 1) you're doing some fancy things.
    Instead of looping the StringList you can simply use list.contains to check if args[0] is a valid tribe name.

    Also, are you using 'isBeingChecked' in another class? You might want to specify which tribe is currently being checked; because currently either all tribes are being check or none.
     
  3. Offline

    KingOfTheEast01

    Alright, I deleted the if statement checking the label, but the usage is back. Also, thanks for the advice on that loop. By the way, the isBeingChecked boolean is going to be used in a different command, but it doesn't have to do with the tribe, but rather the player.

    Anyways, here's my new code:

    Code:
    package me.CallMeFilms.TZ.Cmds;
    
    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    
    import me.CallMeFilms.TZ.TZFront;
    
    public class Choose implements CommandExecutor{
       
        TZFront front = new TZFront();
        public boolean isBeingChecked = false;
       
        @Override
        public boolean onCommand(CommandSender sndr, Command cmd, String label, String[] args) {
                if(!(sndr instanceof Player)) {
                    sndr.sendMessage("Sorry, but that command can not be executed by console personnel. Please try again in-game.");
                } else {
                    Player player = (Player) sndr;
                    player.sendMessage("Test 3");
                    player.sendMessage("Test 4");
                    switch(args.length) {
                    case 0:
                        player.sendMessage(ChatColor.RED + "Usage: /choose <tribe>");
                        break;
                    case 1:
                        if(front.getConfig().getStringList("Tribes").contains(args[0])) {
                            isBeingChecked = true;
                            } else {
                                player.sendMessage(ChatColor.GRAY + "[" + ChatColor.YELLOW + ChatColor.BOLD + "Tribe" + ChatColor.GOLD + ChatColor.BOLD + "z" + ChatColor.GRAY + "] " + ChatColor.WHITE + ChatColor.BOLD + ">> " + ChatColor.RED + args[0] + "is not an existing tribe.");
                            }
                        break;
                    default:
                        player.sendMessage(ChatColor.GRAY + "[" + ChatColor.YELLOW + ChatColor.BOLD + "Tribe" + ChatColor.GOLD + ChatColor.BOLD + "z" + ChatColor.GRAY + "] " + ChatColor.WHITE + ChatColor.BOLD + ">> " + ChatColor.RED + "Too many arguments.");
                        }
                    }
                return true;
                }
        }
    
     
  4. Offline

    Coww

    @KingOfTheEast01 Oh, welp I'm blind. The issue is that you create a new instance of your main plugin class inside your command class. Instead of 'new TZFront()' inside the Choose class you either want to
    1. pass through the instance of your plugin via the constructor of the Choose class (inside your onEnable:
      Code:
      this.getCommand("choose").setExecutor(new Choose(this));
      and create the corresponding constructor inside the Choose class)
    2. or save a reference to the plugin's instance in a static field inside your main class.

    And even if isBeingChecked is later used for a player: What I meant is that you do not know, what player the variable is referring to (you only have 1 variable true or false, no other information). You might want to add the player's uuid to a list (or set) and remove it, once your other task is complete.
     
  5. Offline

    KingOfTheEast01

    Alright, so I tried initializing it as static. I also did the same for the isBeingChecked boolean just to be consistent, but I'm receiving the same results. I knew what you meant by creating an instance in a constructor, but I got a little confused and was wondering if you could provide an example of what you meant.

    Here's my code now:

    Code:
    package me.CallMeFilms.TZ.Cmds;
    
    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    
    import me.CallMeFilms.TZ.TZFront;
    
    public class Choose implements CommandExecutor{
       
        public static TZFront front = new TZFront();
        public static boolean isBeingChecked = false;
       
        @Override
        public boolean onCommand(CommandSender sndr, Command cmd, String label, String[] args) {
                if(!(sndr instanceof Player)) {
                    sndr.sendMessage("Sorry, but that command can not be executed by console personnel. Please try again in-game.");
                } else {
                    Player player = (Player) sndr;
                    player.sendMessage("Test 3");
                    player.sendMessage("Test 4");
                    switch(args.length) {
                    case 0:
                        player.sendMessage(ChatColor.RED + "Usage: /choose <tribe>");
                        break;
                    case 1:
                        if(front.getConfig().getStringList("Tribes").contains(args[0])) {
                            isBeingChecked = true;
                            } else {
                                player.sendMessage(ChatColor.GRAY + "[" + ChatColor.YELLOW + ChatColor.BOLD + "Tribe" + ChatColor.GOLD + ChatColor.BOLD + "z" + ChatColor.GRAY + "] " + ChatColor.WHITE + ChatColor.BOLD + ">> " + ChatColor.RED + args[0] + "is not an existing tribe.");
                            }
                        break;
                    default:
                        player.sendMessage(ChatColor.GRAY + "[" + ChatColor.YELLOW + ChatColor.BOLD + "Tribe" + ChatColor.GOLD + ChatColor.BOLD + "z" + ChatColor.GRAY + "] " + ChatColor.WHITE + ChatColor.BOLD + ">> " + ChatColor.RED + "Too many arguments.");
                        }
                    }
                return true;
                }
        }
    
     
  6. Online

    timtower Moderator Moderator

    @KingOfTheEast01 You can't do new TZFront, your console is throwing massive errors, PluginAlreadyInitialzed to be precise.
     
  7. Offline

    Coww

    @KingOfTheEast01 What I meant is either:
    1. Code:
      this.getCommand("choose").setExecutor(new Choose(this));
      in your main class and the following in your Choose class:
      Code:
      private TZFront front;
      
      public Choose(Plugin plugin) {
          front = plugin
      }
    2. or in your main class
      Code:
      public static final TZFront plugin;
      ...
      ... onEnable() {
          plugin = this;
      }
      so you can access the plugin instance with TZFront.plugin
     
  8. Offline

    KingOfTheEast01

    Thank you for this. Seeing @Coww's response also helped explain this. I didn't realize I should have been doing this. This actually helped and I then received an error, but managed to fix it. I just have one question now. You were right about the isBeingChecked boolean needing to be tied to something Coww, and I was wondering how you'd suggest I do this.
     
  9. Offline

    KingOfTheEast01

    Bumpiddy bump bump.
     
  10. Offline

    Coww

    @KingOfTheEast01 As I already said:
    1. create a list (or set) named `isBeingChecked` e.g. in your main class (make it accessible for other classes)
    2. add the player's uuid to that list (or set) in your onCommand method
    3. and once your other task ("the check") is completed, remove the player's uuid from that list/set.
     
Thread Status:
Not open for further replies.

Share This Page