Solved Same Command with Different Actions

Discussion in 'Plugin Development' started by Admison, Jan 22, 2016.

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

    Admison

    Hi there,

    To get to the point, I am trying to make a teleport plugin that could be used for both teleporting to players personally and teleporting players to other players. Sounds simple enough, right? Apparently not for me. I recently started Java and plugin development so I am not an expert by any means. Essentially what I want to do is make it so that if a player does /teleport <player> it takes them to the designated player, and if they do /teleport <player1> <player2> then this takes Player1 to Player2.

    Here's my code:
    Code:
    import org.bukkit.Bukkit;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class Goto extends JavaPlugin {
     
        public boolean onCommand(CommandSender sender, Command cmd, String cmdLabel, String[] args) {
         
            // Teleport yourself to a player.
            Player player = (Player) sender;
            Player target = Bukkit.getServer().getPlayer(args[0]);
         
            if (cmd.getName().equalsIgnoreCase("teleport")) {
                if (!sender.hasPermission("tp.goto")) {
                    sender.sendMessage("§9Permissions> §7This requires Permissions Rank [§9MOD§7].");
                    return true;
                }
                if (args.length == 0) {
                    player.sendMessage("§9Teleport> §7Command List:");
                    player.sendMessage("§6/teleport §7<player1> (<player2>)");
                    return true;
                }
                if (target == null) {
                    player.sendMessage("§9Teleport> §7Player not found.");
                    return true;
                }
                if (target == sender) {
                    player.sendMessage("§9Teleport> §7You cannot teleport to yourself.");
                    return true;
                }
                else {
                    player.teleport(target);
                    player.sendMessage("§9Teleport> §7You teleported to " + target.getName() + ".");
                    return true;
                }
            // Teleport a player to another player.
                Player target1 = Bukkit.getServer().getPlayer(args[1]);
                Player target2 = Bukkit.getServer().getPlayer(args[2]);
             
                if (target1 == target2) {
                    player.sendMessage("§9Teleport> §7You cannot teleport a player to themselves.");
                }
                else {
                    target1.teleport(target2);
                    target1.sendMessage("§9Teleport> §7" + sender + " teleported you to " + target2.getName() + ".");
                    target2.sendMessage("§9Teleport> §7" + sender + " teleported " + target1.getName() + " to you.");
                    player.sendMessage("§9Teleport> §7You teleported " + target1.getName() + " to " + target2.getName() + ".");
                }
                return true;
            }
            return false;
        }
    }
    
    This code, of course, does not work. I realize that the error is unreachable code, but I do not know how to rectify that.

    Finally, I would definitely appreciate if someone could explain args to me. Spigot does not seem to like it if I attempt to change the value under Player target = Bukkit.getServer().getPlayer(args[0]), and as a result I do not have any confidence that the two args underneath my comment are going to help me at all.

    Any and all help, related or unrelated, would definitely be appreciated.
    Thank you. :)
     
  2. Offline

    stefvanschie

    @Admison I would make it check if the length of the args is one, then get the player from args[0] and then teleporting him. After that you check if the length of the args is two, then get both players and teleport them.
     
    Admison likes this.
  3. Offline

    ShowbizLocket61

    @Admison
    Okay. Look at your code a bit closer, you are teleporting the sender to the target if there are not 0 arguments. That means, however many arguments you type into the command, you'll just teleport to the first one. Instead, do it like stefvanschie said, and check for the length of the args array. If it's 0, error message. If it's 1, teleport the sender. If it's 2, teleport target 1 to target 2.

    Before Zombie_Striker gets at you, don't blind cast:
    This will throw you an ugly ClassCastException if you run it from console. Not when, but if.

    args is an Array of Strings. Every element of the array is an extra word in the command. For example, if you type /hi 1 2 3, the args array would be ["1","2","3"]. What do you mean by Spigot not liking you changing the value under Player target = Bukkit.getServer().getPlayer(args[0])?

    That brings me to one last point: The array indices starts at 0. You have that right in the top half, where you used args[0], but then you used args[1] and args[2]. No, it's the same command! That would get you the second and third elements instead of the first and second ones you want.

    Edit: Agh, my wifi made me a double post. How can I delete this one?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jan 23, 2016
    Admison likes this.
  4. Offline

    Admison

    Thank you to both of you for clearing that all up for me. However, I still have a problem. I sorted out all the args and attempted to run the plugin and everything seemed fine. So I decided to go in-game and tried my first command, /tp, and got the following error:

    Code:
    [21:32:44 INFO]: Admison issued server command: /tp
    [21:32:44 ERROR]: null
    org.bukkit.command.CommandException: Unhandled exception executing command 'tp' in plugin Teleport v1.0
            at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[spigot.jar:git-Spigot-db6de12-18fbb24]
            at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) ~[spigot.jar:git-Spigot-db6de12-18fbb24]
            at org.bukkit.craftbukkit.v1_8_R3.CraftServer.dispatchCommand(CraftServer.java:641) ~[spigot.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.PlayerConnection.handleCommand(PlayerConnection.java:1162) [spigot.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java:997) [spigot.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java:45) [spigot.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java:1) [spigot.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.PlayerConnectionUtils$1.run(SourceFile:13) [spigot.jar:git-Spigot-db6de12-18fbb24]
            at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_66]
            at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_66]
            at net.minecraft.server.v1_8_R3.SystemUtils.a(SourceFile:44) [spigot.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:715) [spigot.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:374) [spigot.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:654) [spigot.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:557) [spigot.jar:git-Spigot-db6de12-18fbb24]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_66]
    Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
            at admison.teleport.Goto.onCommand(Goto.java:33) ~[?:?]
            at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[spigot.jar:git-Spigot-db6de12-18fbb24]
            ... 15 more
    I have tried countless ways to fixing this but to no avail. So I would really appreciate the help. Here's my code:
    Code:
    package admison.teleport;
    
    import org.bukkit.Bukkit;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class Goto extends JavaPlugin {
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
            if (!(sender instanceof Player)) {
                if (args.length == 0) {
                    sender.sendMessage("§9Teleport> §7Command List:");
                    sender.sendMessage("§6/tp §7<player>\n§6/tp §7<player1> <player2>");
                    return true;
                }
                if (args.length == 1) {
                    sender.sendMessage("§9Teleport> §7You cannot teleport to players.");
                    return true;
                }
                if (args.length == 2) {
                    sender.sendMessage("ok");
                    return true;
                }
                if (args.length > 2) {
                    sender.sendMessage("§9Teleport> §7Command List:");
                    sender.sendMessage("§6/tp §7<player>\n§6/tp §7<player1> <player2>");
                    return true;
                }
            }
    
            Player p = (Player) sender;
            Player t = Bukkit.getServer().getPlayer(args[0]);
            Player t2 = Bukkit.getServer().getPlayer(args[1]);
    
            /* Teleport yourself to a player. */
    
            if (cmd.getName().equalsIgnoreCase("teleport")) {
                if (!sender.hasPermission("tp.goto")) {
                    sender.sendMessage("§9Permissions> §7This requires Permissions Rank [§9MOD§7].");
                    return true;
                } else {
                    if (t == null) {
                        p.sendMessage("§9Teleport> §7Player §9" + t.getName() + "§7 not found.");
                        return true;
                    }
                    if (t2 == null) {
                        p.sendMessage("§9Teleport> §7Player §9" + t2.getName() + "§7 not found.");
                        return true;
                    }
                    if (t == t2) {
                        p.sendMessage("§9Teleport> §7You cannot teleport §9" + t.getName() + "§7 to themselves.");
                        return true;
                    }
                    if (t == p) {
                        p.sendMessage("§9Teleport> §7You cannot teleport to yourself.");
                        return true;
                    }
                    if (t2 == p) {
                        p.sendMessage("§9Teleport> §7You teleported §9" + t2.getName() + "§7 to yourself.");
                        return true;
                    }
                    if (args.length == 0) {
                        p.sendMessage("§9Teleport> §7You did not specify a player.");
                        return true;
                    }
                    if (args.length == 1) {
                        p.teleport(t);
                        p.sendMessage("§9Teleport> §7You teleported to §9" + t.getName() + "§7.");
                        return true;
                    }
                    if (args.length == 2) {
                        t.teleport(t2);
                        p.sendMessage("§9Teleport> §7You teleported §9" + t.getName() + "§7 to §9" + t2.getName() + "§7.");
                    }
                    if (args.length > 2) {
                        p.sendMessage("§9Teleport> §7Command List:");
                        p.sendMessage("§6/tp §7<player>\n§6/tp §7<player1> <player2>");
                        return true;
                    }
                }
            }
            return true;
        }
    }
    
    }

    Thank you.
     
    Last edited: Jan 23, 2016
  5. Offline

    Vinceguy1

    Your error is line 32 simply put, if the length of args is 1 and you try to get args[1] it won't work, try something like
    Player t2 = null;
    if (args.length == 2)
    {
    t2 = Bukkit.getServer().getPlayer(args[1]);
    }
     
    Admison likes this.
  6. Offline

    ShowbizLocket61

    @Admison
    If you do /tp, args is empty. Taking the first element of an empty array.. that doesn't end well. Do /tp <player>
     
    Admison likes this.
  7. Offline

    Admison

    Ah, I just noticed that I did not paste the package line. Therefore, the actual error is Player p = (Player) sender;... that was my bad, sorry. I edited my previous post. Sorry again.
     
  8. Offline

    ShowbizLocket61

    @Admison
    This is line 33, correct?
    Code:
    Player t = Bukkit.getServer().getPlayer(args[0]);
    args is empty, and you're trying to take its first element with args[0].

    You check for the length of the arguments, but you do it after. Put your length checks before you access the array.
     
    Admison likes this.
  9. Offline

    Admison

    @stefvanschie @ShowbizLocket61
    Hey guys, I just wanted to thank you both for all the help. I sincerely appreciate it. Everything is working perfect now!

    @Vinceguy1
    Of course, I cannot leave you out. I appreciate you attempting to help out. I might try that sometime in the future with a different plugin, if it applies.

    Marking this as solved.
    Requesting a thread lock. :)

    Oh, and do not worry, the code looks a lot better now, in my opinion. I rewrote the whole thing! :p
     
    Last edited: Jan 27, 2016
Thread Status:
Not open for further replies.

Share This Page