From 4f451d8551816622093d05f9d86f698dc0ab85ff Mon Sep 17 00:00:00 2001 From: TudbuT Date: Fri, 4 Oct 2024 22:20:43 +0200 Subject: [PATCH] improve fall damage mitigations --- .../feature/modules/movement/ElytraFly.java | 36 +++++++++++++------ .../feature/modules/movement/NoFall.java | 29 +++++++-------- .../util/interact/ServerDataManager.java | 4 +++ .../client/util/misc/PacketUtils.java | 21 +++++++++++ 4 files changed, 65 insertions(+), 25 deletions(-) create mode 100644 Client/src/main/java/de/com/baseband/client/util/misc/PacketUtils.java diff --git a/Client/src/main/java/de/com/baseband/client/feature/modules/movement/ElytraFly.java b/Client/src/main/java/de/com/baseband/client/feature/modules/movement/ElytraFly.java index 9d6c76c..620af38 100644 --- a/Client/src/main/java/de/com/baseband/client/feature/modules/movement/ElytraFly.java +++ b/Client/src/main/java/de/com/baseband/client/feature/modules/movement/ElytraFly.java @@ -3,18 +3,18 @@ package de.com.baseband.client.feature.modules.movement; import de.com.baseband.client.event.events.MoveEvent; import de.com.baseband.client.event.events.PacketEvent; import de.com.baseband.client.feature.Feature; +import de.com.baseband.client.feature.Features; import de.com.baseband.client.feature.category.Movement; import de.com.baseband.client.registry.annotation.Config; import de.com.baseband.client.registry.annotation.Description; import de.com.baseband.client.registry.annotation.Gate; import de.com.baseband.client.registry.annotation.Range; import de.com.baseband.client.util.adapt.Marker; -import de.com.baseband.client.util.interact.InventoryUtils; import de.com.baseband.client.util.interact.MotionUtil; +import de.com.baseband.client.util.interact.ServerDataManager; import de.tudbut.tools.Lock; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.inventory.ClickType; import net.minecraft.network.Packet; import net.minecraft.network.play.client.CPacketEntityAction; import net.minecraft.network.play.client.CPacketPlayer; @@ -35,10 +35,6 @@ public class ElytraFly extends Feature { @Marker(4) public boolean stopOnDisable = false; - @Config("Stop with packet") - @Gate(4) - public boolean stopWithPacket = true; - @Config("Mixin (recommended)") @Description("Use the client's mixin for ElytraFly control, which is more accurate but can theoretically be broken by other clients.") @Marker(2) @@ -122,19 +118,37 @@ public class ElytraFly extends Feature { public void onDisable() { init = false; if(stopOnDisable && !notIngame()) { - if(stopWithPacket) { - mc.player.connection.sendPacket(new CPacketPlayer.Position(mc.player.posX, mc.player.posY, mc.player.posZ, true)); - mc.player.connection.sendPacket(new CPacketEntityAction(mc.player, CPacketEntityAction.Action.START_FALL_FLYING)); + if(mc.player.motionY >= -0.1 && mc.player.rotationPitch < 40) { + sendDisablePackets(); } else { - InventoryUtils.clickSlot(6, ClickType.PICKUP, 0); - InventoryUtils.clickSlot(6, ClickType.PICKUP, 0); + // stop fall dmg + mc.player.connection.sendPacket(new CPacketPlayer.Rotation(mc.player.rotationYaw, 0, false)); + mc.player.motionY = 0.1; + sendDisableTimer = ServerDataManager.timeToSurelyTicked(); + // use NoFall setting if that's enabled, since the player might prefer something else + Features.ifFeatureEnabled(NoFall.class, x -> sendDisableTimer = x.disengageTime); } } } + private void sendDisablePackets() { + mc.player.connection.sendPacket(new CPacketPlayer.Position(mc.player.posX, mc.player.posY, mc.player.posZ, true)); + mc.player.connection.sendPacket(new CPacketEntityAction(mc.player, CPacketEntityAction.Action.START_FALL_FLYING)); + } + + private int sendDisableTimer = -1; + @Override public void onEveryTick() { + if(sendDisableTimer > 0) { + mc.player.motionY = 0.1; + sendDisableTimer--; + } + if(sendDisableTimer == 0) { + sendDisablePackets(); + sendDisableTimer = -1; + } if (blockMovement) { meta = "Locked"; } else { diff --git a/Client/src/main/java/de/com/baseband/client/feature/modules/movement/NoFall.java b/Client/src/main/java/de/com/baseband/client/feature/modules/movement/NoFall.java index 822abf3..d87548f 100644 --- a/Client/src/main/java/de/com/baseband/client/feature/modules/movement/NoFall.java +++ b/Client/src/main/java/de/com/baseband/client/feature/modules/movement/NoFall.java @@ -3,12 +3,11 @@ package de.com.baseband.client.feature.modules.movement; import de.com.baseband.client.event.events.PacketEvent; import de.com.baseband.client.feature.Feature; import de.com.baseband.client.feature.category.Movement; -import de.com.baseband.client.registry.annotation.Config; -import de.com.baseband.client.registry.annotation.Description; -import de.com.baseband.client.registry.annotation.Gate; -import de.com.baseband.client.registry.annotation.Range; +import de.com.baseband.client.registry.annotation.*; import de.com.baseband.client.util.adapt.FieldFinder; import de.com.baseband.client.util.adapt.Marker; +import de.com.baseband.client.util.interact.ServerDataManager; +import de.com.baseband.client.util.misc.PacketUtils; import net.minecraft.entity.Entity; import net.minecraft.network.datasync.DataParameter; import net.minecraft.network.play.client.CPacketEntityAction; @@ -31,10 +30,17 @@ public class NoFall extends Feature { @Marker(1) boolean modeIsElytra = false; + @Config("Automatic disengage") + @Description("Determines Disengage time automatically based on TPS.") + @Gate(1) + @Marker(2) + public boolean autoDisengage = true; + @Config("Disengage time") - @Description("Directly depends on how performant the server is. If it's always 20TPS, this can be 2, otherwise higher.") + @Description("Directly depends on how performant the server is. If it's always 20TPS, this can be 2, otherwise higher.\nLower is more unsafe but faster.") @Range("2..20") @Gate(1) + @MultiGate(andNot = {2}) public int disengageTime = 2; boolean lastOnGround = true; @@ -50,15 +56,7 @@ public class NoFall extends Feature { // rotations will mess with resetting fall distance when using the elytra! if(mode == Mode.Elytra && cancelElytraNT != 0) { - if(packet instanceof CPacketPlayer.Rotation) { - event.setCancelled(true); - return; - } - if(packet instanceof CPacketPlayer.PositionRotation) { - mc.player.connection.sendPacket(new CPacketPlayer.Position(packet.getX(0), packet.getY(0), packet.getZ(0), packet.isOnGround())); - event.setCancelled(true); - return; - } + PacketUtils.removeRotationsFrom(event, packet); } // we check the fall distance so we dont interfere with things that require server-side onground, **LAMBDA**! @@ -99,6 +97,9 @@ public class NoFall extends Feature { public void onTick() { if(mc.player.onGround) ranThisFall = false; + if(autoDisengage) { + disengageTime = ServerDataManager.timeToSurelyTicked(); + } lastOnGround = mc.player.onGround; lastFallDist = mc.player.fallDistance; if(mode == Mode.Elytra && !mc.player.isElytraFlying()) { diff --git a/Client/src/main/java/de/com/baseband/client/util/interact/ServerDataManager.java b/Client/src/main/java/de/com/baseband/client/util/interact/ServerDataManager.java index 868aa67..7ddf434 100644 --- a/Client/src/main/java/de/com/baseband/client/util/interact/ServerDataManager.java +++ b/Client/src/main/java/de/com/baseband/client/util/interact/ServerDataManager.java @@ -83,4 +83,8 @@ public class ServerDataManager { lock.waitHere(); } } + + public static int timeToSurelyTicked() { + return (int) Math.ceil((20f / tps) * 3f); // 20 => 3, 10 => 6, etc + } } diff --git a/Client/src/main/java/de/com/baseband/client/util/misc/PacketUtils.java b/Client/src/main/java/de/com/baseband/client/util/misc/PacketUtils.java new file mode 100644 index 0000000..7bc6a35 --- /dev/null +++ b/Client/src/main/java/de/com/baseband/client/util/misc/PacketUtils.java @@ -0,0 +1,21 @@ +package de.com.baseband.client.util.misc; + +import de.com.baseband.client.event.events.PacketEvent; +import net.minecraft.network.play.client.CPacketPlayer; + +import static de.com.baseband.client.BaseBand.mc; + +public class PacketUtils { + + public static void removeRotationsFrom(PacketEvent.Send event, CPacketPlayer packet) { + if(packet instanceof CPacketPlayer.Rotation) { + event.setCancelled(true); + return; + } + if(packet instanceof CPacketPlayer.PositionRotation) { + mc.player.connection.sendPacket(new CPacketPlayer.Position(packet.getX(0), packet.getY(0), packet.getZ(0), packet.isOnGround())); + event.setCancelled(true); + return; + } + } +}