Change Player Location On Disconnect

Discussion in 'Plugin Development' started by SteppingHat, Jul 5, 2012.

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

    SteppingHat

    Hey there!

    So, this plugin I'm working on is a plugin which temporarily teleports a user. When they teleport to a player, after a specified amount of time, they are teleported back.

    A problem I am having is that during the countdown, if they log out and log back in, they are at the location they teleported to without the countdown timer to teleport them back. An exploit in the plugin.

    So I've been trying to find a way to either set their location so when they log back in, they spawn in the spot where they were before initiating the countdown.

    The source code for the timer portion is as follows. If you need some more code, just ask.
    Code:
    this.getServer().getScheduler().scheduleAsyncRepeatingTask(this, new Runnable() {
        int userseconds = getConfig().getInt("teleporttime");
        int halfseconds = configseconds / 2;
        int quarterseconds = configseconds / 4;
        public void run() {
            if(userseconds != -1) {
                if(userseconds != 0) {
                    if(userseconds == halfseconds) {
                        player.sendMessage(ChatColor.YELLOW + "" + userseconds + ChatColor.RED + " seconds left");
                    }
                    if(userseconds == quarterseconds) {
                        player.sendMessage(ChatColor.YELLOW + "" + userseconds + ChatColor.RED + " seconds left");
                    }
                    if(userseconds == 3) {
                        player.sendMessage(ChatColor.YELLOW + "" + userseconds + ChatColor.RED + " seconds left");
                    }
                    userseconds--;
                } else {
                    player.teleport(originalPlayerLocation);
                    userseconds--;
                    player.sendMessage(ChatColor.RED + "Your time has expired and you have been teleported back");
                }
            }
        }
    }, 0L, 20L);
    Thanks in advance for all your help! It's much appreciated :)
     
  2. Your code relies on the Player object being the same... which it can break any time expecially when player reconnects.

    I'm unsure if there's an easier way... but basically you can store the player's name as final before running that and use the name to get the OfflinePlayer object, check if player is online and continue normally... if he's not online, set his last location to the teleport location so when he re-joins he'll spawn there... that is, if the teleporting back is that critical.

    Still, you didn't supply enough code, show what you have before that task.

    Also, you use alot of conditions when you can use more of them in one single condition... example:
    Code:
    if(condition1 || condition2 || condition3)
    {
        // if any one of those condition is true, this code will execute
        // the || is logic OR, which means... well, or =) "this or that or whatever"
        // also, the && is logic AND, which you can use to require all conditions to be true in order to execute...
    }
     
  3. Offline

    r0306

    SteppingHat
    Add this block of code to where ever your code is to teleport the players back inside the scheduler is located:
    Code:
    if (!player.isOnline())
    {
     
      toTeleport.add(player.getName());
     
    }
    Then add another event handler and a list:
    Code:
    List<String> toTeleport = new ArrayList<String>();
     
    @EventHandler
    public void onJoin(PlayerJoinEvent event)
    {
     
        Player player = event.getPlayer();
     
        if (toTeleport.contains(player.getName())
        {
       
                player.teleport(originalPlayerLocation);
                toTeleport.remove(player.getName());
     
        }
     
    }
    This should successfully teleport them back when their time limit is reached by putting them in the list.
     
  4. Offline

    SteppingHat

    r0306
    That won't work because the originalPlayerLocation isn't stored anywhere so it can't be recalled in the PlayerJoinEvent.

    So the plugin will know if someone left during the teleport period, just wouldn't know where to teleport them to.
     
  5. Offline

    the_merciless

    how i would do it.... (not going to write it all just give u my basic idea)

    If player types command,
    save player location
    tp to other player
    add player to hashmap
    wait 10 seconds (or however long)
    tp back to saved location.
    remove from hashmap

    then on a playerquit event

    if player is in hashmap
    tp to saved location
    remove from hashmap

    Im guessing the only reason you would want this is so ppl can give each other items, if thats the case wouldnt it be easier to make a command that would send the items to the player if its in your inventory? Just an idea, may not be what ur looking for.
     
  6. Offline

    r0306

    That's why you have to store it somewhere like in a hashmap.
     
  7. Offline

    SteppingHat

    Yeah I know that. I just don't know how to store and reacal location variables :p
    Hashmaps is something that I just learnt about a week or so ago so I'm fairly new to the thing.
     
  8. Offline

    r0306

    SteppingHat
    It's quite simple actually. You can store anything in a hashmap as long as you define it in the variable declaration.
    Code:
    HashMap<String, Location> locations = new HashMap<String, Location>();
     
    //to store the info, use
     
    locations.put(player.getName(), originalPlayerLocation);
     
    //then to call it up from another method, you would use
     
    Location originalPlayerLocation = locations.get(event.getPlayer().getName());
     
    //don't forget to remove the item after you're done
     
    locations.remove(event.getPlayer().getName());
     
  9. Offline

    SteppingHat

    Ahh so that's how you recall it. Thanks heaps!
    I'll tell you in a few if it works.

    It hasn't seemed to work because my onPlayerJoin event doesn't seem to work

    Code:
    @EventHandler
        public void onJoin(PlayerJoinEvent event) {
            Player player = event.getPlayer();
            Bukkit.getServer().broadcastMessage(player.getDisplayName() + " has logged in and ");
           
            if (toTeleport.contains(player.getName())) {
                Location originalPlayerLocation = toTeleportLoc.get(event.getPlayer().getName());
                player.teleport(originalPlayerLocation);
                toTeleport.remove(player.getName());
                toTeleportLoc.remove(event.getPlayer().getName());
                Bukkit.getServer().broadcastMessage("is in the hashmap");
            } else {
                Bukkit.getServer().broadcastMessage("is not in the hashmap");
            }
        }
    I've imported all the stuff I needed to and it doesn't come up with any errors.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 26, 2016
  10. Offline

    r0306

    SteppingHat
    Does it show the "is not in the hashmap" message?
     
  11. Offline

    SteppingHat

    Nup
     
  12. Offline

    r0306

    SteppingHat
    Does it even show the message you put in the beginning?
     
  13. Offline

    SteppingHat

Thread Status:
Not open for further replies.

Share This Page