4040import com .viaversion .viaversion .protocols .v1_21to1_21_2 .storage .ChunkLoadTracker ;
4141import com .viaversion .viaversion .protocols .v1_21to1_21_2 .storage .ClientVehicleStorage ;
4242import com .viaversion .viaversion .protocols .v1_21to1_21_2 .storage .EntityTracker1_21_2 ;
43+ import com .viaversion .viaversion .protocols .v1_21to1_21_2 .storage .GroundFlagTracker ;
4344import com .viaversion .viaversion .protocols .v1_21to1_21_2 .storage .PlayerPositionStorage ;
4445import com .viaversion .viaversion .rewriter .EntityRewriter ;
4546import com .viaversion .viaversion .rewriter .RegistryDataRewriter ;
@@ -163,6 +164,7 @@ public void register() {
163164
164165 trackWorldDataByKey1_20_5 (wrapper .user (), dimensionId , world );
165166
167+ wrapper .user ().put (new GroundFlagTracker ());
166168 wrapper .user ().remove (ClientVehicleStorage .class );
167169 });
168170
@@ -314,15 +316,15 @@ public void register() {
314316 wrapper .passthrough (Types .DOUBLE ); // X
315317 wrapper .passthrough (Types .DOUBLE ); // Y
316318 wrapper .passthrough (Types .DOUBLE ); // Z
317- readOnGround (wrapper );
319+ handleOnGround (wrapper );
318320 });
319321 protocol .registerServerbound (ServerboundPackets1_21_2 .MOVE_PLAYER_POS_ROT , wrapper -> {
320322 final double x = wrapper .passthrough (Types .DOUBLE ); // X
321323 final double y = wrapper .passthrough (Types .DOUBLE ); // Y
322324 final double z = wrapper .passthrough (Types .DOUBLE ); // Z
323325 final float yaw = wrapper .passthrough (Types .FLOAT ); // Yaw
324326 final float pitch = wrapper .passthrough (Types .FLOAT ); // Pitch
325- readOnGround (wrapper );
327+ handleOnGround (wrapper );
326328
327329 final PlayerPositionStorage playerPositionStorage = wrapper .user ().get (PlayerPositionStorage .class );
328330 if (playerPositionStorage .checkCaptureNextPlayerPositionPacket ()) {
@@ -335,9 +337,19 @@ public void register() {
335337 protocol .registerServerbound (ServerboundPackets1_21_2 .MOVE_PLAYER_ROT , wrapper -> {
336338 wrapper .passthrough (Types .FLOAT ); // Yaw
337339 wrapper .passthrough (Types .FLOAT ); // Pitch
338- readOnGround (wrapper );
340+ handleOnGround (wrapper );
341+ });
342+ protocol .registerServerbound (ServerboundPackets1_21_2 .MOVE_PLAYER_STATUS_ONLY , wrapper -> {
343+ final GroundFlagTracker tracker = wrapper .user ().get (GroundFlagTracker .class );
344+ final boolean prevOnGround = tracker .onGround ();
345+ final boolean prevHorizontalCollision = tracker .horizontalCollision ();
346+
347+ handleOnGround (wrapper );
348+ if (prevOnGround == tracker .onGround () && prevHorizontalCollision != tracker .horizontalCollision ()) {
349+ // Newer clients will send idle packets even though the on ground state didn't change, ignore them
350+ wrapper .cancel ();
351+ }
339352 });
340- protocol .registerServerbound (ServerboundPackets1_21_2 .MOVE_PLAYER_STATUS_ONLY , this ::readOnGround );
341353 protocol .registerServerbound (ServerboundPackets1_21_2 .ACCEPT_TELEPORTATION , wrapper -> {
342354 final PlayerPositionStorage playerPositionStorage = wrapper .user ().get (PlayerPositionStorage .class );
343355 if (playerPositionStorage .checkHasPlayerPosition ()) {
@@ -370,9 +382,12 @@ private RegistryDataRewriter registryDataRewriter() {
370382 return registryDataRewriter ;
371383 }
372384
373- private void readOnGround (final PacketWrapper wrapper ) {
385+ private void handleOnGround (final PacketWrapper wrapper ) {
386+ final GroundFlagTracker tracker = wrapper .user ().get (GroundFlagTracker .class );
387+
374388 final short data = wrapper .read (Types .UNSIGNED_BYTE );
375- wrapper .write (Types .BOOLEAN , (data & 1 ) != 0 ); // On ground, ignoring horizontal collision data
389+ wrapper .write (Types .BOOLEAN , tracker .setOnGround ((data & 1 ) != 0 )); // Ignoring horizontal collision data
390+ tracker .setHorizontalCollision ((data & 2 ) != 0 );
376391 }
377392
378393 private void storeEntityPositionRotation (final PacketWrapper wrapper , final boolean position , final boolean rotation ) {
0 commit comments