Solved I have a command above 2 args and it shows error but when only 1 arg then its ok. HELP

Discussion in 'Spigot Plugin Development' started by parpar8090, Aug 15, 2019.

  1. So I have a command /survivalperks coins <set|add|remove|reset> <number>. and when I do so, I mean when I do /survivalperks coins, it shows me a big error:
    parpar8090 issued server command: /survivalperks coins set
    [12:23:58] [Server thread/ERROR]: null
    org.bukkit.command.CommandException: Unhandled exception executing command 'survivalperks' in plugin SurvivalPerks v1.0
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:47) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:149) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    at org.bukkit.craftbukkit.v1_14_R1.CraftServer.dispatchCommand(CraftServer.java:710) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.PlayerConnection.handleCommand(PlayerConnection.java:1641) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.PlayerConnection.a(PlayerConnection.java:1481) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.PacketPlayInChat.a(PacketPlayInChat.java:47) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.PacketPlayInChat.a(PacketPlayInChat.java:1) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.PlayerConnectionUtils.lambda$0(PlayerConnectionUtils.java:19) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.TickTask.run(SourceFile:18) [spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.IAsyncTaskHandler.executeTask(SourceFile:144) [spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.IAsyncTaskHandlerReentrant.executeTask(SourceFile:23) [spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.IAsyncTaskHandler.executeNext(SourceFile:118) [spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.MinecraftServer.aX(MinecraftServer.java:908) [spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.MinecraftServer.executeNext(MinecraftServer.java:901) [spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.IAsyncTaskHandler.awaitTasks(SourceFile:127) [spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.MinecraftServer.sleepForTick(MinecraftServer.java:885) [spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.MinecraftServer.run(MinecraftServer.java:818) [spigot.jar:git-Spigot-1981d55-da62a66]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_221]
    Caused by: java.lang.ArrayIndexOutOfBoundsException: 2
    at survivalperks.src.commands.MainCMD.onCommand(MainCMD.java:45) ~[?:?]
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    ... 17 more
    In the command class:
    Code (Java):
    else if(args[1].isEmpty()) {
                                    sender.sendMessage("§dTry /survivalperks coins set <number>");
                                    sender.sendMessage("§cTry /survivalperks coins add <number>");
                                    sender.sendMessage("§dTry /survivalperks coins remove <number>");
                                    sender.sendMessage("§cTry /survivalperks coins reset");
                                }
     
  2. first check if the ‘args’ variable has a length of 2, like so:

    if (args.length == 2) {
    // now you can use ‘args[1]’
    }
     
    • Agree Agree x 1
  3. Check the length of the args array using args.length before you access its elements.
     
    • Agree Agree x 2
  4. check args.length...
     
    • Agree Agree x 2
  5. When you use args[1], it is required that the array "args" has a length of two elements or more. So each time you use an array with an unknown length, you should always check its length. You can retrieve it using args.length and then compare it to a number that matches the number of args you need. For example, to execute /survivalperks coins (one command one argument) you should check if the length of the array "args" is equal to 1. If you want to execute the whole command, you should check if the length of the array "args" is equal to 3 and also check if arg[s1] (the second argument) is equal to "set", "add" or "remove". Then convert args[2] to a number. Now for /survivalperks coins reset, you should check if the length of the array "args" is equal to 2 and also check if args[1] is equal to "reset". In all cases you should check if args[0] equals to "coins". Hope I helped :)
     
    • Informative Informative x 2
    • Agree Agree x 1
  6. Thank you! Also if we speak about commands, I have another error that I think it triggered by the
    /survivalperks coins [set|add|remove] <NUMBER. this arg is what causes the new error, coz its a string int, but how to fix it>:
    parpar8090 issued server command: /survivalperks coins set 1
    [21:43:14] [Server thread/ERROR]: null
    org.bukkit.command.CommandException: Unhandled exception executing command 'survivalperks' in plugin SurvivalPerks v1.0
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:47) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:149) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    at org.bukkit.craftbukkit.v1_14_R1.CraftServer.dispatchCommand(CraftServer.java:710) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.PlayerConnection.handleCommand(PlayerConnection.java:1641) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.PlayerConnection.a(PlayerConnection.java:1481) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.PacketPlayInChat.a(PacketPlayInChat.java:47) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.PacketPlayInChat.a(PacketPlayInChat.java:1) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.PlayerConnectionUtils.lambda$0(PlayerConnectionUtils.java:19) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.TickTask.run(SourceFile:18) [spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.IAsyncTaskHandler.executeTask(SourceFile:144) [spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.IAsyncTaskHandlerReentrant.executeTask(SourceFile:23) [spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.IAsyncTaskHandler.executeNext(SourceFile:118) [spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.MinecraftServer.aX(MinecraftServer.java:908) [spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.MinecraftServer.executeNext(MinecraftServer.java:901) [spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.IAsyncTaskHandler.awaitTasks(SourceFile:127) [spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.MinecraftServer.sleepForTick(MinecraftServer.java:885) [spigot.jar:git-Spigot-1981d55-da62a66]
    at net.minecraft.server.v1_14_R1.MinecraftServer.run(MinecraftServer.java:818) [spigot.jar:git-Spigot-1981d55-da62a66]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_221]
    Caused by: java.lang.NullPointerException
    at survivalperks.src.commands.MainCMD.onCommand(MainCMD.java:42) ~[?:?]
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[spigot.jar:git-Spigot-1981d55-da62a66]
    ... 17 more
    The function of the command:
    Code (Java):
                            else if(args[0].equalsIgnoreCase("coins")) {
                                if(args.length >= 2){
                                    if(args[1].equalsIgnoreCase("set")) {
                                        if(args.length >= 3) {
                                            if(Integer.valueOf(args[2]) != null) {
                                                plugin.setBalance(p.getUniqueId().toString(), Integer.valueOf(args[2]));
                                                sender.sendMessage("§aThis Player Now Have " + Integer.valueOf(args[2]) + "§a Coins Successfully");
                                            }
                                        }
                                        else {
                                            sender.sendMessage("§dTry /survivalperks coins set <number>");
                                        }
                                    }
                                    else if(args[1].equalsIgnoreCase("add")) {
                                        if(args.length >= 3) {
                                            plugin.setBalance(p.getUniqueId().toString(), plugin.getBalance(p.getUniqueId().toString()) + Integer.valueOf(args[2]));
                                        }
                                        else {
                                            sender.sendMessage("§cTry /survivalperks coins add <number>");
                                        }
                                    }
                                    else if(args[1].equalsIgnoreCase("remove")) {
                                        if(args.length == 3) {
                                           
                                        }
                                        else {
                                            sender.sendMessage("§cTry /survivalperks coins remove <number>");
                                        }
                                    }
                                    else if(args[1].equalsIgnoreCase("reset")) {
                                        plugin.setBalance(p.getUniqueId().toString(), 0);
                                    }
                                    else {
                                        p.sendMessage("§cUnknown command!");
                                    }
                                }
                                else {
                                    sender.sendMessage("§dTry /survivalperks coins set <number>");
                                    sender.sendMessage("§cTry /survivalperks coins add <number>");
                                    sender.sendMessage("§dTry /survivalperks coins remove <number>");
                                    sender.sendMessage("§cTry /survivalperks coins reset");
                                }
                            }
     
  7. Thank you, but as you saw, the comment before you told me to do it, I already did fixed it but didn't replay, you still did a good job and teached me what the args.length does :)
    Now please read this comment:
     
    • Agree Agree x 1
  8. Line 42: plugin.setBalance(p.getUniqueId().toString(), Integer.valueOf(args[2]));
     
  9. Strahan

    Benefactor

    Is your plugin instance valid? Is the player variable valid? I'm pretty sure Integer.valueOf cannot return a null, so it would be in one of those two other variables.

    PS - BTW you should be implementing a try/catch to handle invalid data being passed to prevent the plugin from puking if they do something stupid like /survivalperks coins set twenty

    PPS - Also I'd suggest a little restructuring. You have a redundant args length check in there (no sense in the overall args.length >=2 check when each subcommand checks as well) and as ItsSchatten suggested, I'd use switch. Something like this:

    Code (Text):
    elseif(args[0].equalsIgnoreCase("coins")) {
      if (args.length < 2) {
        // show help
        return true;
      }

      switch (args[1].toLowerCase()) {
      case "set":
        if(args.length < 3) {
          // show help
          return true;
        }

        try {
          int value = Integer.valueOf(args[2]);
          plugin.setBalance(p.getUniqueId().toString(), value);
          sender.sendMessage(ChatColor.GREEN + "This Player Now Have " + value + " Coins Successfully");
        } catch (NumberFormatException e) {
          // send an error to player
        }
        break;

      case "add":
        etc etc
    I also prefer to check for a negative condition and return rather than keep wrapping code in indents. Oh, also don't embed color codes directly, use the ChatColor enum. That's why it exists. Lastly, your wording is a bit weird. "This Player Now Have ## Coins Successfully" is a bit awkward. Something like "The player's balance has been set to ## coins successfully" would sound a little better.
     
    #10 Strahan, Aug 15, 2019
    Last edited: Aug 15, 2019
    • Useful Useful x 2
  10. your “p” variable or either “plugin” variable on line 42 in MainCMD is null. We do not hve more code to figure out which value could be null. You may try System.out.println(“p: ” + p) & System.out.println(“plugin: ” + plugin)
    To find out quickly in the console which variable is null, but you have to put these before line 42.
     
    • Agree Agree x 1
  11. I had an error before that was with the var PLUGIN and it was null, but I fixed it, so it's no more. also p var is just:
    Player p = (Player) sender;
    and it's ok, I mean the cast needs to be here
     
  12. Please show your full command class and your full class where you register the command.
     
  13. I saw in a random post that the Integer.valueOf(args[2]) is not a good choice, and it should be replaced with something else, but why?
     
  14. The command class
    Code (Java):
    public class MainCMD implements CommandExecutor, Listener {

        public SurvivalPerks plugin;

        public MainCMD(SurvivalPerks plugin) {
            this.plugin = plugin;
        }
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
            if (sender instanceof Player) {
                Player p = (Player) sender;
                //if(p.hasPermission("survivalperks.cmd.main")) {
                   
                    if (cmd.getName().equalsIgnoreCase("survivalperks")) {
                       
                        if(args.length >= 1){
                            if(args[0].equalsIgnoreCase("help")) {
                                p.sendMessage(ChatColor.DARK_GREEN + ">> Available Commands:");
                                p.sendMessage(ChatColor.AQUA + "-> /survivalperks reloadconfig");
                                p.sendMessage(ChatColor.AQUA + "-> /survivalperks coins");
                            }
                            else if(args[0].equalsIgnoreCase("reloadconfig")) {
                                //plugin.reloadCustomConfig();
                                sender.sendMessage("§a> Successfully reloaded!");
                            }
                            else if(args[0].equalsIgnoreCase("coins")) {
                                if(args.length >= 2){
                                    if(args[1].equalsIgnoreCase("set")) {
                                        if(args.length >= 3) {
                                            //if(Integer.valueOf(args[2]) != null) {
                                                try {
                                                      int value = Integer.valueOf(args[2]);
                                                      plugin.setBalance(p.getUniqueId(), value);
                                                      sender.sendMessage(ChatColor.GREEN + "This Player Now Have " + value + " Coins Successfully");
                                                    } catch (NumberFormatException e) {
                                                      // send an error to player
                                                        p.sendMessage("§4Error: §cIt must be a full number!");
                                                    }
                                                //plugin.setBalance(p.getUniqueId().toString(), Integer.valueOf(args[2]));
                                                //sender.sendMessage("§aThis Player Now Have " + Integer.valueOf(args[2]) + "§a Coins Successfully");
                                            //}
                                        }
                                        else {
                                            sender.sendMessage("§dTry /survivalperks coins set <number>");
                                        }
                                    }
                                    else if(args[1].equalsIgnoreCase("add")) {
                                        if(args.length >= 3) {
                                            try {
                                                  int value = Integer.valueOf(args[2]);
                                                  plugin.setBalance(p.getUniqueId(), value);
                                                  sender.sendMessage(ChatColor.GREEN + "This Player Now Have " + value + " Coins Successfully");
                                                } catch (NumberFormatException e) {
                                                  // send an error to player
                                                    p.sendMessage("§4Error:§c It must be a full number!");
                                                }
                                            //plugin.setBalance(p.getUniqueId().toString(), plugin.getBalance(p.getUniqueId().toString())+Integer.valueOf(args[2]));
                                        }
                                        else {
                                            sender.sendMessage("§cTry /survivalperks coins add <number>");
                                        }
                                    }
                                    else if(args[1].equalsIgnoreCase("remove")) {
                                        if(args.length == 3) {
                                           
                                        }
                                        else {
                                            sender.sendMessage("§cTry /survivalperks coins remove <number>");
                                        }
                                    }
                                    else if(args[1].equalsIgnoreCase("reset")) {
                                        plugin.setBalance(p.getUniqueId(), 0);
                                    }
                                    else {
                                        p.sendMessage("§cUnknown command!");
                                    }
                                }
                                else {
                                    sender.sendMessage("§dTry /survivalperks coins set <number>");
                                    sender.sendMessage("§cTry /survivalperks coins add <number>");
                                    sender.sendMessage("§dTry /survivalperks coins remove <number>");
                                    sender.sendMessage("§cTry /survivalperks coins reset");
                                }
                            }
                            else {
                                p.sendMessage("§cUnknown command! Try §n/survivalperks help");
                            }
                        }
                        else{
                            p.sendMessage(ChatColor.AQUA + "Try /survivalperks help");
                        }
                    }
                    //}
                }
            //}
            return true;
        }
    }
    where I register the command class, is in my main class:
    Code (Java):
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.Reader;
    import java.util.UUID;
    import java.util.logging.Level;

    import org.bukkit.ChatColor;
    import org.bukkit.attribute.Attribute;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.configuration.file.YamlConfiguration;
    import org.bukkit.entity.EnderDragon;
    import org.bukkit.entity.LivingEntity;
    import org.bukkit.entity.Monster;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.entity.EntityDeathEvent;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.potion.PotionEffect;
    import org.bukkit.potion.PotionEffectType;

    import net.md_5.bungee.api.ChatMessageType;
    import net.md_5.bungee.api.chat.ComponentBuilder;
    import survivalperks.src.commands.GuiFunction;
    import survivalperks.src.commands.MainCMD;
    import survivalperks.src.perks.ReceiveBlocks;
    import survivalperks.src.perks.SharpnessOnKill;

    public class SurvivalPerks extends JavaPlugin implements Listener, CommandExecutor {
     
        public File customConfigFile;
        public FileConfiguration customConfig;
       
        @Override
        public void onEnable(){
            System.out.println("///////////////////////////////");
                  System.out.println("//                           //");
               System.out.println("// SurvivalPerks Is Enabled! //");
               System.out.println("//                           //");
               System.out.println("///////////////////////////////");
               this.getCommand("survivalperks").setExecutor((CommandExecutor) new MainCMD(null));
               this.getCommand("perks").setExecutor((CommandExecutor) new Perks());
               this.getCommand("mymoney").setExecutor(this);

               this.saveCustomConfig();
             
               getServer().getPluginManager().registerEvents(new GuiFunction(this), this);
               getServer().getPluginManager().registerEvents(new ReceiveBlocks(), this);
               //getServer().getPluginManager().registerEvents(new MoreHealth(this), this);
               getServer().getPluginManager().registerEvents(new MainCMD(this), this);
               getServer().getPluginManager().registerEvents(new SharpnessOnKill(), this);
       
               getServer().getPluginManager().registerEvents(this, this);
        }

        public void reloadCustomConfig() {
            if (customConfigFile == null) {
                customConfigFile = new File(getDataFolder(), "config.yml");
            }
            customConfig = YamlConfiguration.loadConfiguration(customConfigFile);

            // Look for defaults in the jar
            Reader defConfigStream = new InputStreamReader(this.getResource("config.yml"));
            if (defConfigStream != null) {
                YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
                customConfig.setDefaults(defConfig);
            }
        }
        public FileConfiguration getCustomConfig() {
            if (customConfig == null) {
                reloadCustomConfig();
            }
            return customConfig;
        }
        public void saveCustomConfig() {
            if (customConfig == null || customConfigFile == null) {
                return;
            }
            try {
                getCustomConfig().save(customConfigFile);
            } catch (IOException ex) {
                getLogger().log(Level.SEVERE, "Could not save config to " + customConfigFile, ex);
            }
        }
       
        public int getBalance(String playerUuid) {
            return getCustomConfig().getInt("Players." + playerUuid + ".Coins");
        }
        public void PlayerBal(String playerUuid, int amount) {
            getCustomConfig().set("Players." + playerUuid + ".Coins", amount);
        }
        public void setBalance(UUID uuid, int number) {
            getCustomConfig().set("Players." + uuid + ".Coins", number);
        }
    }
     
  15. I am giving you the full class, can you please read?
     
  16. Guys! I think my
    Code (Java):
    public int getBalance(String playerUuid) {
            return getCustomConfig().getInt("Players." + playerUuid + ".Coins");
        }
        public void PlayerBal(String playerUuid, int amount) {
            getCustomConfig().set("Players." + playerUuid + ".Coins", amount);
        }
        public void setBalance(UUID uuid, int number) {
            getCustomConfig().set("Players." + uuid + ".Coins", number);
        }
    aren't correct! I tried Integer.parseInt(args[2]) and it still shows error in the line of:
    Code (Text):
    plugin.setBalance(((Player) sender).getUniqueId(), Integer.parseInt(args[2]));
    So I think the 'setBalance(playerUUID, --) ' isn't working as needed.
     
  17. Please stop wasting our time and take a look at this line.

    It explains the NullPointerException. I recommend to learn how to debug code and learn Java. It will prevent unnecessary questions.
     
  18. Oh sorry! it should be: MainCMD(this); oops
     
  19. Strahan

    Benefactor

    Why are you casting your command classes? That's not necessary. Also as I see you are registering each command to its own class (good); in that case in the command class there is no need to do stuff like if (cmd.getName().equalsIgnoreCase("survivalperks")) as that's the only command that class will ever get. Spigot doesn't run every command through every onCommand handler you know.

    Also your obnoxiously large enable message is redundant; Spigot already sends enable/disable messages.