diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallPacket.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallPacket.kt index e404c72565e..476f6d32328 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallPacket.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallPacket.kt @@ -20,14 +20,25 @@ package net.ccbluex.liquidbounce.features.module.modules.player.nofall.modes import net.ccbluex.liquidbounce.config.types.Choice import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable +import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable +import net.ccbluex.liquidbounce.event.events.QueuePacketEvent +import net.ccbluex.liquidbounce.event.events.TransferOrigin +import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.event.tickHandler +import net.ccbluex.liquidbounce.features.module.modules.player.ModuleBlink import net.ccbluex.liquidbounce.features.module.modules.player.nofall.ModuleNoFall +import net.ccbluex.liquidbounce.features.module.modules.player.nofall.modes.NoFallPacket.Filter.FallDistance.DistanceMode.Constant +import net.ccbluex.liquidbounce.features.module.modules.player.nofall.modes.NoFallPacket.Filter.FallDistance.DistanceMode.Smart import net.ccbluex.liquidbounce.utils.client.MovePacketType +import net.ccbluex.liquidbounce.utils.client.PacketQueueManager +import net.ccbluex.liquidbounce.utils.client.PacketQueueManager.Action +import net.ccbluex.liquidbounce.utils.entity.SimulatedPlayer +import net.ccbluex.liquidbounce.utils.movement.DirectionalInput import net.minecraft.entity.attribute.EntityAttributes internal object NoFallPacket : Choice("Packet") { private val packetType by enumChoice("PacketType", MovePacketType.FULL) - private val filter = choices("Filter", FallDistance, arrayOf(FallDistance, Always)) + private val filter = choices("Filter", Filter.FallDistance, arrayOf(Filter.FallDistance, Filter.Always)) override val parent: ChoiceConfigurable<*> get() = ModuleNoFall.modes @@ -38,9 +49,7 @@ internal object NoFallPacket : Choice("Packet") { onGround = true }) - if (filter.activeChoice is FallDistance && FallDistance.resetFallDistance) { - player.onLanding() - } + filter.activeChoice.onPacket() } } @@ -49,34 +58,95 @@ internal object NoFallPacket : Choice("Packet") { get() = filter abstract val isActive: Boolean - } + open fun onPacket() {} - private object FallDistance : Filter("FallDistance") { - override val isActive: Boolean - get() = player.fallDistance - player.velocity.y > distance.activeChoice.value && player.age > 20 + object FallDistance : Filter("FallDistance") { + override val isActive: Boolean + get() { + val fallDistance = player.fallDistance - (if (resetFallDistance) packetFallDistance else 0f) + return fallDistance - player.velocity.y >= distance.activeChoice.value && player.age > 20 + } - private val distance = choices("Distance", Smart, arrayOf(Smart, Constant)) - val resetFallDistance by boolean("ResetFallDistance", true) + private val distance = choices("Distance", Smart, arrayOf(Smart, Constant)) + val resetFallDistance by boolean("ResetFallDistance", true) + object Blink : ToggleableConfigurable(this, "Blink", false) { + val disableOnSpoof by boolean("DisableOnSpoof", false) + private val predictionTicks by int("PredictionTicks", 10, 1..30) - private abstract class DistanceMode(name: String) : Choice(name) { - override val parent: ChoiceConfigurable<*> - get() = distance + @Suppress("unused") + private val blinkHandler = handler { event -> + if (event.origin != TransferOrigin.SEND || player.isOnGround || player.age <= 20) { + return@handler + } - abstract val value: Float - } + if (player.fallDistance >= distance.activeChoice.value && player.age > 20) { + event.action = Action.QUEUE + return@handler + } - private object Smart : DistanceMode("Smart") { - override val value: Float - get() = player.getAttributeValue(EntityAttributes.SAFE_FALL_DISTANCE).toFloat() - } + val simulatedPlayer = SimulatedPlayer.fromClientPlayer( + SimulatedPlayer.SimulatedPlayerInput( + DirectionalInput(player.input), + player.input.playerInput.jump, + player.isSprinting, + true + ) + ) + + for (i in 1..predictionTicks) { + simulatedPlayer.tick() + if (simulatedPlayer.fallDistance >= distance.activeChoice.value) { + event.action = Action.QUEUE + return@handler + } + } + } + } + + init { tree(Blink) } + + private var lastFallDistance = 0f + private var packetFallDistance = 0f + + override fun onPacket() { + packetFallDistance = player.fallDistance + + if (Blink.running && Blink.disableOnSpoof && !ModuleBlink.running) { + PacketQueueManager.flush { snapshot -> snapshot.origin == TransferOrigin.SEND } + } + } + + val repeatable = tickHandler { + if (lastFallDistance > 0 && player.isOnGround) { + packetFallDistance = 0f + if (Blink.running && !ModuleBlink.running) { + PacketQueueManager.flush { snapshot -> snapshot.origin == TransferOrigin.SEND } + } + } + + lastFallDistance = player.fallDistance + } + + private abstract class DistanceMode(name: String) : Choice(name) { + override val parent: ChoiceConfigurable<*> + get() = distance - private object Constant : DistanceMode("Constant") { - override val value by float("Value", 2f, 0f..5f) + abstract val value: Float + + object Smart : DistanceMode("Smart") { + override val value: Float + get() = player.getAttributeValue(EntityAttributes.SAFE_FALL_DISTANCE).toFloat() + } + + object Constant : DistanceMode("Constant") { + override val value by float("Value", 2f, 0f..5f) + } + } } - } - private object Always : Filter("Always") { - override val isActive: Boolean - get() = true + object Always : Filter("Always") { + override val isActive + get() = true + } } } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallPacketJump.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallPacketJump.kt index c60a41157b8..0a70737709d 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallPacketJump.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallPacketJump.kt @@ -2,11 +2,24 @@ package net.ccbluex.liquidbounce.features.module.modules.player.nofall.modes import net.ccbluex.liquidbounce.config.types.Choice import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable +import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable import net.ccbluex.liquidbounce.event.events.PacketEvent import net.ccbluex.liquidbounce.event.events.PlayerTickEvent +import net.ccbluex.liquidbounce.event.events.QueuePacketEvent +import net.ccbluex.liquidbounce.event.events.TransferOrigin import net.ccbluex.liquidbounce.event.handler +import net.ccbluex.liquidbounce.event.tickHandler +import net.ccbluex.liquidbounce.features.module.modules.player.ModuleBlink import net.ccbluex.liquidbounce.features.module.modules.player.nofall.ModuleNoFall +import net.ccbluex.liquidbounce.features.module.modules.player.nofall.modes.NoFallPacketJump.DistanceMode.Constant +import net.ccbluex.liquidbounce.features.module.modules.player.nofall.modes.NoFallPacketJump.DistanceMode.Smart +import net.ccbluex.liquidbounce.features.module.modules.player.nofall.modes.NoFallPacketJump.Timing.Falling +import net.ccbluex.liquidbounce.features.module.modules.player.nofall.modes.NoFallPacketJump.Timing.Landing import net.ccbluex.liquidbounce.utils.client.MovePacketType +import net.ccbluex.liquidbounce.utils.client.PacketQueueManager +import net.ccbluex.liquidbounce.utils.client.PacketQueueManager.Action +import net.ccbluex.liquidbounce.utils.entity.SimulatedPlayer +import net.ccbluex.liquidbounce.utils.movement.DirectionalInput import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket @@ -22,14 +35,15 @@ internal object NoFallPacketJump : Choice("PacketJump") { get() = ModuleNoFall.modes val tickHandler = handler { - falling = player.fallDistance > fallDistance.activeChoice.value + val resetFallDistance = timing.activeChoice is Falling && Falling.resetFallDistance + val distance = player.fallDistance - (if (resetFallDistance) Falling.packetFallDistance else 0f) + falling = distance >= fallDistance.activeChoice.value if (timing.activeChoice is Falling && !player.isOnGround && falling) { network.sendPacket(packetType.generatePacket().apply { y += 1.0E-9 }) - if (Falling.resetFallDistance) { - player.onLanding() - } + + Falling.onPacket() } } @@ -45,16 +59,72 @@ internal object NoFallPacketJump : Choice("PacketJump") { } } - private object Landing : Choice("Landing") { + private abstract class Timing(name: String) : Choice(name) { override val parent: ChoiceConfigurable<*> get() = timing - } - private object Falling : Choice("Falling") { - override val parent: ChoiceConfigurable<*> - get() = timing + object Landing : Timing("Landing") + + object Falling : Timing("Falling") { + val resetFallDistance by boolean("ResetFallDistance", true) + object Blink : ToggleableConfigurable(this, "Blink", false) { + val disableOnSpoof by boolean("DisableOnSpoof", false) + private val predictionTicks by int("PredictionTicks", 10, 1..30) + + @Suppress("unused") + private val blinkHandler = handler { event -> + if (event.origin != TransferOrigin.SEND || player.isOnGround || player.age <= 20) { + return@handler + } + + if (player.fallDistance >= fallDistance.activeChoice.value && player.age > 20) { + event.action = Action.QUEUE + return@handler + } + + val simulatedPlayer = SimulatedPlayer.fromClientPlayer( + SimulatedPlayer.SimulatedPlayerInput( + DirectionalInput(player.input), + player.input.playerInput.jump, + player.isSprinting, + true + ) + ) + + for (i in 1..predictionTicks) { + simulatedPlayer.tick() + if (simulatedPlayer.fallDistance >= fallDistance.activeChoice.value) { + event.action = Action.QUEUE + return@handler + } + } + } + } + + init { tree(Blink) } - val resetFallDistance by boolean("ResetFallDistance", true) + private var lastFallDistance = 0f + var packetFallDistance = 0f + + fun onPacket() { + packetFallDistance = player.fallDistance + + if (Blink.running && Blink.disableOnSpoof && !ModuleBlink.running) { + PacketQueueManager.flush { snapshot -> snapshot.origin == TransferOrigin.SEND } + } + } + + val repeatable = tickHandler { + if (lastFallDistance > 0 && player.isOnGround) { + packetFallDistance = 0f + if (Blink.running && !ModuleBlink.running) { + PacketQueueManager.flush { snapshot -> snapshot.origin == TransferOrigin.SEND } + } + } + + lastFallDistance = player.fallDistance + } + } } private abstract class DistanceMode(name: String) : Choice(name) { @@ -62,14 +132,14 @@ internal object NoFallPacketJump : Choice("PacketJump") { get() = fallDistance abstract val value: Float - } - private object Smart : DistanceMode("Smart") { - override val value: Float - get() = player.getAttributeValue(EntityAttributes.SAFE_FALL_DISTANCE).toFloat() - } + object Smart : DistanceMode("Smart") { + override val value + get() = player.getAttributeValue(EntityAttributes.SAFE_FALL_DISTANCE).toFloat() + } - private object Constant : DistanceMode("Constant") { - override val value by float("Value", 3f, 0f..5f) + object Constant : DistanceMode("Constant") { + override val value by float("Value", 3f, 0f..5f) + } } } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallSpoofGround.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallSpoofGround.kt index 811d05ba538..781c84acc95 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallSpoofGround.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallSpoofGround.kt @@ -20,9 +20,19 @@ package net.ccbluex.liquidbounce.features.module.modules.player.nofall.modes import net.ccbluex.liquidbounce.config.types.Choice import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable +import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable import net.ccbluex.liquidbounce.event.events.PacketEvent +import net.ccbluex.liquidbounce.event.events.QueuePacketEvent +import net.ccbluex.liquidbounce.event.events.TransferOrigin import net.ccbluex.liquidbounce.event.handler +import net.ccbluex.liquidbounce.features.module.modules.player.ModuleBlink import net.ccbluex.liquidbounce.features.module.modules.player.nofall.ModuleNoFall +import net.ccbluex.liquidbounce.features.module.modules.player.nofall.modes.NoFallSpoofGround.DistanceMode.Constant +import net.ccbluex.liquidbounce.features.module.modules.player.nofall.modes.NoFallSpoofGround.DistanceMode.Smart +import net.ccbluex.liquidbounce.utils.client.PacketQueueManager +import net.ccbluex.liquidbounce.utils.client.PacketQueueManager.Action +import net.ccbluex.liquidbounce.utils.entity.SimulatedPlayer +import net.ccbluex.liquidbounce.utils.movement.DirectionalInput import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket @@ -33,6 +43,15 @@ import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket internal object NoFallSpoofGround : Choice("SpoofGround") { private val fallDistance = choices("FallDistance", Smart, arrayOf(Smart, Constant)) private val resetFallDistance by boolean("ResetFallDistance", true) + private object Blink : ToggleableConfigurable(this, "Blink", false) { + val disableOnSpoof by boolean("DisableOnSpoof", false) + val predictionTicks by int("PredictionTicks", 10, 1..30) + } + + init { tree(Blink) } + + private var lastFallDistance = 0f + private var spoofFallDistance = 0f // Specify the parent configuration for this mode override val parent: ChoiceConfigurable<*> @@ -44,11 +63,56 @@ internal object NoFallSpoofGround : Choice("SpoofGround") { val packet = it.packet // Check if the packet is a PlayerMoveC2SPacket - if (packet is PlayerMoveC2SPacket && player.fallDistance >= fallDistance.activeChoice.value) { - // Modify the 'onGround' flag to true, preventing fall damage - packet.onGround = true - if (resetFallDistance) { - player.onLanding() + if (packet is PlayerMoveC2SPacket) { + if (lastFallDistance > 0 && player.isOnGround) { + spoofFallDistance = 0f + if (Blink.enabled && !ModuleBlink.running) { + PacketQueueManager.flush { snapshot -> snapshot.origin == TransferOrigin.SEND } + } + } + + val distance = player.fallDistance - (if (resetFallDistance) spoofFallDistance else 0f) + if (distance >= fallDistance.activeChoice.value) { + // Modify the 'onGround' flag to true, preventing fall damage + packet.onGround = true + + if (resetFallDistance) { + spoofFallDistance = player.fallDistance + } + + if (Blink.enabled && Blink.disableOnSpoof && !ModuleBlink.running) { + PacketQueueManager.flush { snapshot -> snapshot.origin == TransferOrigin.SEND } + } + } + + lastFallDistance = player.fallDistance + } + } + + @Suppress("unused") + private val blinkHandler = handler { event -> + if (event.origin != TransferOrigin.SEND || !Blink.enabled || player.isOnGround) { + return@handler + } + + if (player.fallDistance >= fallDistance.activeChoice.value) { + event.action = Action.QUEUE + return@handler + } + + val simulatedPlayer = SimulatedPlayer.fromClientPlayer( + SimulatedPlayer.SimulatedPlayerInput( + DirectionalInput(player.input), + player.input.playerInput.jump, + player.isSprinting, + true + )) + + for (i in 1..Blink.predictionTicks) { + simulatedPlayer.tick() + if (simulatedPlayer.fallDistance >= fallDistance.activeChoice.value) { + event.action = Action.QUEUE + return@handler } } } @@ -58,14 +122,14 @@ internal object NoFallSpoofGround : Choice("SpoofGround") { get() = fallDistance abstract val value: Float - } - private object Smart : DistanceMode("Smart") { - override val value: Float - get() = player.getAttributeValue(EntityAttributes.SAFE_FALL_DISTANCE).toFloat() - } + object Smart : DistanceMode("Smart") { + override val value + get() = player.getAttributeValue(EntityAttributes.SAFE_FALL_DISTANCE).toFloat() + } - private object Constant : DistanceMode("Constant") { - override val value by float("Value", 1.7f, 0f..5f) + object Constant : DistanceMode("Constant") { + override val value by float("Value", 1.7f, 0f..5f) + } } }