if player moved too fast

Discussion in 'Plugin Development' started by CAPS123987, Oct 28, 2022.

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

    CAPS123987

    Hi, I have a question, how can I detect if player moved too fast. In Console there is message: player moved too quickly! Can I somehow detect this event/thing, and how can i get the position where he moved?
     
  2. Offline

    Kars

    PlayerMoveEvent is called many times per second, but you can't deduce speed from it.
    I solved this problem before and the only way to do it is to have a repeating task that saves the player's current location and compares it to the last known location every interval; then determine speed that way.
     
  3. Offline

    CAPS123987

    Oh, thank you :)
     
  4. Offline

    Kars

    @CAPS123987 best to do it asynchronously for performance purposes.
     
  5. Offline

    Strahan

    Well, you could always filter PME and reject mouse movement triggers. If you only process when the player actually traversed a block it may be useable.
     
  6. Offline

    CAPS123987

    Sory but what is PME?
     
  7. Offline

    Kars

    Yea i tried that but there's no way of knowing the speed still. You have to calculate it by distance traveled since the last measurement, and with PME there's no way of knowing the interval; unless you calculate it which is troublesome.
    A repeating task is the best way because you can do this asynchronously also.
    PlayerMoveEvent
     
  8. Offline

    CAPS123987

    well I solved it like that and it works


    HashMap<Object, Location> Locationtemp = new HashMap<Object, Location>();

    public void PlayerMoved(PlayerMoveEvent e) {
    Player p = e.getPlayer();

    double loc = Locationtemp.get(p).distance(e.getFrom());
    if(loc > 1) {
    p.teleport(Locationtemp.get(p)); //do what you want if player moved too fast
    p.sendMessage(String.valueOf(loc) + "you telepoted");
    }else {
    Locationtemp.put(p, e.getTo());
    }
    }
     
  9. Offline

    Kars

    @CAPS123987 yea but this is extremely performance heavy, as this happens every tick for every player on your server. And it happens in the main thread, that is the central issue. If you don't care about performance this is fine but there is another issue still.

    You have no control over the interval and thus the speed that you check. With your method, you might not be able to fly with elytra or be launched into the air with TNT. I suggest you try it.

    If you want control over the interval, performance and movement speed. And also perhaps not rubberband players under certain conditions, using a repeating task asynchronously (so in another thread) is ideal.
     
  10. Offline

    CAPS123987

    well I have very small server only with 3 players so it will do.
    and it works even if you fly with elytra o tnt, I tested it :)
     
  11. Offline

    Strahan

    Yea, you have to keep a collection to track time since last movement. Can be more work, true, but I'm a bit anal about avoiding tasks when I can.

    It looks like you are basically just checking to see if they moved more than one block distance since their last move, right? If so, why are you using the Map at all? PME has getFrom and getTo to let you know where they came from and where they went. Would seem to be a bit simpler.

    Also you should filter it, no need to run every time they move the mouse around. Why are you keying on Object btw? You are using Player, so just set it to Player. If you are going to make a collection keyed on players btw, you should be listening for PlayerQuitEvent and removing them when they leave otherwise it will cause a memory leak. If you said this works, I assume you are adding people to the map when they join, right? Because if not, the first time someone joins and moves it should start filling your log with errors since you are getting from Locationtemp without checking for existence.

    Lastly, and this is getting into the weeds a bit but you really should declare the collection as Map<Player, Location> locationtemp = new HashMap<>(); per SOLID design. They way you did violates Liskov Substitution Principle. Doesn't matter in this use case, but it's good to form proper habits. Also variables should be camelCase, not PascalCase.
     
  12. Offline

    Kars

    @Strahan he said he doesn't care about performance and apparently wants to do it the easy way with the least amount of work.
     
    Strahan likes this.
  13. Offline

    CAPS123987

    @Strahan it checks if player moved between PME, that hapens only if you teleport. I also remove them from HashMap-I just didn't include it here and lastly, yes i add them to HashMap when they join.
    Realy thanks to you guys
     
Thread Status:
Not open for further replies.

Share This Page