Array Index Out of Bounds

Discussion in 'Plugin Development' started by jkcclemens, Dec 5, 2011.

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

    jkcclemens

    So, this is my first plugin, and it's mainly for just the staff on my server to use. This is the code I have so far (it's only one class, not everything):
    Code:
    package tk.royalcraf.royalcommands;
    
    import java.util.logging.Logger;
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    
    public class RoyalCommandsCommandExecutor implements CommandExecutor {
    Logger log = Logger.getLogger("Minecraft");
    private RoyalCommands plugin;
    public RoyalCommandsCommandExecutor(RoyalCommands plugin) {
    this.plugin = plugin;
    }
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
    Player player = null;
    Player victim = plugin.getServer().getPlayer(args[0]);
    Player[] onlineplayers = Bukkit.getOnlinePlayers();
    if (sender instanceof Player) {
    player = (Player) sender;
    }
    
    if(cmd.getName().equalsIgnoreCase("level")) {
    if (player == null) {
    sender.sendMessage(ChatColor.RED + "This command can only be used by players!");
    } else {
    player.setLevel(player.getLevel()+1);
    sender.sendMessage(ChatColor.BLUE + "XP level raised by one! You may need to relog to see the changes.");
    }
    return true;
    }
    if(cmd.getName().equalsIgnoreCase("setlevel")) {
    if (player == null) {
    sender.sendMessage(ChatColor.RED + "This command can only be used by players!");
    } else {
    if(player.hasPermission("rcmds.setlevel")) {
    if (args.length < 1) {
    return false;
    } else {
    int toLevel = 0;
    try { toLevel = Integer.parseInt(args[0]); }
    catch (NumberFormatException e) {
    sender.sendMessage(ChatColor.RED + "Your input was not an integer!");
    }
    if (toLevel < 0) {
    sender.sendMessage(ChatColor.RED + "You cannot input anything below 0.");
    } else {
    player.setLevel(toLevel);
    sender.sendMessage(ChatColor.BLUE + "Your XP level was set to " + toLevel + "! You may need to relog to see the changes.");
    }
    }
    }
    }
    return true;
    }
    if(cmd.getName().equalsIgnoreCase("sci")) {
    int errord = 0;
    if (args.length < 2) {
    return false;
    }
    for(int i = 0; i < onlineplayers.length; i++){
        if(!onlineplayers[i].getName().equals(args[0])) {
    sender.sendMessage(ChatColor.RED + "You must input an online player.");
    errord = 1;
        }
    }
    if (errord == 0) {
    int removeID = 0;
    try { removeID = Integer.parseInt(args[1]); }
    catch (NumberFormatException e) { sender.sendMessage(ChatColor.RED + "You must input a numerical ID to remove."); }
    if(removeID <= 0 || removeID > 382 || removeID > 2256 && removeID < 2266) {
    sender.sendMessage(ChatColor.RED + "You must specify a valid item ID.");
    } else {
    victim.getInventory().remove(removeID);
    victim.sendMessage(ChatColor.RED + "You have just had all of your item ID " + ChatColor.BLUE + removeID + ChatColor.RED + " removed by " + ChatColor.RED + sender.getName() + ChatColor.BLUE + "!");
    sender.sendMessage(ChatColor.BLUE + "You have just removed all of the item ID " + ChatColor.RED + removeID + ChatColor.BLUE + " from " + ChatColor.RED + victim.getName() + ChatColor.BLUE + "'s inventory.");
    }
    return true;
    }
    }
    if(cmd.getName().equalsIgnoreCase("speak")) {
    if(args.length < 2) {
    return false;
    }
    int errord = 0;
    for(int i = 0; i < onlineplayers.length; i++){
        if(!onlineplayers[i].getName().equals(args[0])) {
    sender.sendMessage(ChatColor.RED + "You must input an online player.");
    errord = 1;
        }
    }
    if(errord == 0) {
    victim.chat(args[1]);
    }
    }
    return true;
    }
    }
    
    Whenever any of these commands is run without arguments, I get
    Code:
    23:42:21 [SEVERE] null
    org.bukkit.command.CommandException: Unhandled exception executing command 'setlevel' in plugin RoyalCommands v0.0.1
    	at org.bukkit.command.PluginCommand.execute(PluginCommand.java:42)
    	at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:163)
    	at org.bukkit.craftbukkit.CraftServer.dispatchCommand(CraftServer.java:370)
    	at net.minecraft.server.NetServerHandler.handleCommand(NetServerHandler.java:756)
    	at net.minecraft.server.NetServerHandler.chat(NetServerHandler.java:721)
    	at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:714)
    	at org.getspout.spout.SpoutNetServerHandler.a(SpoutNetServerHandler.java:179)
    	at net.minecraft.server.Packet3Chat.a(Packet3Chat.java:33)
    	at net.minecraft.server.NetworkManager.b(NetworkManager.java:226)
    	at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:92)
    	at org.getspout.spout.SpoutNetServerHandler.a(SpoutNetServerHandler.java:546)
    	at net.minecraft.server.NetworkListenThread.a(SourceFile:108)
    	at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:516)
    	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:414)
    	at net.minecraft.server.ThreadServerApplication.run(SourceFile:457)
    Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
    	at tk.royalcraf.royalcommands.RoyalCommandsCommandExecutor.onCommand(RoyalCommandsCommandExecutor.java:28)
    	at org.bukkit.command.PluginCommand.execute(PluginCommand.java:40)
    	... 14 more
    
    So, I can tell that it's having a problem with 0 arguments being passed, but I think that the return false; with the args.length < 2 should cover that.

    Any advice (also, code cleanup tips)?

    PS.
    How does one get all of an array? I want something like args[1:] in Python. If you see the speak command above, you can tell what I'm going for.
     
  2. Offline

    CptSausage

    It could, but it's the wrong way round. args.length > 2 (or args.length >= 2, because I don't see you using args[2] in the code) should do it.
     
  3. Player victim = plugin.getServer().getPlayer(args[0]);

    This line, right at the beginning.
    You are using it without checking first.
     
    CptSausage likes this.
  4. Offline

    CptSausage

    Omg my post is so wrong. Sry. :'(
     
  5. Offline

    halley

    @jkcclemens, Pandemoneus123 has answered correctly. The :28 part of the message is a line number. You should use that to figure out exactly where errors are coming from.

    Code:
    at tk.royalcraf.royalcommands.RoyalCommandsCommandExecutor.onCommand(RoyalCommandsCommandExecutor.java:28)
    
    I don't know if it's a problem with tab characters and cut-and-paste into this editor, but if your code really looks like that, you may want to format it more cleanly. Indentation does not matter to the Java compiler, but it helps the reader understand how the code flows. If you're using Eclipse, you can select the whole file and right-click it, and choose something like Format Code to get it laid out in a more readable way.
     
  6. Offline

    jkcclemens

    Yea, I know how to read a stack trace (probably from the amounts of Python I write), but I didn't realize that :28 was wrong.

    Also, that's just how [ code ] formatted it, indentation is my favorite thing about writing Python, it's also how I code everything else.

    Sorry for the newbishness, but how would you check the Player victim?

    EDIT:

    --facepalm--

    I should've realized this. Fixed by moving it so it can be applied individually.

    Code:
    
    		else if (cmd.getName().equalsIgnoreCase("speak")) {
    			if (args.length < 2) {
    				return false;
    			}
    
    			victim = (Player) plugin.getServer().getPlayer(args[0]);
    
    			int errord = 0;
    			for (int i = 0; i < onlineplayers.length; i++) {
    I also solved the args problem with another class.
     
Thread Status:
Not open for further replies.

Share This Page