Detect if player flying

Discussion in 'Plugin Development' started by AndrewM16921, Nov 6, 2011.

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

    AndrewM16921

    Is there a simple way to detect if a player is flying or not?
     
  2. Offline

    bergerkiller

    @AndrewM16921 Simple answer: no
    However, you can check if the expected new location calculated from the player velocity and old location matches the new location in onPlayerMove.
     
  3. Offline

    AndrewM16921

    So... if the expected location is not equal to the new location, given some margin of cushion?

    or... if I wanted to "cancel" it, I could set the new location to the expected location perhaps? Or would that make it all funky... *tries it out*

    Eh... not exactly working out. I'm too lazy, so forget it. Thanks though. :)
     
  4. Offline

    halley

    Don't forget 'player can jump while sprinting', 'player can climb ladders', and other complications. It's very tricky to calculate the "expected" location and the appropriate margin for lag. Instead of writing my own, I would rely on the already-written, already-debugged plugins that get this mostly right.
     
  5. Can't you test if there is AIR under the players feet. AND player is not falling down or jumping or touching ladder.
     
  6. Offline

    Taco

    Here's what I think would determine them as flying:

    They are more than 2 blocks above a solid block and their velocity is either upwards or 0 in the Y direction.
     
  7. Offline

    bergerkiller

    @Taco and don't forget players that run faster than normal, but you can use a simple velocity check for that.
     
  8. Offline

    halley

    So players aren't allowed to jump from rooftop to rooftop? Half of that jump will be in the upward direction, and they'll be far over the ground after they leave the first roof. I know lots of jumping-puzzles that would break if you disallowed this situation.

    What you can do is keep track of their suspiciousness over time. Let's say that your condition "2 blocks above a solid block" was 1 suspicion point. Let's say that your condition "velocity is upward" is 1 suspicion point. On every tick, accumulate all of the suspicious conditions. Flush their suspicion points back to 0 if they're clearly safe on the ground at a standstill. If their suspicion point total gets over a certain threshold (say 50 suspicion points), then they're likely to be flying. I'm making up numbers here, but run some measurement tests. Mind you, all of these tests are going to take time to calculate (especially if you have to search for solid blocks), so if there are a lot of online players, you may need to throttle back and only test a few players at a time.

    Again, I'd rather trust some other plugin that's already written, than try to code this up from scratch.
     
  9. Offline

    Father Of Time

    It seems like a lot of people are looking at correcting this issue from the vertical velocity, but when I was contemplating fixes for this for my server I was thinking of approaching it from another angle.

    I was thinking of making this detection based off OnPlayerMovement. Now you can’t simply kick players who are airborne with zero Y velocity because this would trigger every time a player reached the apex of a leap, but what you could do is compare the MoveFrom location to the MoveTo location, and if the X or Z changed without the Y changing it means they moved laterally in mid air.

    Granted you would need to put a small margin of error because I’m sure there are some instances where a player could have some lateral movement while at the apex of a jumping arch, but I would imagine there is no legitimate situation where a person would move 2 blocks or more in one direction in mid air without losing any altitude.

    After reading Halleys wonderful idea regarding an accumulated point system I think these two ideas combined would make an effective fly detection system. Basically you could make it so that every second a point decays, and every time a player moves in the X or Z direction while airborne without any Y velocity will result in a “flyingpoint” being earned, then simply set the threshold of how many points it takes to trigger an action.

    What holes can you guys find with this logic, I’m curious if there is some major flaw with my idea, because frankly its easy concept seems too good to be true.
     
  10. Offline

    AndrewM16921

    Well, much of this discussion was very interesting. I will certainly try out some of these methods and see what happens. I'd use an existing plugin, but 1. I like to challenge myself to make stuff myself, not just to use on my server, but for the programming experience; 2. I have a number of additional conditions that would require me to actually take their code and modify it rather than simply using their plugins next to mine, so I'd rather implement it myself if possible; 3. I don't want to kick on flight, but rather (seeing as I only want to detect flight in the pvp world on my server) implement some consequences, whether it be teleporting them to the spawn, inflicting damage, or actually teleporting the player back to the ground or something to effectively prevent this asshattery.
     
    Father Of Time likes this.
  11. Offline

    Father Of Time

    If only I heard this more often! :D I say make it send them the message "You fly too close to the Heavens and anger the Gods" and blast their a$$ with a lightning bolt!

    I am interested in hearing about any success/failures the suggested ideas result in, please do us the favor of reporting your findings.

    Good luck with your project Andrew!
     
  12. Offline

    AndrewM16921

    :D Ironic you say that, the pvp world I designed is sick (in my opinion), with constant lightning striking in loaded chunks every ... i think it was every second ... and nether environment and a landscape which I actually based off the wilderness from runescape (lol). So actually, striking them with a lightning bolt would be a reallllly good idea. Thanks! :)

    "You flew too close to the Heavens, and Zeus smited your ass!" xD
     
  13. Offline

    Father Of Time

    Sounds like a good time, I love how some simple environment changes can really change the feel of the game. Glad my aimless rambling actually lead to a good idea! :D

    Keep us informed about your progress with this project, I'm curious to see what ends up working. Funny enough after commenting in this thread yesterday it peeked my interest, so I decided to just write some psudo code during my lunch break at work for sh*ts and giggles.

    Code:
    import java.util.List;
    import org.bukkit.ChatColor;
    import org.bukkit.entity.Player;
    import org.bukkit.event.player.PlayerListener;
    import org.bukkit.event.player.PlayerMoveEvent;
    
    public class PlayerListener extends PlayerListener
    {
        private static Map<String, int> ViolationDatabase = new HashMap<String, int>();
        public void onPlayerMove(PlayerMoveEvent event)
        {
            Player player = event.getPlayer();
    `        String playername = player.getName();
            Block blockatfeet = player.getLocation().getBlock().getRelative(BlockFace.DOWN);
            if ( block.getType() == Material.AIR )
            {
                Location fromloc = event.getFrom();
                Location toloc = event.getTo();
    
                if ( ( fromloc.getBlockX() != toloc.getBlockX() || fromloc.getBlockZ() != toloc.getBlockZ() ) && fromloc.getBlockY() == toloc.getBlockY() )
                {
                    if( ExceedsThreshold( playername, 1 ) )
                    {
                        // Take punishment action here, they have violated too many times.
                    }
    
                    else
                    {
                        RecordViolation( String playername, int penalty )
                        player.SendMessage( ChatColor.RED + "Warning" + ChatColor.WHITE + ": You've been acused of flying and have earned a violation point.");
                        // log.info( playername + " has earned a fly violation.");
                    }
                }
            }
        }
    
        public static void RecordViolation( String playername, int penalty )
        {
            if( ViolationDatabase.contains( playername ) )
                ViolationDatabase.get( playername ) += penalty;
    
            else
            ViolationDatabase.put( playername, penalty );
        }
    
        public static boolean ExceedsThreshold( String playername, int penalty )
        {
            if( ViolationDatabase.contains( playername ) )
            {
                if( ViolationDatabase.get( playername ) + penalty > 10 )
                    return true;
            }
    
            return false;
        }
    
        public static void ViolationDecay()
        {
            List<String> topurge = new List<String>();
            for (Map.Entry<String, int> Record : ViolationDatabase.entrySet() )
            {
                ViolationDatabase.get( record.getKey() ) -= 1;
                if( ViolationDatabase.get( record.getKey() ) <= 0 )
                    topurge.add( Record.getKey() );
            }
    
            for( String name : topurge )
            {
                ViolationDatabase.remove( name );
            }
        }
    
        public static void InitiateDBTimer()
        {
            Bukkit.getServer().getScheduler().scheduleAsyncRepeatingTask(Bukkit.getPluginManager().getPlugin("MCAuthority"), new Runnable(){public void run()
            {
                ViolationDecay();
            } }, 20L, 20L * 60L ); // every 60 seconds a violation will decay
        }
    }
    I haven't had a chance to plug this into the server to test out how well it detects flying, if at all; but I thought I would share my thought process.

    Every time a player moves 1 block North/South/East/West without dropping in altitude with air underneath them they will earn a violation point, after a player earns 50 violation points it triggers a function (this is where you would put your "take action". Also, it has a timer that will decay 1 violation point for each person in the violation list every second (I don't like the current double loop, I want tot think of a better way to purge a single violation point every second from every record in the map) So if a player legitimately earns a violation, say from jumping and hitting the apex of the leap they will earn a point but quickly lose it, but if someone is openly flying north they will fastly rack up violation points, and after traveling 50 tiles trigger the punishment event.

    again, this was simply some daydreaming while I was eating my nachos, but I figured I would share it. I hope it manages to help!
     
  14. Offline

    Evangon

    I'm not a great coder, so don't expect any sophisitcated code, or even anything, but it's a suggestion.

    When the player jumps or moves, check if the player has Air underneth, and then start a tick-countdown. If the tick-countdown has stopped and the player still has Air undernethe, you can assume that the player is flying. It can be very buggy because if the player decides to have a lag spike or very laggy if the server is slow and it has to check
    every single little step/jump the player takes.
     
Thread Status:
Not open for further replies.

Share This Page