@@ -29,50 +29,102 @@ public class GroundSpoofA extends Check implements Listener {
2929
3030 private int buffer = 0 ;
3131
32- private boolean isLastOnGround ;
33-
3432 public GroundSpoofA () {
3533 super ("GroundSpoof" , "A" , false );
3634 }
3735
38- @ EventHandler
39- public void check (PlayerMoveEvent e ) {
36+ private Map <UUID , Boolean > lastInAir = new HashMap <>();
37+ private Map <UUID , Boolean > lastOnGround = new HashMap <>();
38+
39+ @ Override
40+ public void onPacketPlayReceive (PacketPlayReceiveEvent e ) {
4041 Player player = e .getPlayer ();
4142
42- if (player .getLocation ().getY () < 1
43- || player .isDead ()
44- || player .isInsideVehicle ()) {
45- return ;
46- }
43+ if (e .getPacketId () == PacketType .Play .Client .POSITION || e .getPacketId () == PacketType .Play .Client .POSITION_LOOK ) {
4744
48- double groundY = 0.015625 ;
49- boolean client = player .isOnGround (), server = e .getTo ().getY () % groundY < 0.0001 ;
50-
51- if (client && !server && !e .getFrom ().getBlock ().getType ().name ().contains ("LADDER" )
52- && !e .getTo ().getBlock ().getType ().name ().contains ("LADDER" )
53- && !e .getFrom ().getBlock ().getType ().name ().contains ("VINE" )
54- && !e .getTo ().getBlock ().getType ().name ().contains ("VINE" )) {
55-
56- boolean boat = false ;
57- boolean shulker = false ;
58- boolean pistonHead = false ;
59- // TODO Implement better pistons
60- for (Entity entity : player .getNearbyEntities (1.5 , 2 , 1.5 )) {
61- if (entity .getType () == EntityType .BOAT && player .getLocation ().getY () > entity .getLocation ().getY ()) {
62- boat = true ;
63- break ;
45+ WrappedPacketInFlying packet = new WrappedPacketInFlying (e .getNMSPacket ());
46+
47+ if (ServerUtil .lowTPS (("checks." + check + "." + checkType ).toLowerCase ()) || player .getLocation ().getY () < 1 || player .isDead ()){
48+ return ;
49+ }
50+
51+ if (player .isInsideVehicle ()){
52+ return ;
53+ }
54+
55+ double groundY = 0.015625 ;
56+ boolean client = packet .isOnGround (), server = packet .getY () % groundY < 0.0001 ;
57+
58+ if (client && !server && !PlayerUtil .isOnClimbable (player )) {
59+ if (++buffer > 1 ) {
60+
61+ boolean boat = false ;
62+ boolean shulker = false ;
63+ boolean pistonHead = false ;
64+
65+ AtomicReference <List <Entity >> nearby = new AtomicReference <>();
66+ sync (() -> nearby .set (player .getNearbyEntities (1.5 , 10 , 1.5 )));
67+
68+ for (Entity entity : nearby .get ()) {
69+ if (entity .getType () == EntityType .BOAT && player .getLocation ().getY () > entity .getLocation ().getY ()) {
70+ boat = true ;
71+ break ;
72+ }
73+
74+ if (entity .getType () == EntityType .SHULKER && player .getLocation ().getY () > entity .getBoundingBox ().getMinY ()) {
75+ shulker = true ;
76+ break ;
77+ }
78+ }
79+
80+ for (Block block : PlayerUtil .getNearbyBlocks (new Location (player .getWorld (), packet .getX (), packet .getY (), packet .getZ ()), 2 )) {
81+
82+ if (Tag .SHULKER_BOXES .isTagged (block .getType ())) {
83+ shulker = true ;
84+ break ;
85+ }
86+
87+ if (block .getType () == Material .PISTON_HEAD ) {
88+ pistonHead = true ;
89+ break ;
90+ }
91+ }
92+
93+ if (!boat && !shulker && !pistonHead ) {
94+ String suspectedHack ;
95+ if (packet .getY () % groundY == 0.0 ){
96+ suspectedHack = "Criticals/Anti Hunger" ;
97+ } else {
98+ suspectedHack = "NoFall" ;
99+ }
100+ fail ("mod=" + packet .getY () % groundY + " &7Client: &2" + client + " &7Server: &2" + server + " &7Suspected Hack: &2" + suspectedHack , player );
101+ }
64102 }
103+ } else if (buffer > 0 ) buffer -=0.5 ;
104+
105+ boolean inAir = true ;
65106
66- if (entity .getType () == EntityType .SHULKER ) {
67- shulker = true ;
107+ boolean lastInAir = this .lastInAir .getOrDefault (player .getUniqueId (), false );
108+
109+ for (Block block : PlayerUtil .getNearbyBlocksConfigurable (new Location (player .getWorld (), player .getLocation ().getX (), player .getLocation ().getY () -1 , player .getLocation ().getZ ()), 1 , 0 , 1 )) {
110+ if (block .getType () != Material .AIR ) {
111+ inAir = false ;
68112 break ;
69113 }
70114 }
71115
72- if (!boat && !shulker && !pistonHead && ++buffer > 1 ) {
73- Bukkit .getScheduler ().runTaskAsynchronously (FlappyAnticheat .getInstance (), () -> fail ("mod=" + e .getTo ().getY () % groundY + " &7Client: &2" + client + " &7Server: &2" + server , player ));
116+ boolean lastOnGround = this .lastOnGround .getOrDefault (player .getUniqueId (), true );
117+
118+ //check if they have packet on ground, are in the air, and were last in the air.
119+ if (packet .isOnGround () && lastOnGround && inAir && lastInAir ) {
120+ String suspectedHack = "NoFall" ;
121+
122+ fail ("mod=" + packet .getY () % groundY + " &7Client: &2" + client + " &7Server: &2" + server + " &7Suspected Hack: &2" + suspectedHack , player );
123+
74124 }
75- } else if (buffer > 0 )
76- buffer -= 0.5 ;
125+
126+ this .lastOnGround .put (player .getUniqueId (), packet .isOnGround ());
127+ this .lastInAir .put (player .getUniqueId (), inAir );
128+ }
77129 }
78130}
0 commit comments