Solved Stop teleport if player moves

Discussion in 'Plugin Development' started by FreeMotion45, Oct 21, 2015.

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

    FreeMotion45

    Hello,

    This may be a question of someone that is VERY beginner. And I am.
    I tried to stop the player from teleporting if he moves. Though I didn't get it to work...

    It cancels it on the moment I run the command. My code :

    Code:
    Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
                                    @Override
                                    public void run() {
                                        if(getConfig().getBoolean("global_enabled")==true){
                                            Player p = (Player) sender;
                                            double x = getConfig().getDouble("global_x");
                                            double z = getConfig().getDouble("global_z");
                                            double y = getConfig().getDouble("global_y");
                                            double pitch2 = getConfig().getDouble("global_pitch");
                                            double yaw2 = getConfig().getDouble("global_yaw");
                                            String world2 = getConfig().getString("global_world");
                                            World world = Bukkit.getServer().getWorld(world2);
                                            Location gog = new Location(world, x, y, z, (float)yaw2, (float)pitch2);
                                            p.teleport(gog);
                                            return;
                                        }
                                        else
                                        {
                                            ((Player)sender).teleport(((Player)sender).getWorld().getSpawnLocation());
                                        }
                                    }
                                }, delay*20L);
                                Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable(){
    
                                    @Override
                                    public void run() {
                                        Player p = (Player) sender;
                                        double x = p.getLocation().getX();
                                        double y = p.getLocation().getY();
                                        double z = p.getLocation().getZ();
                                        World w = p.getLocation().getWorld();
                                        Location lol = new Location(w, x, y, z);
                                        if(lol != p.getLocation()){
                                            p.sendMessage("Teleport cancel");
                                            Bukkit.getScheduler().cancelAllTasks();
                                        }
                                      
                                    }
                                  
                                }, 0L, 20L);
    Thanks for the help !
    ( I know I tried to compare the players current location to his location in the repeating task... )

    Best Regards,

    FreeMotion
     
  2. Offline

    mcdorli

    Nah, this isn't really a beginner question.
    My idea:

    Create a boolean named sonething like "playerMoved" inside your listeners class.

    If the command was fired, set it to false, and start a bukkitRunnable with the correct delay.

    If the variable is false, and the player move event fired, set the variable to true, and send the player a message.

    In task, you need to check, if the variable is true or false, and only teleport, if the player didn't move.

    Some notes:
    You should store the booleans in a hashmap with the player uuid as a key.

    EDIT:
    I really over complicated this. just cancel the task if the player moves and send him a message.
     
  3. Offline

    FreeMotion45

    Thats what I tried to do. But I can't get if the player has moved or not. I stored the location but it constantly repeats to store them, so its trying to check if stored location = players location. And the both are the same because its restoring them constantly.
     
  4. Offline

    mcdorli

    Not easier just to use the playerMoveEvent?
     
  5. Offline

    FreeMotion45

    Cant use it, since I am doing it through a command. Or there is a way and I dont know, because I am still new to java .
     
  6. @FreeMotion45 You can use it. Use his suggestion of marking the player in a HashMap (Use their UUID or you will regret it) on the command. If a player moves, check if they are marked as allowed to move or not. If not allowed, cancel the move event.
     
  7. Offline

    RoboticPlayer

    @0ct0berBkkitPlgins Why a HashMap? You could just use an ArrayList. Also, no need to store the UUID here. Just use the players name since it's for temporary data.
     
  8. @henderry2019 I know you could use an ArrayList..... I just happen to like HashMaps for some reason. The UUID is to prevent them changing their name to evade the movement stoppage.
     
  9. Offline

    RoboticPlayer

    @0ct0berBkkitPlgins Honestly, who is going to change their name just so that they can move and teleport one time? Plus, you have to restart the game for the name change to actually take effect.
     
  10. @henderry2019 Maybe someone that is trying to harm a server and/or escape punishment? Besides, there is no "who is going to" or "who would do such a thing". If player A is a moderator and they freeze player B, let's just say player B changes their name just to make it better and being completely oblivious of it's potential cheating. Once player B logs on they suddenly aren't frozen anymore and can walk around and grief the server or hack or go unpunished.

    UUID vs name storage is commonly agreed to be the more secure method. Name reference in commands to apply something to the player is fine, but name storage should NEVER be used unless it is atleast tied with a UUID.

    Plugins on Bukkit should be made as safe as physically possible so that these kind of random issues don't cause security problems.
     
  11. Offline

    Chloe-chan

    Back on the topic,

    You can create a scheduled task to teleport the player after the set amount of time. Store this ID of the scheduled task in a HashMap, with the player's UUID as the key.
    When the player moves (by listening to PlayerMoveEvent), check if his (or her) UUID exists in the Map, then cancel the scheduled task.

    Remember to remove the HashMap entry after acting on the event, like teleporting the player or cancelling the teleport.
     
    Last edited: Oct 21, 2015
  12. Offline

    RoboticPlayer

    Also, if you were to use a HashMap, they key would be the player's name, but what would the value be?
     
  13. Offline

    Chloe-chan

    1. Please take this argument to your own conversation.
    2. It doesn't matter if the UUID or the player name is stored here. In OP's context, this temporary storage is short-lived. It won't be, and it doesn't need to, persist after a few seconds.
    3. It's better (IMO) to store this in a HashMap, so you can see if a key exists in the Map, before acting on the event.
     
  14. Offline

    FreeMotion45

    Thanks for all the help guys,

    So should I do :

    Code:
    HashMap<UUID, task1> task = new HashMap<UUID, task1>();
    ?

    If you could give me a small example.

    Best Regards,

    FreeMotion :)
     
  15. Offline

    Chloe-chan

    HashMap<UUID, Integer> would be the one.

    EDIT: From what I'm reading off your code, you are confused.
    Event handlers should never be in a scheduler. You can call the scheduler in your event handler. Add the ID of the scheduled task to the HashMap, with the player's UUID as the key.
     
  16. I think the easiest way for beginners is with a delayed task and then check if the location changed:
    Code:
    Location a = player.getLocation();
    new BukkitRunnable() {
    public void run() {
    Location b = player.getLocation();
    
    if (a.equals(b)) {
    //Player didn't move
    } else {
    //Player moved
    }
    }
    }.runTaskLater(plugin, 3 * 20);
    But the better way is to use the PlayerMoveEvent because it gets cancelled instantly after the player moves and not after the delay like the example above
     
  17. Offline

    Chloe-chan

    I agree.. But I thought OP tried it and it didn't work. I realised later on that it's just his implementation that had some hiccups.
     
  18. Offline

    mcdorli

    Oh, it took 3 people, to implement my firsf idea? Am I bad with communication or is this just hard to understand (I'm not offensive right now, I really am curios about it)
     
  19. Offline

    Chloe-chan

    No idea. I was just voicing out my opinion.
     
    Last edited: Oct 22, 2015
  20. Offline

    FreeMotion45

    Thanks !

    I solved it, I just registered the players x y z and world right after he ran the command, and then I used a repeat scheduler to check as you did if theloc.equals(secondloc).

    Then I just did an else{ }

    And made everything I need inside. Thanks for all of the help guys :)
     
Thread Status:
Not open for further replies.

Share This Page