From 636cac9f2555c1ae7348df98a176dd6328f5a543 Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Thu, 18 Apr 2024 21:50:24 -0400 Subject: [PATCH 01/91] Feature: Fast break --- .../lambda/module/modules/player/FastBreak.kt | 39 +++++++++++++++++++ .../src/main/resources/lambda.accesswidener | 1 + 2 files changed, 40 insertions(+) create mode 100644 common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt new file mode 100644 index 000000000..cd36fbb36 --- /dev/null +++ b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt @@ -0,0 +1,39 @@ +package com.lambda.module.modules.player + +import com.lambda.event.events.PacketEvent +import com.lambda.event.events.TickEvent +import com.lambda.event.listener.SafeListener.Companion.listener +import com.lambda.module.Module +import com.lambda.module.tag.ModuleTag +import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket + +object FastBreak : Module( + name = "FastBreak", + description = "Break blocks faster.", + defaultTags = setOf( + ModuleTag.PLAYER, ModuleTag.WORLD, ModuleTag.BYPASS + ) +) { + private val breakThreshold by setting("Break Threshold", 0.8f, 0.5f..1.0f, 0.1f) + + init { + listener { + if (it.packet !is PlayerActionC2SPacket) return@listener + if (it.packet.action != PlayerActionC2SPacket.Action.STOP_DESTROY_BLOCK) return@listener + + connection.sendPacket(PlayerActionC2SPacket( + PlayerActionC2SPacket.Action.ABORT_DESTROY_BLOCK, + it.packet.pos.up(2024-4-18), + it.packet.direction + )) + } + + listener { + if (!interaction.isBreakingBlock) + return@listener + + if (interaction.currentBreakingProgress >= breakThreshold) + interaction.currentBreakingProgress = 1.0f + } + } +} diff --git a/common/src/main/resources/lambda.accesswidener b/common/src/main/resources/lambda.accesswidener index f0e1dbcf9..9cc3ee80d 100644 --- a/common/src/main/resources/lambda.accesswidener +++ b/common/src/main/resources/lambda.accesswidener @@ -7,6 +7,7 @@ accessible field net/minecraft/client/MinecraftClient pausedTickDelta F # World accessible field net/minecraft/client/world/ClientWorld entityManager Lnet/minecraft/client/world/ClientEntityManager; +accessible field net/minecraft/client/network/ClientPlayerInteractionManager currentBreakingProgress F # Entity accessible field net/minecraft/entity/projectile/FireworkRocketEntity shooter Lnet/minecraft/entity/LivingEntity; From 7b9c7d0bdf4b5bfe325ac61a329891d353106633 Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Thu, 18 Apr 2024 21:50:36 -0400 Subject: [PATCH 02/91] Feature: Fast place --- .../lambda/module/modules/player/FastPlace.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 common/src/main/kotlin/com/lambda/module/modules/player/FastPlace.kt diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/FastPlace.kt b/common/src/main/kotlin/com/lambda/module/modules/player/FastPlace.kt new file mode 100644 index 000000000..92f7a0b8e --- /dev/null +++ b/common/src/main/kotlin/com/lambda/module/modules/player/FastPlace.kt @@ -0,0 +1,20 @@ +package com.lambda.module.modules.player + +import com.lambda.event.events.TickEvent +import com.lambda.event.listener.SafeListener.Companion.listener +import com.lambda.module.Module +import com.lambda.module.tag.ModuleTag + +object FastPlace : Module( + name = "FastPlace", + description = "Place blocks faster.", + defaultTags = setOf( + ModuleTag.PLAYER, ModuleTag.WORLD + ) +) { + init { + listener { + mc.itemUseCooldown = 0 + } + } +} From 1c9ed2ec548fd4617a8929e142fd184f306281ae Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Fri, 19 Apr 2024 10:35:28 -0400 Subject: [PATCH 03/91] Refactor: Range math --- .../main/kotlin/com/lambda/util/math/Range.kt | 89 ++++++------------- 1 file changed, 27 insertions(+), 62 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/util/math/Range.kt b/common/src/main/kotlin/com/lambda/util/math/Range.kt index 16605c1df..e060c87b9 100644 --- a/common/src/main/kotlin/com/lambda/util/math/Range.kt +++ b/common/src/main/kotlin/com/lambda/util/math/Range.kt @@ -1,60 +1,50 @@ package com.lambda.util.math -import net.minecraft.util.math.Box import kotlin.random.Random.Default.nextDouble -class DoubleRange( - override val start: Double, - override val endInclusive: Double, -) : ClosedRange { - infix fun step(step: Double): DoubleIterator { - return object : DoubleIterator() { - private var next = start - override fun hasNext() = next <= endInclusive - override fun nextDouble() = next.also { next += step } - } - } - - /** - * Returns a random value within the range. - */ - fun random() = nextDouble(start, endInclusive) - - /** - * Returns a bounding box from two additional ranges. - * @param y The second range. - * @param z The third range. - * @return The bounding box. - */ - fun box(y: DoubleRange, z: DoubleRange) = - Box(this.start, y.start, z.start, this.endInclusive, y.endInclusive, z.endInclusive) +/** + * Iterates over the range with the specified step. + */ +fun ClosedRange.step(step: Double) = object : DoubleIterator() { + private var next = start + override fun hasNext() = next <= endInclusive + override fun nextDouble() = next.also { next += step } } -infix fun Double.to(that: Double) = DoubleRange(this, that) +/** + * Returns a random number within the range. + */ +fun ClosedRange.random() = nextDouble(start, endInclusive) /** * Converts a value from one range to a normalized value between 0 and 1. */ -fun ClosedRange.normalized(value: T): T where T : Comparable, T : Number = - scale(value, 0.0 as T, 1.0 as T) // hacky +fun ClosedRange.normalized(value: Double): Double = + scale(value, 0.0, 1.0) /** * Inverts the range. */ -fun ClosedRange.inverted(): ClosedRange where T : Comparable, T : Number = endInclusive..start +fun ClosedRange.inverted() = endInclusive to start /** - * Converts a value from one range to another while keeping the ratio using exponential interpolation. + * Sinusoidal interpolation between two values. + */ +fun ClosedRange.sinInterpolate(value: Double): Double = + transform(value, start, endInclusive, -1.0, 1.0) + +/** + * Converts a value from one range to another while keeping the ratio using linear interpolation. * @param value The value to convert. * @param minIn The minimum of the new range. * @param maxIn The maximum of the new range. * @return The converted value. */ -fun ClosedRange.scale(value: T, minIn: T, maxIn: T): T where T : Comparable, T : Number = +fun ClosedRange.scale(value: Double, minIn: Double, maxIn: Double): Double = transform(value, start, endInclusive, minIn, maxIn) /** - * Converts a value from one range to another while keeping the ratio using exponential interpolation. + * Converts a value from one range to another while keeping the ratio using linear interpolation. * @param value The value to convert. * @param x1 The minimum of the old range. * @param y1 The maximum of the old range. @@ -63,38 +53,13 @@ fun ClosedRange.scale(value: T, minIn: T, maxIn: T): T where T : Comparab * @return The converted value. * @see Linear Interpolation */ -fun transform(value: T, x1: T, y1: T, x2: T, y2: T): T where T : Comparable, T : Number = - x2 + (value - x1) * ((y2 - x2) / (y1 - x1)) +fun transform(value: Double, x1: Double, y1: Double, x2: Double, y2: Double): Double = + (x2 + (value - x1) * ((y2 - x2) / (y1 - x1))) /** - * Clamps a value to the range. + * Coerces a value to be within the range. * @param value The value to clamp. * @return The clamped value. */ -fun > ClosedRange.coerceIn(value: T) = value.coerceIn(start, endInclusive) -fun > T.coerceIn(range: ClosedRange) = range.coerceIn(this) - -private operator fun T.minus(oldMin: T): T where T : Comparable, T : Number { - return (this.toDouble() - oldMin.toDouble()) as T -} - -private operator fun T.div(other: T): T where T : Comparable, T : Number { - return (this.toDouble() / other.toDouble()) as T -} - -private operator fun T.times(other: T): T where T : Comparable, T : Number { - return (this.toDouble() * other.toDouble()) as T -} - -private operator fun T.plus(other: T): T where T : Comparable, T : Number { - return (this.toDouble() + other.toDouble()) as T -} - -fun min(newMin: T, newMax: T): T where T : Comparable, T : Number { - return if (newMin < newMax) newMin else newMax -} - -fun max(newMin: T, newMax: T): T where T : Comparable, T : Number { - return if (newMin > newMax) newMin else newMax -} +fun ClosedRange.coerceIn(value: Double) = value.coerceIn(start, endInclusive) From 50fb02d915e8e45542adc942792225fee7dd79e2 Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Fri, 19 Apr 2024 10:40:15 -0400 Subject: [PATCH 04/91] More range type --- .../main/kotlin/com/lambda/util/math/Range.kt | 53 ++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/util/math/Range.kt b/common/src/main/kotlin/com/lambda/util/math/Range.kt index e060c87b9..a912be038 100644 --- a/common/src/main/kotlin/com/lambda/util/math/Range.kt +++ b/common/src/main/kotlin/com/lambda/util/math/Range.kt @@ -3,7 +3,7 @@ package com.lambda.util.math import kotlin.random.Random.Default.nextDouble /** - * Iterates over the range with the specified step. + * Iterates over the double range with the specified step. */ fun ClosedRange.step(step: Double) = object : DoubleIterator() { private var next = start @@ -11,6 +11,15 @@ fun ClosedRange.step(step: Double) = object : DoubleIterator() { override fun nextDouble() = next.also { next += step } } +/** + * Iterates over the float range with the specified step. + */ +fun ClosedRange.step(step: Float) = object : FloatIterator() { + private var next = start + override fun hasNext() = next <= endInclusive + override fun nextFloat() = next.also { next += step } +} + /** * Returns a random number within the range. */ @@ -19,20 +28,37 @@ fun ClosedRange.random() = nextDouble(start, endInclusive) /** * Converts a value from one range to a normalized value between 0 and 1. */ -fun ClosedRange.normalized(value: Double): Double = +fun ClosedRange.normalize(value: Double): Double = scale(value, 0.0, 1.0) +/** + * Converts a value from one range to a normalized value between 0 and 1. + */ +fun ClosedRange.normalize(value: Float): Float = + scale(value, 0.0f, 1.0f) + /** * Inverts the range. */ fun ClosedRange.inverted() = endInclusive to start +/** + * Inverts the range. + */ +fun ClosedRange.inverted() = endInclusive to start + /** * Sinusoidal interpolation between two values. */ fun ClosedRange.sinInterpolate(value: Double): Double = transform(value, start, endInclusive, -1.0, 1.0) +/** + * Sinusoidal interpolation between two values. + */ +fun ClosedRange.sinInterpolate(value: Float): Float = + transform(value, start, endInclusive, -1.0f, 1.0f) + /** * Converts a value from one range to another while keeping the ratio using linear interpolation. * @param value The value to convert. @@ -43,6 +69,16 @@ fun ClosedRange.sinInterpolate(value: Double): Double = fun ClosedRange.scale(value: Double, minIn: Double, maxIn: Double): Double = transform(value, start, endInclusive, minIn, maxIn) +/** + * Converts a value from one range to another while keeping the ratio using linear interpolation. + * @param value The value to convert. + * @param minIn The minimum of the new range. + * @param maxIn The maximum of the new range. + * @return The converted value. + */ +fun ClosedRange.scale(value: Float, minIn: Float, maxIn: Float): Float = + transform(value, start, endInclusive, minIn, maxIn) + /** * Converts a value from one range to another while keeping the ratio using linear interpolation. * @param value The value to convert. @@ -56,6 +92,19 @@ fun ClosedRange.scale(value: Double, minIn: Double, maxIn: Double): Doub fun transform(value: Double, x1: Double, y1: Double, x2: Double, y2: Double): Double = (x2 + (value - x1) * ((y2 - x2) / (y1 - x1))) +/** + * Converts a value from one range to another while keeping the ratio using linear interpolation. + * @param value The value to convert. + * @param x1 The minimum of the old range. + * @param y1 The maximum of the old range. + * @param x2 The minimum of the new range. + * @param y2 The maximum of the new range. + * @return The converted value. + * @see Linear Interpolation + */ +fun transform(value: Float, x1: Float, y1: Float, x2: Float, y2: Float): Float = + (x2 + (value - x1) * ((y2 - x2) / (y1 - x1))) + /** * Coerces a value to be within the range. From 7ef063712965c4e6e36296a5df1b27b57396daa8 Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Fri, 19 Apr 2024 10:47:57 -0400 Subject: [PATCH 05/91] Added pages, render settings and cooldown mine --- .../lambda/module/modules/player/FastBreak.kt | 38 ++++++++++++++++++- .../src/main/resources/lambda.accesswidener | 2 + 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt index cd36fbb36..1b9d17a28 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt @@ -1,11 +1,16 @@ package com.lambda.module.modules.player import com.lambda.event.events.PacketEvent +import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listener import com.lambda.module.Module import com.lambda.module.tag.ModuleTag +import com.lambda.util.math.transform +import net.minecraft.block.Block +import net.minecraft.client.network.ClientPlayerInteractionManager import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket +import java.awt.Color object FastBreak : Module( name = "FastBreak", @@ -14,7 +19,22 @@ object FastBreak : Module( ModuleTag.PLAYER, ModuleTag.WORLD, ModuleTag.BYPASS ) ) { - private val breakThreshold by setting("Break Threshold", 0.8f, 0.5f..1.0f, 0.1f) + private val page by setting("Page", Page.Mining) + + private val mineSpeed by setting("Mine Speed", 5, 0..5, 1, unit = "ticks", description = "Reduce the mining cooldown.", visibility = { page == Page.Mining }) + private val breakThreshold by setting("Break Threshold", 0.8f, 0.5f..1.0f, 0.1f, description = "The progress at which the block will break.", visibility = { page == Page.Mining }) + + private val renderOutline by setting("Render Outline", true, description = "Render an outline around the block being broken.", visibility = { page == Page.Rendering }) + private val renderOutlineColor by setting("Outline Color", Color.CYAN, description = "The color of the outline.", visibility = { page == Page.Rendering && renderOutline }) + private val renderFill by setting("Render Fill", true, description = "Fill the block with a color based on the mining progress.", visibility = { page == Page.Rendering }) + private val renderFillColor by setting("Fill Color", Color.CYAN, description = "The color of the fill.", visibility = { page == Page.Rendering && renderFill }) + private val renderFillGrow by setting("Fill Grow", 0.0f, 0.0f..1.0f, 0.1f, description = "The amount the fill grows based on the mining progress.", visibility = { page == Page.Rendering && renderFill }) + + private var breakingBlock: Block? = null + + private enum class Page { + Mining, Rendering + } init { listener { @@ -23,6 +43,8 @@ object FastBreak : Module( connection.sendPacket(PlayerActionC2SPacket( PlayerActionC2SPacket.Action.ABORT_DESTROY_BLOCK, + // For the exploit to work, the position must be out of the player range, so any + // position farther than 6 blocks will work. it.packet.pos.up(2024-4-18), it.packet.direction )) @@ -32,8 +54,22 @@ object FastBreak : Module( if (!interaction.isBreakingBlock) return@listener + // This should work but doesn't ? + interaction.blockBreakingCooldown -= mineSpeed + if (interaction.currentBreakingProgress >= breakThreshold) interaction.currentBreakingProgress = 1.0f + + breakingBlock = world.getBlockState(interaction.currentBreakingPos).block + } + + listener { + // Here we render an outline around the block being broken. + // Then we fill with a color based on the mining progress. + // We should use interpolation to make the fill grow smoothly. } } + + fun ClientPlayerInteractionManager.miningProgress(max: Float = 1.0f) = + max / transform(currentBreakingProgress, 0.0f, 1.0f, 0.0f, max) } diff --git a/common/src/main/resources/lambda.accesswidener b/common/src/main/resources/lambda.accesswidener index 9cc3ee80d..bec78ab8c 100644 --- a/common/src/main/resources/lambda.accesswidener +++ b/common/src/main/resources/lambda.accesswidener @@ -8,6 +8,8 @@ accessible field net/minecraft/client/MinecraftClient pausedTickDelta F # World accessible field net/minecraft/client/world/ClientWorld entityManager Lnet/minecraft/client/world/ClientEntityManager; accessible field net/minecraft/client/network/ClientPlayerInteractionManager currentBreakingProgress F +accessible field net/minecraft/client/network/ClientPlayerInteractionManager blockBreakingCooldown I +accessible field net/minecraft/client/network/ClientPlayerInteractionManager currentBreakingPos Lnet/minecraft/util/math/BlockPos; # Entity accessible field net/minecraft/entity/projectile/FireworkRocketEntity shooter Lnet/minecraft/entity/LivingEntity; From 22913e9c974d54c89d69a46adda8d182b48c00d3 Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:38:27 -0400 Subject: [PATCH 06/91] Removed fast place, already implemented --- .../lambda/module/modules/player/FastPlace.kt | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 common/src/main/kotlin/com/lambda/module/modules/player/FastPlace.kt diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/FastPlace.kt b/common/src/main/kotlin/com/lambda/module/modules/player/FastPlace.kt deleted file mode 100644 index 92f7a0b8e..000000000 --- a/common/src/main/kotlin/com/lambda/module/modules/player/FastPlace.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.lambda.module.modules.player - -import com.lambda.event.events.TickEvent -import com.lambda.event.listener.SafeListener.Companion.listener -import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag - -object FastPlace : Module( - name = "FastPlace", - description = "Place blocks faster.", - defaultTags = setOf( - ModuleTag.PLAYER, ModuleTag.WORLD - ) -) { - init { - listener { - mc.itemUseCooldown = 0 - } - } -} From e8d2c07e523bdc82f78582114abbc558306e5670 Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Sat, 27 Apr 2024 16:05:19 -0400 Subject: [PATCH 07/91] Fast break is implemented in a separate module --- .../main/kotlin/com/lambda/module/modules/player/Interact.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/Interact.kt b/common/src/main/kotlin/com/lambda/module/modules/player/Interact.kt index 694e6d78e..377257400 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/Interact.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/Interact.kt @@ -8,8 +8,6 @@ object Interact : Module( description = "Modify players interaction with the world", defaultTags = setOf(ModuleTag.PLAYER) ) { - // ToDo: Is this fast place / fast use? Should it be relocated with more options? @JvmStatic val placeDelay by setting("Item Use / Place Delay", 4, 0..20, 1, "Sets the delay between placing blocks or using items") -// @JvmStatic val breakDelay by setting("Attack / Break Delay", 10, 0..20, 1) @JvmStatic val multiAction by setting("Multi Action", false, "Allows to use many items while breaking blocks") } From 9b6342391072cb4a5f89238b061e95879f91aa87 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Tue, 11 Jun 2024 05:08:10 +0100 Subject: [PATCH 08/91] - added packet mine --- .../module/modules/player/PacketMine.kt | 256 ++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt new file mode 100644 index 000000000..eb01c6876 --- /dev/null +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -0,0 +1,256 @@ +package com.lambda.module.modules.player + +import com.lambda.context.SafeContext +import com.lambda.event.events.PacketEvent +import com.lambda.event.events.TickEvent +import com.lambda.event.listener.SafeListener.Companion.listener +import com.lambda.module.Module +import com.lambda.module.tag.ModuleTag +import net.minecraft.block.BlockState +import net.minecraft.enchantment.EnchantmentHelper +import net.minecraft.enchantment.Enchantments +import net.minecraft.entity.effect.StatusEffectUtil +import net.minecraft.entity.effect.StatusEffects +import net.minecraft.fluid.Fluids +import net.minecraft.item.ItemStack +import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket +import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket +import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket +import net.minecraft.network.packet.s2c.play.ChunkDeltaUpdateS2CPacket +import net.minecraft.registry.tag.FluidTags +import net.minecraft.state.property.Properties +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Direction +import java.util.function.BiConsumer + +object PacketMine : Module( + name = "Packet Mine", + description = "Mines blocks semi-automatically at a faster rate", + defaultTags = setOf(ModuleTag.PLAYER) +) { + + private val blockTimeout by setting("Block Timeout", 500, 0..3000, 1, "Time delay before cancelling the current block after its time to mine is complete", unit = "milliseconds") + private val speedyReBreak by setting("Speedy Re-Break", false, "Re-breaks blocks instantly however can cause ghost blocks") + + private var currentMiningBlock: BlockData? = null + private var reBreakBlock: BlockData? = null + private var ignorePacketSend = false + + init { + listener { + currentMiningBlock?.apply { + val state = world.getBlockState(this.pos) + + if (state != this.state) { + this.state = state + } + + val bestTool = getBestTool(state, this.pos) + + if (this.mineTicks * calcBreakDelta(this.state, this.pos, bestTool) < 1) { + swapStopBreak(this.pos, bestTool) + } else { + if (!this.awaitingResponse) { + this.awaitingResponse = true + this.timeCompletedAt = System.currentTimeMillis() + } + if (System.currentTimeMillis() - this.timeCompletedAt > blockTimeout) { + currentMiningBlock = null + } + } + this.mineTicks++ + } ?: reBreakBlock?.apply { + if (player.eyePos.distanceTo(this.pos.toCenterPos()) > 6) { + reBreakBlock = null + return@listener + } + this.mineTicks++ + + val state = world.getBlockState(this.pos) + + if (state != this.state) this.state = state + + val bestTool = getBestTool(this.state, this.pos) + + if (this.mineTicks * calcBreakDelta(this.state, this.pos, bestTool) > 0.7) { + if ((!state.isAir && (state.fluidState.isEmpty || state.properties.contains(Properties.WATERLOGGED))) + || speedyReBreak) { + swapStopBreak(this.pos, bestTool) + interaction.breakBlock(this.pos) + } + } + } + } + + listener { + if (it.packet is PlayerActionC2SPacket + && (it.packet.action.equals(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK) + || it.packet.action.equals(PlayerActionC2SPacket.Action.ABORT_DESTROY_BLOCK) + || it.packet.action.equals(PlayerActionC2SPacket.Action.STOP_DESTROY_BLOCK) + )) { + if (ignorePacketSend) return@listener + + it.cancel() + + val state = world.getBlockState(it.packet.pos) + + currentMiningBlock?.let {miningBlock -> + if (it.packet.pos.equals(miningBlock.pos)) return@listener + } + + val bestTool = getBestTool(state, it.packet.pos) + + if (calcBreakDelta(world.getBlockState(it.packet.pos), it.packet.pos, bestTool) > 0.7) { + swapStartBreak(it.packet.pos, bestTool) + currentMiningBlock = null + reBreakBlock = BlockData(it.packet.pos, state) + state.block.onBreak(world, it.packet.pos, state, player) + } else { + swapStartPacketBreak(it.packet.pos, bestTool) + reBreakBlock = null + currentMiningBlock = BlockData(it.packet.pos, state) + } + } + } + + listener { + currentMiningBlock?.let { miningBlock -> + if (it.packet is BlockUpdateS2CPacket + && it.packet.pos.equals(miningBlock.pos) + && (if (miningBlock.state.properties.contains(Properties.WATERLOGGED)) + it.packet.state.fluidState.fluid.equals(Fluids.WATER) + else it.packet.state.isAir)) { + if (player.eyePos.distanceTo(miningBlock.pos.toCenterPos()) < 6) { + reBreakBlock = miningBlock + } + miningBlock.state.block.onBreak(world, miningBlock.pos, miningBlock.state, player) + currentMiningBlock = null + } else if (it.packet is ChunkDeltaUpdateS2CPacket) { + it.packet.visitUpdates(BiConsumer { pos: BlockPos, state: BlockState -> + currentMiningBlock?.let { miningBlock -> + if (pos == miningBlock.pos + && (if (miningBlock.state.properties.contains(Properties.WATERLOGGED)) + state.fluidState.fluid.equals(Fluids.WATER) + else state.isAir)) { + if (player.eyePos.distanceTo(miningBlock.pos.toCenterPos()) < 6) { + reBreakBlock = miningBlock + } + miningBlock.state.block.onBreak(world, miningBlock.pos, miningBlock.state, player) + currentMiningBlock = null + } + } + }) + } + } + } + } + + private fun SafeContext.swapStartPacketBreak(pos: BlockPos, toolSlot: Int) { + connection.sendPacket(UpdateSelectedSlotC2SPacket(toolSlot)) + ignorePacketSend = true + startBreak(pos) + abortBreak(pos) + stopBreak(pos) + ignorePacketSend = false + connection.sendPacket(UpdateSelectedSlotC2SPacket(player.inventory.selectedSlot)) + } + + private fun SafeContext.swapStopBreak(pos: BlockPos, toolSlot: Int) { + connection.sendPacket(UpdateSelectedSlotC2SPacket(toolSlot)) + ignorePacketSend = true + stopBreak(pos) + ignorePacketSend = false + connection.sendPacket(UpdateSelectedSlotC2SPacket(player.inventory.selectedSlot)) + } + + private fun SafeContext.swapStartBreak(pos: BlockPos, toolSlot: Int) { + connection.sendPacket(UpdateSelectedSlotC2SPacket(toolSlot)) + ignorePacketSend = true + startBreak(pos) + ignorePacketSend = false + connection.sendPacket(UpdateSelectedSlotC2SPacket(player.inventory.selectedSlot)) + } + + private fun SafeContext.startBreak(pos: BlockPos) { + connection.sendPacket(PlayerActionC2SPacket(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, pos, Direction.UP, 0)) + } + + private fun SafeContext.abortBreak(pos: BlockPos) { + connection.sendPacket(PlayerActionC2SPacket(PlayerActionC2SPacket.Action.ABORT_DESTROY_BLOCK, pos, Direction.UP, 0)) + } + + private fun SafeContext.stopBreak(pos: BlockPos) { + connection.sendPacket(PlayerActionC2SPacket(PlayerActionC2SPacket.Action.STOP_DESTROY_BLOCK, pos, Direction.UP, 0)) + } + + /* + Still unsure on how the task system works so im using these methods for now + */ + + private fun SafeContext.getBestTool(state: BlockState, pos: BlockPos): Int { + var bestTool = -1 + var bestTimeToMine = 0f + for (i in 0..8) { + val currentToolsTimeToMine = calcBreakDelta(state, pos, i) + if (currentToolsTimeToMine > bestTimeToMine) { + bestTimeToMine = currentToolsTimeToMine + bestTool = i + } + } + return bestTool + } + + private fun SafeContext.calcBreakDelta(state: BlockState, pos: BlockPos, toolSlot: Int): Float { + val f: Float = state.getHardness(world, pos) + if (f == -1.0f) { + return 0.0f + } else { + val i = if (!state.isToolRequired || player.inventory.getStack(toolSlot).isSuitableFor(state)) 30 else 100 + return getBlockBreakingSpeed(state, toolSlot) / f / i.toFloat() + } + } + + private fun SafeContext.getBlockBreakingSpeed(state: BlockState, toolSlot: Int): Float { + var f: Float = player.inventory.getStack(toolSlot).getMiningSpeedMultiplier(state) + if (f > 1.0f) { + val itemStack: ItemStack = player.inventory.getStack(toolSlot) + val i = EnchantmentHelper.getLevel(Enchantments.EFFICIENCY, itemStack) + if (i > 0 && !itemStack.isEmpty) { + f += (i * i + 1).toFloat() + } + } + + if (StatusEffectUtil.hasHaste(player)) { + f *= 1.0f + (StatusEffectUtil.getHasteAmplifier(player) + 1).toFloat() * 0.2f + } + + if (player.hasStatusEffect(StatusEffects.MINING_FATIGUE)) { + val g = when (player.getStatusEffect(StatusEffects.MINING_FATIGUE)?.amplifier) { + 0 -> 0.3f + 1 -> 0.09f + 2 -> 0.0027f + 3 -> 8.1E-4f + else -> 8.1E-4f + } + f *= g + } + + if (player.isSubmergedIn(FluidTags.WATER) + && !EnchantmentHelper.hasAquaAffinity(player) + ) { + f /= 5.0f + } + + if (!player.isOnGround) { + f /= 5.0f + } + + return f + } + + private class BlockData(var pos: BlockPos, var state: BlockState) { + var mineTicks: Int = 0 + var awaitingResponse: Boolean = false + var timeCompletedAt: Long = -1 + } +} \ No newline at end of file From 92813b3fd4fabf0ef3125d3965216ccec12eee92 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Tue, 11 Jun 2024 16:03:19 +0100 Subject: [PATCH 09/91] - added option for rebreak and fast re-break - removed block timeout setting --- .../module/modules/player/PacketMine.kt | 52 +++++++++++++------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index eb01c6876..e468c7871 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -29,8 +29,8 @@ object PacketMine : Module( defaultTags = setOf(ModuleTag.PLAYER) ) { - private val blockTimeout by setting("Block Timeout", 500, 0..3000, 1, "Time delay before cancelling the current block after its time to mine is complete", unit = "milliseconds") - private val speedyReBreak by setting("Speedy Re-Break", false, "Re-breaks blocks instantly however can cause ghost blocks") + private val reBreak by setting("Re-Break", true, "Automatically re-breaks the last mined block if it gets replaced") + private val fastReBreak by setting("Speedy Re-Break", false, "Re-breaks blocks instantly however could potentially cause ghost blocks", visibility = ::reBreak) private var currentMiningBlock: BlockData? = null private var reBreakBlock: BlockData? = null @@ -39,6 +39,10 @@ object PacketMine : Module( init { listener { currentMiningBlock?.apply { + this.mineTicks++ + + if (this.awaitingResponse) return@listener + val state = world.getBlockState(this.pos) if (state != this.state) { @@ -47,18 +51,12 @@ object PacketMine : Module( val bestTool = getBestTool(state, this.pos) - if (this.mineTicks * calcBreakDelta(this.state, this.pos, bestTool) < 1) { - swapStopBreak(this.pos, bestTool) - } else { + if (this.mineTicks * calcBreakDelta(this.state, this.pos, bestTool) > 0.7) { if (!this.awaitingResponse) { this.awaitingResponse = true - this.timeCompletedAt = System.currentTimeMillis() - } - if (System.currentTimeMillis() - this.timeCompletedAt > blockTimeout) { - currentMiningBlock = null + swapStopBreak(this.pos, bestTool) } } - this.mineTicks++ } ?: reBreakBlock?.apply { if (player.eyePos.distanceTo(this.pos.toCenterPos()) > 6) { reBreakBlock = null @@ -74,9 +72,11 @@ object PacketMine : Module( if (this.mineTicks * calcBreakDelta(this.state, this.pos, bestTool) > 0.7) { if ((!state.isAir && (state.fluidState.isEmpty || state.properties.contains(Properties.WATERLOGGED))) - || speedyReBreak) { + || fastReBreak) { swapStopBreak(this.pos, bestTool) - interaction.breakBlock(this.pos) + if (fastReBreak) { + interaction.breakBlock(this.pos) + } } } } @@ -103,7 +103,9 @@ object PacketMine : Module( if (calcBreakDelta(world.getBlockState(it.packet.pos), it.packet.pos, bestTool) > 0.7) { swapStartBreak(it.packet.pos, bestTool) currentMiningBlock = null - reBreakBlock = BlockData(it.packet.pos, state) + if (reBreak) { + reBreakBlock = BlockData(it.packet.pos, state) + } state.block.onBreak(world, it.packet.pos, state, player) } else { swapStartPacketBreak(it.packet.pos, bestTool) @@ -120,7 +122,8 @@ object PacketMine : Module( && (if (miningBlock.state.properties.contains(Properties.WATERLOGGED)) it.packet.state.fluidState.fluid.equals(Fluids.WATER) else it.packet.state.isAir)) { - if (player.eyePos.distanceTo(miningBlock.pos.toCenterPos()) < 6) { + if (reBreak + && player.eyePos.distanceTo(miningBlock.pos.toCenterPos()) < 6) { reBreakBlock = miningBlock } miningBlock.state.block.onBreak(world, miningBlock.pos, miningBlock.state, player) @@ -132,7 +135,8 @@ object PacketMine : Module( && (if (miningBlock.state.properties.contains(Properties.WATERLOGGED)) state.fluidState.fluid.equals(Fluids.WATER) else state.isAir)) { - if (player.eyePos.distanceTo(miningBlock.pos.toCenterPos()) < 6) { + if (reBreak + && player.eyePos.distanceTo(miningBlock.pos.toCenterPos()) < 6) { reBreakBlock = miningBlock } miningBlock.state.block.onBreak(world, miningBlock.pos, miningBlock.state, player) @@ -141,6 +145,23 @@ object PacketMine : Module( } }) } + } ?: reBreakBlock?.let { reBlock -> + if (it.packet is BlockUpdateS2CPacket + && it.packet.pos.equals(reBlock.pos) + && (if (reBlock.state.properties.contains(Properties.WATERLOGGED)) + it.packet.state.fluidState.fluid.equals(Fluids.WATER) + else it.packet.state.isAir)) { + if (!fastReBreak) reBlock.state.block.onBreak(world, reBlock.pos, reBlock.state, player) + } else if (it.packet is ChunkDeltaUpdateS2CPacket) { + it.packet.visitUpdates(BiConsumer { pos: BlockPos, state: BlockState -> + if (pos == reBlock.pos + && (if (reBlock.state.properties.contains(Properties.WATERLOGGED)) + state.fluidState.fluid.equals(Fluids.WATER) + else state.isAir)) { + if (!fastReBreak) reBlock.state.block.onBreak(world, reBlock.pos, reBlock.state, player) + } + }) + } } } } @@ -251,6 +272,5 @@ object PacketMine : Module( private class BlockData(var pos: BlockPos, var state: BlockState) { var mineTicks: Int = 0 var awaitingResponse: Boolean = false - var timeCompletedAt: Long = -1 } } \ No newline at end of file From e2dafbf8b0deb3ddf8a05cd8a43bf11804ef219c Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Wed, 12 Jun 2024 15:59:08 +0100 Subject: [PATCH 10/91] - swapped out the two block breaking var's for a state enum --- .../module/modules/player/PacketMine.kt | 142 +++++++++--------- 1 file changed, 70 insertions(+), 72 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index e468c7871..ac50805a5 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -33,49 +33,33 @@ object PacketMine : Module( private val fastReBreak by setting("Speedy Re-Break", false, "Re-breaks blocks instantly however could potentially cause ghost blocks", visibility = ::reBreak) private var currentMiningBlock: BlockData? = null - private var reBreakBlock: BlockData? = null private var ignorePacketSend = false init { listener { currentMiningBlock?.apply { - this.mineTicks++ - - if (this.awaitingResponse) return@listener - val state = world.getBlockState(this.pos) - - if (state != this.state) { - this.state = state - } - - val bestTool = getBestTool(state, this.pos) - - if (this.mineTicks * calcBreakDelta(this.state, this.pos, bestTool) > 0.7) { - if (!this.awaitingResponse) { - this.awaitingResponse = true - swapStopBreak(this.pos, bestTool) - } - } - } ?: reBreakBlock?.apply { - if (player.eyePos.distanceTo(this.pos.toCenterPos()) > 6) { - reBreakBlock = null - return@listener - } this.mineTicks++ - val state = world.getBlockState(this.pos) - if (state != this.state) this.state = state + val bestTool = getBestTool(state, this.pos) - val bestTool = getBestTool(this.state, this.pos) - - if (this.mineTicks * calcBreakDelta(this.state, this.pos, bestTool) > 0.7) { - if ((!state.isAir && (state.fluidState.isEmpty || state.properties.contains(Properties.WATERLOGGED))) - || fastReBreak) { + if (this.breakState == BreakState.BREAKING) { + if (this.mineTicks * calcBreakDelta(this.state, this.pos, bestTool) > 0.7) { + this.breakState = BreakState.AWAITING_RESPONSE swapStopBreak(this.pos, bestTool) + } + } else if (this.breakState == BreakState.REBREAKING) { + if (player.eyePos.distanceTo(this.pos.toCenterPos()) > 6) { + currentMiningBlock = null + return@listener + } + if (this.mineTicks * calcBreakDelta(this.state, this.pos, bestTool) > 0.7) { if (fastReBreak) { + swapStopBreak(this.pos, bestTool) interaction.breakBlock(this.pos) + } else if (!state.isAir && (state.fluidState.isEmpty || state.properties.contains(Properties.WATERLOGGED))) { + swapStopBreak(this.pos, bestTool) } } } @@ -102,66 +86,77 @@ object PacketMine : Module( if (calcBreakDelta(world.getBlockState(it.packet.pos), it.packet.pos, bestTool) > 0.7) { swapStartBreak(it.packet.pos, bestTool) - currentMiningBlock = null - if (reBreak) { - reBreakBlock = BlockData(it.packet.pos, state) + swapStartPacketBreak(it.packet.pos, bestTool) + currentMiningBlock = if (reBreak) { + BlockData(it.packet.pos, state, BreakState.REBREAKING) + } else { + null } - state.block.onBreak(world, it.packet.pos, state, player) + currentMiningBlock?.instaBroken = true + interaction.breakBlock(it.packet.pos) } else { swapStartPacketBreak(it.packet.pos, bestTool) - reBreakBlock = null - currentMiningBlock = BlockData(it.packet.pos, state) + currentMiningBlock = BlockData(it.packet.pos, state, BreakState.BREAKING) } } } listener { - currentMiningBlock?.let { miningBlock -> + currentMiningBlock?.apply { if (it.packet is BlockUpdateS2CPacket - && it.packet.pos.equals(miningBlock.pos) - && (if (miningBlock.state.properties.contains(Properties.WATERLOGGED)) + && it.packet.pos.equals(this.pos) + && (if (this.state.properties.contains(Properties.WATERLOGGED)) it.packet.state.fluidState.fluid.equals(Fluids.WATER) else it.packet.state.isAir)) { - if (reBreak - && player.eyePos.distanceTo(miningBlock.pos.toCenterPos()) < 6) { - reBreakBlock = miningBlock + + if (this.breakState == BreakState.BREAKING || this.breakState == BreakState.AWAITING_RESPONSE) { + this.state.block.onBreak(world, this.pos, this.state, player) + if (reBreak + && player.eyePos.distanceTo(this.pos.toCenterPos()) < 6) { + this.breakState = BreakState.REBREAKING + } else { + currentMiningBlock = null + } + + } else if (this.breakState == BreakState.REBREAKING) { + if (!fastReBreak) { + if (!this.instaBroken) { + this.state.block.onBreak(world, this.pos, this.state, player) + } else { + this.instaBroken = false + } + } } - miningBlock.state.block.onBreak(world, miningBlock.pos, miningBlock.state, player) - currentMiningBlock = null } else if (it.packet is ChunkDeltaUpdateS2CPacket) { it.packet.visitUpdates(BiConsumer { pos: BlockPos, state: BlockState -> - currentMiningBlock?.let { miningBlock -> - if (pos == miningBlock.pos - && (if (miningBlock.state.properties.contains(Properties.WATERLOGGED)) + currentMiningBlock?.apply { + if (pos == this.pos + && (if (this.state.properties.contains(Properties.WATERLOGGED)) state.fluidState.fluid.equals(Fluids.WATER) else state.isAir)) { - if (reBreak - && player.eyePos.distanceTo(miningBlock.pos.toCenterPos()) < 6) { - reBreakBlock = miningBlock + + if (this.breakState == BreakState.BREAKING || this.breakState == BreakState.AWAITING_RESPONSE) { + this.state.block.onBreak(world, this.pos, this.state, player) + if (reBreak + && player.eyePos.distanceTo(this.pos.toCenterPos()) < 6) { + this.breakState = BreakState.REBREAKING + } else { + currentMiningBlock = null + } + + } else if (this.breakState == BreakState.REBREAKING) { + if (!fastReBreak) { + if (!this.instaBroken) { + this.state.block.onBreak(world, this.pos, this.state, player) + } else { + this.instaBroken = false + } + } } - miningBlock.state.block.onBreak(world, miningBlock.pos, miningBlock.state, player) - currentMiningBlock = null } } }) } - } ?: reBreakBlock?.let { reBlock -> - if (it.packet is BlockUpdateS2CPacket - && it.packet.pos.equals(reBlock.pos) - && (if (reBlock.state.properties.contains(Properties.WATERLOGGED)) - it.packet.state.fluidState.fluid.equals(Fluids.WATER) - else it.packet.state.isAir)) { - if (!fastReBreak) reBlock.state.block.onBreak(world, reBlock.pos, reBlock.state, player) - } else if (it.packet is ChunkDeltaUpdateS2CPacket) { - it.packet.visitUpdates(BiConsumer { pos: BlockPos, state: BlockState -> - if (pos == reBlock.pos - && (if (reBlock.state.properties.contains(Properties.WATERLOGGED)) - state.fluidState.fluid.equals(Fluids.WATER) - else state.isAir)) { - if (!fastReBreak) reBlock.state.block.onBreak(world, reBlock.pos, reBlock.state, player) - } - }) - } } } } @@ -269,8 +264,11 @@ object PacketMine : Module( return f } - private class BlockData(var pos: BlockPos, var state: BlockState) { - var mineTicks: Int = 0 - var awaitingResponse: Boolean = false + private class BlockData(var pos: BlockPos, var state: BlockState, var breakState: BreakState) { + var mineTicks = 0 + var instaBroken = false + } + private enum class BreakState { + BREAKING, REBREAKING, AWAITING_RESPONSE } } \ No newline at end of file From dd27c98aa153ffac6e8adec312f090562188e5f5 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Wed, 12 Jun 2024 20:46:36 +0100 Subject: [PATCH 11/91] - fixed reset rotations method --- .../src/main/kotlin/com/lambda/interaction/RotationManager.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/kotlin/com/lambda/interaction/RotationManager.kt b/common/src/main/kotlin/com/lambda/interaction/RotationManager.kt index 11031eb63..693a18057 100644 --- a/common/src/main/kotlin/com/lambda/interaction/RotationManager.kt +++ b/common/src/main/kotlin/com/lambda/interaction/RotationManager.kt @@ -46,7 +46,7 @@ object RotationManager : Loadable { } init { - listener { event -> + listener { event -> val packet = event.packet if (packet !is PlayerPositionLookS2CPacket) return@listener From 4966c413bd54cc072b5afd0ce98c3296dc6307c5 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 14 Jun 2024 19:40:42 +0100 Subject: [PATCH 12/91] - added queue and cleaned up code a ton --- .../module/modules/player/PacketMine.kt | 253 +++++++++++------- 1 file changed, 154 insertions(+), 99 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index ac50805a5..92cc224b2 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -14,6 +14,7 @@ import net.minecraft.entity.effect.StatusEffects import net.minecraft.fluid.Fluids import net.minecraft.item.ItemStack import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket +import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket import net.minecraft.network.packet.s2c.play.ChunkDeltaUpdateS2CPacket @@ -31,134 +32,188 @@ object PacketMine : Module( private val reBreak by setting("Re-Break", true, "Automatically re-breaks the last mined block if it gets replaced") private val fastReBreak by setting("Speedy Re-Break", false, "Re-breaks blocks instantly however could potentially cause ghost blocks", visibility = ::reBreak) + private val queueBlocks by setting("Queue Blocks", false, "Queues any blocks you click for breaking").apply { this.onValueSet { _, to -> if (!to) blockQueue.clear() } } + private val doubleBreakQueue by setting("Double Break Queue", false, "Queues any blocks you click for breaking", visibility = ::queueBlocks) - private var currentMiningBlock: BlockData? = null + private var currentMiningBlock: BreakingContext? = null private var ignorePacketSend = false + private val blockQueue: ArrayDeque = ArrayDeque() + + private val validActions = setOf(Action.START_DESTROY_BLOCK, Action.STOP_DESTROY_BLOCK, Action.ABORT_DESTROY_BLOCK) init { listener { currentMiningBlock?.apply { + mineTicks++ + val activeState = world.getBlockState(pos) + if (activeState != state) state = activeState + val bestTool = getBestTool(activeState, pos) - this.mineTicks++ - val state = world.getBlockState(this.pos) - if (state != this.state) this.state = state - val bestTool = getBestTool(state, this.pos) + when (breakState) { + BreakState.BREAKING -> { + if (mineTicks * calcBreakDelta(state, pos, bestTool) < 0.7) return@listener - if (this.breakState == BreakState.BREAKING) { - if (this.mineTicks * calcBreakDelta(this.state, this.pos, bestTool) > 0.7) { - this.breakState = BreakState.AWAITING_RESPONSE - swapStopBreak(this.pos, bestTool) - } - } else if (this.breakState == BreakState.REBREAKING) { - if (player.eyePos.distanceTo(this.pos.toCenterPos()) > 6) { - currentMiningBlock = null - return@listener + swapStopBreak(pos, bestTool) + breakState = BreakState.AWAITING_RESPONSE } - if (this.mineTicks * calcBreakDelta(this.state, this.pos, bestTool) > 0.7) { - if (fastReBreak) { - swapStopBreak(this.pos, bestTool) - interaction.breakBlock(this.pos) - } else if (!state.isAir && (state.fluidState.isEmpty || state.properties.contains(Properties.WATERLOGGED))) { - swapStopBreak(this.pos, bestTool) + BreakState.REBREAKING -> { + if (breakNextQueueBlock()) return@listener + + if (player.eyePos.distanceTo(pos.toCenterPos()) > 6) { + currentMiningBlock = null + return@listener } - } - } - } - } - listener { - if (it.packet is PlayerActionC2SPacket - && (it.packet.action.equals(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK) - || it.packet.action.equals(PlayerActionC2SPacket.Action.ABORT_DESTROY_BLOCK) - || it.packet.action.equals(PlayerActionC2SPacket.Action.STOP_DESTROY_BLOCK) - )) { - if (ignorePacketSend) return@listener + if (mineTicks * calcBreakDelta(state, pos, bestTool) < 0.7) return@listener - it.cancel() + swapStopBreak(pos, bestTool) - val state = world.getBlockState(it.packet.pos) + if (!fastReBreak) return@listener - currentMiningBlock?.let {miningBlock -> - if (it.packet.pos.equals(miningBlock.pos)) return@listener - } + interaction.breakBlock(pos) + } + BreakState.AWAITING_RESPONSE -> { + if (mineTicks * calcBreakDelta(state, pos, getBestTool(state, pos)) < 1) return@listener - val bestTool = getBestTool(state, it.packet.pos) + if (breakNextQueueBlock()) return@listener - if (calcBreakDelta(world.getBlockState(it.packet.pos), it.packet.pos, bestTool) > 0.7) { - swapStartBreak(it.packet.pos, bestTool) - swapStartPacketBreak(it.packet.pos, bestTool) - currentMiningBlock = if (reBreak) { - BlockData(it.packet.pos, state, BreakState.REBREAKING) - } else { - null + currentMiningBlock = null } - currentMiningBlock?.instaBroken = true - interaction.breakBlock(it.packet.pos) - } else { - swapStartPacketBreak(it.packet.pos, bestTool) - currentMiningBlock = BlockData(it.packet.pos, state, BreakState.BREAKING) } + } ?: run { + breakNextQueueBlock() } } + listener { + if (it.packet !is PlayerActionC2SPacket || !validActions.contains(it.packet.action) || ignorePacketSend) return@listener + it.cancel() + + val packetPos = it.packet.pos + + if (queueBlocks + && (currentMiningBlock != null + && currentMiningBlock?.breakState != BreakState.REBREAKING + && currentMiningBlock?.pos != packetPos) + || (!blockQueue.isEmpty() + && !blockQueue.contains(packetPos)) + ) { + blockQueue.add(packetPos) + return@listener + } + + startBreaking(packetPos) + } + listener { currentMiningBlock?.apply { if (it.packet is BlockUpdateS2CPacket - && it.packet.pos.equals(this.pos) - && (if (this.state.properties.contains(Properties.WATERLOGGED)) - it.packet.state.fluidState.fluid.equals(Fluids.WATER) + && it.packet.pos.equals(pos) + && (if (state.properties.contains(Properties.WATERLOGGED)) it.packet.state.fluidState.fluid.equals(Fluids.WATER) else it.packet.state.isAir)) { - if (this.breakState == BreakState.BREAKING || this.breakState == BreakState.AWAITING_RESPONSE) { - this.state.block.onBreak(world, this.pos, this.state, player) - if (reBreak - && player.eyePos.distanceTo(this.pos.toCenterPos()) < 6) { - this.breakState = BreakState.REBREAKING - } else { - currentMiningBlock = null - } + if (breakState == BreakState.REBREAKING) { + if (fastReBreak) return@listener - } else if (this.breakState == BreakState.REBREAKING) { - if (!fastReBreak) { - if (!this.instaBroken) { - this.state.block.onBreak(world, this.pos, this.state, player) - } else { - this.instaBroken = false - } + if (instaBroken) { + instaBroken = false + return@listener } + + state.block.onBreak(world, pos, state, player) + return@listener } - } else if (it.packet is ChunkDeltaUpdateS2CPacket) { - it.packet.visitUpdates(BiConsumer { pos: BlockPos, state: BlockState -> - currentMiningBlock?.apply { - if (pos == this.pos - && (if (this.state.properties.contains(Properties.WATERLOGGED)) - state.fluidState.fluid.equals(Fluids.WATER) - else state.isAir)) { - - if (this.breakState == BreakState.BREAKING || this.breakState == BreakState.AWAITING_RESPONSE) { - this.state.block.onBreak(world, this.pos, this.state, player) - if (reBreak - && player.eyePos.distanceTo(this.pos.toCenterPos()) < 6) { - this.breakState = BreakState.REBREAKING - } else { - currentMiningBlock = null - } - - } else if (this.breakState == BreakState.REBREAKING) { - if (!fastReBreak) { - if (!this.instaBroken) { - this.state.block.onBreak(world, this.pos, this.state, player) - } else { - this.instaBroken = false - } - } - } + + state.block.onBreak(world, pos, state, player) + + if (reBreak + && player.eyePos.distanceTo(pos.toCenterPos()) < 6) { + breakState = BreakState.REBREAKING + return@listener + } + + currentMiningBlock = null + return@listener + } + + if (it.packet !is ChunkDeltaUpdateS2CPacket) return@listener + + it.packet.visitUpdates(BiConsumer { changedPos: BlockPos, changedState: BlockState -> + currentMiningBlock?.apply { + if (changedPos != pos + || !(if (state.properties.contains(Properties.WATERLOGGED)) changedState.fluidState.fluid.equals(Fluids.WATER) + else changedState.isAir)) return@BiConsumer + + if (breakState == BreakState.REBREAKING) { + if (fastReBreak) return@BiConsumer + + if (instaBroken) { + instaBroken = false + return@BiConsumer } + + state.block.onBreak(world, pos, state, player) + return@BiConsumer } - }) - } + + state.block.onBreak(world, pos, state, player) + + if (reBreak + && player.eyePos.distanceTo(pos.toCenterPos()) < 6) { + breakState = BreakState.REBREAKING + return@BiConsumer + } + + currentMiningBlock = null + } + }) + } + } + } + + private fun SafeContext.startBreaking(pos: BlockPos) { + if (currentMiningBlock?.pos == pos) return + + val state = world.getBlockState(pos) + + val bestTool = getBestTool(state, pos) + + if (calcBreakDelta(world.getBlockState(pos), pos, bestTool) > 0.7) { + swapStartBreak(pos, bestTool) + swapStartPacketBreak(pos, bestTool) + currentMiningBlock = if (reBreak) { + BreakingContext(pos, state, BreakState.REBREAKING) + } else { + null } + currentMiningBlock?.instaBroken = true + state.block.onBreak(world, pos, state, player) + return } + + swapStartPacketBreak(pos, bestTool) + currentMiningBlock = BreakingContext(pos, state, BreakState.BREAKING) + } + + private fun SafeContext.breakNextQueueBlock(): Boolean { + if (!queueBlocks) return false + + while (true) { + val block = blockQueue.firstOrNull() ?: run { return false } + + if (player.eyePos.distanceTo(block.toCenterPos()) > 6) { + blockQueue.removeFirst() + continue + } + + break + } + + if (blockQueue.isEmpty()) return false + + startBreaking(blockQueue.first()) + blockQueue.removeFirst() + return true } private fun SafeContext.swapStartPacketBreak(pos: BlockPos, toolSlot: Int) { @@ -188,15 +243,15 @@ object PacketMine : Module( } private fun SafeContext.startBreak(pos: BlockPos) { - connection.sendPacket(PlayerActionC2SPacket(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, pos, Direction.UP, 0)) + connection.sendPacket(PlayerActionC2SPacket(Action.START_DESTROY_BLOCK, pos, Direction.UP, 0)) } private fun SafeContext.abortBreak(pos: BlockPos) { - connection.sendPacket(PlayerActionC2SPacket(PlayerActionC2SPacket.Action.ABORT_DESTROY_BLOCK, pos, Direction.UP, 0)) + connection.sendPacket(PlayerActionC2SPacket(Action.ABORT_DESTROY_BLOCK, pos, Direction.UP, 0)) } private fun SafeContext.stopBreak(pos: BlockPos) { - connection.sendPacket(PlayerActionC2SPacket(PlayerActionC2SPacket.Action.STOP_DESTROY_BLOCK, pos, Direction.UP, 0)) + connection.sendPacket(PlayerActionC2SPacket(Action.STOP_DESTROY_BLOCK, pos, Direction.UP, 0)) } /* @@ -264,7 +319,7 @@ object PacketMine : Module( return f } - private class BlockData(var pos: BlockPos, var state: BlockState, var breakState: BreakState) { + private data class BreakingContext(var pos: BlockPos, var state: BlockState, var breakState: BreakState) { var mineTicks = 0 var instaBroken = false } From 423e800211273efd6275805c3326fc2243244356 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Sat, 15 Jun 2024 03:31:46 +0100 Subject: [PATCH 13/91] - added pages - changed the default packets to more generic packets with an "alternative packets" setting - swapped the block updates event listener for the world event block updates event - added "client side break" option - bug fixes --- .../module/modules/player/PacketMine.kt | 196 +++++++++--------- 1 file changed, 93 insertions(+), 103 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 92cc224b2..fb1fe92c8 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -3,6 +3,7 @@ package com.lambda.module.modules.player import com.lambda.context.SafeContext import com.lambda.event.events.PacketEvent import com.lambda.event.events.TickEvent +import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listener import com.lambda.module.Module import com.lambda.module.tag.ModuleTag @@ -16,24 +17,26 @@ import net.minecraft.item.ItemStack import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket -import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket -import net.minecraft.network.packet.s2c.play.ChunkDeltaUpdateS2CPacket import net.minecraft.registry.tag.FluidTags import net.minecraft.state.property.Properties import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction -import java.util.function.BiConsumer object PacketMine : Module( name = "Packet Mine", description = "Mines blocks semi-automatically at a faster rate", defaultTags = setOf(ModuleTag.PLAYER) ) { + private val page by setting("Page", Page.General) - private val reBreak by setting("Re-Break", true, "Automatically re-breaks the last mined block if it gets replaced") - private val fastReBreak by setting("Speedy Re-Break", false, "Re-breaks blocks instantly however could potentially cause ghost blocks", visibility = ::reBreak) - private val queueBlocks by setting("Queue Blocks", false, "Queues any blocks you click for breaking").apply { this.onValueSet { _, to -> if (!to) blockQueue.clear() } } - private val doubleBreakQueue by setting("Double Break Queue", false, "Queues any blocks you click for breaking", visibility = ::queueBlocks) + private val breakSpeed by setting("Break Speed", 1.0, 0.0..1.0, 0.1, "Breaks the selected block at the time to break of the block multiplied by this value", visibility = { page == Page.General}) + private val clientSideBreak by setting("Client Side Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) + private val timeoutDelay by setting("Timeout Delay", 0.20, 0.00..1.00, 0.1, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && !clientSideBreak }) + private val alternativePackets by setting("Alternative Packets", false, "Uses a different set of packets which tend to work better on servers using an anti-cheat like grim", visibility = { page == Page.General }) + private val queueBlocks by setting("Queue Blocks", false, "Queues any blocks you click for breaking", visibility = { page == Page.Queue }).apply { this.onValueSet { _, to -> if (!to) blockQueue.clear() } } + private val doubleBreakQueue by setting("Double Break Queue", false, "Queues any blocks you click for breaking", visibility = { page == Page.Queue && queueBlocks }) + private val reBreak by setting("Re-Break", true, "Automatically re-breaks the last mined block if it gets replaced", visibility = { page == Page.ReBreak}) + private val fastReBreak by setting("Fast Re-Break", false, "Re-breaks blocks instantly however could potentially cause ghost blocks", visibility = { page == Page.ReBreak && reBreak }) private var currentMiningBlock: BreakingContext? = null private var ignorePacketSend = false @@ -50,13 +53,30 @@ object PacketMine : Module( val bestTool = getBestTool(activeState, pos) when (breakState) { - BreakState.BREAKING -> { - if (mineTicks * calcBreakDelta(state, pos, bestTool) < 0.7) return@listener + BreakState.Breaking -> { + if (mineTicks * calcBreakDelta(state, pos, bestTool) < breakSpeed) return@listener + timeCompleted = System.currentTimeMillis() swapStopBreak(pos, bestTool) - breakState = BreakState.AWAITING_RESPONSE + + if (!clientSideBreak) { + breakState = BreakState.AwaitingResponse + return@listener + } + + interaction.breakBlock(pos) + + if (breakNextQueueBlock()) return@listener + + if (reBreak + && player.eyePos.distanceTo(pos.toCenterPos()) < 6) { + breakState = BreakState.ReBreaking + return@listener + } + + currentMiningBlock = null } - BreakState.REBREAKING -> { + BreakState.ReBreaking -> { if (breakNextQueueBlock()) return@listener if (player.eyePos.distanceTo(pos.toCenterPos()) > 6) { @@ -64,24 +84,32 @@ object PacketMine : Module( return@listener } - if (mineTicks * calcBreakDelta(state, pos, bestTool) < 0.7) return@listener + if (mineTicks * calcBreakDelta(state, pos, bestTool) < breakSpeed) return@listener - swapStopBreak(pos, bestTool) - - if (!fastReBreak) return@listener + if (!fastReBreak + && (activeState.isAir + || (!activeState.fluidState.isEmpty && !activeState.properties.contains(Properties.WATERLOGGED))) + ) return@listener - interaction.breakBlock(pos) + swapStopBreak(pos, bestTool) + if (clientSideBreak) interaction.breakBlock(pos) } - BreakState.AWAITING_RESPONSE -> { - if (mineTicks * calcBreakDelta(state, pos, getBestTool(state, pos)) < 1) return@listener + BreakState.AwaitingResponse -> { + if (clientSideBreak) return@listener + + if (System.currentTimeMillis() - timeCompleted < timeoutDelay) return@listener if (breakNextQueueBlock()) return@listener + if (reBreak + && player.eyePos.distanceTo(pos.toCenterPos()) < 6) { + breakState = BreakState.ReBreaking + return@listener + } + currentMiningBlock = null } } - } ?: run { - breakNextQueueBlock() } } @@ -93,10 +121,9 @@ object PacketMine : Module( if (queueBlocks && (currentMiningBlock != null - && currentMiningBlock?.breakState != BreakState.REBREAKING + && currentMiningBlock?.breakState != BreakState.ReBreaking && currentMiningBlock?.pos != packetPos) - || (!blockQueue.isEmpty() - && !blockQueue.contains(packetPos)) + || (!blockQueue.isEmpty() && !blockQueue.contains(packetPos)) ) { blockQueue.add(packetPos) return@listener @@ -105,68 +132,25 @@ object PacketMine : Module( startBreaking(packetPos) } - listener { + listener { currentMiningBlock?.apply { - if (it.packet is BlockUpdateS2CPacket - && it.packet.pos.equals(pos) - && (if (state.properties.contains(Properties.WATERLOGGED)) it.packet.state.fluidState.fluid.equals(Fluids.WATER) - else it.packet.state.isAir)) { - - if (breakState == BreakState.REBREAKING) { - if (fastReBreak) return@listener - - if (instaBroken) { - instaBroken = false - return@listener - } + if (it.pos != pos + || !(if (state.properties.contains(Properties.WATERLOGGED)) it.state.fluidState.fluid.equals(Fluids.WATER) + else it.state.isAir)) return@listener + if (!clientSideBreak) state.block.onBreak(world, pos, world.getBlockState(pos), player) - state.block.onBreak(world, pos, state, player) - return@listener - } + if (breakState == BreakState.ReBreaking) return@listener - state.block.onBreak(world, pos, state, player) + if (breakNextQueueBlock()) return@listener - if (reBreak - && player.eyePos.distanceTo(pos.toCenterPos()) < 6) { - breakState = BreakState.REBREAKING - return@listener - } - - currentMiningBlock = null + if (reBreak + && player.eyePos.distanceTo(pos.toCenterPos()) < 6) { + breakState = BreakState.ReBreaking return@listener } - if (it.packet !is ChunkDeltaUpdateS2CPacket) return@listener - - it.packet.visitUpdates(BiConsumer { changedPos: BlockPos, changedState: BlockState -> - currentMiningBlock?.apply { - if (changedPos != pos - || !(if (state.properties.contains(Properties.WATERLOGGED)) changedState.fluidState.fluid.equals(Fluids.WATER) - else changedState.isAir)) return@BiConsumer - - if (breakState == BreakState.REBREAKING) { - if (fastReBreak) return@BiConsumer - - if (instaBroken) { - instaBroken = false - return@BiConsumer - } - - state.block.onBreak(world, pos, state, player) - return@BiConsumer - } - - state.block.onBreak(world, pos, state, player) - - if (reBreak - && player.eyePos.distanceTo(pos.toCenterPos()) < 6) { - breakState = BreakState.REBREAKING - return@BiConsumer - } - - currentMiningBlock = null - } - }) + currentMiningBlock = null + return@listener } } } @@ -178,21 +162,28 @@ object PacketMine : Module( val bestTool = getBestTool(state, pos) - if (calcBreakDelta(world.getBlockState(pos), pos, bestTool) > 0.7) { - swapStartBreak(pos, bestTool) - swapStartPacketBreak(pos, bestTool) - currentMiningBlock = if (reBreak) { - BreakingContext(pos, state, BreakState.REBREAKING) + swapStartPacketBreak(pos, bestTool) + + if (calcBreakDelta(world.getBlockState(pos), pos, bestTool) > breakSpeed) { + if (reBreak) { + swapStartPacketBreak(pos, bestTool) + currentMiningBlock = BreakingContext(pos, state, BreakState.ReBreaking) } else { - null + currentMiningBlock = if (clientSideBreak) { + null + } else { + BreakingContext(pos, state, BreakState.AwaitingResponse) + } } - currentMiningBlock?.instaBroken = true + + if (!clientSideBreak) return + state.block.onBreak(world, pos, state, player) + return } - swapStartPacketBreak(pos, bestTool) - currentMiningBlock = BreakingContext(pos, state, BreakState.BREAKING) + currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking) } private fun SafeContext.breakNextQueueBlock(): Boolean { @@ -220,8 +211,10 @@ object PacketMine : Module( connection.sendPacket(UpdateSelectedSlotC2SPacket(toolSlot)) ignorePacketSend = true startBreak(pos) - abortBreak(pos) - stopBreak(pos) + if (alternativePackets) { + abortBreak(pos) + stopBreak(pos) + } ignorePacketSend = false connection.sendPacket(UpdateSelectedSlotC2SPacket(player.inventory.selectedSlot)) } @@ -234,26 +227,18 @@ object PacketMine : Module( connection.sendPacket(UpdateSelectedSlotC2SPacket(player.inventory.selectedSlot)) } - private fun SafeContext.swapStartBreak(pos: BlockPos, toolSlot: Int) { - connection.sendPacket(UpdateSelectedSlotC2SPacket(toolSlot)) - ignorePacketSend = true - startBreak(pos) - ignorePacketSend = false - connection.sendPacket(UpdateSelectedSlotC2SPacket(player.inventory.selectedSlot)) - } - private fun SafeContext.startBreak(pos: BlockPos) { connection.sendPacket(PlayerActionC2SPacket(Action.START_DESTROY_BLOCK, pos, Direction.UP, 0)) } - private fun SafeContext.abortBreak(pos: BlockPos) { - connection.sendPacket(PlayerActionC2SPacket(Action.ABORT_DESTROY_BLOCK, pos, Direction.UP, 0)) - } - private fun SafeContext.stopBreak(pos: BlockPos) { connection.sendPacket(PlayerActionC2SPacket(Action.STOP_DESTROY_BLOCK, pos, Direction.UP, 0)) } + private fun SafeContext.abortBreak(pos: BlockPos) { + connection.sendPacket(PlayerActionC2SPacket(Action.ABORT_DESTROY_BLOCK, pos, Direction.UP, 0)) + } + /* Still unsure on how the task system works so im using these methods for now */ @@ -321,9 +306,14 @@ object PacketMine : Module( private data class BreakingContext(var pos: BlockPos, var state: BlockState, var breakState: BreakState) { var mineTicks = 0 - var instaBroken = false + var timeCompleted: Long = -1 } + private enum class BreakState { - BREAKING, REBREAKING, AWAITING_RESPONSE + Breaking, ReBreaking, AwaitingResponse + } + + private enum class Page { + General, Queue, ReBreak } } \ No newline at end of file From d4a7e95adfb4d6c3eb7769006316e7f10671e3f7 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Sat, 15 Jun 2024 03:46:02 +0100 Subject: [PATCH 14/91] - removed rebreak triggering if block times out instead of being broken --- .../kotlin/com/lambda/module/modules/player/PacketMine.kt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index fb1fe92c8..1b56faa03 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -101,12 +101,6 @@ object PacketMine : Module( if (breakNextQueueBlock()) return@listener - if (reBreak - && player.eyePos.distanceTo(pos.toCenterPos()) < 6) { - breakState = BreakState.ReBreaking - return@listener - } - currentMiningBlock = null } } From a7180cf6d7316eed0369110bcdb29074bfa9e814 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 17 Jun 2024 03:08:00 +0100 Subject: [PATCH 15/91] - added pause while using items setting - added reverse queue order settings - fixed timeout setting - general bug fixes / improvements --- .../module/modules/player/PacketMine.kt | 80 ++++++++++++------- 1 file changed, 52 insertions(+), 28 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 1b56faa03..8e688c9ac 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -30,11 +30,15 @@ object PacketMine : Module( private val page by setting("Page", Page.General) private val breakSpeed by setting("Break Speed", 1.0, 0.0..1.0, 0.1, "Breaks the selected block at the time to break of the block multiplied by this value", visibility = { page == Page.General}) + private val pauseWhileUsingItems by setting("Pause While Using Items", true, "Will prevent breaking while using items like eating or aiming a bow", visibility = { page == Page.General }) + //ToDo: Implement these settings +// private val rotate by setting("Rotate", false, "Rotates the player to look at the current mining block", visibility = { page == Page.General }) +// private val autoSwap by setting("Auto Force Swap", false, "Hard swaps to the best tool rather than silent swapping. This is often used on servers with a stricter anti-cheat system", visibility = { page == Page.General}) private val clientSideBreak by setting("Client Side Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) private val timeoutDelay by setting("Timeout Delay", 0.20, 0.00..1.00, 0.1, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && !clientSideBreak }) private val alternativePackets by setting("Alternative Packets", false, "Uses a different set of packets which tend to work better on servers using an anti-cheat like grim", visibility = { page == Page.General }) private val queueBlocks by setting("Queue Blocks", false, "Queues any blocks you click for breaking", visibility = { page == Page.Queue }).apply { this.onValueSet { _, to -> if (!to) blockQueue.clear() } } - private val doubleBreakQueue by setting("Double Break Queue", false, "Queues any blocks you click for breaking", visibility = { page == Page.Queue && queueBlocks }) + private val reverseQueueOrder by setting("Reverse Queue Order", false, "Breaks the latest addition to the queue first", visibility = { page == Page.Queue && queueBlocks}) private val reBreak by setting("Re-Break", true, "Automatically re-breaks the last mined block if it gets replaced", visibility = { page == Page.ReBreak}) private val fastReBreak by setting("Fast Re-Break", false, "Re-breaks blocks instantly however could potentially cause ghost blocks", visibility = { page == Page.ReBreak && reBreak }) @@ -42,12 +46,16 @@ object PacketMine : Module( private var ignorePacketSend = false private val blockQueue: ArrayDeque = ArrayDeque() + //ToDo: Replace this with mixin private val validActions = setOf(Action.START_DESTROY_BLOCK, Action.STOP_DESTROY_BLOCK, Action.ABORT_DESTROY_BLOCK) init { listener { currentMiningBlock?.apply { mineTicks++ + + if (pauseWhileUsingItems && player.isUsingItem) return@listener + val activeState = world.getBlockState(pos) if (activeState != state) state = activeState val bestTool = getBestTool(activeState, pos) @@ -97,7 +105,7 @@ object PacketMine : Module( BreakState.AwaitingResponse -> { if (clientSideBreak) return@listener - if (System.currentTimeMillis() - timeCompleted < timeoutDelay) return@listener + if (System.currentTimeMillis() - timeCompleted < timeoutDelay * 1000) return@listener if (breakNextQueueBlock()) return@listener @@ -109,29 +117,29 @@ object PacketMine : Module( listener { if (it.packet !is PlayerActionC2SPacket || !validActions.contains(it.packet.action) || ignorePacketSend) return@listener + it.cancel() val packetPos = it.packet.pos - if (queueBlocks - && (currentMiningBlock != null - && currentMiningBlock?.breakState != BreakState.ReBreaking - && currentMiningBlock?.pos != packetPos) - || (!blockQueue.isEmpty() && !blockQueue.contains(packetPos)) - ) { - blockQueue.add(packetPos) + if (!shouldBePlacedInBlockQueue(packetPos)) { + startBreaking(packetPos) return@listener } - startBreaking(packetPos) + blockQueue.add(packetPos) } + //Todo: Change the onBreak checks to save awaiting positions to a list with a timeout rather than just the + // current mining block to allow for old block break attempts that arent active anymore to still get block break particle renders and sounds listener { currentMiningBlock?.apply { if (it.pos != pos || !(if (state.properties.contains(Properties.WATERLOGGED)) it.state.fluidState.fluid.equals(Fluids.WATER) - else it.state.isAir)) return@listener - if (!clientSideBreak) state.block.onBreak(world, pos, world.getBlockState(pos), player) + else it.state.isAir) + ) return@listener + + if (!clientSideBreak) interaction.breakBlock(pos) if (breakState == BreakState.ReBreaking) return@listener @@ -150,10 +158,9 @@ object PacketMine : Module( } private fun SafeContext.startBreaking(pos: BlockPos) { - if (currentMiningBlock?.pos == pos) return + if (currentMiningBlock?.pos == pos || blockQueue.contains(pos)) return val state = world.getBlockState(pos) - val bestTool = getBestTool(state, pos) swapStartPacketBreak(pos, bestTool) @@ -169,36 +176,55 @@ object PacketMine : Module( BreakingContext(pos, state, BreakState.AwaitingResponse) } } + currentMiningBlock?.timeCompleted = System.currentTimeMillis() if (!clientSideBreak) return - state.block.onBreak(world, pos, state, player) - + interaction.breakBlock(pos) return } currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking) } + private fun shouldBePlacedInBlockQueue(pos: BlockPos): Boolean { + return !(currentMiningBlock == null + || currentMiningBlock?.breakState == BreakState.ReBreaking + || currentMiningBlock?.pos == pos + || blockQueue.contains(pos)) + } + private fun SafeContext.breakNextQueueBlock(): Boolean { if (!queueBlocks) return false + filterBlockQueueUntilNextPossible()?.apply { + blockQueue.remove(this) + startBreaking(this) + return true + } + + return false + } + + private fun getNextUncheckedQueueBlock(): BlockPos? { + return if (reverseQueueOrder) { + blockQueue.lastOrNull() + } else { + blockQueue.firstOrNull() + } + } + + private fun SafeContext.filterBlockQueueUntilNextPossible(): BlockPos? { while (true) { - val block = blockQueue.firstOrNull() ?: run { return false } + val block = getNextUncheckedQueueBlock() ?: return null if (player.eyePos.distanceTo(block.toCenterPos()) > 6) { - blockQueue.removeFirst() + blockQueue.remove(block) continue } - break + return block } - - if (blockQueue.isEmpty()) return false - - startBreaking(blockQueue.first()) - blockQueue.removeFirst() - return true } private fun SafeContext.swapStartPacketBreak(pos: BlockPos, toolSlot: Int) { @@ -233,9 +259,7 @@ object PacketMine : Module( connection.sendPacket(PlayerActionC2SPacket(Action.ABORT_DESTROY_BLOCK, pos, Direction.UP, 0)) } - /* - Still unsure on how the task system works so im using these methods for now - */ + //Todo: Replace with task system private fun SafeContext.getBestTool(state: BlockState, pos: BlockPos): Int { var bestTool = -1 From 0dbd78839f36b511156d3a2d577a4e761a65a721 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 17 Jun 2024 13:16:32 +0100 Subject: [PATCH 16/91] - forgot to add check for if the queue blocks setting is enabled --- .../com/lambda/module/modules/player/PacketMine.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 8e688c9ac..29d48865e 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -122,12 +122,12 @@ object PacketMine : Module( val packetPos = it.packet.pos - if (!shouldBePlacedInBlockQueue(packetPos)) { - startBreaking(packetPos) + if (shouldBePlacedInBlockQueue(packetPos)) { + blockQueue.add(packetPos) return@listener } - blockQueue.add(packetPos) + startBreaking(packetPos) } //Todo: Change the onBreak checks to save awaiting positions to a list with a timeout rather than just the @@ -188,7 +188,8 @@ object PacketMine : Module( } private fun shouldBePlacedInBlockQueue(pos: BlockPos): Boolean { - return !(currentMiningBlock == null + return !(!queueBlocks + || currentMiningBlock == null || currentMiningBlock?.breakState == BreakState.ReBreaking || currentMiningBlock?.pos == pos || blockQueue.contains(pos)) From 2e3f960c45c11dec6f7dcf0588d864cf71282d7c Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 17 Jun 2024 14:03:08 +0100 Subject: [PATCH 17/91] - replaced packet send listener with mixin --- .../ClientPlayInteractionManagerMixin.java | 7 +++++++ .../lambda/event/events/InteractionEvent.kt | 9 +++++++++ .../module/modules/player/PacketMine.kt | 19 ++++++++----------- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java b/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java index 03da40258..ce5e03068 100644 --- a/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java +++ b/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java @@ -8,6 +8,8 @@ import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -27,4 +29,9 @@ public void interactBlockHead(final ClientPlayerEntity player, final Hand hand, if (client.world == null) return; EventFlow.post(new InteractionEvent.Block(client.world, hitResult)); } + + @Inject(method = "attackBlock", at = @At("HEAD"), cancellable = true) + public void onAttackBlock(BlockPos pos, Direction side, CallbackInfoReturnable cir) { + if (EventFlow.post(new InteractionEvent.AttackBlock(pos, side)).isCanceled()) cir.cancel(); + } } diff --git a/common/src/main/kotlin/com/lambda/event/events/InteractionEvent.kt b/common/src/main/kotlin/com/lambda/event/events/InteractionEvent.kt index 8fce4adc7..742263f07 100644 --- a/common/src/main/kotlin/com/lambda/event/events/InteractionEvent.kt +++ b/common/src/main/kotlin/com/lambda/event/events/InteractionEvent.kt @@ -1,12 +1,21 @@ package com.lambda.event.events import com.lambda.event.Event +import com.lambda.event.callback.Cancellable +import com.lambda.event.callback.ICancellable import net.minecraft.client.world.ClientWorld import net.minecraft.util.hit.BlockHitResult +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Direction sealed class InteractionEvent : Event { class Block( val world: ClientWorld, val blockHitResult: BlockHitResult ) : InteractionEvent() + + class AttackBlock( + val pos: BlockPos, + val side: Direction + ): InteractionEvent(), ICancellable by Cancellable() } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 29d48865e..07691a122 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -1,7 +1,7 @@ package com.lambda.module.modules.player import com.lambda.context.SafeContext -import com.lambda.event.events.PacketEvent +import com.lambda.event.events.InteractionEvent import com.lambda.event.events.TickEvent import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listener @@ -19,6 +19,7 @@ import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket import net.minecraft.registry.tag.FluidTags import net.minecraft.state.property.Properties +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction @@ -46,9 +47,6 @@ object PacketMine : Module( private var ignorePacketSend = false private val blockQueue: ArrayDeque = ArrayDeque() - //ToDo: Replace this with mixin - private val validActions = setOf(Action.START_DESTROY_BLOCK, Action.STOP_DESTROY_BLOCK, Action.ABORT_DESTROY_BLOCK) - init { listener { currentMiningBlock?.apply { @@ -115,19 +113,18 @@ object PacketMine : Module( } } - listener { - if (it.packet !is PlayerActionC2SPacket || !validActions.contains(it.packet.action) || ignorePacketSend) return@listener - + listener { it.cancel() + player.swingHand(Hand.MAIN_HAND) - val packetPos = it.packet.pos + val pos = it.pos - if (shouldBePlacedInBlockQueue(packetPos)) { - blockQueue.add(packetPos) + if (shouldBePlacedInBlockQueue(pos)) { + blockQueue.add(pos) return@listener } - startBreaking(packetPos) + startBreaking(pos) } //Todo: Change the onBreak checks to save awaiting positions to a list with a timeout rather than just the From e0e6ecd6d4ded2e0993c0994ed41a341836aa7eb Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 17 Jun 2024 17:53:52 +0100 Subject: [PATCH 18/91] - small cleanup for readability --- .../module/modules/player/PacketMine.kt | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 07691a122..141da2884 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -45,7 +45,7 @@ object PacketMine : Module( private var currentMiningBlock: BreakingContext? = null private var ignorePacketSend = false - private val blockQueue: ArrayDeque = ArrayDeque() + private val blockQueue = ArrayDeque() init { listener { @@ -74,8 +74,7 @@ object PacketMine : Module( if (breakNextQueueBlock()) return@listener - if (reBreak - && player.eyePos.distanceTo(pos.toCenterPos()) < 6) { + if (reBreak && player.eyePos.distanceTo(pos.toCenterPos()) < 6) { breakState = BreakState.ReBreaking return@listener } @@ -92,9 +91,7 @@ object PacketMine : Module( if (mineTicks * calcBreakDelta(state, pos, bestTool) < breakSpeed) return@listener - if (!fastReBreak - && (activeState.isAir - || (!activeState.fluidState.isEmpty && !activeState.properties.contains(Properties.WATERLOGGED))) + if (!fastReBreak && (activeState.isAir || (!activeState.fluidState.isEmpty && !activeState.properties.contains(Properties.WATERLOGGED))) ) return@listener swapStopBreak(pos, bestTool) @@ -117,14 +114,12 @@ object PacketMine : Module( it.cancel() player.swingHand(Hand.MAIN_HAND) - val pos = it.pos - - if (shouldBePlacedInBlockQueue(pos)) { - blockQueue.add(pos) + if (shouldBePlacedInBlockQueue(it.pos)) { + blockQueue.add(it.pos) return@listener } - startBreaking(pos) + startBreaking(it.pos) } //Todo: Change the onBreak checks to save awaiting positions to a list with a timeout rather than just the @@ -142,8 +137,7 @@ object PacketMine : Module( if (breakNextQueueBlock()) return@listener - if (reBreak - && player.eyePos.distanceTo(pos.toCenterPos()) < 6) { + if (reBreak && player.eyePos.distanceTo(pos.toCenterPos()) < 6) { breakState = BreakState.ReBreaking return@listener } From 2ef55bafae3bbbfe3a2b1a53c1ab6dac24ca7989 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 21 Jun 2024 01:53:06 +0100 Subject: [PATCH 19/91] - fixed waterlogged checks breaking blocks that could be waterlogged but arent --- .../kotlin/com/lambda/module/modules/player/PacketMine.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 141da2884..758937afe 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -91,7 +91,7 @@ object PacketMine : Module( if (mineTicks * calcBreakDelta(state, pos, bestTool) < breakSpeed) return@listener - if (!fastReBreak && (activeState.isAir || (!activeState.fluidState.isEmpty && !activeState.properties.contains(Properties.WATERLOGGED))) + if (!fastReBreak && (activeState.isAir || (!activeState.fluidState.isEmpty && !(activeState.properties.contains(Properties.WATERLOGGED) && activeState.get(Properties.WATERLOGGED)))) ) return@listener swapStopBreak(pos, bestTool) @@ -127,7 +127,7 @@ object PacketMine : Module( listener { currentMiningBlock?.apply { if (it.pos != pos - || !(if (state.properties.contains(Properties.WATERLOGGED)) it.state.fluidState.fluid.equals(Fluids.WATER) + || !(if (state.properties.contains(Properties.WATERLOGGED) && state.get(Properties.WATERLOGGED)) it.state.fluidState.fluid.equals(Fluids.WATER) else it.state.isAir) ) return@listener From d9a0f6bb4398424b5871102a9c25d2c448160f21 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Sun, 23 Jun 2024 04:42:15 +0100 Subject: [PATCH 20/91] - swapped some duplicate code for methods --- .../module/modules/player/PacketMine.kt | 56 ++++++++++--------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 758937afe..388263dfc 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -47,6 +47,8 @@ object PacketMine : Module( private var ignorePacketSend = false private val blockQueue = ArrayDeque() + //ToDo: Make work on CC + init { listener { currentMiningBlock?.apply { @@ -72,14 +74,7 @@ object PacketMine : Module( interaction.breakBlock(pos) - if (breakNextQueueBlock()) return@listener - - if (reBreak && player.eyePos.distanceTo(pos.toCenterPos()) < 6) { - breakState = BreakState.ReBreaking - return@listener - } - - currentMiningBlock = null + onBlockBreak() } BreakState.ReBreaking -> { if (breakNextQueueBlock()) return@listener @@ -91,11 +86,13 @@ object PacketMine : Module( if (mineTicks * calcBreakDelta(state, pos, bestTool) < breakSpeed) return@listener - if (!fastReBreak && (activeState.isAir || (!activeState.fluidState.isEmpty && !(activeState.properties.contains(Properties.WATERLOGGED) && activeState.get(Properties.WATERLOGGED)))) + if (!fastReBreak + && (activeState.isAir || (!activeState.fluidState.isEmpty && !(activeState.properties.contains(Properties.WATERLOGGED) && activeState.get(Properties.WATERLOGGED)))) ) return@listener swapStopBreak(pos, bestTool) - if (clientSideBreak) interaction.breakBlock(pos) + + checkClientBreak(false, pos) } BreakState.AwaitingResponse -> { if (clientSideBreak) return@listener @@ -122,8 +119,6 @@ object PacketMine : Module( startBreaking(it.pos) } - //Todo: Change the onBreak checks to save awaiting positions to a list with a timeout rather than just the - // current mining block to allow for old block break attempts that arent active anymore to still get block break particle renders and sounds listener { currentMiningBlock?.apply { if (it.pos != pos @@ -131,19 +126,11 @@ object PacketMine : Module( else it.state.isAir) ) return@listener - if (!clientSideBreak) interaction.breakBlock(pos) + checkClientBreak(true, pos) if (breakState == BreakState.ReBreaking) return@listener - if (breakNextQueueBlock()) return@listener - - if (reBreak && player.eyePos.distanceTo(pos.toCenterPos()) < 6) { - breakState = BreakState.ReBreaking - return@listener - } - - currentMiningBlock = null - return@listener + onBlockBreak() } } } @@ -169,15 +156,32 @@ object PacketMine : Module( } currentMiningBlock?.timeCompleted = System.currentTimeMillis() - if (!clientSideBreak) return - - interaction.breakBlock(pos) - return + checkClientBreak(false, pos) } currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking) } + private fun SafeContext.onBlockBreak() { + currentMiningBlock?.apply { + if (breakNextQueueBlock()) return + + if (reBreak && player.eyePos.distanceTo(pos.toCenterPos()) < 6) { + breakState = BreakState.ReBreaking + return + } + + currentMiningBlock = null + } + } + + private fun SafeContext.checkClientBreak(packetReceiveBreak: Boolean, pos: BlockPos) { + if ((packetReceiveBreak && !clientSideBreak) + || (!packetReceiveBreak && clientSideBreak)) { + interaction.breakBlock(pos) + } + } + private fun shouldBePlacedInBlockQueue(pos: BlockPos): Boolean { return !(!queueBlocks || currentMiningBlock == null From 9ab317456803e358f1095140e265e13e6312c600 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Thu, 27 Jun 2024 22:53:25 +0100 Subject: [PATCH 21/91] - update the breaking texture based on the fast break speed --- .../ClientPlayInteractionManagerMixin.java | 25 ++++++++++++++- .../lambda/event/events/InteractionEvent.kt | 19 +++++++++++- .../lambda/module/modules/player/FastBreak.kt | 31 ++++++++++++------- .../src/main/resources/lambda.accesswidener | 6 ++-- 4 files changed, 64 insertions(+), 17 deletions(-) diff --git a/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java b/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java index ce5e03068..5be075dbb 100644 --- a/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java +++ b/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java @@ -2,20 +2,28 @@ import com.lambda.event.EventFlow; import com.lambda.event.events.InteractionEvent; +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import net.minecraft.block.BlockState; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerInteractionManager; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; +import net.minecraft.world.BlockView; +import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(ClientPlayerInteractionManager.class) public class ClientPlayInteractionManagerMixin { @@ -34,4 +42,19 @@ public void interactBlockHead(final ClientPlayerEntity player, final Hand hand, public void onAttackBlock(BlockPos pos, Direction side, CallbackInfoReturnable cir) { if (EventFlow.post(new InteractionEvent.AttackBlock(pos, side)).isCanceled()) cir.cancel(); } -} + + @Inject(method = "updateBlockBreakingProgress", at = @At("HEAD")) + private void updateBlockBreakingProgressPre(BlockPos pos, Direction side, CallbackInfoReturnable cir) { + EventFlow.post(new InteractionEvent.UpdateBlockBreakingProgress.Pre(pos, side)); + } + + @Inject(method = "updateBlockBreakingProgress", at = @At("TAIL")) + private void updateBlockBreakingProgressPost(BlockPos pos, Direction side, CallbackInfoReturnable cir) { + EventFlow.post(new InteractionEvent.UpdateBlockBreakingProgress.Post(pos, side)); + } + + @ModifyReturnValue(method = "getBlockBreakingProgress", at = @At("RETURN")) + private int onGetBlockBreakingProgressReturn(int original) { + return EventFlow.post(new InteractionEvent.GetBlockBreakingProgress(original)).getValue(); + } +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/event/events/InteractionEvent.kt b/common/src/main/kotlin/com/lambda/event/events/InteractionEvent.kt index 742263f07..2adde7ed0 100644 --- a/common/src/main/kotlin/com/lambda/event/events/InteractionEvent.kt +++ b/common/src/main/kotlin/com/lambda/event/events/InteractionEvent.kt @@ -17,5 +17,22 @@ sealed class InteractionEvent : Event { class AttackBlock( val pos: BlockPos, val side: Direction - ): InteractionEvent(), ICancellable by Cancellable() + ) : InteractionEvent(), ICancellable by Cancellable() + + abstract class UpdateBlockBreakingProgress : InteractionEvent() { + + class Pre( + val pos: BlockPos, + val side: Direction, + ) : UpdateBlockBreakingProgress() + + class Post( + val pos: BlockPos, + val side: Direction, + ) : UpdateBlockBreakingProgress() + } + + class GetBlockBreakingProgress( + var value: Int + ) : InteractionEvent() } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt index 1b9d17a28..6e42bfb18 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt @@ -1,28 +1,29 @@ package com.lambda.module.modules.player +import com.lambda.event.events.InteractionEvent import com.lambda.event.events.PacketEvent import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listener import com.lambda.module.Module import com.lambda.module.tag.ModuleTag -import com.lambda.util.math.transform +import com.lambda.util.world.raycast.RayCastUtils.blockResult import net.minecraft.block.Block -import net.minecraft.client.network.ClientPlayerInteractionManager import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket +import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action import java.awt.Color object FastBreak : Module( name = "FastBreak", description = "Break blocks faster.", defaultTags = setOf( - ModuleTag.PLAYER, ModuleTag.WORLD, ModuleTag.BYPASS + ModuleTag.PLAYER, ModuleTag.WORLD ) ) { private val page by setting("Page", Page.Mining) private val mineSpeed by setting("Mine Speed", 5, 0..5, 1, unit = "ticks", description = "Reduce the mining cooldown.", visibility = { page == Page.Mining }) - private val breakThreshold by setting("Break Threshold", 0.8f, 0.5f..1.0f, 0.1f, description = "The progress at which the block will break.", visibility = { page == Page.Mining }) + private val breakThreshold by setting("Break Threshold", 0.7f, 0.2f..1.0f, 0.1f, description = "The progress at which the block will break.", visibility = { page == Page.Mining }) private val renderOutline by setting("Render Outline", true, description = "Render an outline around the block being broken.", visibility = { page == Page.Rendering }) private val renderOutlineColor by setting("Outline Color", Color.CYAN, description = "The color of the outline.", visibility = { page == Page.Rendering && renderOutline }) @@ -39,10 +40,10 @@ object FastBreak : Module( init { listener { if (it.packet !is PlayerActionC2SPacket) return@listener - if (it.packet.action != PlayerActionC2SPacket.Action.STOP_DESTROY_BLOCK) return@listener + if (it.packet.action != Action.STOP_DESTROY_BLOCK) return@listener connection.sendPacket(PlayerActionC2SPacket( - PlayerActionC2SPacket.Action.ABORT_DESTROY_BLOCK, + Action.ABORT_DESTROY_BLOCK, // For the exploit to work, the position must be out of the player range, so any // position farther than 6 blocks will work. it.packet.pos.up(2024-4-18), @@ -56,11 +57,20 @@ object FastBreak : Module( // This should work but doesn't ? interaction.blockBreakingCooldown -= mineSpeed + } - if (interaction.currentBreakingProgress >= breakThreshold) - interaction.currentBreakingProgress = 1.0f + listener { + if (!interaction.isBreakingBlock || interaction.currentBreakingProgress < breakThreshold) return@listener - breakingBlock = world.getBlockState(interaction.currentBreakingPos).block + connection.sendPacket(PlayerActionC2SPacket( + Action.STOP_DESTROY_BLOCK + , interaction.currentBreakingPos + , mc.crosshairTarget?.blockResult?.side) + ) + } + + listener { + it.value = (interaction.currentBreakingProgress * (2f - breakThreshold) * 10).toInt().coerceAtMost(9) } listener { @@ -69,7 +79,4 @@ object FastBreak : Module( // We should use interpolation to make the fill grow smoothly. } } - - fun ClientPlayerInteractionManager.miningProgress(max: Float = 1.0f) = - max / transform(currentBreakingProgress, 0.0f, 1.0f, 0.0f, max) } diff --git a/common/src/main/resources/lambda.accesswidener b/common/src/main/resources/lambda.accesswidener index 617eee65c..0d57bb025 100644 --- a/common/src/main/resources/lambda.accesswidener +++ b/common/src/main/resources/lambda.accesswidener @@ -8,9 +8,6 @@ accessible field net/minecraft/client/MinecraftClient thread Ljava/lang/Thread; # World accessible field net/minecraft/client/world/ClientWorld entityManager Lnet/minecraft/client/world/ClientEntityManager; -accessible field net/minecraft/client/network/ClientPlayerInteractionManager currentBreakingProgress F -accessible field net/minecraft/client/network/ClientPlayerInteractionManager blockBreakingCooldown I -accessible field net/minecraft/client/network/ClientPlayerInteractionManager currentBreakingPos Lnet/minecraft/util/math/BlockPos; accessible field net/minecraft/client/world/ClientEntityManager cache Lnet/minecraft/world/entity/SectionedEntityCache; accessible field net/minecraft/world/entity/EntityTrackingSection collection Lnet/minecraft/util/collection/TypeFilterableList; accessible field net/minecraft/client/world/ClientChunkManager chunks Lnet/minecraft/client/world/ClientChunkManager$ClientChunkMap; @@ -52,6 +49,9 @@ accessible field net/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPa accessible field net/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket type Lnet/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket$InteractTypeHandler; accessible class net/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket$InteractTypeHandler accessible class net/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket$InteractAtHandler +accessible method net/minecraft/network/ClientConnection handlePacket (Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/listener/PacketListener;)V +accessible field net/minecraft/network/ClientConnection packetsSentCounter I +accessible field net/minecraft/network/ClientConnection packetsReceivedCounter I # Other accessible field net/minecraft/world/explosion/Explosion behavior Lnet/minecraft/world/explosion/ExplosionBehavior; From 192637f447a111636102fffc5ac84a7aa68f56df Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 28 Jun 2024 01:10:35 +0100 Subject: [PATCH 22/91] - implemented validate break setting in fast break - refactored client side break in packet mine to validate break --- .../ClientPlayInteractionManagerMixin.java | 7 ------ .../lambda/module/modules/player/FastBreak.kt | 25 +++++++++++++------ .../module/modules/player/PacketMine.kt | 22 ++++++++-------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java b/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java index 5be075dbb..4e36f49d7 100644 --- a/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java +++ b/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java @@ -3,27 +3,20 @@ import com.lambda.event.EventFlow; import com.lambda.event.events.InteractionEvent; import com.llamalad7.mixinextras.injector.ModifyReturnValue; -import net.minecraft.block.BlockState; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; -import net.minecraft.world.BlockView; -import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArg; -import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(ClientPlayerInteractionManager.class) public class ClientPlayInteractionManagerMixin { diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt index 6e42bfb18..417d24fe5 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt @@ -1,16 +1,14 @@ package com.lambda.module.modules.player -import com.lambda.event.events.InteractionEvent -import com.lambda.event.events.PacketEvent -import com.lambda.event.events.RenderEvent -import com.lambda.event.events.TickEvent +import com.lambda.event.events.* import com.lambda.event.listener.SafeListener.Companion.listener import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.world.raycast.RayCastUtils.blockResult -import net.minecraft.block.Block +import net.minecraft.fluid.WaterFluid import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action +import net.minecraft.state.property.Properties import java.awt.Color object FastBreak : Module( @@ -24,6 +22,7 @@ object FastBreak : Module( private val mineSpeed by setting("Mine Speed", 5, 0..5, 1, unit = "ticks", description = "Reduce the mining cooldown.", visibility = { page == Page.Mining }) private val breakThreshold by setting("Break Threshold", 0.7f, 0.2f..1.0f, 0.1f, description = "The progress at which the block will break.", visibility = { page == Page.Mining }) + private val validateBreak by setting("Validate Break", true, "Waits for a response from the server before breaking the block", visibility = { page == Page.Mining }) private val renderOutline by setting("Render Outline", true, description = "Render an outline around the block being broken.", visibility = { page == Page.Rendering }) private val renderOutlineColor by setting("Outline Color", Color.CYAN, description = "The color of the outline.", visibility = { page == Page.Rendering && renderOutline }) @@ -31,8 +30,6 @@ object FastBreak : Module( private val renderFillColor by setting("Fill Color", Color.CYAN, description = "The color of the fill.", visibility = { page == Page.Rendering && renderFill }) private val renderFillGrow by setting("Fill Grow", 0.0f, 0.0f..1.0f, 0.1f, description = "The amount the fill grows based on the mining progress.", visibility = { page == Page.Rendering && renderFill }) - private var breakingBlock: Block? = null - private enum class Page { Mining, Rendering } @@ -67,6 +64,20 @@ object FastBreak : Module( , interaction.currentBreakingPos , mc.crosshairTarget?.blockResult?.side) ) + + if (!validateBreak) interaction.breakBlock(interaction.currentBreakingPos) + } + + listener { + if (!validateBreak || it.pos != interaction.currentBreakingPos) return@listener + + val state = world.getBlockState(interaction.currentBreakingPos) + if (if (state.properties.contains(Properties.WATERLOGGED) && state.get(Properties.WATERLOGGED)) it.state.fluidState.fluid !is WaterFluid + else !it.state.isAir) { + return@listener + } + + interaction.breakBlock(interaction.currentBreakingPos) } listener { diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 388263dfc..8e874b408 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -12,7 +12,7 @@ import net.minecraft.enchantment.EnchantmentHelper import net.minecraft.enchantment.Enchantments import net.minecraft.entity.effect.StatusEffectUtil import net.minecraft.entity.effect.StatusEffects -import net.minecraft.fluid.Fluids +import net.minecraft.fluid.WaterFluid import net.minecraft.item.ItemStack import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action @@ -35,8 +35,8 @@ object PacketMine : Module( //ToDo: Implement these settings // private val rotate by setting("Rotate", false, "Rotates the player to look at the current mining block", visibility = { page == Page.General }) // private val autoSwap by setting("Auto Force Swap", false, "Hard swaps to the best tool rather than silent swapping. This is often used on servers with a stricter anti-cheat system", visibility = { page == Page.General}) - private val clientSideBreak by setting("Client Side Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) - private val timeoutDelay by setting("Timeout Delay", 0.20, 0.00..1.00, 0.1, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && !clientSideBreak }) + private val validateBreak by setting("Validate Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) + private val timeoutDelay by setting("Timeout Delay", 0.20, 0.00..1.00, 0.1, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && validateBreak }) private val alternativePackets by setting("Alternative Packets", false, "Uses a different set of packets which tend to work better on servers using an anti-cheat like grim", visibility = { page == Page.General }) private val queueBlocks by setting("Queue Blocks", false, "Queues any blocks you click for breaking", visibility = { page == Page.Queue }).apply { this.onValueSet { _, to -> if (!to) blockQueue.clear() } } private val reverseQueueOrder by setting("Reverse Queue Order", false, "Breaks the latest addition to the queue first", visibility = { page == Page.Queue && queueBlocks}) @@ -67,7 +67,7 @@ object PacketMine : Module( timeCompleted = System.currentTimeMillis() swapStopBreak(pos, bestTool) - if (!clientSideBreak) { + if (validateBreak) { breakState = BreakState.AwaitingResponse return@listener } @@ -95,7 +95,7 @@ object PacketMine : Module( checkClientBreak(false, pos) } BreakState.AwaitingResponse -> { - if (clientSideBreak) return@listener + if (!validateBreak) return@listener if (System.currentTimeMillis() - timeCompleted < timeoutDelay * 1000) return@listener @@ -122,9 +122,10 @@ object PacketMine : Module( listener { currentMiningBlock?.apply { if (it.pos != pos - || !(if (state.properties.contains(Properties.WATERLOGGED) && state.get(Properties.WATERLOGGED)) it.state.fluidState.fluid.equals(Fluids.WATER) - else it.state.isAir) - ) return@listener + || if (state.properties.contains(Properties.WATERLOGGED) && state.get(Properties.WATERLOGGED)) it.state.fluidState.fluid !is WaterFluid + else !it.state.isAir) { + return@listener + } checkClientBreak(true, pos) @@ -148,7 +149,7 @@ object PacketMine : Module( swapStartPacketBreak(pos, bestTool) currentMiningBlock = BreakingContext(pos, state, BreakState.ReBreaking) } else { - currentMiningBlock = if (clientSideBreak) { + currentMiningBlock = if (!validateBreak) { null } else { BreakingContext(pos, state, BreakState.AwaitingResponse) @@ -176,8 +177,7 @@ object PacketMine : Module( } private fun SafeContext.checkClientBreak(packetReceiveBreak: Boolean, pos: BlockPos) { - if ((packetReceiveBreak && !clientSideBreak) - || (!packetReceiveBreak && clientSideBreak)) { + if (packetReceiveBreak == validateBreak) { interaction.breakBlock(pos) } } From bfad334c6407b39c213b041647d7fc95c7f731fa Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 28 Jun 2024 02:03:19 +0100 Subject: [PATCH 23/91] - fixed mine speed setting and changed it to break delay --- .../com/lambda/module/modules/player/FastBreak.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt index 417d24fe5..459130a79 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt @@ -20,7 +20,7 @@ object FastBreak : Module( ) { private val page by setting("Page", Page.Mining) - private val mineSpeed by setting("Mine Speed", 5, 0..5, 1, unit = "ticks", description = "Reduce the mining cooldown.", visibility = { page == Page.Mining }) + private val breakDelay by setting("Break Delay", 5, 0..5, 1, unit = "ticks", description = "The tick delay between breaking blocks", visibility = { page == Page.Mining }) private val breakThreshold by setting("Break Threshold", 0.7f, 0.2f..1.0f, 0.1f, description = "The progress at which the block will break.", visibility = { page == Page.Mining }) private val validateBreak by setting("Validate Break", true, "Waits for a response from the server before breaking the block", visibility = { page == Page.Mining }) @@ -41,19 +41,19 @@ object FastBreak : Module( connection.sendPacket(PlayerActionC2SPacket( Action.ABORT_DESTROY_BLOCK, - // For the exploit to work, the position must be out of the player range, so any + // For the exploit to work, the position must be outside the player range, so any // position farther than 6 blocks will work. + // This is only required for grim 2 and potentially grim 3 in the future if they update it it.packet.pos.up(2024-4-18), it.packet.direction )) } listener { - if (!interaction.isBreakingBlock) + if (interaction.blockBreakingCooldown != 5 || breakDelay == 5) return@listener - // This should work but doesn't ? - interaction.blockBreakingCooldown -= mineSpeed + interaction.blockBreakingCooldown = breakDelay } listener { From 23ae28a121bee727ca74684d4d95a9670a0b6d14 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 28 Jun 2024 02:21:18 +0100 Subject: [PATCH 24/91] - swapped cooldown check for coerce at most --- .../kotlin/com/lambda/module/modules/player/FastBreak.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt index 459130a79..2266c1b06 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt @@ -50,10 +50,7 @@ object FastBreak : Module( } listener { - if (interaction.blockBreakingCooldown != 5 || breakDelay == 5) - return@listener - - interaction.blockBreakingCooldown = breakDelay + interaction.blockBreakingCooldown = interaction.blockBreakingCooldown.coerceAtMost(breakDelay) } listener { From 4b7da4c9b5d85a5bfd1864c66956b9655cc7ef39 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 28 Jun 2024 03:57:29 +0100 Subject: [PATCH 25/91] - added breaking animation setting to show block breaking progress --- .../module/modules/player/PacketMine.kt | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 8e874b408..9f4588ea7 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -38,11 +38,16 @@ object PacketMine : Module( private val validateBreak by setting("Validate Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) private val timeoutDelay by setting("Timeout Delay", 0.20, 0.00..1.00, 0.1, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && validateBreak }) private val alternativePackets by setting("Alternative Packets", false, "Uses a different set of packets which tend to work better on servers using an anti-cheat like grim", visibility = { page == Page.General }) + private val queueBlocks by setting("Queue Blocks", false, "Queues any blocks you click for breaking", visibility = { page == Page.Queue }).apply { this.onValueSet { _, to -> if (!to) blockQueue.clear() } } private val reverseQueueOrder by setting("Reverse Queue Order", false, "Breaks the latest addition to the queue first", visibility = { page == Page.Queue && queueBlocks}) + private val reBreak by setting("Re-Break", true, "Automatically re-breaks the last mined block if it gets replaced", visibility = { page == Page.ReBreak}) private val fastReBreak by setting("Fast Re-Break", false, "Re-breaks blocks instantly however could potentially cause ghost blocks", visibility = { page == Page.ReBreak && reBreak }) + private val breakingAnimation by setting("Breaking Animation", false, "Renders the block breaking animation like vanilla would to show progress", visibility = { page == Page.Render }) + + private var currentMiningBlock: BreakingContext? = null private var ignorePacketSend = false private val blockQueue = ArrayDeque() @@ -59,6 +64,9 @@ object PacketMine : Module( val activeState = world.getBlockState(pos) if (activeState != state) state = activeState val bestTool = getBestTool(activeState, pos) + val blockBreakAmount = mineTicks * calcBreakDelta(state, pos, bestTool) + + if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, (blockBreakAmount * (2 - breakSpeed) * 10).toInt().coerceAtMost(9)) when (breakState) { BreakState.Breaking -> { @@ -80,15 +88,16 @@ object PacketMine : Module( if (breakNextQueueBlock()) return@listener if (player.eyePos.distanceTo(pos.toCenterPos()) > 6) { - currentMiningBlock = null + nullifyCurrentBreakingBlock() return@listener } if (mineTicks * calcBreakDelta(state, pos, bestTool) < breakSpeed) return@listener if (!fastReBreak - && (activeState.isAir || (!activeState.fluidState.isEmpty && !(activeState.properties.contains(Properties.WATERLOGGED) && activeState.get(Properties.WATERLOGGED)))) - ) return@listener + && (activeState.isAir || (!activeState.fluidState.isEmpty && !(activeState.properties.contains(Properties.WATERLOGGED) && activeState.get(Properties.WATERLOGGED))))) { + return@listener + } swapStopBreak(pos, bestTool) @@ -101,7 +110,7 @@ object PacketMine : Module( if (breakNextQueueBlock()) return@listener - currentMiningBlock = null + nullifyCurrentBreakingBlock() } } } @@ -172,8 +181,15 @@ object PacketMine : Module( return } - currentMiningBlock = null + nullifyCurrentBreakingBlock() + } + } + + private fun SafeContext.nullifyCurrentBreakingBlock() { + currentMiningBlock?.apply { + if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, 0) } + currentMiningBlock = null } private fun SafeContext.checkClientBreak(packetReceiveBreak: Boolean, pos: BlockPos) { @@ -328,6 +344,6 @@ object PacketMine : Module( } private enum class Page { - General, Queue, ReBreak + General, Queue, ReBreak, Render } } \ No newline at end of file From 07012dab68b6a6fae3ec4e5ff701c53535e5c462 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 28 Jun 2024 18:11:33 +0100 Subject: [PATCH 26/91] - added basic renders but need altering to update on every frame render --- .../module/modules/player/PacketMine.kt | 107 ++++++++++++++---- .../kotlin/com/lambda/util/math/MathUtils.kt | 11 ++ 2 files changed, 97 insertions(+), 21 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 9f4588ea7..ce5ff70f1 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -1,12 +1,16 @@ package com.lambda.module.modules.player +import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.event.events.InteractionEvent +import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listener +import com.lambda.interaction.construction.result.Drawable import com.lambda.module.Module import com.lambda.module.tag.ModuleTag +import com.lambda.util.math.MathUtils.lerp import net.minecraft.block.BlockState import net.minecraft.enchantment.EnchantmentHelper import net.minecraft.enchantment.Enchantments @@ -21,7 +25,9 @@ import net.minecraft.registry.tag.FluidTags import net.minecraft.state.property.Properties import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Box import net.minecraft.util.math.Direction +import java.awt.Color object PacketMine : Module( name = "Packet Mine", @@ -46,6 +52,8 @@ object PacketMine : Module( private val fastReBreak by setting("Fast Re-Break", false, "Re-breaks blocks instantly however could potentially cause ghost blocks", visibility = { page == Page.ReBreak && reBreak }) private val breakingAnimation by setting("Breaking Animation", false, "Renders the block breaking animation like vanilla would to show progress", visibility = { page == Page.Render }) + private val renderMode by setting("Render Mode", RenderMode.InOut, "Renders a box with size corresponding to amount broken", visibility = { page == Page.Render }) + private val renderColor by setting("Render Colour", Color.RED, "The colour used to render the breaking box", visibility = { page == Page.Render }) private var currentMiningBlock: BreakingContext? = null @@ -64,13 +72,18 @@ object PacketMine : Module( val activeState = world.getBlockState(pos) if (activeState != state) state = activeState val bestTool = getBestTool(activeState, pos) - val blockBreakAmount = mineTicks * calcBreakDelta(state, pos, bestTool) - if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, (blockBreakAmount * (2 - breakSpeed) * 10).toInt().coerceAtMost(9)) + currentBreakDelta = calcBreakDelta(state, pos, bestTool) + + if (renderMode.isEnabled()) updateBoxList(currentBreakDelta) + + val miningProgress = mineTicks * currentBreakDelta + + if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, (miningProgress * (2 - breakSpeed) * 10).toInt().coerceAtMost(9)) when (breakState) { BreakState.Breaking -> { - if (mineTicks * calcBreakDelta(state, pos, bestTool) < breakSpeed) return@listener + if (miningProgress < breakSpeed) return@listener timeCompleted = System.currentTimeMillis() swapStopBreak(pos, bestTool) @@ -92,7 +105,7 @@ object PacketMine : Module( return@listener } - if (mineTicks * calcBreakDelta(state, pos, bestTool) < breakSpeed) return@listener + if (miningProgress < breakSpeed) return@listener if (!fastReBreak && (activeState.isAir || (!activeState.fluidState.isEmpty && !(activeState.properties.contains(Properties.WATERLOGGED) && activeState.get(Properties.WATERLOGGED))))) { @@ -143,6 +156,12 @@ object PacketMine : Module( onBlockBreak() } } + + listener { + currentMiningBlock?.apply { + buildRenderer() + } + } } private fun SafeContext.startBreaking(pos: BlockPos) { @@ -153,15 +172,17 @@ object PacketMine : Module( swapStartPacketBreak(pos, bestTool) - if (calcBreakDelta(world.getBlockState(pos), pos, bestTool) > breakSpeed) { + val breakDelta = calcBreakDelta(world.getBlockState(pos), pos, bestTool) + + if (breakDelta > breakSpeed) { if (reBreak) { swapStartPacketBreak(pos, bestTool) - currentMiningBlock = BreakingContext(pos, state, BreakState.ReBreaking) + currentMiningBlock = BreakingContext(pos, state, BreakState.ReBreaking, breakDelta) } else { currentMiningBlock = if (!validateBreak) { null } else { - BreakingContext(pos, state, BreakState.AwaitingResponse) + BreakingContext(pos, state, BreakState.AwaitingResponse, breakDelta) } } currentMiningBlock?.timeCompleted = System.currentTimeMillis() @@ -169,7 +190,7 @@ object PacketMine : Module( checkClientBreak(false, pos) } - currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking) + currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking, breakDelta) } private fun SafeContext.onBlockBreak() { @@ -239,6 +260,14 @@ object PacketMine : Module( } } + private fun getLerp(box: Box, factor: Float): Box { + return if (renderMode == RenderMode.InOut) { + lerp(Box(box.center, box.center), box, factor.toDouble()) + } else { + lerp(box, Box(box.center, box.center), factor.toDouble()) + } + } + private fun SafeContext.swapStartPacketBreak(pos: BlockPos, toolSlot: Int) { connection.sendPacket(UpdateSelectedSlotC2SPacket(toolSlot)) ignorePacketSend = true @@ -271,6 +300,55 @@ object PacketMine : Module( connection.sendPacket(PlayerActionC2SPacket(Action.ABORT_DESTROY_BLOCK, pos, Direction.UP, 0)) } + private data class BreakingContext( + val pos: BlockPos, + var state: BlockState, + var breakState: BreakState, + var currentBreakDelta: Float + ) : Drawable { + var mineTicks = 0 + var timeCompleted: Long = -1 + + var previousBreakDelta = 0f + + var boxList = if (renderMode.isEnabled()) { + state.getCollisionShape(mc.world, pos).boundingBoxes.toSet() + } else { + null + } + + fun updateBoxList(newBreakDelta: Float) { + previousBreakDelta = currentBreakDelta + currentBreakDelta = newBreakDelta + if (renderMode.isEnabled()) + boxList = state.getCollisionShape(mc.world, pos).boundingBoxes.toSet() + } + + override fun SafeContext.buildRenderer() { + boxList?.forEach { box -> + withBox(lerp( + getLerp(box, (mineTicks - 1) * previousBreakDelta * (2 - breakSpeed.toFloat())).offset(pos) + , getLerp(box, mineTicks * currentBreakDelta * (2 - breakSpeed.toFloat())).offset(pos) + , mc.tickDelta.toDouble()) + , renderColor) + } + } + } + + private enum class RenderMode { + InOut, OutIn, None; + fun isEnabled(): Boolean = + this != None + } + + private enum class BreakState { + Breaking, ReBreaking, AwaitingResponse + } + + private enum class Page { + General, Queue, ReBreak, Render + } + //Todo: Replace with task system private fun SafeContext.getBestTool(state: BlockState, pos: BlockPos): Int { @@ -333,17 +411,4 @@ object PacketMine : Module( return f } - - private data class BreakingContext(var pos: BlockPos, var state: BlockState, var breakState: BreakState) { - var mineTicks = 0 - var timeCompleted: Long = -1 - } - - private enum class BreakState { - Breaking, ReBreaking, AwaitingResponse - } - - private enum class Page { - General, Queue, ReBreak, Render - } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/util/math/MathUtils.kt b/common/src/main/kotlin/com/lambda/util/math/MathUtils.kt index 8ef87927b..5489c90d6 100644 --- a/common/src/main/kotlin/com/lambda/util/math/MathUtils.kt +++ b/common/src/main/kotlin/com/lambda/util/math/MathUtils.kt @@ -5,6 +5,7 @@ import com.lambda.util.math.ColorUtils.a import com.lambda.util.math.ColorUtils.b import com.lambda.util.math.ColorUtils.g import com.lambda.util.math.ColorUtils.r +import net.minecraft.util.math.Box import net.minecraft.util.math.Vec3d import java.awt.Color import java.math.BigDecimal @@ -113,6 +114,16 @@ object MathUtils { fun lerp(start: Double, end: Double, factor: Double) = start + ((end - start) * factor.coerceIn(0.0, 1.0)) + fun lerp(start: Box, end: Box, factor: Double) = + Box( + lerp(start.minX, end.minX, factor), + lerp(start.minY, end.minY, factor), + lerp(start.minZ, end.minZ, factor), + lerp(start.maxX, end.maxX, factor), + lerp(start.maxY, end.maxY, factor), + lerp(start.maxZ, end.maxZ, factor) + ) + fun lerp(start: Vec3d, end: Vec3d, factor: Double) = Vec3d( lerp(start.x, end.x, factor), From 04da475a23e6f2ff678dab8c1e72ea41b57c734c Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:45:08 -0400 Subject: [PATCH 27/91] Refactor: Events --- .../ClientPlayInteractionManagerMixin.java | 27 ++++++----- .../lambda/event/events/InteractionEvent.kt | 28 ++++++----- .../lambda/module/modules/player/FastBreak.kt | 47 ++++++++++++------- 3 files changed, 61 insertions(+), 41 deletions(-) diff --git a/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java b/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java index 4e36f49d7..15c61a311 100644 --- a/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java +++ b/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java @@ -2,7 +2,6 @@ import com.lambda.event.EventFlow; import com.lambda.event.events.InteractionEvent; -import com.llamalad7.mixinextras.injector.ModifyReturnValue; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerInteractionManager; @@ -25,29 +24,35 @@ public class ClientPlayInteractionManagerMixin { @Shadow private MinecraftClient client; + @Shadow + public float currentBreakingProgress; + @Inject(method = "interactBlock", at = @At("HEAD")) public void interactBlockHead(final ClientPlayerEntity player, final Hand hand, final BlockHitResult hitResult, final CallbackInfoReturnable cir) { if (client.world == null) return; EventFlow.post(new InteractionEvent.Block(client.world, hitResult)); } - @Inject(method = "attackBlock", at = @At("HEAD"), cancellable = true) + @Inject(method = "attackBlock", at = @At("HEAD")) public void onAttackBlock(BlockPos pos, Direction side, CallbackInfoReturnable cir) { - if (EventFlow.post(new InteractionEvent.AttackBlock(pos, side)).isCanceled()) cir.cancel(); + if (EventFlow.post(new InteractionEvent.BlockAttack.Pre(pos, side)).isCanceled()) cir.cancel(); + } + + @Inject(method = "attackBlock", at = @At("TAIL")) + public void onAttackBlockPost(BlockPos pos, Direction side, CallbackInfoReturnable cir) { + EventFlow.post(new InteractionEvent.BlockAttack.Post(pos, side)); } @Inject(method = "updateBlockBreakingProgress", at = @At("HEAD")) private void updateBlockBreakingProgressPre(BlockPos pos, Direction side, CallbackInfoReturnable cir) { - EventFlow.post(new InteractionEvent.UpdateBlockBreakingProgress.Pre(pos, side)); + var event = EventFlow.post(new InteractionEvent.BreakingProgress.Pre(pos, side, currentBreakingProgress)); + if (event.isCanceled()) cir.cancel(); + + currentBreakingProgress = event.getProgress(); } @Inject(method = "updateBlockBreakingProgress", at = @At("TAIL")) private void updateBlockBreakingProgressPost(BlockPos pos, Direction side, CallbackInfoReturnable cir) { - EventFlow.post(new InteractionEvent.UpdateBlockBreakingProgress.Post(pos, side)); - } - - @ModifyReturnValue(method = "getBlockBreakingProgress", at = @At("RETURN")) - private int onGetBlockBreakingProgressReturn(int original) { - return EventFlow.post(new InteractionEvent.GetBlockBreakingProgress(original)).getValue(); + EventFlow.post(new InteractionEvent.BreakingProgress.Post(pos, side, currentBreakingProgress)); } -} \ No newline at end of file +} diff --git a/common/src/main/kotlin/com/lambda/event/events/InteractionEvent.kt b/common/src/main/kotlin/com/lambda/event/events/InteractionEvent.kt index 2adde7ed0..deca6c695 100644 --- a/common/src/main/kotlin/com/lambda/event/events/InteractionEvent.kt +++ b/common/src/main/kotlin/com/lambda/event/events/InteractionEvent.kt @@ -14,25 +14,29 @@ sealed class InteractionEvent : Event { val blockHitResult: BlockHitResult ) : InteractionEvent() - class AttackBlock( - val pos: BlockPos, - val side: Direction - ) : InteractionEvent(), ICancellable by Cancellable() + sealed class BlockAttack : InteractionEvent() { + class Pre( + val pos: BlockPos, + val side: Direction + ) : BlockAttack(), ICancellable by Cancellable() - abstract class UpdateBlockBreakingProgress : InteractionEvent() { + class Post( + val pos: BlockPos, + val side: Direction + ) : BlockAttack() + } + sealed class BreakingProgress : InteractionEvent() { class Pre( val pos: BlockPos, val side: Direction, - ) : UpdateBlockBreakingProgress() + var progress: Float, + ) : BreakingProgress(), ICancellable by Cancellable() class Post( val pos: BlockPos, val side: Direction, - ) : UpdateBlockBreakingProgress() + val progress: Float, + ) : BreakingProgress() } - - class GetBlockBreakingProgress( - var value: Int - ) : InteractionEvent() -} \ No newline at end of file +} diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt index 2266c1b06..d76508ae7 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt @@ -1,9 +1,11 @@ package com.lambda.module.modules.player +import com.lambda.context.SafeContext import com.lambda.event.events.* import com.lambda.event.listener.SafeListener.Companion.listener import com.lambda.module.Module import com.lambda.module.tag.ModuleTag +import com.lambda.util.math.transform import com.lambda.util.world.raycast.RayCastUtils.blockResult import net.minecraft.fluid.WaterFluid import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket @@ -23,8 +25,8 @@ object FastBreak : Module( private val breakDelay by setting("Break Delay", 5, 0..5, 1, unit = "ticks", description = "The tick delay between breaking blocks", visibility = { page == Page.Mining }) private val breakThreshold by setting("Break Threshold", 0.7f, 0.2f..1.0f, 0.1f, description = "The progress at which the block will break.", visibility = { page == Page.Mining }) private val validateBreak by setting("Validate Break", true, "Waits for a response from the server before breaking the block", visibility = { page == Page.Mining }) - private val renderOutline by setting("Render Outline", true, description = "Render an outline around the block being broken.", visibility = { page == Page.Rendering }) + private val renderOutlineColor by setting("Outline Color", Color.CYAN, description = "The color of the outline.", visibility = { page == Page.Rendering && renderOutline }) private val renderFill by setting("Render Fill", true, description = "Fill the block with a color based on the mining progress.", visibility = { page == Page.Rendering }) private val renderFillColor by setting("Fill Color", Color.CYAN, description = "The color of the fill.", visibility = { page == Page.Rendering && renderFill }) @@ -39,27 +41,29 @@ object FastBreak : Module( if (it.packet !is PlayerActionC2SPacket) return@listener if (it.packet.action != Action.STOP_DESTROY_BLOCK) return@listener - connection.sendPacket(PlayerActionC2SPacket( - Action.ABORT_DESTROY_BLOCK, - // For the exploit to work, the position must be outside the player range, so any - // position farther than 6 blocks will work. - // This is only required for grim 2 and potentially grim 3 in the future if they update it - it.packet.pos.up(2024-4-18), - it.packet.direction - )) + connection.sendPacket( + PlayerActionC2SPacket( + Action.ABORT_DESTROY_BLOCK, + // For the exploit to work, the position must be outside the player range, so any + // position farther than 6 blocks will work. + // This is only required for grim 2 and potentially grim 3 in the future if they update it + it.packet.pos.up(2024 - 4 - 18), + it.packet.direction + ) + ) } listener { interaction.blockBreakingCooldown = interaction.blockBreakingCooldown.coerceAtMost(breakDelay) } - listener { + listener { if (!interaction.isBreakingBlock || interaction.currentBreakingProgress < breakThreshold) return@listener - connection.sendPacket(PlayerActionC2SPacket( - Action.STOP_DESTROY_BLOCK - , interaction.currentBreakingPos - , mc.crosshairTarget?.blockResult?.side) + connection.sendPacket( + PlayerActionC2SPacket( + Action.STOP_DESTROY_BLOCK, interaction.currentBreakingPos, mc.crosshairTarget?.blockResult?.side + ) ) if (!validateBreak) interaction.breakBlock(interaction.currentBreakingPos) @@ -69,16 +73,20 @@ object FastBreak : Module( if (!validateBreak || it.pos != interaction.currentBreakingPos) return@listener val state = world.getBlockState(interaction.currentBreakingPos) - if (if (state.properties.contains(Properties.WATERLOGGED) && state.get(Properties.WATERLOGGED)) it.state.fluidState.fluid !is WaterFluid - else !it.state.isAir) { + if ( + state.properties.contains(Properties.WATERLOGGED) + && state.get(Properties.WATERLOGGED) + && it.state.fluidState.fluid !is WaterFluid + || !it.state.isAir + ) { return@listener } interaction.breakBlock(interaction.currentBreakingPos) } - listener { - it.value = (interaction.currentBreakingProgress * (2f - breakThreshold) * 10).toInt().coerceAtMost(9) + listener { + it.progress = (interaction.currentBreakingProgress * (2f - breakThreshold) * 10).coerceAtMost(9f) } listener { @@ -87,4 +95,7 @@ object FastBreak : Module( // We should use interpolation to make the fill grow smoothly. } } + + fun SafeContext.interpolateProgress(min: Double = 0.0, max: Double = 1.0) = + transform(interaction.currentBreakingProgress.toDouble(), 0.0, 1.0, min, max) } From 430752c1ae3434fc2b8889c155e1787442049a81 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 28 Jun 2024 20:08:49 +0100 Subject: [PATCH 28/91] - fixed crash --- .../mixin/entity/ClientPlayInteractionManagerMixin.java | 4 ++-- .../kotlin/com/lambda/module/modules/player/PacketMine.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java b/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java index 15c61a311..ba47f6bed 100644 --- a/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java +++ b/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java @@ -33,7 +33,7 @@ public void interactBlockHead(final ClientPlayerEntity player, final Hand hand, EventFlow.post(new InteractionEvent.Block(client.world, hitResult)); } - @Inject(method = "attackBlock", at = @At("HEAD")) + @Inject(method = "attackBlock", at = @At("HEAD"), cancellable = true) public void onAttackBlock(BlockPos pos, Direction side, CallbackInfoReturnable cir) { if (EventFlow.post(new InteractionEvent.BlockAttack.Pre(pos, side)).isCanceled()) cir.cancel(); } @@ -43,7 +43,7 @@ public void onAttackBlockPost(BlockPos pos, Direction side, CallbackInfoReturnab EventFlow.post(new InteractionEvent.BlockAttack.Post(pos, side)); } - @Inject(method = "updateBlockBreakingProgress", at = @At("HEAD")) + @Inject(method = "updateBlockBreakingProgress", at = @At("HEAD"), cancellable = true) private void updateBlockBreakingProgressPre(BlockPos pos, Direction side, CallbackInfoReturnable cir) { var event = EventFlow.post(new InteractionEvent.BreakingProgress.Pre(pos, side, currentBreakingProgress)); if (event.isCanceled()) cir.cancel(); diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index ce5ff70f1..2ce07dea5 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -129,7 +129,7 @@ object PacketMine : Module( } } - listener { + listener { it.cancel() player.swingHand(Hand.MAIN_HAND) From 33fac37f036fcbbd138b38762b5c6680b05a45d4 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Tue, 2 Jul 2024 04:13:50 +0100 Subject: [PATCH 29/91] - fixed / refactored fast break - made renders smooooth in packet mine --- .../lambda/module/modules/player/FastBreak.kt | 42 ++-------- .../module/modules/player/PacketMine.kt | 78 +++++++++++-------- 2 files changed, 53 insertions(+), 67 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt index d76508ae7..a4f59ee6d 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt @@ -6,11 +6,8 @@ import com.lambda.event.listener.SafeListener.Companion.listener import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.math.transform -import com.lambda.util.world.raycast.RayCastUtils.blockResult -import net.minecraft.fluid.WaterFluid import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action -import net.minecraft.state.property.Properties import java.awt.Color object FastBreak : Module( @@ -24,9 +21,8 @@ object FastBreak : Module( private val breakDelay by setting("Break Delay", 5, 0..5, 1, unit = "ticks", description = "The tick delay between breaking blocks", visibility = { page == Page.Mining }) private val breakThreshold by setting("Break Threshold", 0.7f, 0.2f..1.0f, 0.1f, description = "The progress at which the block will break.", visibility = { page == Page.Mining }) - private val validateBreak by setting("Validate Break", true, "Waits for a response from the server before breaking the block", visibility = { page == Page.Mining }) - private val renderOutline by setting("Render Outline", true, description = "Render an outline around the block being broken.", visibility = { page == Page.Rendering }) + private val renderOutline by setting("Render Outline", true, description = "Render an outline around the block being broken.", visibility = { page == Page.Rendering }) private val renderOutlineColor by setting("Outline Color", Color.CYAN, description = "The color of the outline.", visibility = { page == Page.Rendering && renderOutline }) private val renderFill by setting("Render Fill", true, description = "Fill the block with a color based on the mining progress.", visibility = { page == Page.Rendering }) private val renderFillColor by setting("Fill Color", Color.CYAN, description = "The color of the fill.", visibility = { page == Page.Rendering && renderFill }) @@ -38,8 +34,9 @@ object FastBreak : Module( init { listener { - if (it.packet !is PlayerActionC2SPacket) return@listener - if (it.packet.action != Action.STOP_DESTROY_BLOCK) return@listener + if (it.packet !is PlayerActionC2SPacket + || it.packet.action != Action.STOP_DESTROY_BLOCK + ) return@listener connection.sendPacket( PlayerActionC2SPacket( @@ -57,36 +54,9 @@ object FastBreak : Module( interaction.blockBreakingCooldown = interaction.blockBreakingCooldown.coerceAtMost(breakDelay) } - listener { - if (!interaction.isBreakingBlock || interaction.currentBreakingProgress < breakThreshold) return@listener - - connection.sendPacket( - PlayerActionC2SPacket( - Action.STOP_DESTROY_BLOCK, interaction.currentBreakingPos, mc.crosshairTarget?.blockResult?.side - ) - ) - - if (!validateBreak) interaction.breakBlock(interaction.currentBreakingPos) - } - - listener { - if (!validateBreak || it.pos != interaction.currentBreakingPos) return@listener - - val state = world.getBlockState(interaction.currentBreakingPos) - if ( - state.properties.contains(Properties.WATERLOGGED) - && state.get(Properties.WATERLOGGED) - && it.state.fluidState.fluid !is WaterFluid - || !it.state.isAir - ) { - return@listener - } - - interaction.breakBlock(interaction.currentBreakingPos) - } - listener { - it.progress = (interaction.currentBreakingProgress * (2f - breakThreshold) * 10).coerceAtMost(9f) + it.progress += world.getBlockState(it.pos) + .calcBlockBreakingDelta(player, world, it.pos) * (1 - breakThreshold) } listener { diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 2ce07dea5..49f9b354f 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -36,13 +36,13 @@ object PacketMine : Module( ) { private val page by setting("Page", Page.General) - private val breakSpeed by setting("Break Speed", 1.0, 0.0..1.0, 0.1, "Breaks the selected block at the time to break of the block multiplied by this value", visibility = { page == Page.General}) + private val breakThreshold by setting("Break Threshold", 0.7f, 0.0f..1.0f, 0.1f, "Breaks the selected block once the block breaking progress passes this value, 1 being 100%", visibility = { page == Page.General}) private val pauseWhileUsingItems by setting("Pause While Using Items", true, "Will prevent breaking while using items like eating or aiming a bow", visibility = { page == Page.General }) //ToDo: Implement these settings // private val rotate by setting("Rotate", false, "Rotates the player to look at the current mining block", visibility = { page == Page.General }) // private val autoSwap by setting("Auto Force Swap", false, "Hard swaps to the best tool rather than silent swapping. This is often used on servers with a stricter anti-cheat system", visibility = { page == Page.General}) private val validateBreak by setting("Validate Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) - private val timeoutDelay by setting("Timeout Delay", 0.20, 0.00..1.00, 0.1, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && validateBreak }) + private val timeoutDelay by setting("Timeout Delay", 0.20f, 0.00f..1.00f, 0.1f, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && validateBreak }) private val alternativePackets by setting("Alternative Packets", false, "Uses a different set of packets which tend to work better on servers using an anti-cheat like grim", visibility = { page == Page.General }) private val queueBlocks by setting("Queue Blocks", false, "Queues any blocks you click for breaking", visibility = { page == Page.Queue }).apply { this.onValueSet { _, to -> if (!to) blockQueue.clear() } } @@ -53,8 +53,29 @@ object PacketMine : Module( private val breakingAnimation by setting("Breaking Animation", false, "Renders the block breaking animation like vanilla would to show progress", visibility = { page == Page.Render }) private val renderMode by setting("Render Mode", RenderMode.InOut, "Renders a box with size corresponding to amount broken", visibility = { page == Page.Render }) - private val renderColor by setting("Render Colour", Color.RED, "The colour used to render the breaking box", visibility = { page == Page.Render }) + private val renderSetting by setting("Render Setting", RenderSetting.Both, "The different ways to draw the renders", visibility = { page == Page.Render && renderMode.isEnabled() }) + private val fillColor by setting("Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline }) + private val outlineColor by setting("Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) + private val outlineWidth by setting("Outline Width", 1f, 0f..3f, 0.1f, "the thickness of the outline", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) + private enum class RenderMode { + InOut, OutIn, None; + + fun isEnabled(): Boolean = + this != None + } + + private enum class RenderSetting { + Both, Fill, Outline + } + + private enum class BreakState { + Breaking, ReBreaking, AwaitingResponse + } + + private enum class Page { + General, Queue, ReBreak, Render + } private var currentMiningBlock: BreakingContext? = null private var ignorePacketSend = false @@ -79,11 +100,11 @@ object PacketMine : Module( val miningProgress = mineTicks * currentBreakDelta - if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, (miningProgress * (2 - breakSpeed) * 10).toInt().coerceAtMost(9)) + if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, (miningProgress * (2 - breakThreshold) * 10).toInt().coerceAtMost(9)) when (breakState) { BreakState.Breaking -> { - if (miningProgress < breakSpeed) return@listener + if (miningProgress < breakThreshold) return@listener timeCompleted = System.currentTimeMillis() swapStopBreak(pos, bestTool) @@ -105,7 +126,7 @@ object PacketMine : Module( return@listener } - if (miningProgress < breakSpeed) return@listener + if (miningProgress < breakThreshold) return@listener if (!fastReBreak && (activeState.isAir || (!activeState.fluidState.isEmpty && !(activeState.properties.contains(Properties.WATERLOGGED) && activeState.get(Properties.WATERLOGGED))))) { @@ -157,9 +178,11 @@ object PacketMine : Module( } } - listener { + listener { currentMiningBlock?.apply { + renderer.clear() buildRenderer() + renderer.upload() } } } @@ -174,7 +197,7 @@ object PacketMine : Module( val breakDelta = calcBreakDelta(world.getBlockState(pos), pos, bestTool) - if (breakDelta > breakSpeed) { + if (breakDelta > breakThreshold) { if (reBreak) { swapStartPacketBreak(pos, bestTool) currentMiningBlock = BreakingContext(pos, state, BreakState.ReBreaking, breakDelta) @@ -308,11 +331,9 @@ object PacketMine : Module( ) : Drawable { var mineTicks = 0 var timeCompleted: Long = -1 - var previousBreakDelta = 0f - var boxList = if (renderMode.isEnabled()) { - state.getCollisionShape(mc.world, pos).boundingBoxes.toSet() + state.getOutlineShape(mc.world, pos).boundingBoxes.toSet() } else { null } @@ -321,34 +342,29 @@ object PacketMine : Module( previousBreakDelta = currentBreakDelta currentBreakDelta = newBreakDelta if (renderMode.isEnabled()) - boxList = state.getCollisionShape(mc.world, pos).boundingBoxes.toSet() + boxList = state.getOutlineShape(mc.world, pos).boundingBoxes.toSet() } override fun SafeContext.buildRenderer() { boxList?.forEach { box -> - withBox(lerp( - getLerp(box, (mineTicks - 1) * previousBreakDelta * (2 - breakSpeed.toFloat())).offset(pos) - , getLerp(box, mineTicks * currentBreakDelta * (2 - breakSpeed.toFloat())).offset(pos) - , mc.tickDelta.toDouble()) - , renderColor) + val lerpBox = lerp( + getLerp(box, (mineTicks - 1) * previousBreakDelta * (2 - breakThreshold)).offset(pos) + , getLerp(box, mineTicks * currentBreakDelta * (2 - breakThreshold)).offset(pos) + , mc.tickDelta.toDouble() + ) + + if (renderSetting != RenderSetting.Outline) { + withBox(lerpBox, fillColor) + } + + if (renderSetting != RenderSetting.Fill) { + // Currently there isn't an outline method and I don't want to mess with anything that might have different plans + withBox(lerpBox, outlineColor) + } } } } - private enum class RenderMode { - InOut, OutIn, None; - fun isEnabled(): Boolean = - this != None - } - - private enum class BreakState { - Breaking, ReBreaking, AwaitingResponse - } - - private enum class Page { - General, Queue, ReBreak, Render - } - //Todo: Replace with task system private fun SafeContext.getBestTool(state: BlockState, pos: BlockPos): Int { From fa231197c4bdeeeecdb1a3a4c8e8275354eb3fd9 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Wed, 3 Jul 2024 22:15:46 +0100 Subject: [PATCH 30/91] - added renders to fast break --- .../lambda/module/modules/player/FastBreak.kt | 73 ++++++++++++++++--- .../module/modules/player/PacketMine.kt | 2 +- 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt index a4f59ee6d..75fc736f9 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt @@ -3,11 +3,16 @@ package com.lambda.module.modules.player import com.lambda.context.SafeContext import com.lambda.event.events.* import com.lambda.event.listener.SafeListener.Companion.listener +import com.lambda.graphics.renderer.esp.global.BlockESPRenderer +import com.lambda.graphics.renderer.esp.global.buildFilled +import com.lambda.graphics.renderer.esp.global.buildOutline import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.math.transform import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action +import com.lambda.util.math.MathUtils.lerp +import net.minecraft.util.math.Box import java.awt.Color object FastBreak : Module( @@ -22,14 +27,29 @@ object FastBreak : Module( private val breakDelay by setting("Break Delay", 5, 0..5, 1, unit = "ticks", description = "The tick delay between breaking blocks", visibility = { page == Page.Mining }) private val breakThreshold by setting("Break Threshold", 0.7f, 0.2f..1.0f, 0.1f, description = "The progress at which the block will break.", visibility = { page == Page.Mining }) - private val renderOutline by setting("Render Outline", true, description = "Render an outline around the block being broken.", visibility = { page == Page.Rendering }) - private val renderOutlineColor by setting("Outline Color", Color.CYAN, description = "The color of the outline.", visibility = { page == Page.Rendering && renderOutline }) - private val renderFill by setting("Render Fill", true, description = "Fill the block with a color based on the mining progress.", visibility = { page == Page.Rendering }) - private val renderFillColor by setting("Fill Color", Color.CYAN, description = "The color of the fill.", visibility = { page == Page.Rendering && renderFill }) - private val renderFillGrow by setting("Fill Grow", 0.0f, 0.0f..1.0f, 0.1f, description = "The amount the fill grows based on the mining progress.", visibility = { page == Page.Rendering && renderFill }) + private val renderMode by setting("Render Mode", RenderMode.InOut, "The animation style of the renders", visibility = { page == Page.Render }) + private val renderSetting by setting("Render Setting", RenderSetting.Both, "The different ways to draw the renders", visibility = { page == Page.Render && renderMode.isEnabled() }) + private val fillColor by setting("Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline }) + private val outlineColor by setting("Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) + private val outlineWidth by setting("Outline Width", 1f, 0f..3f, 0.1f, "the thickness of the outline", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) + + + private val renderer = BlockESPRenderer + private var boxSet = emptySet() private enum class Page { - Mining, Rendering + Mining, Render + } + + private enum class RenderMode { + InOut, OutIn, None; + + fun isEnabled(): Boolean = + this != None + } + + private enum class RenderSetting { + Both, Fill, Outline } init { @@ -59,10 +79,45 @@ object FastBreak : Module( .calcBlockBreakingDelta(player, world, it.pos) * (1 - breakThreshold) } + listener { + if (!renderMode.isEnabled()) return@listener + + val pos = interaction.currentBreakingPos + boxSet = world.getBlockState(pos).getOutlineShape(world, pos).boundingBoxes.toSet() + } + listener { - // Here we render an outline around the block being broken. - // Then we fill with a color based on the mining progress. - // We should use interpolation to make the fill grow smoothly. + if (!interaction.isBreakingBlock || !renderMode.isEnabled()) return@listener + + val pos = interaction.currentBreakingPos + val breakDelta = world.getBlockState(pos).calcBlockBreakingDelta(player, world, pos) + + renderer.clear() + boxSet.forEach { box -> + val lerpBox = lerp( + getLerp(box, interaction.currentBreakingProgress - breakDelta).offset(pos) + , getLerp(box, interaction.currentBreakingProgress).offset(pos) + , mc.tickDelta.toDouble() + ) + + if (renderSetting != RenderSetting.Outline) { + renderer.buildFilled(lerpBox, fillColor) + } + + if (renderSetting != RenderSetting.Fill) { + // Currently there isn't an outline method and I don't want to mess with anything that might have different plans + renderer.buildOutline(lerpBox, outlineColor) + } + } + renderer.upload() + } + } + + private fun getLerp(box: Box, factor: Float): Box { + return if (renderMode == RenderMode.InOut) { + lerp(Box(box.center, box.center), box, factor.toDouble()) + } else { + lerp(box, Box(box.center, box.center), factor.toDouble()) } } diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 49f9b354f..c4654499f 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -52,7 +52,7 @@ object PacketMine : Module( private val fastReBreak by setting("Fast Re-Break", false, "Re-breaks blocks instantly however could potentially cause ghost blocks", visibility = { page == Page.ReBreak && reBreak }) private val breakingAnimation by setting("Breaking Animation", false, "Renders the block breaking animation like vanilla would to show progress", visibility = { page == Page.Render }) - private val renderMode by setting("Render Mode", RenderMode.InOut, "Renders a box with size corresponding to amount broken", visibility = { page == Page.Render }) + private val renderMode by setting("Render Mode", RenderMode.InOut, "The animation style of the renders", visibility = { page == Page.Render }) private val renderSetting by setting("Render Setting", RenderSetting.Both, "The different ways to draw the renders", visibility = { page == Page.Render && renderMode.isEnabled() }) private val fillColor by setting("Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline }) private val outlineColor by setting("Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) From 264a9b6fc47169e3f5693087c598454a73828ced Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Thu, 4 Jul 2024 02:27:07 +0100 Subject: [PATCH 31/91] - added colour lerp to packet mine renders and fixed tiny bug --- .../module/modules/player/PacketMine.kt | 180 +++++++++++------- 1 file changed, 112 insertions(+), 68 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index c4654499f..43bf55110 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -7,7 +7,9 @@ import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listener -import com.lambda.interaction.construction.result.Drawable +import com.lambda.graphics.renderer.esp.global.BlockESPRenderer +import com.lambda.graphics.renderer.esp.global.buildFilled +import com.lambda.graphics.renderer.esp.global.buildOutline import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.math.MathUtils.lerp @@ -51,16 +53,25 @@ object PacketMine : Module( private val reBreak by setting("Re-Break", true, "Automatically re-breaks the last mined block if it gets replaced", visibility = { page == Page.ReBreak}) private val fastReBreak by setting("Fast Re-Break", false, "Re-breaks blocks instantly however could potentially cause ghost blocks", visibility = { page == Page.ReBreak && reBreak }) + private val breakingAnimation by setting("Breaking Animation", false, "Renders the block breaking animation like vanilla would to show progress", visibility = { page == Page.Render }) - private val renderMode by setting("Render Mode", RenderMode.InOut, "The animation style of the renders", visibility = { page == Page.Render }) + private val renderMode by setting("Render Mode", RenderMode.Out, "The animation style of the renders", visibility = { page == Page.Render }) private val renderSetting by setting("Render Setting", RenderSetting.Both, "The different ways to draw the renders", visibility = { page == Page.Render && renderMode.isEnabled() }) - private val fillColor by setting("Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline }) - private val outlineColor by setting("Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) + + private val fillColourMode by setting("Fill Mode", FillColourMode.Dynamic, visibility = { page == Page.Render && renderSetting != RenderSetting.Outline }) + private val staticFillColour by setting("Static Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the static fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == FillColourMode.Static }) + private val startFillColour by setting("Start Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the start fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == FillColourMode.Dynamic }) + private val endFillColour by setting("End Fill Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == FillColourMode.Dynamic }) + + private val outlineColourMode by setting("Outline Mode", FillColourMode.Dynamic, visibility = { page == Page.Render && renderSetting != RenderSetting.Fill }) + private val staticOutlineColour by setting("Static Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the static outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == FillColourMode.Static }) + private val startOutlineColour by setting("Start Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the start outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == FillColourMode.Dynamic }) + private val endOutlineColour by setting("End Outline Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == FillColourMode.Dynamic }) private val outlineWidth by setting("Outline Width", 1f, 0f..3f, 0.1f, "the thickness of the outline", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) private enum class RenderMode { - InOut, OutIn, None; - + Out, In, Static, None; + fun isEnabled(): Boolean = this != None } @@ -69,6 +80,10 @@ object PacketMine : Module( Both, Fill, Outline } + private enum class FillColourMode { + Static, Dynamic + } + private enum class BreakState { Breaking, ReBreaking, AwaitingResponse } @@ -96,11 +111,16 @@ object PacketMine : Module( currentBreakDelta = calcBreakDelta(state, pos, bestTool) - if (renderMode.isEnabled()) updateBoxList(currentBreakDelta) + if (renderMode.isEnabled()) updateRenders(currentBreakDelta) val miningProgress = mineTicks * currentBreakDelta - if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, (miningProgress * (2 - breakThreshold) * 10).toInt().coerceAtMost(9)) + if (breakingAnimation) + world.setBlockBreakingInfo( + player.id, + pos, + (miningProgress * (2 - breakThreshold) * 10).toInt().coerceAtMost(9) + ) when (breakState) { BreakState.Breaking -> { @@ -118,6 +138,7 @@ object PacketMine : Module( onBlockBreak() } + BreakState.ReBreaking -> { if (breakNextQueueBlock()) return@listener @@ -129,7 +150,10 @@ object PacketMine : Module( if (miningProgress < breakThreshold) return@listener if (!fastReBreak - && (activeState.isAir || (!activeState.fluidState.isEmpty && !(activeState.properties.contains(Properties.WATERLOGGED) && activeState.get(Properties.WATERLOGGED))))) { + && (activeState.isAir || (!activeState.fluidState.isEmpty + && !(activeState.properties.contains(Properties.WATERLOGGED) + && activeState.get(Properties.WATERLOGGED)))) + ) { return@listener } @@ -137,6 +161,7 @@ object PacketMine : Module( checkClientBreak(false, pos) } + BreakState.AwaitingResponse -> { if (!validateBreak) return@listener @@ -166,7 +191,8 @@ object PacketMine : Module( currentMiningBlock?.apply { if (it.pos != pos || if (state.properties.contains(Properties.WATERLOGGED) && state.get(Properties.WATERLOGGED)) it.state.fluidState.fluid !is WaterFluid - else !it.state.isAir) { + else !it.state.isAir + ) { return@listener } @@ -181,7 +207,7 @@ object PacketMine : Module( listener { currentMiningBlock?.apply { renderer.clear() - buildRenderer() + buildRenders() renderer.upload() } } @@ -197,23 +223,24 @@ object PacketMine : Module( val breakDelta = calcBreakDelta(world.getBlockState(pos), pos, bestTool) - if (breakDelta > breakThreshold) { - if (reBreak) { - swapStartPacketBreak(pos, bestTool) - currentMiningBlock = BreakingContext(pos, state, BreakState.ReBreaking, breakDelta) + if (breakDelta < breakThreshold) { + currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking, breakDelta) + return + } + + if (reBreak) { + swapStartPacketBreak(pos, bestTool) + currentMiningBlock = BreakingContext(pos, state, BreakState.ReBreaking, breakDelta) + } else { + currentMiningBlock = if (!validateBreak) { + null } else { - currentMiningBlock = if (!validateBreak) { - null - } else { - BreakingContext(pos, state, BreakState.AwaitingResponse, breakDelta) - } + BreakingContext(pos, state, BreakState.AwaitingResponse, breakDelta) } - currentMiningBlock?.timeCompleted = System.currentTimeMillis() - - checkClientBreak(false, pos) } + currentMiningBlock?.timeCompleted = System.currentTimeMillis() - currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking, breakDelta) + checkClientBreak(false, pos) } private fun SafeContext.onBlockBreak() { @@ -283,14 +310,73 @@ object PacketMine : Module( } } - private fun getLerp(box: Box, factor: Float): Box { - return if (renderMode == RenderMode.InOut) { + private fun getLerpBox(box: Box, factor: Float): Box { + return if (renderMode == RenderMode.Out) { lerp(Box(box.center, box.center), box, factor.toDouble()) } else { lerp(box, Box(box.center, box.center), factor.toDouble()) } } + private data class BreakingContext( + val pos: BlockPos, + var state: BlockState, + var breakState: BreakState, + var currentBreakDelta: Float + ) { + val renderer = BlockESPRenderer + var mineTicks = 0 + var timeCompleted: Long = -1 + var previousBreakDelta = 0f + + var boxList = if (renderMode.isEnabled()) { + state.getOutlineShape(mc.world, pos).boundingBoxes.toSet() + } else { + null + } + + fun updateRenders(newBreakDelta: Float) { + previousBreakDelta = currentBreakDelta + currentBreakDelta = newBreakDelta + if (renderMode.isEnabled()) + boxList = state.getOutlineShape(mc.world, pos).boundingBoxes.toSet() + } + + fun SafeContext.buildRenders() { + boxList?.forEach { box -> + val previousFactor = (mineTicks - 1) * previousBreakDelta * (2 - breakThreshold) + val nextFactor = mineTicks * currentBreakDelta * (2 - breakThreshold) + val currentFactor = lerp(previousFactor, nextFactor, mc.tickDelta) + + val fillColour = if (fillColourMode == FillColourMode.Dynamic) { + lerp(startFillColour, endFillColour, currentFactor.toDouble()) + } else { + staticFillColour + } + + val outlineColour = if (outlineColourMode == FillColourMode.Dynamic) { + lerp(startOutlineColour, endOutlineColour, currentFactor.toDouble()) + } else { + staticOutlineColour + } + + val renderBox = if (renderMode != RenderMode.Static) { + getLerpBox(box, currentFactor).offset(pos) + } else { + box.offset(pos) + } + + if (renderSetting != RenderSetting.Outline) { + renderer.buildFilled(renderBox, fillColour) + } + + if (renderSetting != RenderSetting.Fill) { + renderer.buildOutline(renderBox, outlineColour) + } + } + } + } + private fun SafeContext.swapStartPacketBreak(pos: BlockPos, toolSlot: Int) { connection.sendPacket(UpdateSelectedSlotC2SPacket(toolSlot)) ignorePacketSend = true @@ -323,48 +409,6 @@ object PacketMine : Module( connection.sendPacket(PlayerActionC2SPacket(Action.ABORT_DESTROY_BLOCK, pos, Direction.UP, 0)) } - private data class BreakingContext( - val pos: BlockPos, - var state: BlockState, - var breakState: BreakState, - var currentBreakDelta: Float - ) : Drawable { - var mineTicks = 0 - var timeCompleted: Long = -1 - var previousBreakDelta = 0f - var boxList = if (renderMode.isEnabled()) { - state.getOutlineShape(mc.world, pos).boundingBoxes.toSet() - } else { - null - } - - fun updateBoxList(newBreakDelta: Float) { - previousBreakDelta = currentBreakDelta - currentBreakDelta = newBreakDelta - if (renderMode.isEnabled()) - boxList = state.getOutlineShape(mc.world, pos).boundingBoxes.toSet() - } - - override fun SafeContext.buildRenderer() { - boxList?.forEach { box -> - val lerpBox = lerp( - getLerp(box, (mineTicks - 1) * previousBreakDelta * (2 - breakThreshold)).offset(pos) - , getLerp(box, mineTicks * currentBreakDelta * (2 - breakThreshold)).offset(pos) - , mc.tickDelta.toDouble() - ) - - if (renderSetting != RenderSetting.Outline) { - withBox(lerpBox, fillColor) - } - - if (renderSetting != RenderSetting.Fill) { - // Currently there isn't an outline method and I don't want to mess with anything that might have different plans - withBox(lerpBox, outlineColor) - } - } - } - } - //Todo: Replace with task system private fun SafeContext.getBestTool(state: BlockState, pos: BlockPos): Int { From b57d4ca69559d24c68d9a1eff724545066e047c7 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Thu, 4 Jul 2024 02:51:03 +0100 Subject: [PATCH 32/91] - added in-out and out-in modes for packet mine renders --- .../module/modules/player/PacketMine.kt | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 43bf55110..86ac67b41 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -70,7 +70,7 @@ object PacketMine : Module( private val outlineWidth by setting("Outline Width", 1f, 0f..3f, 0.1f, "the thickness of the outline", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) private enum class RenderMode { - Out, In, Static, None; + Out, In, InOut, OutIn, Static, None; fun isEnabled(): Boolean = this != None @@ -311,10 +311,35 @@ object PacketMine : Module( } private fun getLerpBox(box: Box, factor: Float): Box { - return if (renderMode == RenderMode.Out) { - lerp(Box(box.center, box.center), box, factor.toDouble()) - } else { - lerp(box, Box(box.center, box.center), factor.toDouble()) + val boxCenter = Box(box.center, box.center) + when (renderMode) { + RenderMode.Out -> { + return lerp(boxCenter, box, factor.toDouble()) + } + + RenderMode.In -> { + return lerp(box, boxCenter, factor.toDouble()) + } + + RenderMode.InOut -> { + return if (factor >= 0.5f) { + lerp(boxCenter, box, (factor.toDouble() - 0.5) * 2) + } else { + lerp(box, boxCenter, factor.toDouble() * 2) + } + } + + RenderMode.OutIn -> { + return if (factor >= 0.5f) { + lerp(box, boxCenter, (factor.toDouble() - 0.5) * 2) + } else { + lerp(boxCenter, box, factor.toDouble() * 2) + } + } + + else -> { + return box + } } } From 50acfda3d6948a063665cca49b85c8425669d8c3 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Thu, 4 Jul 2024 03:14:06 +0100 Subject: [PATCH 33/91] - removed unnecessary ignore packet send variable --- .../kotlin/com/lambda/module/modules/player/PacketMine.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 86ac67b41..7b4ad0114 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -93,7 +93,6 @@ object PacketMine : Module( } private var currentMiningBlock: BreakingContext? = null - private var ignorePacketSend = false private val blockQueue = ArrayDeque() //ToDo: Make work on CC @@ -404,21 +403,17 @@ object PacketMine : Module( private fun SafeContext.swapStartPacketBreak(pos: BlockPos, toolSlot: Int) { connection.sendPacket(UpdateSelectedSlotC2SPacket(toolSlot)) - ignorePacketSend = true startBreak(pos) if (alternativePackets) { abortBreak(pos) stopBreak(pos) } - ignorePacketSend = false connection.sendPacket(UpdateSelectedSlotC2SPacket(player.inventory.selectedSlot)) } private fun SafeContext.swapStopBreak(pos: BlockPos, toolSlot: Int) { connection.sendPacket(UpdateSelectedSlotC2SPacket(toolSlot)) - ignorePacketSend = true stopBreak(pos) - ignorePacketSend = false connection.sendPacket(UpdateSelectedSlotC2SPacket(player.inventory.selectedSlot)) } From 0aa1f9d48a4f3b54ece0a99cb25adb8e13f8dd38 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Thu, 4 Jul 2024 03:15:12 +0100 Subject: [PATCH 34/91] - renamed FillColourMode to ColourMode --- .../module/modules/player/PacketMine.kt | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 7b4ad0114..5d1bd46d0 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -58,15 +58,15 @@ object PacketMine : Module( private val renderMode by setting("Render Mode", RenderMode.Out, "The animation style of the renders", visibility = { page == Page.Render }) private val renderSetting by setting("Render Setting", RenderSetting.Both, "The different ways to draw the renders", visibility = { page == Page.Render && renderMode.isEnabled() }) - private val fillColourMode by setting("Fill Mode", FillColourMode.Dynamic, visibility = { page == Page.Render && renderSetting != RenderSetting.Outline }) - private val staticFillColour by setting("Static Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the static fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == FillColourMode.Static }) - private val startFillColour by setting("Start Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the start fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == FillColourMode.Dynamic }) - private val endFillColour by setting("End Fill Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == FillColourMode.Dynamic }) - - private val outlineColourMode by setting("Outline Mode", FillColourMode.Dynamic, visibility = { page == Page.Render && renderSetting != RenderSetting.Fill }) - private val staticOutlineColour by setting("Static Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the static outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == FillColourMode.Static }) - private val startOutlineColour by setting("Start Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the start outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == FillColourMode.Dynamic }) - private val endOutlineColour by setting("End Outline Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == FillColourMode.Dynamic }) + private val fillColourMode by setting("Fill Mode", ColourMode.Dynamic, visibility = { page == Page.Render && renderSetting != RenderSetting.Outline }) + private val staticFillColour by setting("Static Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the static fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Static }) + private val startFillColour by setting("Start Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the start fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Dynamic }) + private val endFillColour by setting("End Fill Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Dynamic }) + + private val outlineColourMode by setting("Outline Mode", ColourMode.Dynamic, visibility = { page == Page.Render && renderSetting != RenderSetting.Fill }) + private val staticOutlineColour by setting("Static Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the static outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Static }) + private val startOutlineColour by setting("Start Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the start outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Dynamic }) + private val endOutlineColour by setting("End Outline Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Dynamic }) private val outlineWidth by setting("Outline Width", 1f, 0f..3f, 0.1f, "the thickness of the outline", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) private enum class RenderMode { @@ -80,7 +80,7 @@ object PacketMine : Module( Both, Fill, Outline } - private enum class FillColourMode { + private enum class ColourMode { Static, Dynamic } @@ -372,13 +372,13 @@ object PacketMine : Module( val nextFactor = mineTicks * currentBreakDelta * (2 - breakThreshold) val currentFactor = lerp(previousFactor, nextFactor, mc.tickDelta) - val fillColour = if (fillColourMode == FillColourMode.Dynamic) { + val fillColour = if (fillColourMode == ColourMode.Dynamic) { lerp(startFillColour, endFillColour, currentFactor.toDouble()) } else { staticFillColour } - val outlineColour = if (outlineColourMode == FillColourMode.Dynamic) { + val outlineColour = if (outlineColourMode == ColourMode.Dynamic) { lerp(startOutlineColour, endOutlineColour, currentFactor.toDouble()) } else { staticOutlineColour From ebe9e13a045e342051959a749fd8bafd25362d1a Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Thu, 4 Jul 2024 04:11:56 +0100 Subject: [PATCH 35/91] - added the new renders to fast break --- .../lambda/module/modules/player/FastBreak.kt | 86 +++++++++++++++---- 1 file changed, 69 insertions(+), 17 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt index 75fc736f9..cc7323bbe 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt @@ -27,10 +27,18 @@ object FastBreak : Module( private val breakDelay by setting("Break Delay", 5, 0..5, 1, unit = "ticks", description = "The tick delay between breaking blocks", visibility = { page == Page.Mining }) private val breakThreshold by setting("Break Threshold", 0.7f, 0.2f..1.0f, 0.1f, description = "The progress at which the block will break.", visibility = { page == Page.Mining }) - private val renderMode by setting("Render Mode", RenderMode.InOut, "The animation style of the renders", visibility = { page == Page.Render }) + private val renderMode by setting("Render Mode", RenderMode.Out, "The animation style of the renders", visibility = { page == Page.Render }) private val renderSetting by setting("Render Setting", RenderSetting.Both, "The different ways to draw the renders", visibility = { page == Page.Render && renderMode.isEnabled() }) - private val fillColor by setting("Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline }) - private val outlineColor by setting("Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) + + private val fillColourMode by setting("Fill Mode", ColourMode.Dynamic, visibility = { page == Page.Render && renderSetting != RenderSetting.Outline }) + private val staticFillColour by setting("Static Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the static fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Static }) + private val startFillColour by setting("Start Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the start fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Dynamic }) + private val endFillColour by setting("End Fill Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Dynamic }) + + private val outlineColourMode by setting("Outline Mode", ColourMode.Dynamic, visibility = { page == Page.Render && renderSetting != RenderSetting.Fill }) + private val staticOutlineColour by setting("Static Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the static outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Static }) + private val startOutlineColour by setting("Start Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the start outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Dynamic }) + private val endOutlineColour by setting("End Outline Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Dynamic }) private val outlineWidth by setting("Outline Width", 1f, 0f..3f, 0.1f, "the thickness of the outline", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) @@ -42,12 +50,16 @@ object FastBreak : Module( } private enum class RenderMode { - InOut, OutIn, None; + Out, In, InOut, OutIn, Static, None; fun isEnabled(): Boolean = this != None } + private enum class ColourMode { + Static, Dynamic + } + private enum class RenderSetting { Both, Fill, Outline } @@ -94,30 +106,70 @@ object FastBreak : Module( renderer.clear() boxSet.forEach { box -> - val lerpBox = lerp( - getLerp(box, interaction.currentBreakingProgress - breakDelta).offset(pos) - , getLerp(box, interaction.currentBreakingProgress).offset(pos) - , mc.tickDelta.toDouble() - ) + val previousFactor = interaction.currentBreakingProgress - breakDelta + val nextFactor = interaction.currentBreakingProgress + val currentFactor = lerp(previousFactor, nextFactor, mc.tickDelta) + + val fillColour = if (fillColourMode == ColourMode.Dynamic) { + lerp(startFillColour, endFillColour, currentFactor.toDouble()) + } else { + staticFillColour + } + + val outlineColour = if (outlineColourMode == ColourMode.Dynamic) { + lerp(startOutlineColour, endOutlineColour, currentFactor.toDouble()) + } else { + staticOutlineColour + } + + val renderBox = if (renderMode != RenderMode.Static) { + getLerpBox(box, currentFactor).offset(pos) + } else { + box.offset(pos) + } if (renderSetting != RenderSetting.Outline) { - renderer.buildFilled(lerpBox, fillColor) + renderer.buildFilled(renderBox, fillColour) } if (renderSetting != RenderSetting.Fill) { - // Currently there isn't an outline method and I don't want to mess with anything that might have different plans - renderer.buildOutline(lerpBox, outlineColor) + renderer.buildOutline(renderBox, outlineColour) } } renderer.upload() } } - private fun getLerp(box: Box, factor: Float): Box { - return if (renderMode == RenderMode.InOut) { - lerp(Box(box.center, box.center), box, factor.toDouble()) - } else { - lerp(box, Box(box.center, box.center), factor.toDouble()) + private fun getLerpBox(box: Box, factor: Float): Box { + val boxCenter = Box(box.center, box.center) + when (renderMode) { + RenderMode.Out -> { + return lerp(boxCenter, box, factor.toDouble()) + } + + RenderMode.In -> { + return lerp(box, boxCenter, factor.toDouble()) + } + + RenderMode.InOut -> { + return if (factor >= 0.5f) { + lerp(boxCenter, box, (factor.toDouble() - 0.5) * 2) + } else { + lerp(box, boxCenter, factor.toDouble() * 2) + } + } + + RenderMode.OutIn -> { + return if (factor >= 0.5f) { + lerp(box, boxCenter, (factor.toDouble() - 0.5) * 2) + } else { + lerp(boxCenter, box, factor.toDouble() * 2) + } + } + + else -> { + return box + } } } From 7aac6916dc0368f8fbf2c8179a64b354cfd5bfde Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Thu, 4 Jul 2024 19:13:35 +0100 Subject: [PATCH 36/91] - fixed instamine blocks not breaking properly without alternative packets. (i was dumb and forgot the stop dig packet) --- .../com/lambda/module/modules/player/PacketMine.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 5d1bd46d0..bb1786477 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -227,11 +227,12 @@ object PacketMine : Module( return } - if (reBreak) { - swapStartPacketBreak(pos, bestTool) - currentMiningBlock = BreakingContext(pos, state, BreakState.ReBreaking, breakDelta) + swapStopBreak(pos, bestTool) + + currentMiningBlock = if (reBreak) { + BreakingContext(pos, state, BreakState.ReBreaking, breakDelta) } else { - currentMiningBlock = if (!validateBreak) { + if (!validateBreak) { null } else { BreakingContext(pos, state, BreakState.AwaitingResponse, breakDelta) From 692cd026c004fdb33f135b7ae2e2f39bd06563a9 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 5 Jul 2024 21:57:21 +0100 Subject: [PATCH 37/91] - fixed for dynamic esp --- .../lambda/module/modules/player/FastBreak.kt | 16 ++++++++++------ .../lambda/module/modules/player/PacketMine.kt | 16 ++++++++++------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt index cc7323bbe..dd0840faf 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt @@ -3,9 +3,10 @@ package com.lambda.module.modules.player import com.lambda.context.SafeContext import com.lambda.event.events.* import com.lambda.event.listener.SafeListener.Companion.listener -import com.lambda.graphics.renderer.esp.global.BlockESPRenderer -import com.lambda.graphics.renderer.esp.global.buildFilled -import com.lambda.graphics.renderer.esp.global.buildOutline +import com.lambda.graphics.renderer.esp.DynamicAABB +import com.lambda.graphics.renderer.esp.builders.buildFilled +import com.lambda.graphics.renderer.esp.builders.buildOutline +import com.lambda.graphics.renderer.esp.global.DynamicESP import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.math.transform @@ -42,7 +43,7 @@ object FastBreak : Module( private val outlineWidth by setting("Outline Width", 1f, 0f..3f, 0.1f, "the thickness of the outline", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) - private val renderer = BlockESPRenderer + private val renderer = DynamicESP private var boxSet = emptySet() private enum class Page { @@ -128,12 +129,15 @@ object FastBreak : Module( box.offset(pos) } + val dynamicAABB = DynamicAABB() + dynamicAABB.update(renderBox) + if (renderSetting != RenderSetting.Outline) { - renderer.buildFilled(renderBox, fillColour) + renderer.buildFilled(dynamicAABB, fillColour) } if (renderSetting != RenderSetting.Fill) { - renderer.buildOutline(renderBox, outlineColour) + renderer.buildOutline(dynamicAABB, outlineColour) } } renderer.upload() diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index bb1786477..766a26b94 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -7,9 +7,10 @@ import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listener -import com.lambda.graphics.renderer.esp.global.BlockESPRenderer -import com.lambda.graphics.renderer.esp.global.buildFilled -import com.lambda.graphics.renderer.esp.global.buildOutline +import com.lambda.graphics.renderer.esp.DynamicAABB +import com.lambda.graphics.renderer.esp.builders.buildFilled +import com.lambda.graphics.renderer.esp.builders.buildOutline +import com.lambda.graphics.renderer.esp.global.DynamicESP import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.math.MathUtils.lerp @@ -349,7 +350,7 @@ object PacketMine : Module( var breakState: BreakState, var currentBreakDelta: Float ) { - val renderer = BlockESPRenderer + val renderer = DynamicESP var mineTicks = 0 var timeCompleted: Long = -1 var previousBreakDelta = 0f @@ -391,12 +392,15 @@ object PacketMine : Module( box.offset(pos) } + val dynamicAABB = DynamicAABB() + dynamicAABB.update(renderBox) + if (renderSetting != RenderSetting.Outline) { - renderer.buildFilled(renderBox, fillColour) + renderer.buildFilled(dynamicAABB, fillColour) } if (renderSetting != RenderSetting.Fill) { - renderer.buildOutline(renderBox, outlineColour) + renderer.buildOutline(dynamicAABB, outlineColour) } } } From 35d9a7b6a2905893bd3abd5ca146945eccdacf9c Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Sat, 6 Jul 2024 02:42:57 +0100 Subject: [PATCH 38/91] - added extra setting checks --- .../module/modules/player/PacketMine.kt | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 766a26b94..ce9880b26 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -30,6 +30,7 @@ import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Box import net.minecraft.util.math.Direction +import net.minecraft.util.math.Vec3d import java.awt.Color object PacketMine : Module( @@ -124,6 +125,11 @@ object PacketMine : Module( when (breakState) { BreakState.Breaking -> { + if (isOutOfRange()) { + nullifyCurrentBreakingBlock() + return@listener + } + if (miningProgress < breakThreshold) return@listener timeCompleted = System.currentTimeMillis() @@ -142,7 +148,7 @@ object PacketMine : Module( BreakState.ReBreaking -> { if (breakNextQueueBlock()) return@listener - if (player.eyePos.distanceTo(pos.toCenterPos()) > 6) { + if (!reBreak || isOutOfRange()) { nullifyCurrentBreakingBlock() return@listener } @@ -163,7 +169,11 @@ object PacketMine : Module( } BreakState.AwaitingResponse -> { - if (!validateBreak) return@listener + if (!validateBreak) { + checkClientBreak(false, pos) + nullifyCurrentBreakingBlock() + return@listener + } if (System.currentTimeMillis() - timeCompleted < timeoutDelay * 1000) return@listener @@ -244,11 +254,17 @@ object PacketMine : Module( checkClientBreak(false, pos) } + private fun SafeContext.isOutOfRange() = + player.eyePos.distanceTo(currentMiningBlock?.pos?.toCenterPos()) > 6 + + private fun SafeContext.isOutOfRange(vec: Vec3d) = + player.eyePos.distanceTo(vec) > 6 + private fun SafeContext.onBlockBreak() { currentMiningBlock?.apply { if (breakNextQueueBlock()) return - if (reBreak && player.eyePos.distanceTo(pos.toCenterPos()) < 6) { + if (reBreak && !isOutOfRange()) { breakState = BreakState.ReBreaking return } @@ -302,7 +318,7 @@ object PacketMine : Module( while (true) { val block = getNextUncheckedQueueBlock() ?: return null - if (player.eyePos.distanceTo(block.toCenterPos()) > 6) { + if (isOutOfRange(block.toCenterPos())) { blockQueue.remove(block) continue } From fa99b5a4b5e6a15f228c72952e2b8b391ab8f4d0 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Sat, 6 Jul 2024 02:57:44 +0100 Subject: [PATCH 39/91] - added range setting --- .../kotlin/com/lambda/module/modules/player/PacketMine.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index ce9880b26..2123cb3b6 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -41,6 +41,7 @@ object PacketMine : Module( private val page by setting("Page", Page.General) private val breakThreshold by setting("Break Threshold", 0.7f, 0.0f..1.0f, 0.1f, "Breaks the selected block once the block breaking progress passes this value, 1 being 100%", visibility = { page == Page.General}) + private val range by setting("Range", 6, 3..6, 1, "The maximum distance between the players eye position and the center of the block", visibility = { page == Page.General }) private val pauseWhileUsingItems by setting("Pause While Using Items", true, "Will prevent breaking while using items like eating or aiming a bow", visibility = { page == Page.General }) //ToDo: Implement these settings // private val rotate by setting("Rotate", false, "Rotates the player to look at the current mining block", visibility = { page == Page.General }) @@ -255,10 +256,10 @@ object PacketMine : Module( } private fun SafeContext.isOutOfRange() = - player.eyePos.distanceTo(currentMiningBlock?.pos?.toCenterPos()) > 6 + player.eyePos.distanceTo(currentMiningBlock?.pos?.toCenterPos()) > range private fun SafeContext.isOutOfRange(vec: Vec3d) = - player.eyePos.distanceTo(vec) > 6 + player.eyePos.distanceTo(vec) > range private fun SafeContext.onBlockBreak() { currentMiningBlock?.apply { From 5c40f554a6104bb489cddc7bd1d9bebf1b5c8dd8 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Sat, 6 Jul 2024 03:02:53 +0100 Subject: [PATCH 40/91] - removed range check for the current breaking block if not rebreaking --- .../kotlin/com/lambda/module/modules/player/PacketMine.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 2123cb3b6..eebd7c6ef 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -126,11 +126,6 @@ object PacketMine : Module( when (breakState) { BreakState.Breaking -> { - if (isOutOfRange()) { - nullifyCurrentBreakingBlock() - return@listener - } - if (miningProgress < breakThreshold) return@listener timeCompleted = System.currentTimeMillis() From 5df01247aa40cba4063c5f57f1554f1e87d47630 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Sat, 6 Jul 2024 03:10:12 +0100 Subject: [PATCH 41/91] - fixed colour settings showing while render setting's disabled --- .../kotlin/com/lambda/module/modules/player/PacketMine.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index eebd7c6ef..cb2cb35b7 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -61,12 +61,12 @@ object PacketMine : Module( private val renderMode by setting("Render Mode", RenderMode.Out, "The animation style of the renders", visibility = { page == Page.Render }) private val renderSetting by setting("Render Setting", RenderSetting.Both, "The different ways to draw the renders", visibility = { page == Page.Render && renderMode.isEnabled() }) - private val fillColourMode by setting("Fill Mode", ColourMode.Dynamic, visibility = { page == Page.Render && renderSetting != RenderSetting.Outline }) + private val fillColourMode by setting("Fill Mode", ColourMode.Dynamic, visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline }) private val staticFillColour by setting("Static Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the static fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Static }) private val startFillColour by setting("Start Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the start fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Dynamic }) private val endFillColour by setting("End Fill Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Dynamic }) - private val outlineColourMode by setting("Outline Mode", ColourMode.Dynamic, visibility = { page == Page.Render && renderSetting != RenderSetting.Fill }) + private val outlineColourMode by setting("Outline Mode", ColourMode.Dynamic, visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) private val staticOutlineColour by setting("Static Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the static outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Static }) private val startOutlineColour by setting("Start Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the start outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Dynamic }) private val endOutlineColour by setting("End Outline Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Dynamic }) From ae7a31e4a8d9c0cc875ba4e5cf16c3ac6c24e06e Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Sun, 7 Jul 2024 14:57:29 +0100 Subject: [PATCH 42/91] - added auto swap setting --- .../module/modules/player/PacketMine.kt | 132 +++++++++++++++--- 1 file changed, 112 insertions(+), 20 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index cb2cb35b7..91a59be27 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -45,7 +45,7 @@ object PacketMine : Module( private val pauseWhileUsingItems by setting("Pause While Using Items", true, "Will prevent breaking while using items like eating or aiming a bow", visibility = { page == Page.General }) //ToDo: Implement these settings // private val rotate by setting("Rotate", false, "Rotates the player to look at the current mining block", visibility = { page == Page.General }) -// private val autoSwap by setting("Auto Force Swap", false, "Hard swaps to the best tool rather than silent swapping. This is often used on servers with a stricter anti-cheat system", visibility = { page == Page.General}) + private val autoSwap by setting("Auto Force Swap", false, "Hard swaps to the best tool rather than silent swapping. This is often used on servers with a stricter anti-cheat system", visibility = { page == Page.General}) private val validateBreak by setting("Validate Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) private val timeoutDelay by setting("Timeout Delay", 0.20f, 0.00f..1.00f, 0.1f, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && validateBreak }) private val alternativePackets by setting("Alternative Packets", false, "Uses a different set of packets which tend to work better on servers using an anti-cheat like grim", visibility = { page == Page.General }) @@ -97,6 +97,9 @@ object PacketMine : Module( private var currentMiningBlock: BreakingContext? = null private val blockQueue = ArrayDeque() + private var returnSlot = -1 + private var swappedSlot = -1 + private var swapped = false //ToDo: Make work on CC @@ -109,7 +112,11 @@ object PacketMine : Module( val activeState = world.getBlockState(pos) if (activeState != state) state = activeState + + val empty = isStateEmpty(activeState) + val bestTool = getBestTool(activeState, pos) + if (!empty) lastValidBestTool = bestTool currentBreakDelta = calcBreakDelta(state, pos, bestTool) @@ -129,7 +136,12 @@ object PacketMine : Module( if (miningProgress < breakThreshold) return@listener timeCompleted = System.currentTimeMillis() - swapStopBreak(pos, bestTool) + + if (swapped) { + stopBreak(pos) + } else { + swapStopBreak(pos, bestTool) + } if (validateBreak) { breakState = BreakState.AwaitingResponse @@ -152,14 +164,20 @@ object PacketMine : Module( if (miningProgress < breakThreshold) return@listener if (!fastReBreak - && (activeState.isAir || (!activeState.fluidState.isEmpty - && !(activeState.properties.contains(Properties.WATERLOGGED) - && activeState.get(Properties.WATERLOGGED)))) + && empty ) { return@listener } - swapStopBreak(pos, bestTool) + if (autoSwap) { + if (!swapped) { + swapTo(lastValidBestTool) + } + stopBreak(pos) + if ((!validateBreak || empty) && swapped) swapToReturnSlot() + } else { + swapStopBreak(pos, lastValidBestTool) + } checkClientBreak(false, pos) } @@ -196,15 +214,19 @@ object PacketMine : Module( listener { currentMiningBlock?.apply { if (it.pos != pos - || if (state.properties.contains(Properties.WATERLOGGED) && state.get(Properties.WATERLOGGED)) it.state.fluidState.fluid !is WaterFluid - else !it.state.isAir + || !isStateBroken(state, it.state) ) { return@listener } checkClientBreak(true, pos) - if (breakState == BreakState.ReBreaking) return@listener + if (breakState == BreakState.ReBreaking) { + if (swapped) { + swapToReturnSlot() + } + return@listener + } onBlockBreak() } @@ -225,16 +247,27 @@ object PacketMine : Module( val state = world.getBlockState(pos) val bestTool = getBestTool(state, pos) - swapStartPacketBreak(pos, bestTool) - val breakDelta = calcBreakDelta(world.getBlockState(pos), pos, bestTool) + if (autoSwap) { + swapTo(bestTool) + } else { + silentSwapTo(bestTool) + } + startBreak(pos) + if (alternativePackets) { + abortBreak(pos) + stopBreak(pos) + } + if (breakDelta < breakThreshold) { + if (!swapped) silentSwapTo(player.inventory.selectedSlot) currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking, breakDelta) return } - swapStopBreak(pos, bestTool) + stopBreak(pos) + if (!swapped) silentSwapTo(player.inventory.selectedSlot) currentMiningBlock = if (reBreak) { BreakingContext(pos, state, BreakState.ReBreaking, breakDelta) @@ -245,11 +278,51 @@ object PacketMine : Module( BreakingContext(pos, state, BreakState.AwaitingResponse, breakDelta) } } - currentMiningBlock?.timeCompleted = System.currentTimeMillis() + + currentMiningBlock?.apply { + timeCompleted = System.currentTimeMillis() + lastValidBestTool = bestTool + + if (!validateBreak && swapped) { + swapToReturnSlot() + } + } checkClientBreak(false, pos) } + private fun SafeContext.swapToReturnSlot() { + if (!swapped || returnSlot == -1) return + + player.inventory.selectedSlot = returnSlot + connection.sendPacket(UpdateSelectedSlotC2SPacket(returnSlot)) + returnSlot = -1 + swappedSlot = -1 + swapped = false + + return + } + + private fun SafeContext.swapTo(slot: Int) { + if (returnSlot == -1) { + returnSlot = player.inventory.selectedSlot + } + player.inventory.selectedSlot = slot + connection.sendPacket(UpdateSelectedSlotC2SPacket(slot)) + swappedSlot = slot + swapped = true + } + + private fun SafeContext.cancelSwap() { + returnSlot = -1 + swappedSlot = -1 + swapped = false + } + + private fun SafeContext.silentSwapTo(slot: Int) { + connection.sendPacket(UpdateSelectedSlotC2SPacket(slot)) + } + private fun SafeContext.isOutOfRange() = player.eyePos.distanceTo(currentMiningBlock?.pos?.toCenterPos()) > range @@ -261,6 +334,7 @@ object PacketMine : Module( if (breakNextQueueBlock()) return if (reBreak && !isOutOfRange()) { + if (swapped) swapToReturnSlot() breakState = BreakState.ReBreaking return } @@ -269,10 +343,29 @@ object PacketMine : Module( } } + private fun isStateBroken(previousState: BlockState, activeState: BlockState) = + activeState.isAir || ( + activeState.fluidState.fluid is WaterFluid + && previousState.properties.contains(Properties.WATERLOGGED) + && previousState.get(Properties.WATERLOGGED) + ) + + private fun isStateEmpty(state: BlockState) = + state.isAir || ( + (!state.properties.contains(Properties.WATERLOGGED) + || !state.get(Properties.WATERLOGGED)) + && state.fluidState.fluid is WaterFluid + ) + private fun SafeContext.nullifyCurrentBreakingBlock() { currentMiningBlock?.apply { if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, 0) } + + if (swapped) { + swapToReturnSlot() + } + currentMiningBlock = null } @@ -282,13 +375,11 @@ object PacketMine : Module( } } - private fun shouldBePlacedInBlockQueue(pos: BlockPos): Boolean { - return !(!queueBlocks - || currentMiningBlock == null - || currentMiningBlock?.breakState == BreakState.ReBreaking - || currentMiningBlock?.pos == pos - || blockQueue.contains(pos)) - } + private fun shouldBePlacedInBlockQueue(pos: BlockPos): Boolean = queueBlocks + && currentMiningBlock != null + && currentMiningBlock?.breakState != BreakState.ReBreaking + && currentMiningBlock?.pos != pos + && !blockQueue.contains(pos) private fun SafeContext.breakNextQueueBlock(): Boolean { if (!queueBlocks) return false @@ -366,6 +457,7 @@ object PacketMine : Module( var mineTicks = 0 var timeCompleted: Long = -1 var previousBreakDelta = 0f + var lastValidBestTool = -1 var boxList = if (renderMode.isEnabled()) { state.getOutlineShape(mc.world, pos).boundingBoxes.toSet() From af8ede4cb3874f964bb322136c3c1f3a6f43733e Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Sun, 7 Jul 2024 18:42:14 +0100 Subject: [PATCH 43/91] - fixed auto swap not swapping back to the best tool to finish breaking the block --- .../lambda/module/modules/player/PacketMine.kt | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 91a59be27..de55d2ad8 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -129,7 +129,7 @@ object PacketMine : Module( player.id, pos, (miningProgress * (2 - breakThreshold) * 10).toInt().coerceAtMost(9) - ) + ) when (breakState) { BreakState.Breaking -> { @@ -137,7 +137,10 @@ object PacketMine : Module( timeCompleted = System.currentTimeMillis() - if (swapped) { + if (autoSwap) { + if (!swapped) { + swapTo(bestTool) + } stopBreak(pos) } else { swapStopBreak(pos, bestTool) @@ -510,16 +513,6 @@ object PacketMine : Module( } } - private fun SafeContext.swapStartPacketBreak(pos: BlockPos, toolSlot: Int) { - connection.sendPacket(UpdateSelectedSlotC2SPacket(toolSlot)) - startBreak(pos) - if (alternativePackets) { - abortBreak(pos) - stopBreak(pos) - } - connection.sendPacket(UpdateSelectedSlotC2SPacket(player.inventory.selectedSlot)) - } - private fun SafeContext.swapStopBreak(pos: BlockPos, toolSlot: Int) { connection.sendPacket(UpdateSelectedSlotC2SPacket(toolSlot)) stopBreak(pos) From e2b064ffee13ce049672530f4806b4c91884686b Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Sun, 7 Jul 2024 23:23:39 +0100 Subject: [PATCH 44/91] - getBestTool returns the players current slot if no other tool was found - swapping hotbar slot cancels the current swap --- .../module/modules/player/PacketMine.kt | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index de55d2ad8..3f40ecb45 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -115,10 +115,17 @@ object PacketMine : Module( val empty = isStateEmpty(activeState) - val bestTool = getBestTool(activeState, pos) - if (!empty) lastValidBestTool = bestTool + if (!empty) lastValidBestTool = getBestTool(activeState, pos) - currentBreakDelta = calcBreakDelta(state, pos, bestTool) + if (autoSwap) { + if (player.inventory.selectedSlot != swappedSlot) { + cancelSwap() + } else if (swappedSlot != lastValidBestTool) { + swapTo(lastValidBestTool) + } + } + + currentBreakDelta = calcBreakDelta(state, pos, lastValidBestTool) if (renderMode.isEnabled()) updateRenders(currentBreakDelta) @@ -139,11 +146,11 @@ object PacketMine : Module( if (autoSwap) { if (!swapped) { - swapTo(bestTool) + swapTo(lastValidBestTool) } stopBreak(pos) } else { - swapStopBreak(pos, bestTool) + swapStopBreak(pos, lastValidBestTool) } if (validateBreak) { @@ -164,11 +171,13 @@ object PacketMine : Module( return@listener } - if (miningProgress < breakThreshold) return@listener + if (miningProgress < breakThreshold) { + if (autoSwap) swapTo(lastValidBestTool) + breakState = BreakState.Breaking + return@listener + } - if (!fastReBreak - && empty - ) { + if (!fastReBreak && empty) { return@listener } @@ -316,7 +325,7 @@ object PacketMine : Module( swapped = true } - private fun SafeContext.cancelSwap() { + private fun cancelSwap() { returnSlot = -1 swappedSlot = -1 swapped = false @@ -357,7 +366,7 @@ object PacketMine : Module( state.isAir || ( (!state.properties.contains(Properties.WATERLOGGED) || !state.get(Properties.WATERLOGGED)) - && state.fluidState.fluid is WaterFluid + && !state.fluidState.isEmpty ) private fun SafeContext.nullifyCurrentBreakingBlock() { @@ -365,9 +374,7 @@ object PacketMine : Module( if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, 0) } - if (swapped) { - swapToReturnSlot() - } + if (swapped) swapToReturnSlot() currentMiningBlock = null } @@ -534,9 +541,11 @@ object PacketMine : Module( //Todo: Replace with task system private fun SafeContext.getBestTool(state: BlockState, pos: BlockPos): Int { - var bestTool = -1 - var bestTimeToMine = 0f + val selectedSlot = player.inventory.selectedSlot + var bestTool = selectedSlot + var bestTimeToMine = calcBreakDelta(state, pos, selectedSlot) for (i in 0..8) { + if (i == selectedSlot) continue val currentToolsTimeToMine = calcBreakDelta(state, pos, i) if (currentToolsTimeToMine > bestTimeToMine) { bestTimeToMine = currentToolsTimeToMine From 686d1ddad185bc0b6f16c6db44df51967ded97da Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 8 Jul 2024 01:05:53 +0100 Subject: [PATCH 45/91] - moved some things around --- .../module/modules/player/PacketMine.kt | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 3f40ecb45..c23857e0b 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -72,6 +72,10 @@ object PacketMine : Module( private val endOutlineColour by setting("End Outline Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Dynamic }) private val outlineWidth by setting("Outline Width", 1f, 0f..3f, 0.1f, "the thickness of the outline", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) + private enum class Page { + General, Queue, ReBreak, Render + } + private enum class RenderMode { Out, In, InOut, OutIn, Static, None; @@ -91,10 +95,6 @@ object PacketMine : Module( Breaking, ReBreaking, AwaitingResponse } - private enum class Page { - General, Queue, ReBreak, Render - } - private var currentMiningBlock: BreakingContext? = null private val blockQueue = ArrayDeque() private var returnSlot = -1 @@ -325,16 +325,16 @@ object PacketMine : Module( swapped = true } + private fun SafeContext.silentSwapTo(slot: Int) { + connection.sendPacket(UpdateSelectedSlotC2SPacket(slot)) + } + private fun cancelSwap() { returnSlot = -1 swappedSlot = -1 swapped = false } - private fun SafeContext.silentSwapTo(slot: Int) { - connection.sendPacket(UpdateSelectedSlotC2SPacket(slot)) - } - private fun SafeContext.isOutOfRange() = player.eyePos.distanceTo(currentMiningBlock?.pos?.toCenterPos()) > range @@ -355,6 +355,16 @@ object PacketMine : Module( } } + private fun SafeContext.nullifyCurrentBreakingBlock() { + currentMiningBlock?.apply { + if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, 0) + } + + if (swapped) swapToReturnSlot() + + currentMiningBlock = null + } + private fun isStateBroken(previousState: BlockState, activeState: BlockState) = activeState.isAir || ( activeState.fluidState.fluid is WaterFluid @@ -369,16 +379,6 @@ object PacketMine : Module( && !state.fluidState.isEmpty ) - private fun SafeContext.nullifyCurrentBreakingBlock() { - currentMiningBlock?.apply { - if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, 0) - } - - if (swapped) swapToReturnSlot() - - currentMiningBlock = null - } - private fun SafeContext.checkClientBreak(packetReceiveBreak: Boolean, pos: BlockPos) { if (packetReceiveBreak == validateBreak) { interaction.breakBlock(pos) @@ -403,14 +403,6 @@ object PacketMine : Module( return false } - private fun getNextUncheckedQueueBlock(): BlockPos? { - return if (reverseQueueOrder) { - blockQueue.lastOrNull() - } else { - blockQueue.firstOrNull() - } - } - private fun SafeContext.filterBlockQueueUntilNextPossible(): BlockPos? { while (true) { val block = getNextUncheckedQueueBlock() ?: return null @@ -424,6 +416,14 @@ object PacketMine : Module( } } + private fun getNextUncheckedQueueBlock(): BlockPos? { + return if (reverseQueueOrder) { + blockQueue.lastOrNull() + } else { + blockQueue.firstOrNull() + } + } + private fun getLerpBox(box: Box, factor: Float): Box { val boxCenter = Box(box.center, box.center) when (renderMode) { From ac5dfa155988ae8476b5921f104052bb27581d4b Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 8 Jul 2024 03:31:42 +0100 Subject: [PATCH 46/91] - very basic rotations --- .../module/modules/player/PacketMine.kt | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index c23857e0b..212e3f915 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -2,15 +2,14 @@ package com.lambda.module.modules.player import com.lambda.Lambda.mc import com.lambda.context.SafeContext -import com.lambda.event.events.InteractionEvent -import com.lambda.event.events.RenderEvent -import com.lambda.event.events.TickEvent -import com.lambda.event.events.WorldEvent +import com.lambda.event.events.* import com.lambda.event.listener.SafeListener.Companion.listener import com.lambda.graphics.renderer.esp.DynamicAABB import com.lambda.graphics.renderer.esp.builders.buildFilled import com.lambda.graphics.renderer.esp.builders.buildOutline import com.lambda.graphics.renderer.esp.global.DynamicESP +import com.lambda.interaction.rotation.Rotation +import com.lambda.interaction.visibilty.VisibilityChecker.lookAtBlock import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.math.MathUtils.lerp @@ -32,6 +31,7 @@ import net.minecraft.util.math.Box import net.minecraft.util.math.Direction import net.minecraft.util.math.Vec3d import java.awt.Color +import kotlin.math.exp object PacketMine : Module( name = "Packet Mine", @@ -43,8 +43,7 @@ object PacketMine : Module( private val breakThreshold by setting("Break Threshold", 0.7f, 0.0f..1.0f, 0.1f, "Breaks the selected block once the block breaking progress passes this value, 1 being 100%", visibility = { page == Page.General}) private val range by setting("Range", 6, 3..6, 1, "The maximum distance between the players eye position and the center of the block", visibility = { page == Page.General }) private val pauseWhileUsingItems by setting("Pause While Using Items", true, "Will prevent breaking while using items like eating or aiming a bow", visibility = { page == Page.General }) - //ToDo: Implement these settings -// private val rotate by setting("Rotate", false, "Rotates the player to look at the current mining block", visibility = { page == Page.General }) + private val rotate by setting("Rotate", false, "Rotates the player to look at the current mining block", visibility = { page == Page.General }) private val autoSwap by setting("Auto Force Swap", false, "Hard swaps to the best tool rather than silent swapping. This is often used on servers with a stricter anti-cheat system", visibility = { page == Page.General}) private val validateBreak by setting("Validate Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) private val timeoutDelay by setting("Timeout Delay", 0.20f, 0.00f..1.00f, 0.1f, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && validateBreak }) @@ -100,6 +99,8 @@ object PacketMine : Module( private var returnSlot = -1 private var swappedSlot = -1 private var swapped = false + private var expectedRotation: Rotation? = null + private var pauseForRotation = false //ToDo: Make work on CC @@ -108,7 +109,8 @@ object PacketMine : Module( currentMiningBlock?.apply { mineTicks++ - if (pauseWhileUsingItems && player.isUsingItem) return@listener + if ((pauseWhileUsingItems && player.isUsingItem) || pauseForRotation) + return@listener val activeState = world.getBlockState(pos) if (activeState != state) state = activeState @@ -244,6 +246,25 @@ object PacketMine : Module( } } + listener { + if (!rotate) return@listener + + currentMiningBlock?.apply { + val rotationContext = lookAtBlock(pos) + it.context = rotationContext + expectedRotation = rotationContext?.rotation + } + } + + listener { + expectedRotation?.apply { + if (it.context.rotation != expectedRotation) + pauseForRotation = true + } ?: run { + pauseForRotation = false + } + } + listener { currentMiningBlock?.apply { renderer.clear() From e790b6729952fcd6f6bf866222c2acc17fc20fe5 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Tue, 9 Jul 2024 20:00:41 +0100 Subject: [PATCH 47/91] - added different rotation modes - added different swap mode - added different packet modes --- .../module/modules/player/PacketMine.kt | 241 ++++++++++++++---- 1 file changed, 187 insertions(+), 54 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 212e3f915..5a27fdaf4 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -9,8 +9,9 @@ import com.lambda.graphics.renderer.esp.builders.buildFilled import com.lambda.graphics.renderer.esp.builders.buildOutline import com.lambda.graphics.renderer.esp.global.DynamicESP import com.lambda.interaction.rotation.Rotation -import com.lambda.interaction.visibilty.VisibilityChecker.lookAtBlock +import com.lambda.interaction.visibilty.VisibilityChecker.findRotation import com.lambda.module.Module +import com.lambda.module.modules.client.TaskFlow import com.lambda.module.tag.ModuleTag import com.lambda.util.math.MathUtils.lerp import net.minecraft.block.BlockState @@ -31,7 +32,6 @@ import net.minecraft.util.math.Box import net.minecraft.util.math.Direction import net.minecraft.util.math.Vec3d import java.awt.Color -import kotlin.math.exp object PacketMine : Module( name = "Packet Mine", @@ -43,11 +43,12 @@ object PacketMine : Module( private val breakThreshold by setting("Break Threshold", 0.7f, 0.0f..1.0f, 0.1f, "Breaks the selected block once the block breaking progress passes this value, 1 being 100%", visibility = { page == Page.General}) private val range by setting("Range", 6, 3..6, 1, "The maximum distance between the players eye position and the center of the block", visibility = { page == Page.General }) private val pauseWhileUsingItems by setting("Pause While Using Items", true, "Will prevent breaking while using items like eating or aiming a bow", visibility = { page == Page.General }) - private val rotate by setting("Rotate", false, "Rotates the player to look at the current mining block", visibility = { page == Page.General }) - private val autoSwap by setting("Auto Force Swap", false, "Hard swaps to the best tool rather than silent swapping. This is often used on servers with a stricter anti-cheat system", visibility = { page == Page.General}) + private val autoSwap by setting("Auto Swap", SwapMode.Silent, "Changes the swap method used. For example, silent swaps once at the beginning, and once at the end without updating client side, and constant swaps for the whole break", visibility = { page == Page.General}) + private val rotate by setting("Rotation Mode", RotationMode.None, "Changes the method used to make the player look at the current mining block", visibility = { page == Page.General }) + private val rotateReleaseDelay by setting("Rotation Release Delay", 2, 0..50, 1, "The number of ticks to wait before releasing the rotation", visibility = { page == Page.General && rotate.isEnabled() }) + private val packets by setting("Packets", PacketMode.Vanilla, "Chooses different packets to send for each mode", visibility = { page == Page.General }) private val validateBreak by setting("Validate Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) private val timeoutDelay by setting("Timeout Delay", 0.20f, 0.00f..1.00f, 0.1f, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && validateBreak }) - private val alternativePackets by setting("Alternative Packets", false, "Uses a different set of packets which tend to work better on servers using an anti-cheat like grim", visibility = { page == Page.General }) private val queueBlocks by setting("Queue Blocks", false, "Queues any blocks you click for breaking", visibility = { page == Page.Queue }).apply { this.onValueSet { _, to -> if (!to) blockQueue.clear() } } private val reverseQueueOrder by setting("Reverse Queue Order", false, "Breaks the latest addition to the queue first", visibility = { page == Page.Queue && queueBlocks}) @@ -75,10 +76,43 @@ object PacketMine : Module( General, Queue, ReBreak, Render } + private enum class PacketMode { + Vanilla, Grim, NCP + } + + private enum class RotationMode { + None, Constant, StartAndEnd; + + fun isEnabled() = + this != None + + fun isConstant() = + this == Constant + + fun isStartAndEnd() = + this == StartAndEnd + } + + private enum class SwapMode { + None, Silent, Constant, StartAndEnd; + + fun isEnabled() = + this != None + + fun isSilent() = + this == Silent + + fun isConstant() = + this == Constant + + fun isStartAndEnd() = + this == StartAndEnd + } + private enum class RenderMode { Out, In, InOut, OutIn, Static, None; - fun isEnabled(): Boolean = + fun isEnabled() = this != None } @@ -95,39 +129,74 @@ object PacketMine : Module( } private var currentMiningBlock: BreakingContext? = null + private var lastNonEmptyState: BlockState? = null private val blockQueue = ArrayDeque() private var returnSlot = -1 private var swappedSlot = -1 private var swapped = false private var expectedRotation: Rotation? = null + private var rotationPosition: BlockPos? = null private var pauseForRotation = false + private var releaseRotateDelayCounter = 0 + private var rotated = false + private var waitingToReleaseRotation = false - //ToDo: Make work on CC + //ToDo: Make silent swap work on cc init { listener { + if (rotated && waitingToReleaseRotation) { + if (releaseRotateDelayCounter <= 0) { + waitingToReleaseRotation = false + rotationPosition = null + rotated = false + } else { + releaseRotateDelayCounter-- + } + } + currentMiningBlock?.apply { mineTicks++ - if ((pauseWhileUsingItems && player.isUsingItem) || pauseForRotation) - return@listener - val activeState = world.getBlockState(pos) if (activeState != state) state = activeState val empty = isStateEmpty(activeState) + if (!empty) { + lastNonEmptyState = state + } + lastNonEmptyState?.let { + lastValidBestTool = getBestTool(it, pos) + } + + if (rotate.isEnabled() && rotate.isStartAndEnd()) checkReleaseRotation() + + if ((pauseWhileUsingItems && player.isUsingItem) || pauseForRotation) + return@listener - if (!empty) lastValidBestTool = getBestTool(activeState, pos) + if (swapped) { + when { + player.inventory.selectedSlot != swappedSlot -> { + cancelSwap() + } - if (autoSwap) { - if (player.inventory.selectedSlot != swappedSlot) { - cancelSwap() - } else if (swappedSlot != lastValidBestTool) { - swapTo(lastValidBestTool) + autoSwap.isConstant() -> { + if (swappedSlot != lastValidBestTool) { + swapTo(lastValidBestTool) + } + } + + autoSwap.isStartAndEnd() -> { + swapToReturnSlot() + } } } - currentBreakDelta = calcBreakDelta(state, pos, lastValidBestTool) + currentBreakDelta = if (autoSwap.isEnabled()) { + calcBreakDelta(state, pos, lastValidBestTool) + } else { + calcBreakDelta(state, pos, player.inventory.selectedSlot) + } if (renderMode.isEnabled()) updateRenders(currentBreakDelta) @@ -146,13 +215,19 @@ object PacketMine : Module( timeCompleted = System.currentTimeMillis() - if (autoSwap) { - if (!swapped) { - swapTo(lastValidBestTool) + if (rotate.isEnabled() && !rotated) rotateTo(pos) + + if (autoSwap.isEnabled()) { + if (autoSwap.isConstant() || autoSwap.isStartAndEnd()) { + if (!swapped) { + swapTo(lastValidBestTool) + } + packetStopBreak(pos) + } else { + swapStopBreak(pos, lastValidBestTool) } - stopBreak(pos) } else { - swapStopBreak(pos, lastValidBestTool) + packetStopBreak(pos) } if (validateBreak) { @@ -174,7 +249,8 @@ object PacketMine : Module( } if (miningProgress < breakThreshold) { - if (autoSwap) swapTo(lastValidBestTool) + if (autoSwap.isConstant()) swapTo(lastValidBestTool) + if (rotate.isConstant()) rotateTo(pos) breakState = BreakState.Breaking return@listener } @@ -183,14 +259,24 @@ object PacketMine : Module( return@listener } - if (autoSwap) { - if (!swapped) { - swapTo(lastValidBestTool) + if (rotate.isEnabled() && !rotated) rotateTo(pos) + + if (autoSwap.isEnabled()) { + if (autoSwap.isConstant() || autoSwap.isStartAndEnd()) { + if (!swapped) { + swapTo(lastValidBestTool) + } + packetStopBreak(pos) + } else { + swapStopBreak(pos, lastValidBestTool) } - stopBreak(pos) - if ((!validateBreak || empty) && swapped) swapToReturnSlot() } else { - swapStopBreak(pos, lastValidBestTool) + packetStopBreak(pos) + } + + if (!validateBreak || empty) { + if (swapped) swapToReturnSlot() + checkReleaseRotation() } checkClientBreak(false, pos) @@ -227,9 +313,7 @@ object PacketMine : Module( listener { currentMiningBlock?.apply { - if (it.pos != pos - || !isStateBroken(state, it.state) - ) { + if (it.pos != pos || !isStateBroken(state, it.state)) { return@listener } @@ -239,6 +323,7 @@ object PacketMine : Module( if (swapped) { swapToReturnSlot() } + checkReleaseRotation() return@listener } @@ -247,16 +332,25 @@ object PacketMine : Module( } listener { - if (!rotate) return@listener - - currentMiningBlock?.apply { - val rotationContext = lookAtBlock(pos) - it.context = rotationContext - expectedRotation = rotationContext?.rotation + if (!rotate.isEnabled()) return@listener + + lastNonEmptyState?.let { state -> + rotationPosition?.let { pos -> + val boxList = state.getOutlineShape(world, pos).boundingBoxes.map { it.offset(pos) } + val rotationContext = findRotation(boxList, TaskFlow.rotation, TaskFlow.interact, emptySet(), verify = { true }) + rotationContext?.let { context -> + it.context = context + expectedRotation = context.rotation + } + } ?: run { + expectedRotation = null + } } } listener { + if (!rotate.isEnabled()) return@listener + expectedRotation?.apply { if (it.context.rotation != expectedRotation) pauseForRotation = true @@ -280,50 +374,77 @@ object PacketMine : Module( val state = world.getBlockState(pos) val bestTool = getBestTool(state, pos) + lastNonEmptyState = state + val breakDelta = calcBreakDelta(world.getBlockState(pos), pos, bestTool) - if (autoSwap) { - swapTo(bestTool) - } else { - silentSwapTo(bestTool) + if (rotate.isEnabled()) rotateTo(pos) + + if (autoSwap.isEnabled()) { + if (autoSwap.isConstant() || autoSwap.isStartAndEnd()) { + swapTo(bestTool) + } else { + silentSwapTo(bestTool) + } } + startBreak(pos) - if (alternativePackets) { + if (packets != PacketMode.Vanilla) { abortBreak(pos) - stopBreak(pos) + } + if (packets == PacketMode.Grim) { + packetStopBreak(pos) } if (breakDelta < breakThreshold) { if (!swapped) silentSwapTo(player.inventory.selectedSlot) - currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking, breakDelta) + currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking, breakDelta, bestTool) return } - stopBreak(pos) + packetStopBreak(pos) if (!swapped) silentSwapTo(player.inventory.selectedSlot) currentMiningBlock = if (reBreak) { - BreakingContext(pos, state, BreakState.ReBreaking, breakDelta) + BreakingContext(pos, state, BreakState.ReBreaking, breakDelta, bestTool) } else { if (!validateBreak) { null } else { - BreakingContext(pos, state, BreakState.AwaitingResponse, breakDelta) + BreakingContext(pos, state, BreakState.AwaitingResponse, breakDelta, bestTool) } } currentMiningBlock?.apply { timeCompleted = System.currentTimeMillis() - lastValidBestTool = bestTool - if (!validateBreak && swapped) { - swapToReturnSlot() + if (!validateBreak) { + if (swapped) swapToReturnSlot() + checkReleaseRotation() } } checkClientBreak(false, pos) } + private fun rotateTo(pos: BlockPos) { + waitingToReleaseRotation = false + releaseRotateDelayCounter = rotateReleaseDelay + rotationPosition = pos + rotated = true + } + + private fun checkReleaseRotation() { + if (!rotated || waitingToReleaseRotation) return + + if (releaseRotateDelayCounter <= 0) { + rotationPosition = null + rotated = false + } else { + waitingToReleaseRotation = true + } + } + private fun SafeContext.swapToReturnSlot() { if (!swapped || returnSlot == -1) return @@ -368,6 +489,7 @@ object PacketMine : Module( if (reBreak && !isOutOfRange()) { if (swapped) swapToReturnSlot() + checkReleaseRotation() breakState = BreakState.ReBreaking return } @@ -382,6 +504,7 @@ object PacketMine : Module( } if (swapped) swapToReturnSlot() + checkReleaseRotation() currentMiningBlock = null } @@ -482,13 +605,13 @@ object PacketMine : Module( val pos: BlockPos, var state: BlockState, var breakState: BreakState, - var currentBreakDelta: Float + var currentBreakDelta: Float, + var lastValidBestTool: Int ) { val renderer = DynamicESP var mineTicks = 0 var timeCompleted: Long = -1 var previousBreakDelta = 0f - var lastValidBestTool = -1 var boxList = if (renderMode.isEnabled()) { state.getOutlineShape(mc.world, pos).boundingBoxes.toSet() @@ -543,10 +666,20 @@ object PacketMine : Module( private fun SafeContext.swapStopBreak(pos: BlockPos, toolSlot: Int) { connection.sendPacket(UpdateSelectedSlotC2SPacket(toolSlot)) - stopBreak(pos) + packetStopBreak(pos) connection.sendPacket(UpdateSelectedSlotC2SPacket(player.inventory.selectedSlot)) } + private fun SafeContext.packetStopBreak(pos: BlockPos) { + stopBreak(pos) + //ToDo: Try and improve these packets + if (packets == PacketMode.NCP) { + abortBreak(pos) + startBreak(pos) + stopBreak(pos) + } + } + //ToDo: Get the correct sequence number for the packets private fun SafeContext.startBreak(pos: BlockPos) { connection.sendPacket(PlayerActionC2SPacket(Action.START_DESTROY_BLOCK, pos, Direction.UP, 0)) } From fbf6a2688ebbf1c17e37c8201e666191d950c909 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Thu, 11 Jul 2024 18:40:45 +0100 Subject: [PATCH 48/91] - lots of refactoring. There are now handlers for rotations and auto swap which work based on the different progress stages --- .../module/modules/player/PacketMine.kt | 448 ++++++++++-------- 1 file changed, 252 insertions(+), 196 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 5a27fdaf4..6df9acd65 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -14,6 +14,7 @@ import com.lambda.module.Module import com.lambda.module.modules.client.TaskFlow import com.lambda.module.tag.ModuleTag import com.lambda.util.math.MathUtils.lerp +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap import net.minecraft.block.BlockState import net.minecraft.enchantment.EnchantmentHelper import net.minecraft.enchantment.Enchantments @@ -21,10 +22,12 @@ import net.minecraft.entity.effect.StatusEffectUtil import net.minecraft.entity.effect.StatusEffects import net.minecraft.fluid.WaterFluid import net.minecraft.item.ItemStack +import net.minecraft.network.packet.c2s.play.ClickSlotC2SPacket import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket import net.minecraft.registry.tag.FluidTags +import net.minecraft.screen.slot.SlotActionType import net.minecraft.state.property.Properties import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos @@ -43,7 +46,7 @@ object PacketMine : Module( private val breakThreshold by setting("Break Threshold", 0.7f, 0.0f..1.0f, 0.1f, "Breaks the selected block once the block breaking progress passes this value, 1 being 100%", visibility = { page == Page.General}) private val range by setting("Range", 6, 3..6, 1, "The maximum distance between the players eye position and the center of the block", visibility = { page == Page.General }) private val pauseWhileUsingItems by setting("Pause While Using Items", true, "Will prevent breaking while using items like eating or aiming a bow", visibility = { page == Page.General }) - private val autoSwap by setting("Auto Swap", SwapMode.Silent, "Changes the swap method used. For example, silent swaps once at the beginning, and once at the end without updating client side, and constant swaps for the whole break", visibility = { page == Page.General}) + private val autoSwap by setting("Auto Swap", SwapMode.StandardSilent, "Changes the swap method used. For example, silent swaps once at the beginning, and once at the end without updating client side, and constant swaps for the whole break", visibility = { page == Page.General}) private val rotate by setting("Rotation Mode", RotationMode.None, "Changes the method used to make the player look at the current mining block", visibility = { page == Page.General }) private val rotateReleaseDelay by setting("Rotation Release Delay", 2, 0..50, 1, "The number of ticks to wait before releasing the rotation", visibility = { page == Page.General && rotate.isEnabled() }) private val packets by setting("Packets", PacketMode.Vanilla, "Chooses different packets to send for each mode", visibility = { page == Page.General }) @@ -94,13 +97,19 @@ object PacketMine : Module( } private enum class SwapMode { - None, Silent, Constant, StartAndEnd; + None, StandardSilent, NCPSilent, Constant, StartAndEnd; fun isEnabled() = this != None fun isSilent() = - this == Silent + this == StandardSilent || this == NCPSilent + + fun isStandardSilent() = + this == StandardSilent + + fun isNCPSilent() = + this == NCPSilent fun isConstant() = this == Constant @@ -109,6 +118,10 @@ object PacketMine : Module( this == StartAndEnd } + private enum class ProgressStage { + StartPre, StartPost, PreTick, During, EndPre, EndPost, PacketReceiveBreak, TimedOut + } + private enum class RenderMode { Out, In, InOut, OutIn, Static, None; @@ -144,6 +157,18 @@ object PacketMine : Module( //ToDo: Make silent swap work on cc init { + listener { + it.cancel() + player.swingHand(Hand.MAIN_HAND) + + if (shouldBePlacedInBlockQueue(it.pos)) { + blockQueue.add(it.pos) + return@listener + } + + startBreaking(it.pos) + } + listener { if (rotated && waitingToReleaseRotation) { if (releaseRotateDelayCounter <= 0) { @@ -162,36 +187,17 @@ object PacketMine : Module( if (activeState != state) state = activeState val empty = isStateEmpty(activeState) - if (!empty) { - lastNonEmptyState = state - } + if (!empty) lastNonEmptyState = state + lastNonEmptyState?.let { lastValidBestTool = getBestTool(it, pos) } - if (rotate.isEnabled() && rotate.isStartAndEnd()) checkReleaseRotation() + runHandlers(ProgressStage.PreTick, pos, lastValidBestTool) if ((pauseWhileUsingItems && player.isUsingItem) || pauseForRotation) return@listener - if (swapped) { - when { - player.inventory.selectedSlot != swappedSlot -> { - cancelSwap() - } - - autoSwap.isConstant() -> { - if (swappedSlot != lastValidBestTool) { - swapTo(lastValidBestTool) - } - } - - autoSwap.isStartAndEnd() -> { - swapToReturnSlot() - } - } - } - currentBreakDelta = if (autoSwap.isEnabled()) { calcBreakDelta(state, pos, lastValidBestTool) } else { @@ -215,18 +221,7 @@ object PacketMine : Module( timeCompleted = System.currentTimeMillis() - if (rotate.isEnabled() && !rotated) rotateTo(pos) - - if (autoSwap.isEnabled()) { - if (autoSwap.isConstant() || autoSwap.isStartAndEnd()) { - if (!swapped) { - swapTo(lastValidBestTool) - } - packetStopBreak(pos) - } else { - swapStopBreak(pos, lastValidBestTool) - } - } else { + runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, lastValidBestTool) { packetStopBreak(pos) } @@ -235,22 +230,12 @@ object PacketMine : Module( return@listener } - interaction.breakBlock(pos) - - onBlockBreak() + onBlockBreak(false) } BreakState.ReBreaking -> { - if (breakNextQueueBlock()) return@listener - - if (!reBreak || isOutOfRange()) { - nullifyCurrentBreakingBlock() - return@listener - } - if (miningProgress < breakThreshold) { - if (autoSwap.isConstant()) swapTo(lastValidBestTool) - if (rotate.isConstant()) rotateTo(pos) + runHandlers(ProgressStage.During, pos, lastValidBestTool) breakState = BreakState.Breaking return@listener } @@ -259,33 +244,17 @@ object PacketMine : Module( return@listener } - if (rotate.isEnabled() && !rotated) rotateTo(pos) - - if (autoSwap.isEnabled()) { - if (autoSwap.isConstant() || autoSwap.isStartAndEnd()) { - if (!swapped) { - swapTo(lastValidBestTool) - } - packetStopBreak(pos) - } else { - swapStopBreak(pos, lastValidBestTool) - } - } else { + runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, lastValidBestTool, empty) { packetStopBreak(pos) } - if (!validateBreak || empty) { - if (swapped) swapToReturnSlot() - checkReleaseRotation() - } - - checkClientBreak(false, pos) + onBlockBreak(false) } BreakState.AwaitingResponse -> { if (!validateBreak) { - checkClientBreak(false, pos) - nullifyCurrentBreakingBlock() + runHandlers(ProgressStage.EndPost, pos, lastValidBestTool) + onBlockBreak(false) return@listener } @@ -293,41 +262,23 @@ object PacketMine : Module( if (breakNextQueueBlock()) return@listener + runHandlers(ProgressStage.TimedOut, pos, lastValidBestTool) + nullifyCurrentBreakingBlock() } } } } - listener { - it.cancel() - player.swingHand(Hand.MAIN_HAND) - - if (shouldBePlacedInBlockQueue(it.pos)) { - blockQueue.add(it.pos) - return@listener - } - - startBreaking(it.pos) - } - listener { currentMiningBlock?.apply { if (it.pos != pos || !isStateBroken(state, it.state)) { return@listener } - checkClientBreak(true, pos) + runHandlers(ProgressStage.PacketReceiveBreak, pos, lastValidBestTool) - if (breakState == BreakState.ReBreaking) { - if (swapped) { - swapToReturnSlot() - } - checkReleaseRotation() - return@listener - } - - onBlockBreak() + onBlockBreak(true) } } @@ -373,58 +324,130 @@ object PacketMine : Module( val state = world.getBlockState(pos) val bestTool = getBestTool(state, pos) - lastNonEmptyState = state val breakDelta = calcBreakDelta(world.getBlockState(pos), pos, bestTool) + val instaBreak = breakDelta >= breakThreshold - if (rotate.isEnabled()) rotateTo(pos) + runBetweenHandlers(ProgressStage.StartPre, ProgressStage.StartPost, pos, bestTool, instaBreak) { + packetStartBreak(pos) - if (autoSwap.isEnabled()) { - if (autoSwap.isConstant() || autoSwap.isStartAndEnd()) { - swapTo(bestTool) - } else { - silentSwapTo(bestTool) + if (!instaBreak) { + currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking, breakDelta, bestTool) + return@runBetweenHandlers } - } - startBreak(pos) - if (packets != PacketMode.Vanilla) { - abortBreak(pos) - } - if (packets == PacketMode.Grim) { packetStopBreak(pos) + + currentMiningBlock = if (reBreak) { + BreakingContext(pos, state, BreakState.ReBreaking, breakDelta, bestTool) + } else { + if (!validateBreak) { + null + } else { + BreakingContext(pos, state, BreakState.AwaitingResponse, breakDelta, bestTool) + } + } + currentMiningBlock?.apply { + timeCompleted = System.currentTimeMillis() + } + + checkClientSideBreak(false, pos) } + } + + private fun SafeContext.runBetweenHandlers( + preStage: ProgressStage, + postStage: ProgressStage, + pos: BlockPos, + bestTool: Int, + empty: Boolean = false, + instaBroken: Boolean = false, + task: Runnable + ) { + runHandlers(preStage, pos, bestTool, empty, instaBroken) + task.run() + runHandlers(postStage, pos, bestTool, empty, instaBroken) + } + + private fun SafeContext.runHandlers( + progressStage: ProgressStage, + pos: BlockPos, + bestTool: Int, + empty: Boolean = false, + instaBroken: Boolean = false + ) { + handleRotations(progressStage, pos, empty, instaBroken) + handleAutoSwap(progressStage, bestTool, empty, instaBroken) + } + + private fun handleRotations(progressStage: ProgressStage, pos: BlockPos, empty: Boolean = false, instaBroken: Boolean = false) { + when (progressStage) { + ProgressStage.PreTick -> if (rotated && rotate.isStartAndEnd()) checkReleaseRotation() - if (breakDelta < breakThreshold) { - if (!swapped) silentSwapTo(player.inventory.selectedSlot) - currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking, breakDelta, bestTool) - return + ProgressStage.StartPre, + ProgressStage.EndPre -> if (rotate.isEnabled() && !rotated) rotateTo(pos) + + ProgressStage.StartPost -> if (instaBroken && !validateBreak) checkReleaseRotation() + + ProgressStage.EndPost -> if (!validateBreak || empty) checkReleaseRotation() + + ProgressStage.During -> if (rotate.isConstant()) rotateTo(pos) + + ProgressStage.PacketReceiveBreak -> if (rotated) checkReleaseRotation() + + ProgressStage.TimedOut -> checkReleaseRotation() } + } - packetStopBreak(pos) - if (!swapped) silentSwapTo(player.inventory.selectedSlot) + private fun SafeContext.handleAutoSwap(progressStage: ProgressStage, bestTool: Int, empty: Boolean = false, instaBroken: Boolean = false) { + if (!autoSwap.isEnabled()) return - currentMiningBlock = if (reBreak) { - BreakingContext(pos, state, BreakState.ReBreaking, breakDelta, bestTool) - } else { - if (!validateBreak) { - null - } else { - BreakingContext(pos, state, BreakState.AwaitingResponse, breakDelta, bestTool) + when (progressStage) { + ProgressStage.PreTick -> { + if (!swapped || autoSwap.isSilent()) return + when { + player.inventory.selectedSlot != swappedSlot -> cancelSwap() + + autoSwap.isConstant() -> { + if (swappedSlot != bestTool) swapTo(bestTool) + } + + autoSwap.isStartAndEnd() -> returnToOriginalSlot() + } } - } - currentMiningBlock?.apply { - timeCompleted = System.currentTimeMillis() + ProgressStage.StartPre, + ProgressStage.EndPre -> { + if (!swapped) swapTo(bestTool) + } + + ProgressStage.StartPost -> { + if (!swapped) return - if (!validateBreak) { - if (swapped) swapToReturnSlot() - checkReleaseRotation() + if ((instaBroken && !validateBreak) + || autoSwap.isSilent() + ) { + returnToOriginalSlot() + } } - } - checkClientBreak(false, pos) + ProgressStage.EndPost -> { + if (!swapped) return + + if ((!validateBreak || empty) + || autoSwap.isSilent() + ) { + returnToOriginalSlot() + } + } + + ProgressStage.During -> if (autoSwap.isConstant()) swapTo(bestTool) + + ProgressStage.PacketReceiveBreak -> if (swapped && !autoSwap.isSilent()) returnToOriginalSlot() + + ProgressStage.TimedOut -> if (swapped) returnToOriginalSlot() + } } private fun rotateTo(pos: BlockPos) { @@ -435,7 +458,7 @@ object PacketMine : Module( } private fun checkReleaseRotation() { - if (!rotated || waitingToReleaseRotation) return + if (waitingToReleaseRotation || !rotated) return if (releaseRotateDelayCounter <= 0) { rotationPosition = null @@ -445,30 +468,61 @@ object PacketMine : Module( } } - private fun SafeContext.swapToReturnSlot() { - if (!swapped || returnSlot == -1) return - - player.inventory.selectedSlot = returnSlot - connection.sendPacket(UpdateSelectedSlotC2SPacket(returnSlot)) - returnSlot = -1 - swappedSlot = -1 - swapped = false - - return - } - private fun SafeContext.swapTo(slot: Int) { if (returnSlot == -1) { returnSlot = player.inventory.selectedSlot } - player.inventory.selectedSlot = slot - connection.sendPacket(UpdateSelectedSlotC2SPacket(slot)) + if (autoSwap.isSilent()) { + silentSwapTo(slot, false) + } else { + player.inventory.selectedSlot = slot + connection.sendPacket(UpdateSelectedSlotC2SPacket(slot)) + } swappedSlot = slot swapped = true } - private fun SafeContext.silentSwapTo(slot: Int) { - connection.sendPacket(UpdateSelectedSlotC2SPacket(slot)) + private fun SafeContext.silentSwapTo(slot: Int, returningToOriginalSlot: Boolean) { + if (autoSwap.isStandardSilent()) { + connection.sendPacket(UpdateSelectedSlotC2SPacket(slot)) + } else { + //ToDo: Make this work + val screenHandler = player.playerScreenHandler + val stack = if (returningToOriginalSlot) { + player.mainHandStack + } else { + player.inventory.getStack(slot) + } + connection.sendPacket(ClickSlotC2SPacket( + screenHandler.syncId, + screenHandler.revision, + player.inventory.selectedSlot, + 0, + SlotActionType.SWAP, + stack, + Int2ObjectOpenHashMap()) + ) + } + } + + private fun SafeContext.returnToOriginalSlot() { + if (!swapped || returnSlot == -1) return + + if (!autoSwap.isSilent()) { + player.inventory.selectedSlot = returnSlot + connection.sendPacket(UpdateSelectedSlotC2SPacket(returnSlot)) + } else { + if (autoSwap.isStandardSilent()) { + connection.sendPacket(UpdateSelectedSlotC2SPacket(returnSlot)) + } else { + silentSwapTo(swappedSlot, true) + } + } + returnSlot = -1 + swappedSlot = -1 + swapped = false + + return } private fun cancelSwap() { @@ -483,14 +537,16 @@ object PacketMine : Module( private fun SafeContext.isOutOfRange(vec: Vec3d) = player.eyePos.distanceTo(vec) > range - private fun SafeContext.onBlockBreak() { + private fun SafeContext.onBlockBreak(packetReceiveBreak: Boolean) { currentMiningBlock?.apply { + checkClientSideBreak(packetReceiveBreak, pos) + if (breakNextQueueBlock()) return if (reBreak && !isOutOfRange()) { - if (swapped) swapToReturnSlot() - checkReleaseRotation() - breakState = BreakState.ReBreaking + if (breakState != BreakState.ReBreaking) { + breakState = BreakState.ReBreaking + } return } @@ -503,9 +559,6 @@ object PacketMine : Module( if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, 0) } - if (swapped) swapToReturnSlot() - checkReleaseRotation() - currentMiningBlock = null } @@ -523,13 +576,12 @@ object PacketMine : Module( && !state.fluidState.isEmpty ) - private fun SafeContext.checkClientBreak(packetReceiveBreak: Boolean, pos: BlockPos) { - if (packetReceiveBreak == validateBreak) { - interaction.breakBlock(pos) - } + private fun SafeContext.checkClientSideBreak(packetReceiveBreak: Boolean, pos: BlockPos) { + if (packetReceiveBreak == validateBreak) interaction.breakBlock(pos) } - private fun shouldBePlacedInBlockQueue(pos: BlockPos): Boolean = queueBlocks + private fun shouldBePlacedInBlockQueue(pos: BlockPos): Boolean = + queueBlocks && currentMiningBlock != null && currentMiningBlock?.breakState != BreakState.ReBreaking && currentMiningBlock?.pos != pos @@ -568,39 +620,6 @@ object PacketMine : Module( } } - private fun getLerpBox(box: Box, factor: Float): Box { - val boxCenter = Box(box.center, box.center) - when (renderMode) { - RenderMode.Out -> { - return lerp(boxCenter, box, factor.toDouble()) - } - - RenderMode.In -> { - return lerp(box, boxCenter, factor.toDouble()) - } - - RenderMode.InOut -> { - return if (factor >= 0.5f) { - lerp(boxCenter, box, (factor.toDouble() - 0.5) * 2) - } else { - lerp(box, boxCenter, factor.toDouble() * 2) - } - } - - RenderMode.OutIn -> { - return if (factor >= 0.5f) { - lerp(box, boxCenter, (factor.toDouble() - 0.5) * 2) - } else { - lerp(boxCenter, box, factor.toDouble() * 2) - } - } - - else -> { - return box - } - } - } - private data class BreakingContext( val pos: BlockPos, var state: BlockState, @@ -662,34 +681,71 @@ object PacketMine : Module( } } } + + private fun getLerpBox(box: Box, factor: Float): Box { + val boxCenter = Box(box.center, box.center) + when (renderMode) { + RenderMode.Out -> { + return lerp(boxCenter, box, factor.toDouble()) + } + + RenderMode.In -> { + return lerp(box, boxCenter, factor.toDouble()) + } + + RenderMode.InOut -> { + return if (factor >= 0.5f) { + lerp(boxCenter, box, (factor.toDouble() - 0.5) * 2) + } else { + lerp(box, boxCenter, factor.toDouble() * 2) + } + } + + RenderMode.OutIn -> { + return if (factor >= 0.5f) { + lerp(box, boxCenter, (factor.toDouble() - 0.5) * 2) + } else { + lerp(boxCenter, box, factor.toDouble() * 2) + } + } + + else -> { + return box + } + } + } } - private fun SafeContext.swapStopBreak(pos: BlockPos, toolSlot: Int) { - connection.sendPacket(UpdateSelectedSlotC2SPacket(toolSlot)) - packetStopBreak(pos) - connection.sendPacket(UpdateSelectedSlotC2SPacket(player.inventory.selectedSlot)) + private fun SafeContext.packetStartBreak(pos: BlockPos) { + startBreak(pos) + if (packets != PacketMode.Vanilla) { + abortBreak(pos) + } + if (packets == PacketMode.Grim) { + packetStopBreak(pos) + } } private fun SafeContext.packetStopBreak(pos: BlockPos) { stopBreak(pos) - //ToDo: Try and improve these packets + //ToDo: maybe improve these packets? Idk what the best ones are for ncp if (packets == PacketMode.NCP) { abortBreak(pos) startBreak(pos) stopBreak(pos) } } - //ToDo: Get the correct sequence number for the packets + private fun SafeContext.startBreak(pos: BlockPos) { - connection.sendPacket(PlayerActionC2SPacket(Action.START_DESTROY_BLOCK, pos, Direction.UP, 0)) + connection.sendPacket(PlayerActionC2SPacket(Action.START_DESTROY_BLOCK, pos, Direction.UP)) } private fun SafeContext.stopBreak(pos: BlockPos) { - connection.sendPacket(PlayerActionC2SPacket(Action.STOP_DESTROY_BLOCK, pos, Direction.UP, 0)) + connection.sendPacket(PlayerActionC2SPacket(Action.STOP_DESTROY_BLOCK, pos, Direction.UP)) } private fun SafeContext.abortBreak(pos: BlockPos) { - connection.sendPacket(PlayerActionC2SPacket(Action.ABORT_DESTROY_BLOCK, pos, Direction.UP, 0)) + connection.sendPacket(PlayerActionC2SPacket(Action.ABORT_DESTROY_BLOCK, pos, Direction.UP)) } //Todo: Replace with task system From 13d460ea57cb185f08ba7f7be769b31bdcaca75d Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 12 Jul 2024 03:12:46 +0100 Subject: [PATCH 49/91] - fixed NCPSilent --- .../module/modules/player/PacketMine.kt | 43 +++++++++---------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 6df9acd65..78bbdce78 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -14,7 +14,7 @@ import com.lambda.module.Module import com.lambda.module.modules.client.TaskFlow import com.lambda.module.tag.ModuleTag import com.lambda.util.math.MathUtils.lerp -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap +import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap import net.minecraft.block.BlockState import net.minecraft.enchantment.EnchantmentHelper import net.minecraft.enchantment.Enchantments @@ -154,8 +154,6 @@ object PacketMine : Module( private var rotated = false private var waitingToReleaseRotation = false - //ToDo: Make silent swap work on cc - init { listener { it.cancel() @@ -486,21 +484,25 @@ object PacketMine : Module( if (autoSwap.isStandardSilent()) { connection.sendPacket(UpdateSelectedSlotC2SPacket(slot)) } else { - //ToDo: Make this work val screenHandler = player.playerScreenHandler - val stack = if (returningToOriginalSlot) { - player.mainHandStack - } else { - player.inventory.getStack(slot) + var itemStack = player.mainHandStack + var newSlot = slot + + if (returningToOriginalSlot) { + newSlot = swappedSlot + itemStack = player.inventory.getStack(swappedSlot) } - connection.sendPacket(ClickSlotC2SPacket( - screenHandler.syncId, - screenHandler.revision, - player.inventory.selectedSlot, - 0, - SlotActionType.SWAP, - stack, - Int2ObjectOpenHashMap()) + + connection.sendPacket( + ClickSlotC2SPacket( + screenHandler.syncId, + screenHandler.revision, + newSlot + 36, + player.inventory.selectedSlot, + SlotActionType.SWAP, + itemStack, + Int2ObjectArrayMap() + ) ) } } @@ -512,11 +514,7 @@ object PacketMine : Module( player.inventory.selectedSlot = returnSlot connection.sendPacket(UpdateSelectedSlotC2SPacket(returnSlot)) } else { - if (autoSwap.isStandardSilent()) { - connection.sendPacket(UpdateSelectedSlotC2SPacket(returnSlot)) - } else { - silentSwapTo(swappedSlot, true) - } + silentSwapTo(returnSlot, true) } returnSlot = -1 swappedSlot = -1 @@ -556,7 +554,7 @@ object PacketMine : Module( private fun SafeContext.nullifyCurrentBreakingBlock() { currentMiningBlock?.apply { - if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, 0) + if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, -1) } currentMiningBlock = null @@ -728,7 +726,6 @@ object PacketMine : Module( private fun SafeContext.packetStopBreak(pos: BlockPos) { stopBreak(pos) - //ToDo: maybe improve these packets? Idk what the best ones are for ncp if (packets == PacketMode.NCP) { abortBreak(pos) startBreak(pos) From fd4238e6ba678c24f32086eed7c337ac8fdd9218 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 12 Jul 2024 05:30:13 +0100 Subject: [PATCH 50/91] - added re-break delay options --- .../module/modules/player/PacketMine.kt | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 78bbdce78..ecbce340c 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -57,7 +57,9 @@ object PacketMine : Module( private val reverseQueueOrder by setting("Reverse Queue Order", false, "Breaks the latest addition to the queue first", visibility = { page == Page.Queue && queueBlocks}) private val reBreak by setting("Re-Break", true, "Automatically re-breaks the last mined block if it gets replaced", visibility = { page == Page.ReBreak}) + private val reBreakDelay by setting("Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-breaking the block", visibility = { page == Page.ReBreak && reBreak }) private val fastReBreak by setting("Fast Re-Break", false, "Re-breaks blocks instantly however could potentially cause ghost blocks", visibility = { page == Page.ReBreak && reBreak }) + private val emptyReBreakDelay by setting("Empty Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-break the block if the block is currently empty", visibility = { page == Page.ReBreak && reBreak && fastReBreak}) private val breakingAnimation by setting("Breaking Animation", false, "Renders the block breaking animation like vanilla would to show progress", visibility = { page == Page.Render }) @@ -151,6 +153,8 @@ object PacketMine : Module( private var rotationPosition: BlockPos? = null private var pauseForRotation = false private var releaseRotateDelayCounter = 0 + private var reBreakDelayCounter = 0 + private var emptyReBreakDelayCounter = 0 private var rotated = false private var waitingToReleaseRotation = false @@ -169,14 +173,20 @@ object PacketMine : Module( listener { if (rotated && waitingToReleaseRotation) { + releaseRotateDelayCounter-- + if (releaseRotateDelayCounter <= 0) { waitingToReleaseRotation = false rotationPosition = null rotated = false - } else { - releaseRotateDelayCounter-- } } + if (reBreakDelayCounter > 0) { + reBreakDelayCounter-- + } + if (emptyReBreakDelayCounter > 0) { + emptyReBreakDelayCounter-- + } currentMiningBlock?.apply { mineTicks++ @@ -238,6 +248,14 @@ object PacketMine : Module( return@listener } + if (empty) { + if (emptyReBreakDelayCounter > 0) return@listener + emptyReBreakDelayCounter = emptyReBreakDelay + } else { + if (reBreakDelayCounter > 0) return@listener + reBreakDelayCounter = reBreakDelay + } + if (!fastReBreak && empty) { return@listener } From 4eb5e96baf9edb55632b556ae010b4769f56abe6 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 12 Jul 2024 06:47:39 +0100 Subject: [PATCH 51/91] - refactored re-break mode settings and added standard for manual re-break --- .../module/modules/player/PacketMine.kt | 67 +++++++++++++++---- 1 file changed, 55 insertions(+), 12 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index ecbce340c..8714a87e9 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -56,10 +56,9 @@ object PacketMine : Module( private val queueBlocks by setting("Queue Blocks", false, "Queues any blocks you click for breaking", visibility = { page == Page.Queue }).apply { this.onValueSet { _, to -> if (!to) blockQueue.clear() } } private val reverseQueueOrder by setting("Reverse Queue Order", false, "Breaks the latest addition to the queue first", visibility = { page == Page.Queue && queueBlocks}) - private val reBreak by setting("Re-Break", true, "Automatically re-breaks the last mined block if it gets replaced", visibility = { page == Page.ReBreak}) - private val reBreakDelay by setting("Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-breaking the block", visibility = { page == Page.ReBreak && reBreak }) - private val fastReBreak by setting("Fast Re-Break", false, "Re-breaks blocks instantly however could potentially cause ghost blocks", visibility = { page == Page.ReBreak && reBreak }) - private val emptyReBreakDelay by setting("Empty Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-break the block if the block is currently empty", visibility = { page == Page.ReBreak && reBreak && fastReBreak}) + private val reBreak by setting("Re-Break", ReBreakMode.Standard, "The different modes for re-breaking the current block", visibility = { page == Page.ReBreak}) + private val reBreakDelay by setting("Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-breaking the block", visibility = { page == Page.ReBreak && (reBreak.isAutomatic() || reBreak.isFastAutomatic()) }) + private val emptyReBreakDelay by setting("Empty Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-break the block if the block is currently empty", visibility = { page == Page.ReBreak && reBreak.isFastAutomatic()}) private val breakingAnimation by setting("Breaking Animation", false, "Renders the block breaking animation like vanilla would to show progress", visibility = { page == Page.Render }) @@ -120,12 +119,28 @@ object PacketMine : Module( this == StartAndEnd } + private enum class ReBreakMode { + None, Standard, Automatic, FastAutomatic; + + fun isEnabled() = + this != None + + fun isStandard() = + this == Standard + + fun isAutomatic() = + this == Automatic + + fun isFastAutomatic() = + this == FastAutomatic + } + private enum class ProgressStage { StartPre, StartPost, PreTick, During, EndPre, EndPost, PacketReceiveBreak, TimedOut } private enum class RenderMode { - Out, In, InOut, OutIn, Static, None; + None, Out, In, InOut, OutIn, Static; fun isEnabled() = this != None @@ -163,6 +178,23 @@ object PacketMine : Module( it.cancel() player.swingHand(Hand.MAIN_HAND) + currentMiningBlock?.apply { + if (it.pos == pos && breakState == BreakState.ReBreaking && reBreak.isStandard()) { + if (!reBreak.isEnabled()) { + nullifyCurrentBreakingBlock() + return@listener + } + + runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, lastValidBestTool) { + packetStopBreak(pos) + } + + onBlockBreak(false) + + return@listener + } + } + if (shouldBePlacedInBlockQueue(it.pos)) { blockQueue.add(it.pos) return@listener @@ -248,6 +280,8 @@ object PacketMine : Module( return@listener } + if (reBreak.isStandard()) return@listener + if (empty) { if (emptyReBreakDelayCounter > 0) return@listener emptyReBreakDelayCounter = emptyReBreakDelay @@ -256,7 +290,12 @@ object PacketMine : Module( reBreakDelayCounter = reBreakDelay } - if (!fastReBreak && empty) { + if (isOutOfRange() || !reBreak.isEnabled()) { + nullifyCurrentBreakingBlock() + return@listener + } + + if (!reBreak.isFastAutomatic() && empty) { return@listener } @@ -355,7 +394,7 @@ object PacketMine : Module( packetStopBreak(pos) - currentMiningBlock = if (reBreak) { + currentMiningBlock = if (reBreak.isEnabled()) { BreakingContext(pos, state, BreakState.ReBreaking, breakDelta, bestTool) } else { if (!validateBreak) { @@ -557,13 +596,17 @@ object PacketMine : Module( currentMiningBlock?.apply { checkClientSideBreak(packetReceiveBreak, pos) - if (breakNextQueueBlock()) return + if (breakState == BreakState.ReBreaking) { + if (reBreak.isEnabled()) return + } else { + if (breakNextQueueBlock()) return - if (reBreak && !isOutOfRange()) { - if (breakState != BreakState.ReBreaking) { - breakState = BreakState.ReBreaking + if (reBreak.isEnabled() && !isOutOfRange()) { + if (breakState != BreakState.ReBreaking) { + breakState = BreakState.ReBreaking + } + return } - return } nullifyCurrentBreakingBlock() From 4407574a0272597a7e23a3307804b42a0b8ddce1 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 12 Jul 2024 07:14:04 +0100 Subject: [PATCH 52/91] - break threshold increments in 0.01 --- .../module/modules/player/PacketMine.kt | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 8714a87e9..9f1950c27 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -43,7 +43,7 @@ object PacketMine : Module( ) { private val page by setting("Page", Page.General) - private val breakThreshold by setting("Break Threshold", 0.7f, 0.0f..1.0f, 0.1f, "Breaks the selected block once the block breaking progress passes this value, 1 being 100%", visibility = { page == Page.General}) + private val breakThreshold by setting("Break Threshold", 0.70f, 0.00f..1.00f, 0.01f, "Breaks the selected block once the block breaking progress passes this value, 1 being 100%", visibility = { page == Page.General}) private val range by setting("Range", 6, 3..6, 1, "The maximum distance between the players eye position and the center of the block", visibility = { page == Page.General }) private val pauseWhileUsingItems by setting("Pause While Using Items", true, "Will prevent breaking while using items like eating or aiming a bow", visibility = { page == Page.General }) private val autoSwap by setting("Auto Swap", SwapMode.StandardSilent, "Changes the swap method used. For example, silent swaps once at the beginning, and once at the end without updating client side, and constant swaps for the whole break", visibility = { page == Page.General}) @@ -179,20 +179,19 @@ object PacketMine : Module( player.swingHand(Hand.MAIN_HAND) currentMiningBlock?.apply { - if (it.pos == pos && breakState == BreakState.ReBreaking && reBreak.isStandard()) { - if (!reBreak.isEnabled()) { - nullifyCurrentBreakingBlock() - return@listener - } - - runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, lastValidBestTool) { - packetStopBreak(pos) - } - - onBlockBreak(false) + if (it.pos != pos || breakState != BreakState.ReBreaking || !reBreak.isStandard()) return@apply + if (!reBreak.isEnabled()) { + nullifyCurrentBreakingBlock() return@listener } + + runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, lastValidBestTool) { + packetStopBreak(pos) + } + + onBlockBreak(false) + return@listener } if (shouldBePlacedInBlockQueue(it.pos)) { From 91ad46b2739ef07b8acdcb4503fe4b7a7ded3651 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 12 Jul 2024 07:47:05 +0100 Subject: [PATCH 53/91] - added queue block break delay --- .../module/modules/player/PacketMine.kt | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 9f1950c27..e84ab991f 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -55,6 +55,7 @@ object PacketMine : Module( private val queueBlocks by setting("Queue Blocks", false, "Queues any blocks you click for breaking", visibility = { page == Page.Queue }).apply { this.onValueSet { _, to -> if (!to) blockQueue.clear() } } private val reverseQueueOrder by setting("Reverse Queue Order", false, "Breaks the latest addition to the queue first", visibility = { page == Page.Queue && queueBlocks}) + private val queueBreakDelay by setting("Break Delay", 0, 0..5, 1, "The delay (in ticks) after breaking a block to break the next queue block", visibility = { page == Page.Queue && queueBlocks }) private val reBreak by setting("Re-Break", ReBreakMode.Standard, "The different modes for re-breaking the current block", visibility = { page == Page.ReBreak}) private val reBreakDelay by setting("Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-breaking the block", visibility = { page == Page.ReBreak && (reBreak.isAutomatic() || reBreak.isFastAutomatic()) }) @@ -161,6 +162,8 @@ object PacketMine : Module( private var currentMiningBlock: BreakingContext? = null private var lastNonEmptyState: BlockState? = null private val blockQueue = ArrayDeque() + private var queueBreakStartCounter = 0 + private var awaitingQueueBreakStartPos: BlockPos? = null private var returnSlot = -1 private var swappedSlot = -1 private var swapped = false @@ -218,6 +221,25 @@ object PacketMine : Module( if (emptyReBreakDelayCounter > 0) { emptyReBreakDelayCounter-- } + if (queueBreakStartCounter > 0) { + queueBreakStartCounter-- + } + + awaitingQueueBreakStartPos?.apply { + if (queueBreakStartCounter <= 0) { + if (isOutOfRange(this.toCenterPos())) { + if (breakNextQueueBlock()) return@listener + awaitingQueueBreakStartPos = null + return@apply + } + + blockQueue.remove(this) + startBreaking(this) + awaitingQueueBreakStartPos = null + } else { + return@listener + } + } currentMiningBlock?.apply { mineTicks++ @@ -289,7 +311,7 @@ object PacketMine : Module( reBreakDelayCounter = reBreakDelay } - if (isOutOfRange() || !reBreak.isEnabled()) { + if (isOutOfRange(pos.toCenterPos()) || !reBreak.isEnabled()) { nullifyCurrentBreakingBlock() return@listener } @@ -585,9 +607,6 @@ object PacketMine : Module( swapped = false } - private fun SafeContext.isOutOfRange() = - player.eyePos.distanceTo(currentMiningBlock?.pos?.toCenterPos()) > range - private fun SafeContext.isOutOfRange(vec: Vec3d) = player.eyePos.distanceTo(vec) > range @@ -600,7 +619,7 @@ object PacketMine : Module( } else { if (breakNextQueueBlock()) return - if (reBreak.isEnabled() && !isOutOfRange()) { + if (reBreak.isEnabled() && !isOutOfRange(pos.toCenterPos())) { if (breakState != BreakState.ReBreaking) { breakState = BreakState.ReBreaking } @@ -649,8 +668,13 @@ object PacketMine : Module( if (!queueBlocks) return false filterBlockQueueUntilNextPossible()?.apply { - blockQueue.remove(this) - startBreaking(this) + if (queueBreakDelay <= 0) { + blockQueue.remove(this) + startBreaking(this) + } else { + queueBreakStartCounter = queueBreakDelay + awaitingQueueBreakStartPos = this + } return true } From da1174c65df23d0a675d9a8a0558c40560e5b4ce Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Sat, 13 Jul 2024 01:07:10 +0100 Subject: [PATCH 54/91] - added hand swing and reset breaking progress options for re-break --- .../module/modules/player/PacketMine.kt | 139 +++++++++++------- 1 file changed, 88 insertions(+), 51 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index e84ab991f..cbcc24184 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -46,10 +46,12 @@ object PacketMine : Module( private val breakThreshold by setting("Break Threshold", 0.70f, 0.00f..1.00f, 0.01f, "Breaks the selected block once the block breaking progress passes this value, 1 being 100%", visibility = { page == Page.General}) private val range by setting("Range", 6, 3..6, 1, "The maximum distance between the players eye position and the center of the block", visibility = { page == Page.General }) private val pauseWhileUsingItems by setting("Pause While Using Items", true, "Will prevent breaking while using items like eating or aiming a bow", visibility = { page == Page.General }) - private val autoSwap by setting("Auto Swap", SwapMode.StandardSilent, "Changes the swap method used. For example, silent swaps once at the beginning, and once at the end without updating client side, and constant swaps for the whole break", visibility = { page == Page.General}) + private val swingMode by setting("Swing Mode", SwingMode.None, "Swings the players hand to simulate vanilla breaking, usually used on stricter anticheats", visibility = { page == Page.General }) + private val swingOnManual by setting("Swing On Hit", true, "Swings when the player attacks a block", visibility = { page == Page.General }) private val rotate by setting("Rotation Mode", RotationMode.None, "Changes the method used to make the player look at the current mining block", visibility = { page == Page.General }) private val rotateReleaseDelay by setting("Rotation Release Delay", 2, 0..50, 1, "The number of ticks to wait before releasing the rotation", visibility = { page == Page.General && rotate.isEnabled() }) - private val packets by setting("Packets", PacketMode.Vanilla, "Chooses different packets to send for each mode", visibility = { page == Page.General }) + private val autoSwap by setting("Swap Mode", SwapMode.StandardSilent, "Changes the swap method used. For example, silent swaps once at the beginning, and once at the end without updating client side, and constant swaps for the whole break", visibility = { page == Page.General}) + private val packets by setting("Packet Mode", PacketMode.Vanilla, "Chooses different packets to send for each mode", visibility = { page == Page.General }) private val validateBreak by setting("Validate Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) private val timeoutDelay by setting("Timeout Delay", 0.20f, 0.00f..1.00f, 0.1f, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && validateBreak }) @@ -60,6 +62,7 @@ object PacketMine : Module( private val reBreak by setting("Re-Break", ReBreakMode.Standard, "The different modes for re-breaking the current block", visibility = { page == Page.ReBreak}) private val reBreakDelay by setting("Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-breaking the block", visibility = { page == Page.ReBreak && (reBreak.isAutomatic() || reBreak.isFastAutomatic()) }) private val emptyReBreakDelay by setting("Empty Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-break the block if the block is currently empty", visibility = { page == Page.ReBreak && reBreak.isFastAutomatic()}) + private val resetProgressOnBreak by setting("Reset Progress", false, "Resets the mining progress after breaking a block, mostly used on stricter servers", visibility = { page == Page.ReBreak && reBreak.isEnabled() }) private val breakingAnimation by setting("Breaking Animation", false, "Renders the block breaking animation like vanilla would to show progress", visibility = { page == Page.Render }) @@ -85,6 +88,22 @@ object PacketMine : Module( Vanilla, Grim, NCP } + private enum class SwingMode { + None, Start, Constant, StartAndEnd; + + fun isEnabled() = + this != None + + fun isStart() = + this == Start + + fun isConstant() = + this == Constant + + fun isStartAndEnd() = + this == StartAndEnd + } + private enum class RotationMode { None, Constant, StartAndEnd; @@ -178,17 +197,13 @@ object PacketMine : Module( init { listener { + //ToDo: Sometimes swinging here when shouldnt it.cancel() - player.swingHand(Hand.MAIN_HAND) + if (swingOnManual) swingMainHand() currentMiningBlock?.apply { if (it.pos != pos || breakState != BreakState.ReBreaking || !reBreak.isStandard()) return@apply - if (!reBreak.isEnabled()) { - nullifyCurrentBreakingBlock() - return@listener - } - runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, lastValidBestTool) { packetStopBreak(pos) } @@ -254,7 +269,7 @@ object PacketMine : Module( lastValidBestTool = getBestTool(it, pos) } - runHandlers(ProgressStage.PreTick, pos, lastValidBestTool) + runHandlers(ProgressStage.PreTick, pos, lastValidBestTool, empty) if ((pauseWhileUsingItems && player.isUsingItem) || pauseForRotation) return@listener @@ -282,13 +297,13 @@ object PacketMine : Module( timeCompleted = System.currentTimeMillis() - runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, lastValidBestTool) { - packetStopBreak(pos) + if (hasBeenBrokenOnce && reBreak.isStandard()) { + breakState = BreakState.ReBreaking + return@listener } - if (validateBreak) { - breakState = BreakState.AwaitingResponse - return@listener + runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, lastValidBestTool) { + packetStopBreak(pos) } onBlockBreak(false) @@ -301,7 +316,12 @@ object PacketMine : Module( return@listener } - if (reBreak.isStandard()) return@listener + if (isOutOfRange(pos.toCenterPos()) || !reBreak.isEnabled()) { + nullifyCurrentBreakingBlock() + return@listener + } + + if (breakNextQueueBlock() || reBreak.isStandard()) return@listener if (empty) { if (emptyReBreakDelayCounter > 0) return@listener @@ -311,11 +331,6 @@ object PacketMine : Module( reBreakDelayCounter = reBreakDelay } - if (isOutOfRange(pos.toCenterPos()) || !reBreak.isEnabled()) { - nullifyCurrentBreakingBlock() - return@listener - } - if (!reBreak.isFastAutomatic() && empty) { return@listener } @@ -408,27 +423,13 @@ object PacketMine : Module( runBetweenHandlers(ProgressStage.StartPre, ProgressStage.StartPost, pos, bestTool, instaBreak) { packetStartBreak(pos) - if (!instaBreak) { - currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking, breakDelta, bestTool) - return@runBetweenHandlers - } + currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking, breakDelta, bestTool) - packetStopBreak(pos) + if (!instaBreak) return@runBetweenHandlers - currentMiningBlock = if (reBreak.isEnabled()) { - BreakingContext(pos, state, BreakState.ReBreaking, breakDelta, bestTool) - } else { - if (!validateBreak) { - null - } else { - BreakingContext(pos, state, BreakState.AwaitingResponse, breakDelta, bestTool) - } - } - currentMiningBlock?.apply { - timeCompleted = System.currentTimeMillis() - } + packetStopBreak(pos) - checkClientSideBreak(false, pos) + onBlockBreak(false) } } @@ -455,6 +456,7 @@ object PacketMine : Module( ) { handleRotations(progressStage, pos, empty, instaBroken) handleAutoSwap(progressStage, bestTool, empty, instaBroken) + handleSwing(progressStage) } private fun handleRotations(progressStage: ProgressStage, pos: BlockPos, empty: Boolean = false, instaBroken: Boolean = false) { @@ -464,12 +466,12 @@ object PacketMine : Module( ProgressStage.StartPre, ProgressStage.EndPre -> if (rotate.isEnabled() && !rotated) rotateTo(pos) + ProgressStage.During -> if (rotate.isConstant()) rotateTo(pos) + ProgressStage.StartPost -> if (instaBroken && !validateBreak) checkReleaseRotation() ProgressStage.EndPost -> if (!validateBreak || empty) checkReleaseRotation() - ProgressStage.During -> if (rotate.isConstant()) rotateTo(pos) - ProgressStage.PacketReceiveBreak -> if (rotated) checkReleaseRotation() ProgressStage.TimedOut -> checkReleaseRotation() @@ -498,6 +500,8 @@ object PacketMine : Module( if (!swapped) swapTo(bestTool) } + ProgressStage.During -> if (autoSwap.isConstant()) swapTo(bestTool) + ProgressStage.StartPost -> { if (!swapped) return @@ -518,14 +522,40 @@ object PacketMine : Module( } } - ProgressStage.During -> if (autoSwap.isConstant()) swapTo(bestTool) - ProgressStage.PacketReceiveBreak -> if (swapped && !autoSwap.isSilent()) returnToOriginalSlot() ProgressStage.TimedOut -> if (swapped) returnToOriginalSlot() } } + private fun SafeContext.handleSwing(progressStage: ProgressStage) { + when (progressStage) { + ProgressStage.PreTick -> { + currentMiningBlock?.apply { + if (breakState != BreakState.ReBreaking + && swingMode.isConstant() + ) { + swingMainHand() + } + } + } + + ProgressStage.During -> if (swingMode.isConstant()) swingMainHand() + + ProgressStage.StartPre, + ProgressStage.StartPost -> if (swingMode.isStart() || swingMode.isStartAndEnd()) swingMainHand() + + ProgressStage.EndPre, + ProgressStage.EndPost -> if (swingMode.isStartAndEnd() || swingMode.isConstant()) swingMainHand() + + ProgressStage.PacketReceiveBreak, + ProgressStage.TimedOut -> {} + } + } + + private fun SafeContext.swingMainHand() = + player.swingHand(Hand.MAIN_HAND) + private fun rotateTo(pos: BlockPos) { waitingToReleaseRotation = false releaseRotateDelayCounter = rotateReleaseDelay @@ -614,17 +644,23 @@ object PacketMine : Module( currentMiningBlock?.apply { checkClientSideBreak(packetReceiveBreak, pos) - if (breakState == BreakState.ReBreaking) { - if (reBreak.isEnabled()) return - } else { - if (breakNextQueueBlock()) return + hasBeenBrokenOnce = true + timeCompleted = System.currentTimeMillis() - if (reBreak.isEnabled() && !isOutOfRange(pos.toCenterPos())) { - if (breakState != BreakState.ReBreaking) { - breakState = BreakState.ReBreaking - } - return + if (validateBreak && breakState == BreakState.Breaking) { + breakState = BreakState.AwaitingResponse + return + } + + if (breakNextQueueBlock()) return + + if (reBreak.isEnabled() && !isOutOfRange(pos.toCenterPos())) { + if (breakState != BreakState.ReBreaking) { + breakState = BreakState.ReBreaking } + + if (resetProgressOnBreak) mineTicks = 0 + return } nullifyCurrentBreakingBlock() @@ -712,6 +748,7 @@ object PacketMine : Module( val renderer = DynamicESP var mineTicks = 0 var timeCompleted: Long = -1 + var hasBeenBrokenOnce = false var previousBreakDelta = 0f var boxList = if (renderMode.isEnabled()) { From 08de262c1a51363da805ea0e9f2d0913139ea5a3 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Sat, 13 Jul 2024 02:01:50 +0100 Subject: [PATCH 55/91] - fixed re-break on instamine blocks --- .../main/kotlin/com/lambda/module/modules/player/PacketMine.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index cbcc24184..155238801 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -428,6 +428,7 @@ object PacketMine : Module( if (!instaBreak) return@runBetweenHandlers packetStopBreak(pos) + if (reBreak.isEnabled()) packetStartBreak(pos) onBlockBreak(false) } From 9d8eb254f18a5124465c9b9e668b024f8ee0d325 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 15 Jul 2024 01:40:40 +0100 Subject: [PATCH 56/91] - cleanup --- .../module/modules/player/PacketMine.kt | 77 ++++++++----------- 1 file changed, 34 insertions(+), 43 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 155238801..f246db573 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -46,14 +46,14 @@ object PacketMine : Module( private val breakThreshold by setting("Break Threshold", 0.70f, 0.00f..1.00f, 0.01f, "Breaks the selected block once the block breaking progress passes this value, 1 being 100%", visibility = { page == Page.General}) private val range by setting("Range", 6, 3..6, 1, "The maximum distance between the players eye position and the center of the block", visibility = { page == Page.General }) private val pauseWhileUsingItems by setting("Pause While Using Items", true, "Will prevent breaking while using items like eating or aiming a bow", visibility = { page == Page.General }) + private val validateBreak by setting("Validate Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) + private val timeoutDelay by setting("Timeout Delay", 0.20f, 0.00f..1.00f, 0.1f, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && validateBreak }) private val swingMode by setting("Swing Mode", SwingMode.None, "Swings the players hand to simulate vanilla breaking, usually used on stricter anticheats", visibility = { page == Page.General }) private val swingOnManual by setting("Swing On Hit", true, "Swings when the player attacks a block", visibility = { page == Page.General }) private val rotate by setting("Rotation Mode", RotationMode.None, "Changes the method used to make the player look at the current mining block", visibility = { page == Page.General }) private val rotateReleaseDelay by setting("Rotation Release Delay", 2, 0..50, 1, "The number of ticks to wait before releasing the rotation", visibility = { page == Page.General && rotate.isEnabled() }) private val autoSwap by setting("Swap Mode", SwapMode.StandardSilent, "Changes the swap method used. For example, silent swaps once at the beginning, and once at the end without updating client side, and constant swaps for the whole break", visibility = { page == Page.General}) private val packets by setting("Packet Mode", PacketMode.Vanilla, "Chooses different packets to send for each mode", visibility = { page == Page.General }) - private val validateBreak by setting("Validate Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) - private val timeoutDelay by setting("Timeout Delay", 0.20f, 0.00f..1.00f, 0.1f, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && validateBreak }) private val queueBlocks by setting("Queue Blocks", false, "Queues any blocks you click for breaking", visibility = { page == Page.Queue }).apply { this.onValueSet { _, to -> if (!to) blockQueue.clear() } } private val reverseQueueOrder by setting("Reverse Queue Order", false, "Breaks the latest addition to the queue first", visibility = { page == Page.Queue && queueBlocks}) @@ -221,39 +221,20 @@ object PacketMine : Module( } listener { - if (rotated && waitingToReleaseRotation) { - releaseRotateDelayCounter-- - - if (releaseRotateDelayCounter <= 0) { - waitingToReleaseRotation = false - rotationPosition = null - rotated = false - } - } - if (reBreakDelayCounter > 0) { - reBreakDelayCounter-- - } - if (emptyReBreakDelayCounter > 0) { - emptyReBreakDelayCounter-- - } - if (queueBreakStartCounter > 0) { - queueBreakStartCounter-- - } + updateCounters() awaitingQueueBreakStartPos?.apply { - if (queueBreakStartCounter <= 0) { - if (isOutOfRange(this.toCenterPos())) { - if (breakNextQueueBlock()) return@listener - awaitingQueueBreakStartPos = null - return@apply - } + if (queueBreakStartCounter > 0) return@listener - blockQueue.remove(this) - startBreaking(this) - awaitingQueueBreakStartPos = null - } else { - return@listener + awaitingQueueBreakStartPos = null + + if (isOutOfRange(this.toCenterPos())) { + if (breakNextQueueBlock()) return@listener + return@apply } + + startBreaking(this) + blockQueue.remove(this) } currentMiningBlock?.apply { @@ -297,11 +278,6 @@ object PacketMine : Module( timeCompleted = System.currentTimeMillis() - if (hasBeenBrokenOnce && reBreak.isStandard()) { - breakState = BreakState.ReBreaking - return@listener - } - runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, lastValidBestTool) { packetStopBreak(pos) } @@ -310,11 +286,7 @@ object PacketMine : Module( } BreakState.ReBreaking -> { - if (miningProgress < breakThreshold) { - runHandlers(ProgressStage.During, pos, lastValidBestTool) - breakState = BreakState.Breaking - return@listener - } + if (miningProgress < breakThreshold) return@listener if (isOutOfRange(pos.toCenterPos()) || !reBreak.isEnabled()) { nullifyCurrentBreakingBlock() @@ -557,6 +529,27 @@ object PacketMine : Module( private fun SafeContext.swingMainHand() = player.swingHand(Hand.MAIN_HAND) + private fun updateCounters() { + if (rotated && waitingToReleaseRotation) { + releaseRotateDelayCounter-- + + if (releaseRotateDelayCounter <= 0) { + waitingToReleaseRotation = false + rotationPosition = null + rotated = false + } + } + if (reBreakDelayCounter > 0) { + reBreakDelayCounter-- + } + if (emptyReBreakDelayCounter > 0) { + emptyReBreakDelayCounter-- + } + if (queueBreakStartCounter > 0) { + queueBreakStartCounter-- + } + } + private fun rotateTo(pos: BlockPos) { waitingToReleaseRotation = false releaseRotateDelayCounter = rotateReleaseDelay @@ -645,7 +638,6 @@ object PacketMine : Module( currentMiningBlock?.apply { checkClientSideBreak(packetReceiveBreak, pos) - hasBeenBrokenOnce = true timeCompleted = System.currentTimeMillis() if (validateBreak && breakState == BreakState.Breaking) { @@ -749,7 +741,6 @@ object PacketMine : Module( val renderer = DynamicESP var mineTicks = 0 var timeCompleted: Long = -1 - var hasBeenBrokenOnce = false var previousBreakDelta = 0f var boxList = if (renderMode.isEnabled()) { From 0a98cbb918604bd8e8b6ef9b9048099463404f47 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 15 Jul 2024 02:56:55 +0100 Subject: [PATCH 57/91] - added todo so i dont forget --- .../main/kotlin/com/lambda/module/modules/player/PacketMine.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index f246db573..41d36ee65 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -223,6 +223,7 @@ object PacketMine : Module( listener { updateCounters() + //ToDo: Fix and improve this, idk why i did it this way :/ awaitingQueueBreakStartPos?.apply { if (queueBreakStartCounter > 0) return@listener From 03127853eaba014b069df38dc8f19592a2b50ac4 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 15 Jul 2024 16:59:11 +0100 Subject: [PATCH 58/91] - fixed queue --- .../module/modules/player/PacketMine.kt | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 41d36ee65..f11130a1b 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -182,7 +182,7 @@ object PacketMine : Module( private var lastNonEmptyState: BlockState? = null private val blockQueue = ArrayDeque() private var queueBreakStartCounter = 0 - private var awaitingQueueBreakStartPos: BlockPos? = null + private var awaitingQueueBreak = false private var returnSlot = -1 private var swappedSlot = -1 private var swapped = false @@ -223,19 +223,11 @@ object PacketMine : Module( listener { updateCounters() - //ToDo: Fix and improve this, idk why i did it this way :/ - awaitingQueueBreakStartPos?.apply { + if (awaitingQueueBreak) { if (queueBreakStartCounter > 0) return@listener - awaitingQueueBreakStartPos = null - - if (isOutOfRange(this.toCenterPos())) { - if (breakNextQueueBlock()) return@listener - return@apply - } - - startBreaking(this) - blockQueue.remove(this) + awaitingQueueBreak = false + if (breakNextQueueBlock()) return@listener } currentMiningBlock?.apply { @@ -646,6 +638,7 @@ object PacketMine : Module( return } + queueBreakStartCounter = queueBreakDelay if (breakNextQueueBlock()) return if (reBreak.isEnabled() && !isOutOfRange(pos.toCenterPos())) { @@ -698,12 +691,12 @@ object PacketMine : Module( if (!queueBlocks) return false filterBlockQueueUntilNextPossible()?.apply { - if (queueBreakDelay <= 0) { + if (queueBreakStartCounter <= 0) { blockQueue.remove(this) startBreaking(this) } else { - queueBreakStartCounter = queueBreakDelay - awaitingQueueBreakStartPos = this + currentMiningBlock = null + awaitingQueueBreak = true } return true } From da7116fcbdc6c3922702cf25b87165c01075f340 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 15 Jul 2024 17:14:03 +0100 Subject: [PATCH 59/91] - fixed the None swing mode not working properly --- .../com/lambda/mixin/entity/ClientPlayerEntityMixin.java | 7 +++++++ .../main/kotlin/com/lambda/event/events/EntityEvent.kt | 5 +++++ .../com/lambda/module/modules/player/PacketMine.kt | 9 +++++++++ 3 files changed, 21 insertions(+) diff --git a/common/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java b/common/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java index 1e1ca65da..b31d26257 100644 --- a/common/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java +++ b/common/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java @@ -2,12 +2,14 @@ import com.lambda.Lambda; import com.lambda.event.EventFlow; +import com.lambda.event.events.EntityEvent; import com.lambda.event.events.MovementEvent; import com.lambda.interaction.PlayerPacketManager; import com.lambda.interaction.RotationManager; import net.minecraft.client.input.Input; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.entity.MovementType; +import net.minecraft.util.Hand; import net.minecraft.util.math.Vec3d; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -79,4 +81,9 @@ float fixHeldItemYaw(ClientPlayerEntity instance) { float fixHeldItemPitch(ClientPlayerEntity instance) { return Objects.requireNonNullElse(RotationManager.getHandPitch(), instance.getPitch()); } + + @Inject(method = "swingHand", at = @At("HEAD"), cancellable = true) + void onSwingHandPre(Hand hand, CallbackInfo ci) { + if (EventFlow.post(new EntityEvent.SwingHand(hand)).isCanceled()) ci.cancel(); + } } diff --git a/common/src/main/kotlin/com/lambda/event/events/EntityEvent.kt b/common/src/main/kotlin/com/lambda/event/events/EntityEvent.kt index 7c65fbf51..33928168a 100644 --- a/common/src/main/kotlin/com/lambda/event/events/EntityEvent.kt +++ b/common/src/main/kotlin/com/lambda/event/events/EntityEvent.kt @@ -3,10 +3,15 @@ package com.lambda.event.events import com.lambda.event.Event import com.lambda.event.callback.Cancellable import com.lambda.event.callback.ICancellable +import net.minecraft.util.Hand abstract class EntityEvent : Event { class ChangeLookDirection( val deltaYaw: Double, val deltaPitch: Double, ) : EntityEvent(), ICancellable by Cancellable() + + class SwingHand( + val hand: Hand + ) : EntityEvent(), ICancellable by Cancellable() } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index f11130a1b..0cb724f64 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -194,12 +194,14 @@ object PacketMine : Module( private var emptyReBreakDelayCounter = 0 private var rotated = false private var waitingToReleaseRotation = false + private var cancelNextSwing = false init { listener { //ToDo: Sometimes swinging here when shouldnt it.cancel() if (swingOnManual) swingMainHand() + if (!swingMode.isEnabled()) cancelNextSwing = true currentMiningBlock?.apply { if (it.pos != pos || breakState != BreakState.ReBreaking || !reBreak.isStandard()) return@apply @@ -220,6 +222,13 @@ object PacketMine : Module( startBreaking(it.pos) } + listener { + if (!cancelNextSwing) return@listener + + cancelNextSwing = false + it.cancel() + } + listener { updateCounters() From 63005791620b385127a488499b6d9a98ca2c2e07 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 15 Jul 2024 18:07:14 +0100 Subject: [PATCH 60/91] - added reset on manual swap setting --- .../com/lambda/module/modules/player/PacketMine.kt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 0cb724f64..bd190c6e3 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -46,6 +46,7 @@ object PacketMine : Module( private val breakThreshold by setting("Break Threshold", 0.70f, 0.00f..1.00f, 0.01f, "Breaks the selected block once the block breaking progress passes this value, 1 being 100%", visibility = { page == Page.General}) private val range by setting("Range", 6, 3..6, 1, "The maximum distance between the players eye position and the center of the block", visibility = { page == Page.General }) private val pauseWhileUsingItems by setting("Pause While Using Items", true, "Will prevent breaking while using items like eating or aiming a bow", visibility = { page == Page.General }) + private val resetOnManualSwap by setting("Reset On Manual Swap", false, "Resets the current breaking progress if you manual swap slot", visibility = { page == Page.General }) private val validateBreak by setting("Validate Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) private val timeoutDelay by setting("Timeout Delay", 0.20f, 0.00f..1.00f, 0.1f, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && validateBreak }) private val swingMode by setting("Swing Mode", SwingMode.None, "Swings the players hand to simulate vanilla breaking, usually used on stricter anticheats", visibility = { page == Page.General }) @@ -186,6 +187,7 @@ object PacketMine : Module( private var returnSlot = -1 private var swappedSlot = -1 private var swapped = false + private var previousSelectedSlot = -1 private var expectedRotation: Rotation? = null private var rotationPosition: BlockPos? = null private var pauseForRotation = false @@ -198,7 +200,6 @@ object PacketMine : Module( init { listener { - //ToDo: Sometimes swinging here when shouldnt it.cancel() if (swingOnManual) swingMainHand() if (!swingMode.isEnabled()) cancelNextSwing = true @@ -254,6 +255,14 @@ object PacketMine : Module( runHandlers(ProgressStage.PreTick, pos, lastValidBestTool, empty) + if (resetOnManualSwap + && !swapped + && player.inventory.selectedSlot != previousSelectedSlot + ) { + mineTicks = 0 + } + previousSelectedSlot = player.inventory.selectedSlot + if ((pauseWhileUsingItems && player.isUsingItem) || pauseForRotation) return@listener @@ -394,6 +403,8 @@ object PacketMine : Module( val breakDelta = calcBreakDelta(world.getBlockState(pos), pos, bestTool) val instaBreak = breakDelta >= breakThreshold + previousSelectedSlot = player.inventory.selectedSlot + runBetweenHandlers(ProgressStage.StartPre, ProgressStage.StartPost, pos, bestTool, instaBreak) { packetStartBreak(pos) From d9946e1e537b220afafd62dfc35e2965de52fc37 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 15 Jul 2024 21:38:03 +0100 Subject: [PATCH 61/91] - added range check to client side break and increased tick event listener priority --- .../kotlin/com/lambda/module/modules/player/PacketMine.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index bd190c6e3..283b4344a 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -29,6 +29,7 @@ import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket import net.minecraft.registry.tag.FluidTags import net.minecraft.screen.slot.SlotActionType import net.minecraft.state.property.Properties +import net.minecraft.text.Text import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Box @@ -230,7 +231,7 @@ object PacketMine : Module( it.cancel() } - listener { + listener(1) { updateCounters() if (awaitingQueueBreak) { @@ -649,7 +650,9 @@ object PacketMine : Module( private fun SafeContext.onBlockBreak(packetReceiveBreak: Boolean) { currentMiningBlock?.apply { - checkClientSideBreak(packetReceiveBreak, pos) + if (!isOutOfRange(pos.toCenterPos()) || packetReceiveBreak) { + checkClientSideBreak(packetReceiveBreak, pos) + } timeCompleted = System.currentTimeMillis() From 5d735a4a4ad525b995be44d1f44805dddd2d5540 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 15 Jul 2024 21:40:37 +0100 Subject: [PATCH 62/91] - forgor to remove unused import --- .../main/kotlin/com/lambda/module/modules/player/PacketMine.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 283b4344a..4d796b681 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -29,7 +29,6 @@ import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket import net.minecraft.registry.tag.FluidTags import net.minecraft.screen.slot.SlotActionType import net.minecraft.state.property.Properties -import net.minecraft.text.Text import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Box From 1ce8f2a3ab1426d8cd7747e91b71f28d15098a0c Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 15 Jul 2024 22:03:55 +0100 Subject: [PATCH 63/91] - added onDisable --- .../module/modules/player/PacketMine.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 4d796b681..7bdcd4ec5 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -391,6 +391,27 @@ object PacketMine : Module( renderer.upload() } } + + onDisable { + currentMiningBlock = null + lastNonEmptyState = null + blockQueue.clear() + queueBreakStartCounter = 0 + awaitingQueueBreak = false + returnSlot = -1 + swappedSlot = -1 + swapped = false + previousSelectedSlot = -1 + expectedRotation = null + rotationPosition = null + pauseForRotation = false + releaseRotateDelayCounter = 0 + reBreakDelayCounter = 0 + emptyReBreakDelayCounter = 0 + rotated = false + waitingToReleaseRotation = false + cancelNextSwing = false + } } private fun SafeContext.startBreaking(pos: BlockPos) { From a8ddd744762b0124fbaeb71f8827189820724fa4 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Tue, 16 Jul 2024 14:56:46 +0100 Subject: [PATCH 64/91] - fixed the progress stage during never getting handled --- .../kotlin/com/lambda/module/modules/player/PacketMine.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 7bdcd4ec5..28385e9f9 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -297,7 +297,10 @@ object PacketMine : Module( } BreakState.ReBreaking -> { - if (miningProgress < breakThreshold) return@listener + if (miningProgress < breakThreshold) { + runHandlers(ProgressStage.During, pos, lastValidBestTool) + return@listener + } if (isOutOfRange(pos.toCenterPos()) || !reBreak.isEnabled()) { nullifyCurrentBreakingBlock() From d01d824703382b780906a1058cb70955d5742b24 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Wed, 17 Jul 2024 19:39:54 +0100 Subject: [PATCH 65/91] - mostly fixed rotation logic, afaik only thing left on that front is the isValid check --- .../module/modules/player/PacketMine.kt | 115 +++++++++++------- 1 file changed, 74 insertions(+), 41 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 28385e9f9..e1fa73401 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -8,12 +8,13 @@ import com.lambda.graphics.renderer.esp.DynamicAABB import com.lambda.graphics.renderer.esp.builders.buildFilled import com.lambda.graphics.renderer.esp.builders.buildOutline import com.lambda.graphics.renderer.esp.global.DynamicESP -import com.lambda.interaction.rotation.Rotation +import com.lambda.interaction.rotation.RotationContext import com.lambda.interaction.visibilty.VisibilityChecker.findRotation import com.lambda.module.Module import com.lambda.module.modules.client.TaskFlow import com.lambda.module.tag.ModuleTag import com.lambda.util.math.MathUtils.lerp +import com.lambda.util.world.raycast.RayCastUtils.blockResult import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap import net.minecraft.block.BlockState import net.minecraft.enchantment.EnchantmentHelper @@ -35,6 +36,7 @@ import net.minecraft.util.math.Box import net.minecraft.util.math.Direction import net.minecraft.util.math.Vec3d import java.awt.Color +import java.util.function.Supplier object PacketMine : Module( name = "Packet Mine", @@ -188,13 +190,14 @@ object PacketMine : Module( private var swappedSlot = -1 private var swapped = false private var previousSelectedSlot = -1 - private var expectedRotation: Rotation? = null + private var expectedRotation: RotationContext? = null private var rotationPosition: BlockPos? = null private var pauseForRotation = false private var releaseRotateDelayCounter = 0 private var reBreakDelayCounter = 0 private var emptyReBreakDelayCounter = 0 private var rotated = false + private var onRotationComplete: Runnable? = null private var waitingToReleaseRotation = false private var cancelNextSwing = false @@ -207,11 +210,11 @@ object PacketMine : Module( currentMiningBlock?.apply { if (it.pos != pos || breakState != BreakState.ReBreaking || !reBreak.isStandard()) return@apply - runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, lastValidBestTool) { + runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, { lastValidBestTool }) { packetStopBreak(pos) - } - onBlockBreak(false) + onBlockBreak(false) + } return@listener } @@ -289,11 +292,11 @@ object PacketMine : Module( timeCompleted = System.currentTimeMillis() - runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, lastValidBestTool) { + runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, { lastValidBestTool }) { packetStopBreak(pos) - } - onBlockBreak(false) + onBlockBreak(false) + } } BreakState.ReBreaking -> { @@ -321,11 +324,11 @@ object PacketMine : Module( return@listener } - runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, lastValidBestTool, empty) { + runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, { lastValidBestTool }, empty) { packetStopBreak(pos) - } - onBlockBreak(false) + onBlockBreak(false) + } } BreakState.AwaitingResponse -> { @@ -362,27 +365,45 @@ object PacketMine : Module( listener { if (!rotate.isEnabled()) return@listener - lastNonEmptyState?.let { state -> - rotationPosition?.let { pos -> + rotationPosition?.let { pos -> + lastNonEmptyState?.let { state -> val boxList = state.getOutlineShape(world, pos).boundingBoxes.map { it.offset(pos) } - val rotationContext = findRotation(boxList, TaskFlow.rotation, TaskFlow.interact, emptySet(), verify = { true }) + val rotationContext = findRotation(boxList, TaskFlow.rotation, TaskFlow.interact, emptySet()) { + blockResult?.blockPos == pos + } rotationContext?.let { context -> it.context = context - expectedRotation = context.rotation + expectedRotation = context } - } ?: run { - expectedRotation = null } + } ?: run { + expectedRotation = null + } + + if (!rotated || !waitingToReleaseRotation) return@listener + + releaseRotateDelayCounter-- + + if (releaseRotateDelayCounter <= 0) { + waitingToReleaseRotation = false + rotationPosition = null + rotated = false } } listener { if (!rotate.isEnabled()) return@listener + //ToDo: Fix findRotation method to return the correct rotation even if its blocked by another block or something. Also improve raycasting stuff and add a setting expectedRotation?.apply { - if (it.context.rotation != expectedRotation) + if (this.isValid) { + onRotationComplete?.run() + onRotationComplete = null + } else { pauseForRotation = true + } } ?: run { + onRotationComplete = null pauseForRotation = false } } @@ -429,7 +450,7 @@ object PacketMine : Module( previousSelectedSlot = player.inventory.selectedSlot - runBetweenHandlers(ProgressStage.StartPre, ProgressStage.StartPost, pos, bestTool, instaBreak) { + runBetweenHandlers(ProgressStage.StartPre, ProgressStage.StartPost, pos, { bestTool }, instaBreak) { packetStartBreak(pos) currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking, breakDelta, bestTool) @@ -447,14 +468,25 @@ object PacketMine : Module( preStage: ProgressStage, postStage: ProgressStage, pos: BlockPos, - bestTool: Int, + bestTool: Supplier, empty: Boolean = false, instaBroken: Boolean = false, task: Runnable ) { - runHandlers(preStage, pos, bestTool, empty, instaBroken) - task.run() - runHandlers(postStage, pos, bestTool, empty, instaBroken) + handleRotations(preStage, pos, empty, instaBroken) + + val postRotationTask = Runnable { + handleAutoSwap(preStage, bestTool.get(), empty, instaBroken) + handleSwing(preStage) + task.run() + runHandlers(postStage, pos, bestTool.get(), empty, instaBroken) + } + + if (pauseForRotation) { + onRotationComplete = postRotationTask + } else { + postRotationTask.run() + } } private fun SafeContext.runHandlers( @@ -471,18 +503,27 @@ object PacketMine : Module( private fun handleRotations(progressStage: ProgressStage, pos: BlockPos, empty: Boolean = false, instaBroken: Boolean = false) { when (progressStage) { - ProgressStage.PreTick -> if (rotated && rotate.isStartAndEnd()) checkReleaseRotation() + ProgressStage.PreTick -> { + if (rotate.isConstant() + && !empty + && (currentMiningBlock?.breakState != BreakState.ReBreaking + || !reBreak.isStandard() + ) + ) { + rotateTo(pos) + } + } ProgressStage.StartPre, - ProgressStage.EndPre -> if (rotate.isEnabled() && !rotated) rotateTo(pos) + ProgressStage.EndPre -> if (rotate.isEnabled() && (validateBreak || !instaBroken)) rotateTo(pos) - ProgressStage.During -> if (rotate.isConstant()) rotateTo(pos) + ProgressStage.During -> if (rotate.isConstant() && !empty) rotateTo(pos) - ProgressStage.StartPost -> if (instaBroken && !validateBreak) checkReleaseRotation() + ProgressStage.StartPost -> if ((instaBroken && !validateBreak) || rotate.isStartAndEnd()) checkReleaseRotation() - ProgressStage.EndPost -> if (!validateBreak || empty) checkReleaseRotation() + ProgressStage.EndPost -> if ((!validateBreak || empty) || rotate.isStartAndEnd()) checkReleaseRotation() - ProgressStage.PacketReceiveBreak -> if (rotated) checkReleaseRotation() + ProgressStage.PacketReceiveBreak -> checkReleaseRotation() ProgressStage.TimedOut -> checkReleaseRotation() } @@ -532,9 +573,9 @@ object PacketMine : Module( } } - ProgressStage.PacketReceiveBreak -> if (swapped && !autoSwap.isSilent()) returnToOriginalSlot() + ProgressStage.PacketReceiveBreak -> if (!autoSwap.isSilent()) returnToOriginalSlot() - ProgressStage.TimedOut -> if (swapped) returnToOriginalSlot() + ProgressStage.TimedOut -> returnToOriginalSlot() } } @@ -567,15 +608,6 @@ object PacketMine : Module( player.swingHand(Hand.MAIN_HAND) private fun updateCounters() { - if (rotated && waitingToReleaseRotation) { - releaseRotateDelayCounter-- - - if (releaseRotateDelayCounter <= 0) { - waitingToReleaseRotation = false - rotationPosition = null - rotated = false - } - } if (reBreakDelayCounter > 0) { reBreakDelayCounter-- } @@ -595,7 +627,7 @@ object PacketMine : Module( } private fun checkReleaseRotation() { - if (waitingToReleaseRotation || !rotated) return + if (!rotated || waitingToReleaseRotation) return if (releaseRotateDelayCounter <= 0) { rotationPosition = null @@ -703,6 +735,7 @@ object PacketMine : Module( private fun SafeContext.nullifyCurrentBreakingBlock() { currentMiningBlock?.apply { if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, -1) + runHandlers(ProgressStage.TimedOut, pos, lastValidBestTool) } currentMiningBlock = null From 61c7a58755f1bf4705ca162933ed3c33056c7aec Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Thu, 18 Jul 2024 00:44:57 +0100 Subject: [PATCH 66/91] - small cleanup --- .../module/modules/player/PacketMine.kt | 49 +++++++++---------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index e1fa73401..5e8dd85ca 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -583,9 +583,7 @@ object PacketMine : Module( when (progressStage) { ProgressStage.PreTick -> { currentMiningBlock?.apply { - if (breakState != BreakState.ReBreaking - && swingMode.isConstant() - ) { + if (breakState != BreakState.ReBreaking && swingMode.isConstant()) { swingMainHand() } } @@ -654,38 +652,39 @@ object PacketMine : Module( private fun SafeContext.silentSwapTo(slot: Int, returningToOriginalSlot: Boolean) { if (autoSwap.isStandardSilent()) { connection.sendPacket(UpdateSelectedSlotC2SPacket(slot)) - } else { - val screenHandler = player.playerScreenHandler - var itemStack = player.mainHandStack - var newSlot = slot + return + } - if (returningToOriginalSlot) { - newSlot = swappedSlot - itemStack = player.inventory.getStack(swappedSlot) - } + val screenHandler = player.playerScreenHandler + var itemStack = player.mainHandStack + var newSlot = slot - connection.sendPacket( - ClickSlotC2SPacket( - screenHandler.syncId, - screenHandler.revision, - newSlot + 36, - player.inventory.selectedSlot, - SlotActionType.SWAP, - itemStack, - Int2ObjectArrayMap() - ) - ) + if (returningToOriginalSlot) { + newSlot = swappedSlot + itemStack = player.inventory.getStack(swappedSlot) } + + connection.sendPacket( + ClickSlotC2SPacket( + screenHandler.syncId, + screenHandler.revision, + newSlot + 36, + player.inventory.selectedSlot, + SlotActionType.SWAP, + itemStack, + Int2ObjectArrayMap() + ) + ) } private fun SafeContext.returnToOriginalSlot() { if (!swapped || returnSlot == -1) return - if (!autoSwap.isSilent()) { + if (autoSwap.isSilent()) { + silentSwapTo(returnSlot, true) + } else { player.inventory.selectedSlot = returnSlot connection.sendPacket(UpdateSelectedSlotC2SPacket(returnSlot)) - } else { - silentSwapTo(returnSlot, true) } returnSlot = -1 swappedSlot = -1 From 8ff3d430c2d89e948e29f9fa9dff79efa2ec9316 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 19 Jul 2024 17:31:55 +0100 Subject: [PATCH 67/91] - added queue block renders --- .../module/modules/player/PacketMine.kt | 118 +++++++++++++----- 1 file changed, 89 insertions(+), 29 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 5e8dd85ca..9d7ce884d 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -13,6 +13,7 @@ import com.lambda.interaction.visibilty.VisibilityChecker.findRotation import com.lambda.module.Module import com.lambda.module.modules.client.TaskFlow import com.lambda.module.tag.ModuleTag +import com.lambda.util.BlockUtils.blockState import com.lambda.util.math.MathUtils.lerp import com.lambda.util.world.raycast.RayCastUtils.blockResult import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap @@ -68,23 +69,39 @@ object PacketMine : Module( private val resetProgressOnBreak by setting("Reset Progress", false, "Resets the mining progress after breaking a block, mostly used on stricter servers", visibility = { page == Page.ReBreak && reBreak.isEnabled() }) - private val breakingAnimation by setting("Breaking Animation", false, "Renders the block breaking animation like vanilla would to show progress", visibility = { page == Page.Render }) - private val renderMode by setting("Render Mode", RenderMode.Out, "The animation style of the renders", visibility = { page == Page.Render }) - private val renderSetting by setting("Render Setting", RenderSetting.Both, "The different ways to draw the renders", visibility = { page == Page.Render && renderMode.isEnabled() }) + private val breakingAnimation by setting("Breaking Animation", false, "Renders the block breaking animation like vanilla would to show progress", visibility = { page == Page.BlockRender }) + private val renderMode by setting("BlockRender Mode", RenderMode.Out, "The animation style of the renders", visibility = { page == Page.BlockRender }) + private val renderSetting by setting("BlockRender Setting", RenderSetting.Both, "The different ways to draw the renders", visibility = { page == Page.BlockRender && renderMode.isEnabled() }) - private val fillColourMode by setting("Fill Mode", ColourMode.Dynamic, visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline }) - private val staticFillColour by setting("Static Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the static fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Static }) - private val startFillColour by setting("Start Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the start fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Dynamic }) - private val endFillColour by setting("End Fill Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Dynamic }) + private val fillColourMode by setting("Fill Mode", ColourMode.Dynamic, visibility = { page == Page.BlockRender && renderMode.isEnabled() && renderSetting != RenderSetting.Outline }) + private val staticFillColour by setting("Static Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the static fill of the box faces", visibility = { page == Page.BlockRender && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Static }) + private val startFillColour by setting("Start Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the start fill of the box faces", visibility = { page == Page.BlockRender && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Dynamic }) + private val endFillColour by setting("End Fill Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end fill of the box faces", visibility = { page == Page.BlockRender && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Dynamic }) + + private val outlineColourMode by setting("Outline Mode", ColourMode.Dynamic, visibility = { page == Page.BlockRender && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) + private val staticOutlineColour by setting("Static Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the outline of the box", visibility = { page == Page.BlockRender && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Static }) + private val startOutlineColour by setting("Start Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the start outline of the box", visibility = { page == Page.BlockRender && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Dynamic }) + private val endOutlineColour by setting("End Outline Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end outline of the box", visibility = { page == Page.BlockRender && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Dynamic }) + private val outlineWidth by setting("Outline Width", 1f, 0f..3f, 0.1f, "the thickness of the outline", visibility = { page == Page.BlockRender && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) + + private val renderQueueMode by setting("Render mode", RenderQueueMode.Shape, "The render type for queue blocks", visibility = { page == Page.QueueRender }) + private val renderQueueSetting by setting("Render Setting", RenderSetting.Both, "The style to render queue blocks", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() }) + private val renderQueueSize by setting("Render Size", 0.3f, 0f..1f, 0.01f, "The scale of the queue render blocks", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() }) + + private val queueFillColourMode by setting("Fill Mode", ColourMode.Static, "The fill colour mode", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Outline }) + private val queueStaticFillColour by setting("Static Fill Colour", Color(1f, 0f, 0f, 0.2f), "The colour used to render the faces for queue blocks", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Outline && queueFillColourMode == ColourMode.Static }) + private val queueStartFillColour by setting("Start Fill Colour", Color(1f, 0f, 0f, 0.2f), "The colour to render the faces for queue blocks closer to being broken next", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Outline && queueFillColourMode == ColourMode.Dynamic }) + private val queueEndFillColour by setting("End Fill Colour", Color(1f, 1f, 0f, 0.2f), "the colour to render the faces for queue blocks closer to the end of the queue", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Outline && queueFillColourMode == ColourMode.Dynamic }) + + private val queueOutlineColourMode by setting("Outline Mode", ColourMode.Static, "The outline colour mode", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Fill }) + private val queueStaticOutlineColour by setting("Static Outline Colour", Color(1f, 0f, 0f), "The colour used to render the outline for queue blocks", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Fill && queueOutlineColourMode == ColourMode.Static }) + private val queueStartOutlineColour by setting("Start Outline Colour", Color(1f, 0f, 0f), "The colour to render the outline for queue blocks closer to being broken next", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Fill && queueOutlineColourMode == ColourMode.Dynamic }) + private val queueEndOutlineColour by setting("End Outline Colour", Color(1f, 1f, 0f), "the colour to render the outline for queue blocks closer to the end of the queue", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Fill && queueOutlineColourMode == ColourMode.Dynamic }) + private val queueOutlineWidth by setting("Outline Width", 1f, 0f..3f, 0.1f, "The thickness of the outline used on queue blocks", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderSetting != RenderSetting.Fill } ) - private val outlineColourMode by setting("Outline Mode", ColourMode.Dynamic, visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) - private val staticOutlineColour by setting("Static Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the static outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Static }) - private val startOutlineColour by setting("Start Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the start outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Dynamic }) - private val endOutlineColour by setting("End Outline Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Dynamic }) - private val outlineWidth by setting("Outline Width", 1f, 0f..3f, 0.1f, "the thickness of the outline", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) private enum class Page { - General, Queue, ReBreak, Render + General, Queue, ReBreak, BlockRender, QueueRender } private enum class PacketMode { @@ -169,6 +186,13 @@ object PacketMine : Module( this != None } + private enum class RenderQueueMode { + None, Cube, Shape; + + fun isEnabled() = + this != None + } + private enum class RenderSetting { Both, Fill, Outline } @@ -181,6 +205,7 @@ object PacketMine : Module( Breaking, ReBreaking, AwaitingResponse } + val renderer = DynamicESP private var currentMiningBlock: BreakingContext? = null private var lastNonEmptyState: BlockState? = null private val blockQueue = ArrayDeque() @@ -219,7 +244,11 @@ object PacketMine : Module( } if (shouldBePlacedInBlockQueue(it.pos)) { - blockQueue.add(it.pos) + if (reverseQueueOrder) { + blockQueue.addFirst(it.pos) + } else { + blockQueue.add(it.pos) + } return@listener } @@ -246,7 +275,7 @@ object PacketMine : Module( currentMiningBlock?.apply { mineTicks++ - val activeState = world.getBlockState(pos) + val activeState = pos.blockState(world) if (activeState != state) state = activeState val empty = isStateEmpty(activeState) @@ -409,11 +438,51 @@ object PacketMine : Module( } listener { + renderer.clear() + currentMiningBlock?.apply { - renderer.clear() buildRenders() - renderer.upload() } + + if (renderQueueMode.isEnabled()) { + blockQueue.forEach { pos -> + var boxes = if (renderQueueMode == RenderQueueMode.Shape) { + pos.blockState(world).getOutlineShape(world, pos).boundingBoxes + } else { + listOf(Box(0.0, 0.0, 0.0, 1.0, 1.0, 1.0)) + } + boxes = boxes.map { val reSized = lerp(Box(it.center, it.center), it, renderQueueSize.toDouble()); reSized.offset(pos) } + + val indexFactor = blockQueue.indexOf(pos).toDouble() / blockQueue.size.toDouble() + + val fillColour = if (queueFillColourMode == ColourMode.Static) { + queueStaticFillColour + } else { + lerp(queueStartFillColour, queueEndFillColour, indexFactor) + } + + val outlineColour = if (queueOutlineColourMode == ColourMode.Static) { + queueStaticOutlineColour + } else { + lerp(queueStartOutlineColour, queueEndOutlineColour, indexFactor) + } + + boxes.forEach { box -> + val dynamicAABB = DynamicAABB() + dynamicAABB.update(box) + + if (renderQueueSetting != RenderSetting.Outline) { + renderer.buildFilled(dynamicAABB, fillColour) + } + + if (renderQueueSetting != RenderSetting.Fill) { + renderer.buildOutline(dynamicAABB, outlineColour) + } + } + } + } + + renderer.upload() } onDisable { @@ -441,11 +510,11 @@ object PacketMine : Module( private fun SafeContext.startBreaking(pos: BlockPos) { if (currentMiningBlock?.pos == pos || blockQueue.contains(pos)) return - val state = world.getBlockState(pos) + val state = pos.blockState(world) val bestTool = getBestTool(state, pos) lastNonEmptyState = state - val breakDelta = calcBreakDelta(world.getBlockState(pos), pos, bestTool) + val breakDelta = calcBreakDelta(state, pos, bestTool) val instaBreak = breakDelta >= breakThreshold previousSelectedSlot = player.inventory.selectedSlot @@ -784,7 +853,7 @@ object PacketMine : Module( private fun SafeContext.filterBlockQueueUntilNextPossible(): BlockPos? { while (true) { - val block = getNextUncheckedQueueBlock() ?: return null + val block = blockQueue.firstOrNull() ?: return null if (isOutOfRange(block.toCenterPos())) { blockQueue.remove(block) @@ -795,14 +864,6 @@ object PacketMine : Module( } } - private fun getNextUncheckedQueueBlock(): BlockPos? { - return if (reverseQueueOrder) { - blockQueue.lastOrNull() - } else { - blockQueue.firstOrNull() - } - } - private data class BreakingContext( val pos: BlockPos, var state: BlockState, @@ -810,7 +871,6 @@ object PacketMine : Module( var currentBreakDelta: Float, var lastValidBestTool: Int ) { - val renderer = DynamicESP var mineTicks = 0 var timeCompleted: Long = -1 var previousBreakDelta = 0f From 62f4129645e31a29e2640578eb52b6676c540c67 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 19 Jul 2024 23:40:30 +0100 Subject: [PATCH 68/91] - fixed renders not showing on rebreak after the block is broken --- .../module/modules/player/PacketMine.kt | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 9d7ce884d..75d44070a 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -31,6 +31,7 @@ import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket import net.minecraft.registry.tag.FluidTags import net.minecraft.screen.slot.SlotActionType import net.minecraft.state.property.Properties +import net.minecraft.text.Text import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Box @@ -59,15 +60,15 @@ object PacketMine : Module( private val autoSwap by setting("Swap Mode", SwapMode.StandardSilent, "Changes the swap method used. For example, silent swaps once at the beginning, and once at the end without updating client side, and constant swaps for the whole break", visibility = { page == Page.General}) private val packets by setting("Packet Mode", PacketMode.Vanilla, "Chooses different packets to send for each mode", visibility = { page == Page.General }) - private val queueBlocks by setting("Queue Blocks", false, "Queues any blocks you click for breaking", visibility = { page == Page.Queue }).apply { this.onValueSet { _, to -> if (!to) blockQueue.clear() } } - private val reverseQueueOrder by setting("Reverse Queue Order", false, "Breaks the latest addition to the queue first", visibility = { page == Page.Queue && queueBlocks}) - private val queueBreakDelay by setting("Break Delay", 0, 0..5, 1, "The delay (in ticks) after breaking a block to break the next queue block", visibility = { page == Page.Queue && queueBlocks }) - private val reBreak by setting("Re-Break", ReBreakMode.Standard, "The different modes for re-breaking the current block", visibility = { page == Page.ReBreak}) private val reBreakDelay by setting("Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-breaking the block", visibility = { page == Page.ReBreak && (reBreak.isAutomatic() || reBreak.isFastAutomatic()) }) private val emptyReBreakDelay by setting("Empty Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-break the block if the block is currently empty", visibility = { page == Page.ReBreak && reBreak.isFastAutomatic()}) private val resetProgressOnBreak by setting("Reset Progress", false, "Resets the mining progress after breaking a block, mostly used on stricter servers", visibility = { page == Page.ReBreak && reBreak.isEnabled() }) + private val queueBlocks by setting("Queue Blocks", false, "Queues any blocks you click for breaking", visibility = { page == Page.Queue }).apply { this.onValueSet { _, to -> if (!to) blockQueue.clear() } } + private val reverseQueueOrder by setting("Reverse Queue Order", false, "Breaks the latest addition to the queue first", visibility = { page == Page.Queue && queueBlocks}) + private val queueBreakDelay by setting("Break Delay", 0, 0..5, 1, "The delay (in ticks) after breaking a block to break the next queue block", visibility = { page == Page.Queue && queueBlocks }) + private val breakingAnimation by setting("Breaking Animation", false, "Renders the block breaking animation like vanilla would to show progress", visibility = { page == Page.BlockRender }) private val renderMode by setting("BlockRender Mode", RenderMode.Out, "The animation style of the renders", visibility = { page == Page.BlockRender }) @@ -88,12 +89,12 @@ object PacketMine : Module( private val renderQueueSetting by setting("Render Setting", RenderSetting.Both, "The style to render queue blocks", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() }) private val renderQueueSize by setting("Render Size", 0.3f, 0f..1f, 0.01f, "The scale of the queue render blocks", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() }) - private val queueFillColourMode by setting("Fill Mode", ColourMode.Static, "The fill colour mode", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Outline }) + private val queueFillColourMode by setting("Fill Mode", ColourMode.Dynamic, visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Outline }) private val queueStaticFillColour by setting("Static Fill Colour", Color(1f, 0f, 0f, 0.2f), "The colour used to render the faces for queue blocks", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Outline && queueFillColourMode == ColourMode.Static }) private val queueStartFillColour by setting("Start Fill Colour", Color(1f, 0f, 0f, 0.2f), "The colour to render the faces for queue blocks closer to being broken next", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Outline && queueFillColourMode == ColourMode.Dynamic }) private val queueEndFillColour by setting("End Fill Colour", Color(1f, 1f, 0f, 0.2f), "the colour to render the faces for queue blocks closer to the end of the queue", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Outline && queueFillColourMode == ColourMode.Dynamic }) - private val queueOutlineColourMode by setting("Outline Mode", ColourMode.Static, "The outline colour mode", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Fill }) + private val queueOutlineColourMode by setting("Outline Mode", ColourMode.Dynamic, visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Fill }) private val queueStaticOutlineColour by setting("Static Outline Colour", Color(1f, 0f, 0f), "The colour used to render the outline for queue blocks", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Fill && queueOutlineColourMode == ColourMode.Static }) private val queueStartOutlineColour by setting("Start Outline Colour", Color(1f, 0f, 0f), "The colour to render the outline for queue blocks closer to being broken next", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Fill && queueOutlineColourMode == ColourMode.Dynamic }) private val queueEndOutlineColour by setting("End Outline Colour", Color(1f, 1f, 0f), "the colour to render the outline for queue blocks closer to the end of the queue", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() && renderQueueSetting != RenderSetting.Fill && queueOutlineColourMode == ColourMode.Dynamic }) @@ -101,7 +102,7 @@ object PacketMine : Module( private enum class Page { - General, Queue, ReBreak, BlockRender, QueueRender + General, ReBreak, Queue, BlockRender, QueueRender } private enum class PacketMode { @@ -276,10 +277,9 @@ object PacketMine : Module( mineTicks++ val activeState = pos.blockState(world) - if (activeState != state) state = activeState val empty = isStateEmpty(activeState) - if (!empty) lastNonEmptyState = state + if (!empty) lastNonEmptyState = activeState lastNonEmptyState?.let { lastValidBestTool = getBestTool(it, pos) @@ -298,11 +298,13 @@ object PacketMine : Module( if ((pauseWhileUsingItems && player.isUsingItem) || pauseForRotation) return@listener - currentBreakDelta = if (autoSwap.isEnabled()) { - calcBreakDelta(state, pos, lastValidBestTool) - } else { - calcBreakDelta(state, pos, player.inventory.selectedSlot) - } + currentBreakDelta = lastNonEmptyState?.let { lastNonEmptyState -> + if (autoSwap.isEnabled()) { + calcBreakDelta(lastNonEmptyState, pos, lastValidBestTool) + } else { + calcBreakDelta(lastNonEmptyState, pos, player.inventory.selectedSlot) + } + } ?: 0f if (renderMode.isEnabled()) updateRenders(currentBreakDelta) @@ -381,7 +383,7 @@ object PacketMine : Module( listener { currentMiningBlock?.apply { - if (it.pos != pos || !isStateBroken(state, it.state)) { + if (it.pos != pos || !isStateBroken(lastNonEmptyState, it.state)) { return@listener } @@ -512,7 +514,7 @@ object PacketMine : Module( val state = pos.blockState(world) val bestTool = getBestTool(state, pos) - lastNonEmptyState = state + if (!isStateEmpty(state)) lastNonEmptyState = state val breakDelta = calcBreakDelta(state, pos, bestTool) val instaBreak = breakDelta >= breakThreshold @@ -809,12 +811,14 @@ object PacketMine : Module( currentMiningBlock = null } - private fun isStateBroken(previousState: BlockState, activeState: BlockState) = - activeState.isAir || ( - activeState.fluidState.fluid is WaterFluid - && previousState.properties.contains(Properties.WATERLOGGED) - && previousState.get(Properties.WATERLOGGED) - ) + private fun isStateBroken(previousState: BlockState?, activeState: BlockState) = + previousState?.let { previous -> + activeState.isAir || ( + activeState.fluidState.fluid is WaterFluid + && previous.properties.contains(Properties.WATERLOGGED) + && previous.get(Properties.WATERLOGGED) + ) + } ?: false private fun isStateEmpty(state: BlockState) = state.isAir || ( @@ -884,8 +888,7 @@ object PacketMine : Module( fun updateRenders(newBreakDelta: Float) { previousBreakDelta = currentBreakDelta currentBreakDelta = newBreakDelta - if (renderMode.isEnabled()) - boxList = state.getOutlineShape(mc.world, pos).boundingBoxes.toSet() + boxList = lastNonEmptyState?.getOutlineShape(mc.world, pos)?.boundingBoxes?.toSet() } fun SafeContext.buildRenders() { From f3be787c5e077a150abfe325eb0e77db58a83dd8 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 19 Jul 2024 23:48:51 +0100 Subject: [PATCH 69/91] - updated onDisable --- .../main/kotlin/com/lambda/module/modules/player/PacketMine.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 75d44070a..935427555 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -31,7 +31,6 @@ import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket import net.minecraft.registry.tag.FluidTags import net.minecraft.screen.slot.SlotActionType import net.minecraft.state.property.Properties -import net.minecraft.text.Text import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Box @@ -504,6 +503,7 @@ object PacketMine : Module( reBreakDelayCounter = 0 emptyReBreakDelayCounter = 0 rotated = false + onRotationComplete = null waitingToReleaseRotation = false cancelNextSwing = false } From cb24c4f64fa5099b1a21cc908b7c6de03d32a2c0 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Sat, 20 Jul 2024 01:48:26 +0100 Subject: [PATCH 70/91] - fixed queued instant mineable blocks all being broken at once without validate break enabled --- .../kotlin/com/lambda/module/modules/player/PacketMine.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 935427555..226f9a1c2 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -225,6 +225,7 @@ object PacketMine : Module( private var onRotationComplete: Runnable? = null private var waitingToReleaseRotation = false private var cancelNextSwing = false + private var instaBreaksPerTickCounter = 0 init { listener { @@ -506,6 +507,7 @@ object PacketMine : Module( onRotationComplete = null waitingToReleaseRotation = false cancelNextSwing = false + instaBreaksPerTickCounter = 0 } } @@ -528,6 +530,8 @@ object PacketMine : Module( if (!instaBreak) return@runBetweenHandlers + instaBreaksPerTickCounter++ + packetStopBreak(pos) if (reBreak.isEnabled()) packetStartBreak(pos) @@ -677,6 +681,8 @@ object PacketMine : Module( player.swingHand(Hand.MAIN_HAND) private fun updateCounters() { + instaBreaksPerTickCounter = 0 + if (reBreakDelayCounter > 0) { reBreakDelayCounter-- } @@ -842,7 +848,7 @@ object PacketMine : Module( if (!queueBlocks) return false filterBlockQueueUntilNextPossible()?.apply { - if (queueBreakStartCounter <= 0) { + if (queueBreakStartCounter <= 0 && instaBreaksPerTickCounter <= 0) { blockQueue.remove(this) startBreaking(this) } else { From e2a9e24f5c1a7253997396cdb34964e1aafa439d Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 22 Jul 2024 04:03:51 +0100 Subject: [PATCH 71/91] - added break mode setting for the different methods of adding up total break amount - combined all progress reset settings into one strict setting - changed auto swap to swap mode and swap method. Also added more options for swap times - added more options for swing times --- .../module/modules/player/PacketMine.kt | 272 ++++++++++++------ 1 file changed, 181 insertions(+), 91 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 226f9a1c2..a6d2bb106 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -25,6 +25,7 @@ import net.minecraft.entity.effect.StatusEffects import net.minecraft.fluid.WaterFluid import net.minecraft.item.ItemStack import net.minecraft.network.packet.c2s.play.ClickSlotC2SPacket +import net.minecraft.network.packet.c2s.play.HandSwingC2SPacket import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket @@ -47,22 +48,23 @@ object PacketMine : Module( private val page by setting("Page", Page.General) private val breakThreshold by setting("Break Threshold", 0.70f, 0.00f..1.00f, 0.01f, "Breaks the selected block once the block breaking progress passes this value, 1 being 100%", visibility = { page == Page.General}) - private val range by setting("Range", 6, 3..6, 1, "The maximum distance between the players eye position and the center of the block", visibility = { page == Page.General }) + private val breakMode by setting("Break Mode", BreakMode.Total, "Changes the way break amount is added up. Total will choose the best tool and act as if its been using it the whole time while additive will add progress throughout the break", visibility = { page == Page.General }) + private val strict by setting("Strict", false, "Resets the breaking progress at various stages to bypass generally stricter anti-cheats", visibility = { page == Page.General }) + private val range by setting("Range", 6.0f, 3.0f..6.0f, 0.1f, "The maximum distance between the players eye position and the center of the block", visibility = { page == Page.General }) private val pauseWhileUsingItems by setting("Pause While Using Items", true, "Will prevent breaking while using items like eating or aiming a bow", visibility = { page == Page.General }) - private val resetOnManualSwap by setting("Reset On Manual Swap", false, "Resets the current breaking progress if you manual swap slot", visibility = { page == Page.General }) private val validateBreak by setting("Validate Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) private val timeoutDelay by setting("Timeout Delay", 0.20f, 0.00f..1.00f, 0.1f, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && validateBreak }) - private val swingMode by setting("Swing Mode", SwingMode.None, "Swings the players hand to simulate vanilla breaking, usually used on stricter anticheats", visibility = { page == Page.General }) - private val swingOnManual by setting("Swing On Hit", true, "Swings when the player attacks a block", visibility = { page == Page.General }) + private val swingMode by setting("Swing Mode", SwingMode.None, "Swings the players hand to simulate vanilla breaking, usually used on stricter anti-cheats", visibility = { page == Page.General }) + private val swingOnManual by setting("Manual Swing", true, "Swings when the player attacks a block", visibility = { page == Page.General }) private val rotate by setting("Rotation Mode", RotationMode.None, "Changes the method used to make the player look at the current mining block", visibility = { page == Page.General }) private val rotateReleaseDelay by setting("Rotation Release Delay", 2, 0..50, 1, "The number of ticks to wait before releasing the rotation", visibility = { page == Page.General && rotate.isEnabled() }) - private val autoSwap by setting("Swap Mode", SwapMode.StandardSilent, "Changes the swap method used. For example, silent swaps once at the beginning, and once at the end without updating client side, and constant swaps for the whole break", visibility = { page == Page.General}) + private val swapMethod by setting("Swap Method", SwapMethod.StandardSilent, "Changes the swap method used. For example, silent swaps once at the beginning, and once at the end without updating client side, and constant swaps for the whole break", visibility = { page == Page.General}) + private val swapMode by setting("Swap Mode", SwapMode.StartAndEnd, "The different times to swap to the best tool", visibility = { page == Page.General && swapMethod.isEnabled()}) private val packets by setting("Packet Mode", PacketMode.Vanilla, "Chooses different packets to send for each mode", visibility = { page == Page.General }) private val reBreak by setting("Re-Break", ReBreakMode.Standard, "The different modes for re-breaking the current block", visibility = { page == Page.ReBreak}) private val reBreakDelay by setting("Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-breaking the block", visibility = { page == Page.ReBreak && (reBreak.isAutomatic() || reBreak.isFastAutomatic()) }) private val emptyReBreakDelay by setting("Empty Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-break the block if the block is currently empty", visibility = { page == Page.ReBreak && reBreak.isFastAutomatic()}) - private val resetProgressOnBreak by setting("Reset Progress", false, "Resets the mining progress after breaking a block, mostly used on stricter servers", visibility = { page == Page.ReBreak && reBreak.isEnabled() }) private val queueBlocks by setting("Queue Blocks", false, "Queues any blocks you click for breaking", visibility = { page == Page.Queue }).apply { this.onValueSet { _, to -> if (!to) blockQueue.clear() } } private val reverseQueueOrder by setting("Reverse Queue Order", false, "Breaks the latest addition to the queue first", visibility = { page == Page.Queue && queueBlocks}) @@ -104,26 +106,36 @@ object PacketMine : Module( General, ReBreak, Queue, BlockRender, QueueRender } + private enum class BreakMode { + Total, Additive; + + fun isTotal() = + this == Total + } + private enum class PacketMode { Vanilla, Grim, NCP } private enum class SwingMode { - None, Start, Constant, StartAndEnd; + None, Constant, Start, End, StartAndEnd; fun isEnabled() = this != None + fun isConstant() = + this == Constant + fun isStart() = this == Start - fun isConstant() = - this == Constant + fun isEnd() = + this == End fun isStartAndEnd() = this == StartAndEnd } - + //ToDo: Add start and end settings private enum class RotationMode { None, Constant, StartAndEnd; @@ -137,8 +149,8 @@ object PacketMine : Module( this == StartAndEnd } - private enum class SwapMode { - None, StandardSilent, NCPSilent, Constant, StartAndEnd; + private enum class SwapMethod { + None, StandardSilent, NCPSilent, Vanilla; fun isEnabled() = this != None @@ -151,10 +163,20 @@ object PacketMine : Module( fun isNCPSilent() = this == NCPSilent + } + + private enum class SwapMode { + StartAndEnd, Start, End, Constant; fun isConstant() = this == Constant + fun isStart() = + this == Start + + fun isEnd() = + this == End + fun isStartAndEnd() = this == StartAndEnd } @@ -217,7 +239,7 @@ object PacketMine : Module( private var previousSelectedSlot = -1 private var expectedRotation: RotationContext? = null private var rotationPosition: BlockPos? = null - private var pauseForRotation = false + private var pausedForRotation = false private var releaseRotateDelayCounter = 0 private var reBreakDelayCounter = 0 private var emptyReBreakDelayCounter = 0 @@ -225,23 +247,24 @@ object PacketMine : Module( private var onRotationComplete: Runnable? = null private var waitingToReleaseRotation = false private var cancelNextSwing = false - private var instaBreaksPerTickCounter = 0 + private var breaksPerTickCounter = 0 + private var swingingNextAttack = true + + //ToDo: Fix swing on mode start, tbh just find a better way to implement swing cancelling, maybe a different place to listen for block attacks? init { + listener { + swingingNextAttack = false + } + listener { it.cancel() if (swingOnManual) swingMainHand() - if (!swingMode.isEnabled()) cancelNextSwing = true - - currentMiningBlock?.apply { - if (it.pos != pos || breakState != BreakState.ReBreaking || !reBreak.isStandard()) return@apply - - runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, { lastValidBestTool }) { - packetStopBreak(pos) - onBlockBreak(false) - } - return@listener + if (swingingNextAttack) { + cancelNextSwing = true + } else { + swingingNextAttack = true } if (shouldBePlacedInBlockQueue(it.pos)) { @@ -253,6 +276,19 @@ object PacketMine : Module( return@listener } + currentMiningBlock?.apply { + if (it.pos != pos || breakState != BreakState.ReBreaking || !reBreak.isStandard()) return@apply + + if (miningProgress < breakThreshold) return@listener + + runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, { lastValidBestTool }) { + packetStopBreak(pos) + + onBlockBreak(false) + } + return@listener + } + startBreaking(it.pos) } @@ -279,7 +315,15 @@ object PacketMine : Module( val activeState = pos.blockState(world) val empty = isStateEmpty(activeState) - if (!empty) lastNonEmptyState = activeState + if (!empty) { + if (activeState != lastNonEmptyState?.block) { + lastNonEmptyState?.apply { + transformProgress(block.hardness / activeState.block.hardness) + } + } + + lastNonEmptyState = activeState + } lastNonEmptyState?.let { lastValidBestTool = getBestTool(it, pos) @@ -287,28 +331,29 @@ object PacketMine : Module( runHandlers(ProgressStage.PreTick, pos, lastValidBestTool, empty) - if (resetOnManualSwap + if (strict && !swapped && player.inventory.selectedSlot != previousSelectedSlot ) { - mineTicks = 0 + resetProgress() } previousSelectedSlot = player.inventory.selectedSlot - if ((pauseWhileUsingItems && player.isUsingItem) || pauseForRotation) + if ((pauseWhileUsingItems && player.isUsingItem) || pausedForRotation) { return@listener + } currentBreakDelta = lastNonEmptyState?.let { lastNonEmptyState -> - if (autoSwap.isEnabled()) { + if (swapMethod.isEnabled()) { calcBreakDelta(lastNonEmptyState, pos, lastValidBestTool) } else { calcBreakDelta(lastNonEmptyState, pos, player.inventory.selectedSlot) } } ?: 0f - if (renderMode.isEnabled()) updateRenders(currentBreakDelta) + updateBreakDeltas(currentBreakDelta) - val miningProgress = mineTicks * currentBreakDelta + if (renderMode.isEnabled()) updateRenders() if (breakingAnimation) world.setBlockBreakingInfo( @@ -332,7 +377,7 @@ object PacketMine : Module( BreakState.ReBreaking -> { if (miningProgress < breakThreshold) { - runHandlers(ProgressStage.During, pos, lastValidBestTool) + runHandlers(ProgressStage.During, pos, lastValidBestTool, empty = empty) return@listener } @@ -355,7 +400,7 @@ object PacketMine : Module( return@listener } - runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, { lastValidBestTool }, empty) { + runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, { lastValidBestTool }, empty = empty) { packetStopBreak(pos) onBlockBreak(false) @@ -383,9 +428,7 @@ object PacketMine : Module( listener { currentMiningBlock?.apply { - if (it.pos != pos || !isStateBroken(lastNonEmptyState, it.state)) { - return@listener - } + if (it.pos != pos || !isStateBroken(pos.blockState(world), it.state)) return@listener runHandlers(ProgressStage.PacketReceiveBreak, pos, lastValidBestTool) @@ -431,11 +474,11 @@ object PacketMine : Module( onRotationComplete?.run() onRotationComplete = null } else { - pauseForRotation = true + pausedForRotation = true } } ?: run { onRotationComplete = null - pauseForRotation = false + pausedForRotation = false } } @@ -499,7 +542,7 @@ object PacketMine : Module( previousSelectedSlot = -1 expectedRotation = null rotationPosition = null - pauseForRotation = false + pausedForRotation = false releaseRotateDelayCounter = 0 reBreakDelayCounter = 0 emptyReBreakDelayCounter = 0 @@ -507,7 +550,7 @@ object PacketMine : Module( onRotationComplete = null waitingToReleaseRotation = false cancelNextSwing = false - instaBreaksPerTickCounter = 0 + breaksPerTickCounter = 0 } } @@ -518,20 +561,22 @@ object PacketMine : Module( val bestTool = getBestTool(state, pos) if (!isStateEmpty(state)) lastNonEmptyState = state - val breakDelta = calcBreakDelta(state, pos, bestTool) + val breakDelta = if (swapMethod.isEnabled()) { + calcBreakDelta(state, pos, bestTool) + } else { + calcBreakDelta(state, pos, player.inventory.selectedSlot) + } val instaBreak = breakDelta >= breakThreshold previousSelectedSlot = player.inventory.selectedSlot - runBetweenHandlers(ProgressStage.StartPre, ProgressStage.StartPost, pos, { bestTool }, instaBreak) { + runBetweenHandlers(ProgressStage.StartPre, ProgressStage.StartPost, pos, { bestTool }, instaBroken = instaBreak) { packetStartBreak(pos) currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking, breakDelta, bestTool) if (!instaBreak) return@runBetweenHandlers - instaBreaksPerTickCounter++ - packetStopBreak(pos) if (reBreak.isEnabled()) packetStartBreak(pos) @@ -548,16 +593,16 @@ object PacketMine : Module( instaBroken: Boolean = false, task: Runnable ) { - handleRotations(preStage, pos, empty, instaBroken) + handleRotations(preStage, pos, empty = empty, instaBroken = instaBroken) val postRotationTask = Runnable { - handleAutoSwap(preStage, bestTool.get(), empty, instaBroken) - handleSwing(preStage) + handleAutoSwap(preStage, bestTool.get(), empty = empty, instaBroken = instaBroken) + handleSwing(preStage, empty = empty, instaBroken = instaBroken) task.run() - runHandlers(postStage, pos, bestTool.get(), empty, instaBroken) + runHandlers(postStage, pos, bestTool.get(), empty = empty, instaBroken = instaBroken) } - if (pauseForRotation) { + if (pausedForRotation) { onRotationComplete = postRotationTask } else { postRotationTask.run() @@ -571,9 +616,9 @@ object PacketMine : Module( empty: Boolean = false, instaBroken: Boolean = false ) { - handleRotations(progressStage, pos, empty, instaBroken) - handleAutoSwap(progressStage, bestTool, empty, instaBroken) - handleSwing(progressStage) + handleRotations(progressStage, pos, empty = empty, instaBroken = instaBroken) + handleAutoSwap(progressStage, bestTool, empty = empty, instaBroken = instaBroken) + handleSwing(progressStage, empty = empty, instaBroken = instaBroken) } private fun handleRotations(progressStage: ProgressStage, pos: BlockPos, empty: Boolean = false, instaBroken: Boolean = false) { @@ -598,41 +643,40 @@ object PacketMine : Module( ProgressStage.EndPost -> if ((!validateBreak || empty) || rotate.isStartAndEnd()) checkReleaseRotation() - ProgressStage.PacketReceiveBreak -> checkReleaseRotation() - + ProgressStage.PacketReceiveBreak, ProgressStage.TimedOut -> checkReleaseRotation() } } private fun SafeContext.handleAutoSwap(progressStage: ProgressStage, bestTool: Int, empty: Boolean = false, instaBroken: Boolean = false) { - if (!autoSwap.isEnabled()) return + if (!swapMethod.isEnabled()) return when (progressStage) { ProgressStage.PreTick -> { - if (!swapped || autoSwap.isSilent()) return + if (!swapped) return + when { player.inventory.selectedSlot != swappedSlot -> cancelSwap() - autoSwap.isConstant() -> { + swapMode.isConstant() -> { if (swappedSlot != bestTool) swapTo(bestTool) } - - autoSwap.isStartAndEnd() -> returnToOriginalSlot() } - } - ProgressStage.StartPre, - ProgressStage.EndPre -> { - if (!swapped) swapTo(bestTool) + if (swapMode.isStartAndEnd()) returnToOriginalSlot() } - ProgressStage.During -> if (autoSwap.isConstant()) swapTo(bestTool) + ProgressStage.StartPre -> if (!swapped && (!swapMode.isEnd() || instaBroken)) swapTo(bestTool) + + ProgressStage.EndPre -> if (!swapped && !swapMode.isStart()) swapTo(bestTool) + + ProgressStage.During -> if (swapped && swapMode.isConstant() && swappedSlot != bestTool) swapTo(bestTool) ProgressStage.StartPost -> { if (!swapped) return if ((instaBroken && !validateBreak) - || autoSwap.isSilent() + || (swapMethod.isSilent() && !swapMode.isConstant()) ) { returnToOriginalSlot() } @@ -642,46 +686,49 @@ object PacketMine : Module( if (!swapped) return if ((!validateBreak || empty) - || autoSwap.isSilent() + || (swapMethod.isSilent() && !swapMode.isConstant()) ) { returnToOriginalSlot() } } - ProgressStage.PacketReceiveBreak -> if (!autoSwap.isSilent()) returnToOriginalSlot() - + ProgressStage.PacketReceiveBreak, ProgressStage.TimedOut -> returnToOriginalSlot() } } - private fun SafeContext.handleSwing(progressStage: ProgressStage) { + private fun SafeContext.handleSwing(progressStage: ProgressStage, empty: Boolean = false, instaBroken: Boolean = false) { + if (!swingMode.isEnabled()) return + when (progressStage) { ProgressStage.PreTick -> { currentMiningBlock?.apply { - if (breakState != BreakState.ReBreaking && swingMode.isConstant()) { + if (swingMode.isConstant() && breakState == BreakState.Breaking) { swingMainHand() } } } - ProgressStage.During -> if (swingMode.isConstant()) swingMainHand() + ProgressStage.During -> if (swingMode.isConstant() && (!empty || reBreak.isFastAutomatic())) swingMainHand() - ProgressStage.StartPre, - ProgressStage.StartPost -> if (swingMode.isStart() || swingMode.isStartAndEnd()) swingMainHand() + ProgressStage.StartPre -> if (!swingMode.isEnd() || instaBroken) swingMainHand() - ProgressStage.EndPre, - ProgressStage.EndPost -> if (swingMode.isStartAndEnd() || swingMode.isConstant()) swingMainHand() + ProgressStage.EndPre -> if (!swingMode.isStart()) swingMainHand() + ProgressStage.EndPost, + ProgressStage.StartPost, ProgressStage.PacketReceiveBreak, ProgressStage.TimedOut -> {} } } - private fun SafeContext.swingMainHand() = - player.swingHand(Hand.MAIN_HAND) + private fun SafeContext.swingMainHand() { + player.swingHand(Hand.MAIN_HAND, false) + connection.sendPacket(HandSwingC2SPacket(Hand.MAIN_HAND)) + } private fun updateCounters() { - instaBreaksPerTickCounter = 0 + breaksPerTickCounter = 0 if (reBreakDelayCounter > 0) { reBreakDelayCounter-- @@ -716,7 +763,7 @@ object PacketMine : Module( if (returnSlot == -1) { returnSlot = player.inventory.selectedSlot } - if (autoSwap.isSilent()) { + if (swapMethod.isSilent()) { silentSwapTo(slot, false) } else { player.inventory.selectedSlot = slot @@ -727,7 +774,7 @@ object PacketMine : Module( } private fun SafeContext.silentSwapTo(slot: Int, returningToOriginalSlot: Boolean) { - if (autoSwap.isStandardSilent()) { + if (swapMethod.isStandardSilent()) { connection.sendPacket(UpdateSelectedSlotC2SPacket(slot)) return } @@ -757,7 +804,7 @@ object PacketMine : Module( private fun SafeContext.returnToOriginalSlot() { if (!swapped || returnSlot == -1) return - if (autoSwap.isSilent()) { + if (swapMethod.isSilent()) { silentSwapTo(returnSlot, true) } else { player.inventory.selectedSlot = returnSlot @@ -792,6 +839,8 @@ object PacketMine : Module( return } + breaksPerTickCounter++ + queueBreakStartCounter = queueBreakDelay if (breakNextQueueBlock()) return @@ -800,7 +849,7 @@ object PacketMine : Module( breakState = BreakState.ReBreaking } - if (resetProgressOnBreak) mineTicks = 0 + if (strict) resetProgress() return } @@ -817,14 +866,18 @@ object PacketMine : Module( currentMiningBlock = null } - private fun isStateBroken(previousState: BlockState?, activeState: BlockState) = + private fun isStateBroken(previousState: BlockState?, activeState: BlockState): Boolean { previousState?.let { previous -> - activeState.isAir || ( + if (isStateEmpty(previous)) return false + + return activeState.isAir || ( activeState.fluidState.fluid is WaterFluid + && !activeState.properties.contains(Properties.WATERLOGGED) && previous.properties.contains(Properties.WATERLOGGED) && previous.get(Properties.WATERLOGGED) ) - } ?: false + } ?: return false + } private fun isStateEmpty(state: BlockState) = state.isAir || ( @@ -848,7 +901,7 @@ object PacketMine : Module( if (!queueBlocks) return false filterBlockQueueUntilNextPossible()?.apply { - if (queueBreakStartCounter <= 0 && instaBreaksPerTickCounter <= 0) { + if (queueBreakStartCounter <= 0 && breaksPerTickCounter <= 0) { blockQueue.remove(this) startBreaking(this) } else { @@ -882,8 +935,10 @@ object PacketMine : Module( var lastValidBestTool: Int ) { var mineTicks = 0 + var additiveBreakDelta = currentBreakDelta var timeCompleted: Long = -1 var previousBreakDelta = 0f + var lastLerpBox: Box? = null var boxList = if (renderMode.isEnabled()) { state.getOutlineShape(mc.world, pos).boundingBoxes.toSet() @@ -891,16 +946,43 @@ object PacketMine : Module( null } - fun updateRenders(newBreakDelta: Float) { + val miningProgress: Float + get() = if (breakMode.isTotal()) { + mineTicks * currentBreakDelta + } else { + additiveBreakDelta + } + + val previousMiningProgress: Float + get() = if (breakMode.isTotal()) { + (mineTicks - 1) * previousBreakDelta + } else { + additiveBreakDelta - currentBreakDelta + } + + fun resetProgress() { + mineTicks = 0 + additiveBreakDelta = 0f + } + + fun transformProgress(percentage: Float) { + additiveBreakDelta *= percentage + } + + fun updateBreakDeltas(newBreakDelta: Float) { previousBreakDelta = currentBreakDelta currentBreakDelta = newBreakDelta + additiveBreakDelta += newBreakDelta + } + + fun updateRenders() { boxList = lastNonEmptyState?.getOutlineShape(mc.world, pos)?.boundingBoxes?.toSet() } fun SafeContext.buildRenders() { boxList?.forEach { box -> - val previousFactor = (mineTicks - 1) * previousBreakDelta * (2 - breakThreshold) - val nextFactor = mineTicks * currentBreakDelta * (2 - breakThreshold) + val previousFactor = previousMiningProgress * (2 - breakThreshold) + val nextFactor = miningProgress * (2 - breakThreshold) val currentFactor = lerp(previousFactor, nextFactor, mc.tickDelta) val fillColour = if (fillColourMode == ColourMode.Dynamic) { @@ -916,13 +998,21 @@ object PacketMine : Module( } val renderBox = if (renderMode != RenderMode.Static) { - getLerpBox(box, currentFactor).offset(pos) + val lerpBox = getLerpBox(box, currentFactor).offset(pos) + if ((!pauseWhileUsingItems || !player.isUsingItem) && !pausedForRotation) { + lastLerpBox = lerpBox + lerpBox + } else { + lastLerpBox + } } else { box.offset(pos) } val dynamicAABB = DynamicAABB() - dynamicAABB.update(renderBox) + renderBox?.apply { + dynamicAABB.update(this) + } if (renderSetting != RenderSetting.Outline) { renderer.buildFilled(dynamicAABB, fillColour) From 517f719f3b04470f627b46d6adc55b2be2ad347b Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 22 Jul 2024 04:04:52 +0100 Subject: [PATCH 72/91] - removed completed todo --- .../main/kotlin/com/lambda/module/modules/player/PacketMine.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index a6d2bb106..804ac77ad 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -250,8 +250,6 @@ object PacketMine : Module( private var breaksPerTickCounter = 0 private var swingingNextAttack = true - //ToDo: Fix swing on mode start, tbh just find a better way to implement swing cancelling, maybe a different place to listen for block attacks? - init { listener { swingingNextAttack = false From 6153a36863e85fe43daa379ecb51cba5c3c284ba Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Wed, 24 Jul 2024 06:01:30 +0100 Subject: [PATCH 73/91] - should prevent non completely silent uses of ncpsilent autoswap from messing up inventory management as much --- .../main/kotlin/com/lambda/module/modules/player/PacketMine.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 804ac77ad..8a3236558 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -758,6 +758,7 @@ object PacketMine : Module( } private fun SafeContext.swapTo(slot: Int) { + if (swapped && swapMethod.isNCPSilent()) returnToOriginalSlot() if (returnSlot == -1) { returnSlot = player.inventory.selectedSlot } From ff81a9defb700be1162c3490f979a63e38e14178 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Wed, 24 Jul 2024 06:14:45 +0100 Subject: [PATCH 74/91] - uses return slot rather than selected stop to prevent messing up inventory management --- .../kotlin/com/lambda/module/modules/player/PacketMine.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 8a3236558..2ad5d2c46 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -781,10 +781,12 @@ object PacketMine : Module( val screenHandler = player.playerScreenHandler var itemStack = player.mainHandStack var newSlot = slot + var fromSlot = player.inventory.selectedSlot if (returningToOriginalSlot) { newSlot = swappedSlot - itemStack = player.inventory.getStack(swappedSlot) + itemStack = player.inventory.getStack(returnSlot) + fromSlot = returnSlot } connection.sendPacket( @@ -792,7 +794,7 @@ object PacketMine : Module( screenHandler.syncId, screenHandler.revision, newSlot + 36, - player.inventory.selectedSlot, + fromSlot, SlotActionType.SWAP, itemStack, Int2ObjectArrayMap() From c71451528d887e1e4f12fd3ee58aa9897907b881 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Wed, 24 Jul 2024 06:15:48 +0100 Subject: [PATCH 75/91] - updated onDisable --- .../main/kotlin/com/lambda/module/modules/player/PacketMine.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 2ad5d2c46..4620a6ada 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -549,6 +549,7 @@ object PacketMine : Module( waitingToReleaseRotation = false cancelNextSwing = false breaksPerTickCounter = 0 + swingingNextAttack = true } } From e71518b8a13d358d50e80c58da280463f78ca220 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Tue, 30 Jul 2024 04:46:05 +0100 Subject: [PATCH 76/91] - fixed rotations and added more options. Also added raycast setting --- .../module/modules/player/PacketMine.kt | 148 +++++++++++------- 1 file changed, 93 insertions(+), 55 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 4620a6ada..daf33a7e8 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -8,6 +8,7 @@ import com.lambda.graphics.renderer.esp.DynamicAABB import com.lambda.graphics.renderer.esp.builders.buildFilled import com.lambda.graphics.renderer.esp.builders.buildOutline import com.lambda.graphics.renderer.esp.global.DynamicESP +import com.lambda.interaction.RotationManager import com.lambda.interaction.rotation.RotationContext import com.lambda.interaction.visibilty.VisibilityChecker.findRotation import com.lambda.module.Module @@ -15,7 +16,6 @@ import com.lambda.module.modules.client.TaskFlow import com.lambda.module.tag.ModuleTag import com.lambda.util.BlockUtils.blockState import com.lambda.util.math.MathUtils.lerp -import com.lambda.util.world.raycast.RayCastUtils.blockResult import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap import net.minecraft.block.BlockState import net.minecraft.enchantment.EnchantmentHelper @@ -33,6 +33,8 @@ import net.minecraft.registry.tag.FluidTags import net.minecraft.screen.slot.SlotActionType import net.minecraft.state.property.Properties import net.minecraft.util.Hand +import net.minecraft.util.hit.BlockHitResult +import net.minecraft.util.hit.HitResult import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Box import net.minecraft.util.math.Direction @@ -54,9 +56,10 @@ object PacketMine : Module( private val pauseWhileUsingItems by setting("Pause While Using Items", true, "Will prevent breaking while using items like eating or aiming a bow", visibility = { page == Page.General }) private val validateBreak by setting("Validate Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) private val timeoutDelay by setting("Timeout Delay", 0.20f, 0.00f..1.00f, 0.1f, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && validateBreak }) - private val swingMode by setting("Swing Mode", SwingMode.None, "Swings the players hand to simulate vanilla breaking, usually used on stricter anti-cheats", visibility = { page == Page.General }) + private val swingMode by setting("Swing Mode", ModeOptions.None, "Swings the players hand to simulate vanilla breaking, usually used on stricter anti-cheats", visibility = { page == Page.General }) private val swingOnManual by setting("Manual Swing", true, "Swings when the player attacks a block", visibility = { page == Page.General }) - private val rotate by setting("Rotation Mode", RotationMode.None, "Changes the method used to make the player look at the current mining block", visibility = { page == Page.General }) + private val rotate by setting("Rotation Mode", ModeOptions.None, "Changes the method used to make the player look at the current mining block", visibility = { page == Page.General }) + private val rayCast by setting("Raycast", false, "Checks if the player is directly looking at the block rather than allowing through walls", visibility = { page == Page.General && rotate.isEnabled() }) private val rotateReleaseDelay by setting("Rotation Release Delay", 2, 0..50, 1, "The number of ticks to wait before releasing the rotation", visibility = { page == Page.General && rotate.isEnabled() }) private val swapMethod by setting("Swap Method", SwapMethod.StandardSilent, "Changes the swap method used. For example, silent swaps once at the beginning, and once at the end without updating client side, and constant swaps for the whole break", visibility = { page == Page.General}) private val swapMode by setting("Swap Mode", SwapMode.StartAndEnd, "The different times to swap to the best tool", visibility = { page == Page.General && swapMethod.isEnabled()}) @@ -117,38 +120,6 @@ object PacketMine : Module( Vanilla, Grim, NCP } - private enum class SwingMode { - None, Constant, Start, End, StartAndEnd; - - fun isEnabled() = - this != None - - fun isConstant() = - this == Constant - - fun isStart() = - this == Start - - fun isEnd() = - this == End - - fun isStartAndEnd() = - this == StartAndEnd - } - //ToDo: Add start and end settings - private enum class RotationMode { - None, Constant, StartAndEnd; - - fun isEnabled() = - this != None - - fun isConstant() = - this == Constant - - fun isStartAndEnd() = - this == StartAndEnd - } - private enum class SwapMethod { None, StandardSilent, NCPSilent, Vanilla; @@ -197,6 +168,25 @@ object PacketMine : Module( this == FastAutomatic } + private enum class ModeOptions { + None, StartAndEnd, Start, End, Constant; + + fun isEnabled() = + this != None + + fun isStartAndEnd() = + this == StartAndEnd + + fun isStart() = + this == Start + + fun isEnd() = + this == End + + fun isConstant() = + this == Constant + } + private enum class ProgressStage { StartPre, StartPost, PreTick, During, EndPre, EndPost, PacketReceiveBreak, TimedOut } @@ -440,9 +430,7 @@ object PacketMine : Module( rotationPosition?.let { pos -> lastNonEmptyState?.let { state -> val boxList = state.getOutlineShape(world, pos).boundingBoxes.map { it.offset(pos) } - val rotationContext = findRotation(boxList, TaskFlow.rotation, TaskFlow.interact, emptySet()) { - blockResult?.blockPos == pos - } + val rotationContext = findRotation(boxList, TaskFlow.rotation, TaskFlow.interact, emptySet()) { true } rotationContext?.let { context -> it.context = context expectedRotation = context @@ -466,18 +454,28 @@ object PacketMine : Module( listener { if (!rotate.isEnabled()) return@listener - //ToDo: Fix findRotation method to return the correct rotation even if its blocked by another block or something. Also improve raycasting stuff and add a setting - expectedRotation?.apply { - if (this.isValid) { - onRotationComplete?.run() - onRotationComplete = null - } else { - pausedForRotation = true + expectedRotation?.let { expectedRot -> + rotationPosition?.let { pos -> + if (it.context != expectedRot) { + pausedForRotation = true + return@listener + } + + val boxList = lastNonEmptyState?.getOutlineShape(world, pos)?.boundingBoxes?.map { it.offset(pos) } + if (verifyRotation(boxList, RotationManager.currentRotation.vector, it.context.hitResult)) { + onRotationComplete?.run() + onRotationComplete = null + pausedForRotation = false + } else { + pausedForRotation = true + } + + return@listener } - } ?: run { - onRotationComplete = null - pausedForRotation = false } + + onRotationComplete = null + pausedForRotation = false } listener { @@ -620,7 +618,7 @@ object PacketMine : Module( handleSwing(progressStage, empty = empty, instaBroken = instaBroken) } - private fun handleRotations(progressStage: ProgressStage, pos: BlockPos, empty: Boolean = false, instaBroken: Boolean = false) { + private fun SafeContext.handleRotations(progressStage: ProgressStage, pos: BlockPos, empty: Boolean = false, instaBroken: Boolean = false) { when (progressStage) { ProgressStage.PreTick -> { if (rotate.isConstant() @@ -633,14 +631,15 @@ object PacketMine : Module( } } - ProgressStage.StartPre, - ProgressStage.EndPre -> if (rotate.isEnabled() && (validateBreak || !instaBroken)) rotateTo(pos) + ProgressStage.StartPre -> if (rotate.isEnabled() && (!rotate.isEnd() || instaBroken)) rotateTo(pos) + + ProgressStage.EndPre -> if (rotate.isEnabled() && !rotate.isStart()) rotateTo(pos) - ProgressStage.During -> if (rotate.isConstant() && !empty) rotateTo(pos) + ProgressStage.During -> if (rotate.isConstant() && !empty && !reBreak.isStandard()) rotateTo(pos) - ProgressStage.StartPost -> if ((instaBroken && !validateBreak) || rotate.isStartAndEnd()) checkReleaseRotation() + ProgressStage.StartPost -> if ((instaBroken && !validateBreak) || (!instaBroken && (rotate.isStart() || rotate.isStartAndEnd()))) checkReleaseRotation() - ProgressStage.EndPost -> if ((!validateBreak || empty) || rotate.isStartAndEnd()) checkReleaseRotation() + ProgressStage.EndPost -> if (!validateBreak || empty) checkReleaseRotation() ProgressStage.PacketReceiveBreak, ProgressStage.TimedOut -> checkReleaseRotation() @@ -740,11 +739,50 @@ object PacketMine : Module( } } - private fun rotateTo(pos: BlockPos) { + private fun SafeContext.rotateTo(pos: BlockPos) { waitingToReleaseRotation = false releaseRotateDelayCounter = rotateReleaseDelay rotationPosition = pos rotated = true + if (!verifyRotation( + lastNonEmptyState?.getOutlineShape(world, pos)?.boundingBoxes?.map { it.offset(pos) }, + RotationManager.currentRotation.vector, + RotationManager.currentContext?.hitResult) + ) { + pausedForRotation = true + } + } + + private fun SafeContext.verifyRotation(boxes: Collection?, lookVec: Vec3d, hitResult: HitResult?): Boolean { + if (rayCast && (hitResult as BlockHitResult?)?.blockPos != rotationPosition) { + return false + } + + boxes?.let { + return it.any { box -> + lookIntersectsBox(player.eyePos, lookVec, box) + } + } ?: return false + } + + private fun lookIntersectsBox(start: Vec3d, direction: Vec3d, box: Box): Boolean { + val invDirX = 1.0 / direction.x + val invDirY = 1.0 / direction.y + val invDirZ = 1.0 / direction.z + + val tMinX = if (invDirX >= 0) (box.minX - start.x) * invDirX else (box.maxX - start.x) * invDirX + val tMaxX = if (invDirX >= 0) (box.maxX - start.x) * invDirX else (box.minX - start.x) * invDirX + + val tMinY = if (invDirY >= 0) (box.minY - start.y) * invDirY else (box.maxY - start.y) * invDirY + val tMaxY = if (invDirY >= 0) (box.maxY - start.y) * invDirY else (box.minY - start.y) * invDirY + + val tMinZ = if (invDirZ >= 0) (box.minZ - start.z) * invDirZ else (box.maxZ - start.z) * invDirZ + val tMaxZ = if (invDirZ >= 0) (box.maxZ - start.z) * invDirZ else (box.minZ - start.z) * invDirZ + + val tMin = maxOf(tMinX, tMinY, tMinZ) + val tMax = minOf(tMaxX, tMaxY, tMaxZ) + + return tMax >= tMin && tMax > 0 } private fun checkReleaseRotation() { From dc7b085de4490cbaf1536cb2722ece5b59ee3a03 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Tue, 30 Jul 2024 17:00:08 +0100 Subject: [PATCH 77/91] - caches last lerp'd colours to use if paused --- .../lambda/module/modules/player/PacketMine.kt | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index daf33a7e8..b0f7d7cb6 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -979,6 +979,8 @@ object PacketMine : Module( var timeCompleted: Long = -1 var previousBreakDelta = 0f var lastLerpBox: Box? = null + var lastLerpFillColour: Color? = null + var lastLerpOutlineColour: Color? = null var boxList = if (renderMode.isEnabled()) { state.getOutlineShape(mc.world, pos).boundingBoxes.toSet() @@ -1026,13 +1028,25 @@ object PacketMine : Module( val currentFactor = lerp(previousFactor, nextFactor, mc.tickDelta) val fillColour = if (fillColourMode == ColourMode.Dynamic) { - lerp(startFillColour, endFillColour, currentFactor.toDouble()) + val lerpColour = lerp(startFillColour, endFillColour, currentFactor.toDouble()) + if ((!pauseWhileUsingItems || !player.isUsingItem) && !pausedForRotation) { + lastLerpFillColour = lerpColour + lerpColour + } else { + lastLerpFillColour ?: startFillColour + } } else { staticFillColour } val outlineColour = if (outlineColourMode == ColourMode.Dynamic) { - lerp(startOutlineColour, endOutlineColour, currentFactor.toDouble()) + val lerpColour = lerp(startOutlineColour, endOutlineColour, currentFactor.toDouble()) + if ((!pauseWhileUsingItems || !player.isUsingItem) && !pausedForRotation) { + lastLerpOutlineColour = lerpColour + lerpColour + } else { + lastLerpOutlineColour ?: startOutlineColour + } } else { staticOutlineColour } From d7f77187aed5d3f0a60bb26eb3c4a85c226701bc Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Tue, 30 Jul 2024 17:18:07 +0100 Subject: [PATCH 78/91] - tiny consistency change --- .../main/kotlin/com/lambda/module/modules/player/PacketMine.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index b0f7d7cb6..172aa9f92 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -462,7 +462,7 @@ object PacketMine : Module( } val boxList = lastNonEmptyState?.getOutlineShape(world, pos)?.boundingBoxes?.map { it.offset(pos) } - if (verifyRotation(boxList, RotationManager.currentRotation.vector, it.context.hitResult)) { + if (verifyRotation(boxList, RotationManager.currentRotation.vector, RotationManager.currentContext?.hitResult)) { onRotationComplete?.run() onRotationComplete = null pausedForRotation = false From 534da314f1c4c75e7e168438f6a5037cd90cb620 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Tue, 30 Jul 2024 20:06:55 +0100 Subject: [PATCH 79/91] - suppress warnings --- .../kotlin/com/lambda/module/modules/player/PacketMine.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 172aa9f92..8bfbbb395 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -109,6 +109,7 @@ object PacketMine : Module( General, ReBreak, Queue, BlockRender, QueueRender } + @Suppress("UNUSED") private enum class BreakMode { Total, Additive; @@ -120,6 +121,7 @@ object PacketMine : Module( Vanilla, Grim, NCP } + @Suppress("UNUSED") private enum class SwapMethod { None, StandardSilent, NCPSilent, Vanilla; @@ -198,6 +200,7 @@ object PacketMine : Module( this != None } + @Suppress("UNUSED") private enum class RenderQueueMode { None, Cube, Shape; @@ -567,6 +570,7 @@ object PacketMine : Module( previousSelectedSlot = player.inventory.selectedSlot + rotationPosition = pos runBetweenHandlers(ProgressStage.StartPre, ProgressStage.StartPost, pos, { bestTool }, instaBroken = instaBreak) { packetStartBreak(pos) From 594016b1532533cd2f1bb700ccd52445bbe34b2f Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Tue, 30 Jul 2024 20:30:32 +0100 Subject: [PATCH 80/91] - added setting to only draw re-break renders if state isnt empty --- .../kotlin/com/lambda/module/modules/player/PacketMine.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 8bfbbb395..5c8a46f4f 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -68,6 +68,7 @@ object PacketMine : Module( private val reBreak by setting("Re-Break", ReBreakMode.Standard, "The different modes for re-breaking the current block", visibility = { page == Page.ReBreak}) private val reBreakDelay by setting("Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-breaking the block", visibility = { page == Page.ReBreak && (reBreak.isAutomatic() || reBreak.isFastAutomatic()) }) private val emptyReBreakDelay by setting("Empty Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-break the block if the block is currently empty", visibility = { page == Page.ReBreak && reBreak.isFastAutomatic()}) + private val renderIfEmpty by setting("Render If Empty", false, "Draws the renders even if the re-break position is empty in the world", visibility = { page == Page.ReBreak && reBreak.isEnabled() }) private val queueBlocks by setting("Queue Blocks", false, "Queues any blocks you click for breaking", visibility = { page == Page.Queue }).apply { this.onValueSet { _, to -> if (!to) blockQueue.clear() } } private val reverseQueueOrder by setting("Reverse Queue Order", false, "Breaks the latest addition to the queue first", visibility = { page == Page.Queue && queueBlocks}) @@ -304,6 +305,7 @@ object PacketMine : Module( mineTicks++ val activeState = pos.blockState(world) + state = activeState val empty = isStateEmpty(activeState) if (!empty) { @@ -1026,6 +1028,8 @@ object PacketMine : Module( } fun SafeContext.buildRenders() { + if (!renderIfEmpty && isStateEmpty(state)) return + boxList?.forEach { box -> val previousFactor = previousMiningProgress * (2 - breakThreshold) val nextFactor = miningProgress * (2 - breakThreshold) From 1257ffbc916f53953f512111d9ba98919f6627b6 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Tue, 30 Jul 2024 23:51:37 +0100 Subject: [PATCH 81/91] - fixed hit result cast crash issue --- .../main/kotlin/com/lambda/module/modules/player/PacketMine.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 5c8a46f4f..420cf763d 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -572,7 +572,6 @@ object PacketMine : Module( previousSelectedSlot = player.inventory.selectedSlot - rotationPosition = pos runBetweenHandlers(ProgressStage.StartPre, ProgressStage.StartPost, pos, { bestTool }, instaBroken = instaBreak) { packetStartBreak(pos) @@ -760,7 +759,7 @@ object PacketMine : Module( } private fun SafeContext.verifyRotation(boxes: Collection?, lookVec: Vec3d, hitResult: HitResult?): Boolean { - if (rayCast && (hitResult as BlockHitResult?)?.blockPos != rotationPosition) { + if (rayCast && (hitResult?.type == HitResult.Type.ENTITY || (hitResult as BlockHitResult?)?.blockPos != rotationPosition)) { return false } From b1a8d0cdca911c96983b415a5ea51c43a2abf90f Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Wed, 31 Jul 2024 05:19:42 +0100 Subject: [PATCH 82/91] - small fix to allow swapping current mining block while paused for rotation --- .../main/kotlin/com/lambda/module/modules/player/PacketMine.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 420cf763d..25a602d9a 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -627,6 +627,7 @@ object PacketMine : Module( when (progressStage) { ProgressStage.PreTick -> { if (rotate.isConstant() + && !rotated && !empty && (currentMiningBlock?.breakState != BreakState.ReBreaking || !reBreak.isStandard() From d1e613c7bdf37ca96c97bb0b1087e252b5e30b61 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Wed, 31 Jul 2024 16:15:06 +0100 Subject: [PATCH 83/91] - lowered minimum keep rotation ticks to 0 --- .../main/kotlin/com/lambda/config/groups/RotationSettings.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/kotlin/com/lambda/config/groups/RotationSettings.kt b/common/src/main/kotlin/com/lambda/config/groups/RotationSettings.kt index 8dae291d3..1d047c154 100644 --- a/common/src/main/kotlin/com/lambda/config/groups/RotationSettings.kt +++ b/common/src/main/kotlin/com/lambda/config/groups/RotationSettings.kt @@ -16,7 +16,7 @@ class RotationSettings( vis ) - override val keepTicks by c.setting("Keep Rotation", 3, 1..10, 1, "Ticks to keep rotation", " ticks", vis) + override val keepTicks by c.setting("Keep Rotation", 3, 0..10, 1, "Ticks to keep rotation", " ticks", vis) override val resetTicks by c.setting("Reset Rotation", 3, 1..10, 1, "Ticks before rotation is reset", " ticks", vis) /** From 871eb69137dcbe5eb22e34e2a01a4d27d95d1ed0 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Thu, 1 Aug 2024 00:28:20 +0100 Subject: [PATCH 84/91] - swapped current mining block to an array in prep for double break --- .../module/modules/player/PacketMine.kt | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 25a602d9a..13732a1ee 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -222,7 +222,7 @@ object PacketMine : Module( } val renderer = DynamicESP - private var currentMiningBlock: BreakingContext? = null + private var currentMiningBlock = Array(2) { null } private var lastNonEmptyState: BlockState? = null private val blockQueue = ArrayDeque() private var queueBreakStartCounter = 0 @@ -268,7 +268,7 @@ object PacketMine : Module( return@listener } - currentMiningBlock?.apply { + currentMiningBlock[0]?.apply { if (it.pos != pos || breakState != BreakState.ReBreaking || !reBreak.isStandard()) return@apply if (miningProgress < breakThreshold) return@listener @@ -301,7 +301,7 @@ object PacketMine : Module( if (breakNextQueueBlock()) return@listener } - currentMiningBlock?.apply { + currentMiningBlock[0]?.apply { mineTicks++ val activeState = pos.blockState(world) @@ -420,7 +420,7 @@ object PacketMine : Module( } listener { - currentMiningBlock?.apply { + currentMiningBlock[0]?.apply { if (it.pos != pos || !isStateBroken(pos.blockState(world), it.state)) return@listener runHandlers(ProgressStage.PacketReceiveBreak, pos, lastValidBestTool) @@ -486,7 +486,7 @@ object PacketMine : Module( listener { renderer.clear() - currentMiningBlock?.apply { + currentMiningBlock[0]?.apply { buildRenders() } @@ -532,7 +532,8 @@ object PacketMine : Module( } onDisable { - currentMiningBlock = null + currentMiningBlock[0] = null + currentMiningBlock[1] = null lastNonEmptyState = null blockQueue.clear() queueBreakStartCounter = 0 @@ -557,7 +558,7 @@ object PacketMine : Module( } private fun SafeContext.startBreaking(pos: BlockPos) { - if (currentMiningBlock?.pos == pos || blockQueue.contains(pos)) return + if (currentMiningBlock[0]?.pos == pos || blockQueue.contains(pos)) return val state = pos.blockState(world) val bestTool = getBestTool(state, pos) @@ -575,7 +576,7 @@ object PacketMine : Module( runBetweenHandlers(ProgressStage.StartPre, ProgressStage.StartPost, pos, { bestTool }, instaBroken = instaBreak) { packetStartBreak(pos) - currentMiningBlock = BreakingContext(pos, state, BreakState.Breaking, breakDelta, bestTool) + currentMiningBlock[0] = BreakingContext(pos, state, BreakState.Breaking, breakDelta, bestTool) if (!instaBreak) return@runBetweenHandlers @@ -629,7 +630,7 @@ object PacketMine : Module( if (rotate.isConstant() && !rotated && !empty - && (currentMiningBlock?.breakState != BreakState.ReBreaking + && (currentMiningBlock[0]?.breakState != BreakState.ReBreaking || !reBreak.isStandard() ) ) { @@ -706,7 +707,7 @@ object PacketMine : Module( when (progressStage) { ProgressStage.PreTick -> { - currentMiningBlock?.apply { + currentMiningBlock[0]?.apply { if (swingMode.isConstant() && breakState == BreakState.Breaking) { swingMainHand() } @@ -873,7 +874,7 @@ object PacketMine : Module( player.eyePos.distanceTo(vec) > range private fun SafeContext.onBlockBreak(packetReceiveBreak: Boolean) { - currentMiningBlock?.apply { + currentMiningBlock[0]?.apply { if (!isOutOfRange(pos.toCenterPos()) || packetReceiveBreak) { checkClientSideBreak(packetReceiveBreak, pos) } @@ -904,12 +905,12 @@ object PacketMine : Module( } private fun SafeContext.nullifyCurrentBreakingBlock() { - currentMiningBlock?.apply { + currentMiningBlock[0]?.apply { if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, -1) runHandlers(ProgressStage.TimedOut, pos, lastValidBestTool) } - currentMiningBlock = null + currentMiningBlock[0] = null } private fun isStateBroken(previousState: BlockState?, activeState: BlockState): Boolean { @@ -938,9 +939,9 @@ object PacketMine : Module( private fun shouldBePlacedInBlockQueue(pos: BlockPos): Boolean = queueBlocks - && currentMiningBlock != null - && currentMiningBlock?.breakState != BreakState.ReBreaking - && currentMiningBlock?.pos != pos + && currentMiningBlock[0] != null + && currentMiningBlock[0]?.breakState != BreakState.ReBreaking + && currentMiningBlock[0]?.pos != pos && !blockQueue.contains(pos) private fun SafeContext.breakNextQueueBlock(): Boolean { @@ -951,7 +952,7 @@ object PacketMine : Module( blockQueue.remove(this) startBreaking(this) } else { - currentMiningBlock = null + currentMiningBlock[0] = null awaitingQueueBreak = true } return true From feff4a14251ba0f42efa0ceaa18168d552f032ec Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Fri, 9 Aug 2024 21:52:20 +0100 Subject: [PATCH 85/91] - fixed skill issue reBreak thing on instamine blocks --- .../main/kotlin/com/lambda/module/modules/player/PacketMine.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 13732a1ee..db2e85b82 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -581,7 +581,6 @@ object PacketMine : Module( if (!instaBreak) return@runBetweenHandlers packetStopBreak(pos) - if (reBreak.isEnabled()) packetStartBreak(pos) onBlockBreak(false) } @@ -1127,7 +1126,7 @@ object PacketMine : Module( abortBreak(pos) } if (packets == PacketMode.Grim) { - packetStopBreak(pos) + stopBreak(pos) } } From 87bf1ba6434411db3965a1b8946c6282e9a2e3fa Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Sun, 11 Aug 2024 23:28:38 +0100 Subject: [PATCH 86/91] - added double break --- .../module/modules/player/PacketMine.kt | 477 ++++++++++++------ 1 file changed, 326 insertions(+), 151 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index db2e85b82..544b6ab86 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -32,6 +32,7 @@ import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket import net.minecraft.registry.tag.FluidTags import net.minecraft.screen.slot.SlotActionType import net.minecraft.state.property.Properties +import net.minecraft.text.Text import net.minecraft.util.Hand import net.minecraft.util.hit.BlockHitResult import net.minecraft.util.hit.HitResult @@ -53,6 +54,7 @@ object PacketMine : Module( private val breakMode by setting("Break Mode", BreakMode.Total, "Changes the way break amount is added up. Total will choose the best tool and act as if its been using it the whole time while additive will add progress throughout the break", visibility = { page == Page.General }) private val strict by setting("Strict", false, "Resets the breaking progress at various stages to bypass generally stricter anti-cheats", visibility = { page == Page.General }) private val range by setting("Range", 6.0f, 3.0f..6.0f, 0.1f, "The maximum distance between the players eye position and the center of the block", visibility = { page == Page.General }) + private val doubleBreak by setting("Double Break", false, "This exploit only works on non strict servers or servers that run grim. It breaks two blocks at once", visibility = { page == Page.General }) private val pauseWhileUsingItems by setting("Pause While Using Items", true, "Will prevent breaking while using items like eating or aiming a bow", visibility = { page == Page.General }) private val validateBreak by setting("Validate Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) private val timeoutDelay by setting("Timeout Delay", 0.20f, 0.00f..1.00f, 0.1f, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && validateBreak }) @@ -221,6 +223,13 @@ object PacketMine : Module( Breaking, ReBreaking, AwaitingResponse } + private enum class BreakType { + Primary, Double; + + fun isPrimary() = + this == Primary + } + val renderer = DynamicESP private var currentMiningBlock = Array(2) { null } private var lastNonEmptyState: BlockState? = null @@ -243,6 +252,9 @@ object PacketMine : Module( private var cancelNextSwing = false private var breaksPerTickCounter = 0 private var swingingNextAttack = true + private var doubleBreakSwapped = false + private var doubleBreakSwappedCounter = 0 + private var doubleBreakReturnSlot = 0 init { listener { @@ -259,26 +271,46 @@ object PacketMine : Module( swingingNextAttack = true } - if (shouldBePlacedInBlockQueue(it.pos)) { - if (reverseQueueOrder) { - blockQueue.addFirst(it.pos) - } else { - blockQueue.add(it.pos) + if (queueBlocks) { + if (shouldBePlacedInBlockQueue(it.pos)) { + if (reverseQueueOrder) { + blockQueue.addFirst(it.pos) + } else { + blockQueue.add(it.pos) + } + return@listener } - return@listener + + if (blockQueue.contains(it.pos)) return@listener } - currentMiningBlock[0]?.apply { - if (it.pos != pos || breakState != BreakState.ReBreaking || !reBreak.isStandard()) return@apply + currentMiningBlock.forEach { ctx -> + ctx?.apply { + if (it.pos != pos) return@forEach + + val primary = breakType.isPrimary() + + if (!primary || (breakState == BreakState.ReBreaking && !reBreak.isStandard())) return@listener + + if (miningProgress < breakThreshold) return@listener - if (miningProgress < breakThreshold) return@listener + runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, { lastValidBestTool }) { + packetStopBreak(pos) - runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, { lastValidBestTool }) { - packetStopBreak(pos) + onBlockBreak() + } - onBlockBreak(false) + return@listener + } + } + + currentMiningBlock[0]?.apply { + + currentMiningBlock[1]?.run { return@apply } + + if (doubleBreak && breakState != BreakState.ReBreaking) { + switchCurrentMiningBlockToDouble() } - return@listener } startBreaking(it.pos) @@ -294,138 +326,182 @@ object PacketMine : Module( listener(1) { updateCounters() - if (awaitingQueueBreak) { - if (queueBreakStartCounter > 0) return@listener + if (shouldWaitForQueuePause()) return@listener - awaitingQueueBreak = false - if (breakNextQueueBlock()) return@listener - } + currentMiningBlock.forEach { ctx -> + ctx?.apply { - currentMiningBlock[0]?.apply { - mineTicks++ + mineTicks++ - val activeState = pos.blockState(world) - state = activeState + val activeState = pos.blockState(world) + state = activeState - val empty = isStateEmpty(activeState) - if (!empty) { - if (activeState != lastNonEmptyState?.block) { - lastNonEmptyState?.apply { - transformProgress(block.hardness / activeState.block.hardness) - } + val empty = isStateEmpty(activeState) + + val bestTool = if (breakType.isPrimary()) { + lastNonEmptyState?.run { + getBestTool(this, pos) + } ?: player.inventory.selectedSlot + } else { + getBestTool(state, pos) } - lastNonEmptyState = activeState - } + if (breakType.isPrimary()) { + if (!empty) { + if (activeState != lastNonEmptyState?.block) { + lastNonEmptyState?.apply { + transformProgress(block.hardness / activeState.block.hardness) + } + } - lastNonEmptyState?.let { - lastValidBestTool = getBestTool(it, pos) - } + lastNonEmptyState = activeState + } - runHandlers(ProgressStage.PreTick, pos, lastValidBestTool, empty) + lastNonEmptyState?.let { + lastValidBestTool = bestTool + } - if (strict - && !swapped - && player.inventory.selectedSlot != previousSelectedSlot - ) { - resetProgress() - } - previousSelectedSlot = player.inventory.selectedSlot + runHandlers(ProgressStage.PreTick, pos, lastValidBestTool, empty) - if ((pauseWhileUsingItems && player.isUsingItem) || pausedForRotation) { - return@listener - } + if (strict + && !swapped + && player.inventory.selectedSlot != previousSelectedSlot + ) { + resetProgress() + currentMiningBlock[1]?.apply { + resetProgress() + } + } + previousSelectedSlot = player.inventory.selectedSlot + } - currentBreakDelta = lastNonEmptyState?.let { lastNonEmptyState -> - if (swapMethod.isEnabled()) { - calcBreakDelta(lastNonEmptyState, pos, lastValidBestTool) + if ((pauseWhileUsingItems && player.isUsingItem) || pausedForRotation) { + return@forEach + } + + currentBreakDelta = if (swapMethod.isEnabled()) { + if (breakType.isPrimary()) { + calcBreakDelta(state, pos, lastValidBestTool) + } else { + calcBreakDelta(state, pos, bestTool) + } } else { - calcBreakDelta(lastNonEmptyState, pos, player.inventory.selectedSlot) + calcBreakDelta(state, pos, player.inventory.selectedSlot) } - } ?: 0f - updateBreakDeltas(currentBreakDelta) + updateBreakDeltas(currentBreakDelta) - if (renderMode.isEnabled()) updateRenders() + if (renderMode.isEnabled()) updateRenders() - if (breakingAnimation) - world.setBlockBreakingInfo( - player.id, - pos, - (miningProgress * (2 - breakThreshold) * 10).toInt().coerceAtMost(9) - ) + if (breakingAnimation + && breakType.isPrimary()) + world.setBlockBreakingInfo( + player.id, + pos, + (miningProgress * (2 - breakThreshold) * 10).toInt().coerceAtMost(9) + ) - when (breakState) { - BreakState.Breaking -> { - if (miningProgress < breakThreshold) return@listener + when (breakState) { + BreakState.Breaking -> { + val threshold = if (breakType.isPrimary()) breakThreshold else 1f - timeCompleted = System.currentTimeMillis() + if (miningProgress < threshold) return@forEach - runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, { lastValidBestTool }) { - packetStopBreak(pos) + timeCompleted = System.currentTimeMillis() - onBlockBreak(false) - } - } + if (breakType.isPrimary()) { + runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, { lastValidBestTool }) { + packetStopBreak(pos) - BreakState.ReBreaking -> { - if (miningProgress < breakThreshold) { - runHandlers(ProgressStage.During, pos, lastValidBestTool, empty = empty) - return@listener - } + onBlockBreak(doubleBreakBlock = false) + } + return@forEach + } - if (isOutOfRange(pos.toCenterPos()) || !reBreak.isEnabled()) { - nullifyCurrentBreakingBlock() - return@listener + doubleBreakSwapTo(bestTool) + onBlockBreak(doubleBreakBlock = true) } - if (breakNextQueueBlock() || reBreak.isStandard()) return@listener + BreakState.ReBreaking -> { + if (miningProgress < breakThreshold) { + runHandlers(ProgressStage.During, pos, lastValidBestTool, empty = empty) + return@forEach + } - if (empty) { - if (emptyReBreakDelayCounter > 0) return@listener - emptyReBreakDelayCounter = emptyReBreakDelay - } else { - if (reBreakDelayCounter > 0) return@listener - reBreakDelayCounter = reBreakDelay - } + if (isOutOfRange(pos.toCenterPos()) || !reBreak.isEnabled()) { + nullifyCurrentBreakingBlock(false) + return@forEach + } - if (!reBreak.isFastAutomatic() && empty) { - return@listener - } + if (breakNextQueueBlock() || reBreak.isStandard()) return@forEach - runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, { lastValidBestTool }, empty = empty) { - packetStopBreak(pos) + if (empty) { + if (emptyReBreakDelayCounter > 0) return@forEach + emptyReBreakDelayCounter = emptyReBreakDelay + } else { + if (reBreakDelayCounter > 0) return@forEach + reBreakDelayCounter = reBreakDelay + } - onBlockBreak(false) - } - } + if (!reBreak.isFastAutomatic() && empty) { + return@forEach + } - BreakState.AwaitingResponse -> { - if (!validateBreak) { - runHandlers(ProgressStage.EndPost, pos, lastValidBestTool) - onBlockBreak(false) - return@listener + runBetweenHandlers(ProgressStage.EndPre, ProgressStage.EndPost, pos, { lastValidBestTool }, empty = empty) { + packetStopBreak(pos) + + onBlockBreak() + } } - if (System.currentTimeMillis() - timeCompleted < timeoutDelay * 1000) return@listener + BreakState.AwaitingResponse -> { + if (!validateBreak) { + if (breakType.isPrimary()) { + runHandlers(ProgressStage.EndPost, pos, lastValidBestTool) + } + onBlockBreak(doubleBreakBlock = !breakType.isPrimary()) + return@forEach + } + + if (System.currentTimeMillis() - timeCompleted < timeoutDelay * 1000) return@forEach - if (breakNextQueueBlock()) return@listener + val primary = breakType.isPrimary() - runHandlers(ProgressStage.TimedOut, pos, lastValidBestTool) + if (!primary) nullifyCurrentBreakingBlock(true) + if (breakNextQueueBlock()) return@forEach - nullifyCurrentBreakingBlock() + if (primary) { + runHandlers(ProgressStage.TimedOut, pos, lastValidBestTool) + } + + nullifyCurrentBreakingBlock(!breakType.isPrimary()) + } } } } } + listener { + if (doubleBreakSwapped && doubleBreakSwappedCounter >= 1) { + returnToOriginalDoubleBreakSlot() + } + } + listener { - currentMiningBlock[0]?.apply { - if (it.pos != pos || !isStateBroken(pos.blockState(world), it.state)) return@listener + currentMiningBlock.forEach { ctx -> + ctx?.apply { + if (it.pos != pos || !isStateBroken(pos.blockState(world), it.state)) return@forEach - runHandlers(ProgressStage.PacketReceiveBreak, pos, lastValidBestTool) + if (breakType.isPrimary()) { + runHandlers(ProgressStage.PacketReceiveBreak, pos, lastValidBestTool) + } else { + if (doubleBreakSwapped) { + returnToOriginalDoubleBreakSlot() + } + } - onBlockBreak(true) + onBlockBreak(packetReceiveBreak = true, doubleBreakBlock = !breakType.isPrimary()) + } } } @@ -486,8 +562,8 @@ object PacketMine : Module( listener { renderer.clear() - currentMiningBlock[0]?.apply { - buildRenders() + currentMiningBlock.forEach { ctx -> + ctx?.run { buildRenders() } } if (renderQueueMode.isEnabled()) { @@ -554,12 +630,13 @@ object PacketMine : Module( cancelNextSwing = false breaksPerTickCounter = 0 swingingNextAttack = true + doubleBreakSwapped = false + doubleBreakSwappedCounter = 0 + doubleBreakReturnSlot = 0 } } private fun SafeContext.startBreaking(pos: BlockPos) { - if (currentMiningBlock[0]?.pos == pos || blockQueue.contains(pos)) return - val state = pos.blockState(world) val bestTool = getBestTool(state, pos) if (!isStateEmpty(state)) lastNonEmptyState = state @@ -582,7 +659,7 @@ object PacketMine : Module( packetStopBreak(pos) - onBlockBreak(false) + onBlockBreak() } } @@ -743,6 +820,15 @@ object PacketMine : Module( if (queueBreakStartCounter > 0) { queueBreakStartCounter-- } + if (doubleBreakSwapped) { + doubleBreakSwappedCounter++ + } + } + + private fun switchCurrentMiningBlockToDouble() { + currentMiningBlock[1] = currentMiningBlock[0] + currentMiningBlock[0] = null + currentMiningBlock[1]?.breakType = BreakType.Double } private fun SafeContext.rotateTo(pos: BlockPos) { @@ -856,6 +942,12 @@ object PacketMine : Module( player.inventory.selectedSlot = returnSlot connection.sendPacket(UpdateSelectedSlotC2SPacket(returnSlot)) } + + if (doubleBreakSwapped && (!swapMethod.isSilent() || swapMode.isConstant())) { + doubleBreakSwapped = false + doubleBreakReturnSlot = 0 + } + returnSlot = -1 swappedSlot = -1 swapped = false @@ -863,6 +955,31 @@ object PacketMine : Module( return } + private fun SafeContext.doubleBreakSwapTo(slot: Int) { + val currentSelectedSlot = player.inventory.selectedSlot + + if (slot != currentSelectedSlot) { + doubleBreakReturnSlot = currentSelectedSlot + player.inventory.selectedSlot = slot + connection.sendPacket(UpdateSelectedSlotC2SPacket(slot)) + } + + doubleBreakSwappedCounter = 0 + doubleBreakSwapped = true + } + + private fun SafeContext.returnToOriginalDoubleBreakSlot() { + if (!doubleBreakSwapped) return + + if (doubleBreakReturnSlot != player.inventory.selectedSlot) { + player.inventory.selectedSlot = doubleBreakReturnSlot + connection.sendPacket(UpdateSelectedSlotC2SPacket(doubleBreakReturnSlot)) + } + + doubleBreakReturnSlot = 0 + doubleBreakSwapped = false + } + private fun cancelSwap() { returnSlot = -1 swappedSlot = -1 @@ -872,25 +989,35 @@ object PacketMine : Module( private fun SafeContext.isOutOfRange(vec: Vec3d) = player.eyePos.distanceTo(vec) > range - private fun SafeContext.onBlockBreak(packetReceiveBreak: Boolean) { - currentMiningBlock[0]?.apply { + private fun SafeContext.onBlockBreak(packetReceiveBreak: Boolean = false, doubleBreakBlock: Boolean = false) { + val block = if (doubleBreakBlock) 1 else 0 + + currentMiningBlock[block]?.apply { if (!isOutOfRange(pos.toCenterPos()) || packetReceiveBreak) { - checkClientSideBreak(packetReceiveBreak, pos) + if (breakType.isPrimary() || packetReceiveBreak) { + checkClientSideBreak(packetReceiveBreak, pos, doubleBreakBlock = doubleBreakBlock) + } } - timeCompleted = System.currentTimeMillis() + if (timeCompleted == -1L) { + timeCompleted = System.currentTimeMillis() + } if (validateBreak && breakState == BreakState.Breaking) { breakState = BreakState.AwaitingResponse return } + if (!breakType.isPrimary() && (breakState == BreakState.AwaitingResponse || !validateBreak)) { + nullifyCurrentBreakingBlock(true) + } + breaksPerTickCounter++ queueBreakStartCounter = queueBreakDelay - if (breakNextQueueBlock()) return + if (breakNextQueueBlock(doubleBreakBlock = doubleBreakBlock)) return - if (reBreak.isEnabled() && !isOutOfRange(pos.toCenterPos())) { + if (reBreak.isEnabled() && !isOutOfRange(pos.toCenterPos()) && breakType.isPrimary()) { if (breakState != BreakState.ReBreaking) { breakState = BreakState.ReBreaking } @@ -899,17 +1026,21 @@ object PacketMine : Module( return } - nullifyCurrentBreakingBlock() + nullifyCurrentBreakingBlock(doubleBreakBlock) } } - private fun SafeContext.nullifyCurrentBreakingBlock() { - currentMiningBlock[0]?.apply { - if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, -1) - runHandlers(ProgressStage.TimedOut, pos, lastValidBestTool) + private fun SafeContext.nullifyCurrentBreakingBlock(doubleBreakBlock: Boolean) { + val block = if (doubleBreakBlock) 1 else 0 + + if (!doubleBreakBlock) { + currentMiningBlock[block]?.apply { + if (breakingAnimation) world.setBlockBreakingInfo(player.id, pos, -1) + runHandlers(ProgressStage.TimedOut, pos, lastValidBestTool) + } } - currentMiningBlock[0] = null + currentMiningBlock[block] = null } private fun isStateBroken(previousState: BlockState?, activeState: BlockState): Boolean { @@ -932,32 +1063,57 @@ object PacketMine : Module( && !state.fluidState.isEmpty ) - private fun SafeContext.checkClientSideBreak(packetReceiveBreak: Boolean, pos: BlockPos) { - if (packetReceiveBreak == validateBreak) interaction.breakBlock(pos) + private fun SafeContext.checkClientSideBreak(packetReceiveBreak: Boolean, pos: BlockPos, doubleBreakBlock: Boolean = false) { + if (packetReceiveBreak == validateBreak || doubleBreakBlock && packetReceiveBreak) { + interaction.breakBlock(pos) + } } + //ToDo: Fix this shit private fun shouldBePlacedInBlockQueue(pos: BlockPos): Boolean = - queueBlocks - && currentMiningBlock[0] != null - && currentMiningBlock[0]?.breakState != BreakState.ReBreaking - && currentMiningBlock[0]?.pos != pos - && !blockQueue.contains(pos) - - private fun SafeContext.breakNextQueueBlock(): Boolean { - if (!queueBlocks) return false - - filterBlockQueueUntilNextPossible()?.apply { - if (queueBreakStartCounter <= 0 && breaksPerTickCounter <= 0) { - blockQueue.remove(this) - startBreaking(this) - } else { - currentMiningBlock[0] = null - awaitingQueueBreak = true - } - return true - } + (((currentMiningBlock[0] != null && !doubleBreak) || currentMiningBlock[1] != null) || !blockQueue.isEmpty()) + && (currentMiningBlock[0]?.breakState != BreakState.ReBreaking || !blockQueue.isEmpty()) + && currentMiningBlock[0]?.pos != pos + && currentMiningBlock[1]?.pos != pos + && !blockQueue.contains(pos) - return false + private fun SafeContext.breakNextQueueBlock(doubleBreakBlock: Boolean = false): Boolean { + if (!queueBlocks || currentMiningBlock.any { it?.timeCompleted == -1L }) return false + + var startedBreakingAtLeastOne = false + + while (true) { + filterBlockQueueUntilNextPossible()?.let { block -> + currentMiningBlock[1]?.run { + return startedBreakingAtLeastOne + } + + val requiresAnotherTickDelay = doubleBreakBlock && !validateBreak && queueBreakDelay <= 0 && doubleBreak + + if (queueBreakStartCounter > 0 || breaksPerTickCounter >= 1 || requiresAnotherTickDelay) { + if (requiresAnotherTickDelay) queueBreakStartCounter++ + awaitingQueueBreak = true + return true + } + + currentMiningBlock[0]?.apply { + if (timeCompleted != -1L || breakState == BreakState.ReBreaking) return@apply + + if (!doubleBreak) return startedBreakingAtLeastOne + + switchCurrentMiningBlockToDouble() + } + + blockQueue.remove(block) + startBreaking(block) + + if (!doubleBreak || startedBreakingAtLeastOne) { + return true + } + + startedBreakingAtLeastOne = true + } ?: return startedBreakingAtLeastOne + } } private fun SafeContext.filterBlockQueueUntilNextPossible(): BlockPos? { @@ -973,14 +1129,26 @@ object PacketMine : Module( } } - private data class BreakingContext( + private fun SafeContext.shouldWaitForQueuePause(): Boolean { + if (awaitingQueueBreak) { + if (queueBreakStartCounter > 0) return true + + awaitingQueueBreak = false + if (breakNextQueueBlock()) return true + } + + return false + } + + private class BreakingContext( val pos: BlockPos, var state: BlockState, var breakState: BreakState, var currentBreakDelta: Float, - var lastValidBestTool: Int + var lastValidBestTool: Int, ) { var mineTicks = 0 + var breakType = BreakType.Primary var additiveBreakDelta = currentBreakDelta var timeCompleted: Long = -1 var previousBreakDelta = 0f @@ -1031,13 +1199,20 @@ object PacketMine : Module( if (!renderIfEmpty && isStateEmpty(state)) return boxList?.forEach { box -> - val previousFactor = previousMiningProgress * (2 - breakThreshold) - val nextFactor = miningProgress * (2 - breakThreshold) + val threshold = if (breakType.isPrimary()) { + 2f - breakThreshold + } else { + 1f + } + val previousFactor = previousMiningProgress * threshold + val nextFactor = miningProgress * threshold val currentFactor = lerp(previousFactor, nextFactor, mc.tickDelta) + val paused = (pauseWhileUsingItems && player.isUsingItem) || pausedForRotation || awaitingQueueBreak + val fillColour = if (fillColourMode == ColourMode.Dynamic) { val lerpColour = lerp(startFillColour, endFillColour, currentFactor.toDouble()) - if ((!pauseWhileUsingItems || !player.isUsingItem) && !pausedForRotation) { + if (!paused) { lastLerpFillColour = lerpColour lerpColour } else { @@ -1049,7 +1224,7 @@ object PacketMine : Module( val outlineColour = if (outlineColourMode == ColourMode.Dynamic) { val lerpColour = lerp(startOutlineColour, endOutlineColour, currentFactor.toDouble()) - if ((!pauseWhileUsingItems || !player.isUsingItem) && !pausedForRotation) { + if (!paused) { lastLerpOutlineColour = lerpColour lerpColour } else { @@ -1061,7 +1236,7 @@ object PacketMine : Module( val renderBox = if (renderMode != RenderMode.Static) { val lerpBox = getLerpBox(box, currentFactor).offset(pos) - if ((!pauseWhileUsingItems || !player.isUsingItem) && !pausedForRotation) { + if (!paused) { lastLerpBox = lerpBox lerpBox } else { @@ -1122,10 +1297,10 @@ object PacketMine : Module( private fun SafeContext.packetStartBreak(pos: BlockPos) { startBreak(pos) - if (packets != PacketMode.Vanilla) { + if (packets != PacketMode.Vanilla || doubleBreak) { abortBreak(pos) } - if (packets == PacketMode.Grim) { + if (packets == PacketMode.Grim || doubleBreak) { stopBreak(pos) } } From cb4308dea6425e556568a8a15ab17d804b40302d Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 12 Aug 2024 04:39:06 +0100 Subject: [PATCH 87/91] - fixed some render issues --- .../module/modules/player/PacketMine.kt | 102 ++++++++++-------- 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 544b6ab86..50bf2e43b 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -32,7 +32,6 @@ import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket import net.minecraft.registry.tag.FluidTags import net.minecraft.screen.slot.SlotActionType import net.minecraft.state.property.Properties -import net.minecraft.text.Text import net.minecraft.util.Hand import net.minecraft.util.hit.BlockHitResult import net.minecraft.util.hit.HitResult @@ -1152,7 +1151,7 @@ object PacketMine : Module( var additiveBreakDelta = currentBreakDelta var timeCompleted: Long = -1 var previousBreakDelta = 0f - var lastLerpBox: Box? = null + var lastLerpedBoxes: HashSet = hashSetOf() var lastLerpFillColour: Color? = null var lastLerpOutlineColour: Color? = null @@ -1192,64 +1191,83 @@ object PacketMine : Module( } fun updateRenders() { - boxList = lastNonEmptyState?.getOutlineShape(mc.world, pos)?.boundingBoxes?.toSet() + boxList = if (breakType.isPrimary()) { + lastNonEmptyState?.getOutlineShape(mc.world, pos)?.boundingBoxes?.toSet() + } else { + state.getOutlineShape(mc.world, pos)?.boundingBoxes?.toSet() + } } fun SafeContext.buildRenders() { if (!renderIfEmpty && isStateEmpty(state)) return - boxList?.forEach { box -> - val threshold = if (breakType.isPrimary()) { - 2f - breakThreshold - } else { - 1f - } - val previousFactor = previousMiningProgress * threshold - val nextFactor = miningProgress * threshold - val currentFactor = lerp(previousFactor, nextFactor, mc.tickDelta) + val threshold = if (breakType.isPrimary()) { + 2f - breakThreshold + } else { + 1f + } + val previousFactor = previousMiningProgress * threshold + val nextFactor = miningProgress * threshold + val currentFactor = lerp(previousFactor, nextFactor, mc.tickDelta) - val paused = (pauseWhileUsingItems && player.isUsingItem) || pausedForRotation || awaitingQueueBreak + val paused = (pauseWhileUsingItems && player.isUsingItem) || pausedForRotation || awaitingQueueBreak - val fillColour = if (fillColourMode == ColourMode.Dynamic) { - val lerpColour = lerp(startFillColour, endFillColour, currentFactor.toDouble()) - if (!paused) { - lastLerpFillColour = lerpColour - lerpColour - } else { - lastLerpFillColour ?: startFillColour - } + val fillColour = if (fillColourMode == ColourMode.Dynamic) { + val lerpColour = lerp(startFillColour, endFillColour, currentFactor.toDouble()) + if (!paused) { + lastLerpFillColour = lerpColour + lerpColour } else { - staticFillColour + lastLerpFillColour ?: startFillColour } + } else { + staticFillColour + } - val outlineColour = if (outlineColourMode == ColourMode.Dynamic) { - val lerpColour = lerp(startOutlineColour, endOutlineColour, currentFactor.toDouble()) - if (!paused) { - lastLerpOutlineColour = lerpColour - lerpColour - } else { - lastLerpOutlineColour ?: startOutlineColour - } + val outlineColour = if (outlineColourMode == ColourMode.Dynamic) { + val lerpColour = lerp(startOutlineColour, endOutlineColour, currentFactor.toDouble()) + if (!paused) { + lastLerpOutlineColour = lerpColour + lerpColour } else { - staticOutlineColour + lastLerpOutlineColour ?: startOutlineColour } + } else { + staticOutlineColour + } - val renderBox = if (renderMode != RenderMode.Static) { - val lerpBox = getLerpBox(box, currentFactor).offset(pos) - if (!paused) { - lastLerpBox = lerpBox - lerpBox - } else { - lastLerpBox + if (paused) { + lastLerpedBoxes.forEach { box -> + val dynamicAABB = DynamicAABB() + dynamicAABB.update(box) + + if (renderSetting != RenderSetting.Outline) { + renderer.buildFilled(dynamicAABB, fillColour) + } + + if (renderSetting != RenderSetting.Fill) { + renderer.buildOutline(dynamicAABB, outlineColour) } + } + + return + } + + lastLerpedBoxes.clear() + + boxList?.forEach { box -> + val positionedBox = box.offset(pos) + + val renderBox = if (renderMode == RenderMode.Static) { + positionedBox } else { - box.offset(pos) + getLerpBox(positionedBox, currentFactor) } + lastLerpedBoxes.add(renderBox) + val dynamicAABB = DynamicAABB() - renderBox?.apply { - dynamicAABB.update(this) - } + dynamicAABB.update(renderBox) if (renderSetting != RenderSetting.Outline) { renderer.buildFilled(dynamicAABB, fillColour) From 38a247c4160c029ce3144ae115276a6a6508b14b Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 12 Aug 2024 04:54:42 +0100 Subject: [PATCH 88/91] - fixed issue with double break swapping --- .../com/lambda/module/modules/player/PacketMine.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 50bf2e43b..b7414032c 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -736,7 +736,7 @@ object PacketMine : Module( if (!swapped) return when { - player.inventory.selectedSlot != swappedSlot -> cancelSwap() + player.inventory.selectedSlot != swappedSlot -> resetSwap() swapMode.isConstant() -> { if (swappedSlot != bestTool) swapTo(bestTool) @@ -947,9 +947,7 @@ object PacketMine : Module( doubleBreakReturnSlot = 0 } - returnSlot = -1 - swappedSlot = -1 - swapped = false + resetSwap() return } @@ -957,8 +955,11 @@ object PacketMine : Module( private fun SafeContext.doubleBreakSwapTo(slot: Int) { val currentSelectedSlot = player.inventory.selectedSlot - if (slot != currentSelectedSlot) { + if (!doubleBreakSwapped) { doubleBreakReturnSlot = currentSelectedSlot + } + + if (slot != currentSelectedSlot) { player.inventory.selectedSlot = slot connection.sendPacket(UpdateSelectedSlotC2SPacket(slot)) } @@ -975,11 +976,10 @@ object PacketMine : Module( connection.sendPacket(UpdateSelectedSlotC2SPacket(doubleBreakReturnSlot)) } - doubleBreakReturnSlot = 0 doubleBreakSwapped = false } - private fun cancelSwap() { + private fun resetSwap() { returnSlot = -1 swappedSlot = -1 swapped = false From 873db39f885d74dcb1c4f317e86389d19c66f5f3 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 12 Aug 2024 05:05:02 +0100 Subject: [PATCH 89/91] - improved checkClientSideBreak stuff --- .../kotlin/com/lambda/module/modules/player/PacketMine.kt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index b7414032c..71ee036bb 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -993,9 +993,7 @@ object PacketMine : Module( currentMiningBlock[block]?.apply { if (!isOutOfRange(pos.toCenterPos()) || packetReceiveBreak) { - if (breakType.isPrimary() || packetReceiveBreak) { - checkClientSideBreak(packetReceiveBreak, pos, doubleBreakBlock = doubleBreakBlock) - } + checkClientSideBreak(packetReceiveBreak, pos, doubleBreakBlock = doubleBreakBlock) } if (timeCompleted == -1L) { @@ -1063,12 +1061,11 @@ object PacketMine : Module( ) private fun SafeContext.checkClientSideBreak(packetReceiveBreak: Boolean, pos: BlockPos, doubleBreakBlock: Boolean = false) { - if (packetReceiveBreak == validateBreak || doubleBreakBlock && packetReceiveBreak) { + if (packetReceiveBreak || (!validateBreak && !doubleBreakBlock)) { interaction.breakBlock(pos) } } - //ToDo: Fix this shit private fun shouldBePlacedInBlockQueue(pos: BlockPos): Boolean = (((currentMiningBlock[0] != null && !doubleBreak) || currentMiningBlock[1] != null) || !blockQueue.isEmpty()) && (currentMiningBlock[0]?.breakState != BreakState.ReBreaking || !blockQueue.isEmpty()) From de5bcc597751f81ef9025c9a15e401877cdf4be1 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 12 Aug 2024 05:09:24 +0100 Subject: [PATCH 90/91] - fixed swapTo() not accounting for if its already swapped for double break --- .../com/lambda/module/modules/player/PacketMine.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 71ee036bb..c273642d0 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -889,15 +889,22 @@ object PacketMine : Module( private fun SafeContext.swapTo(slot: Int) { if (swapped && swapMethod.isNCPSilent()) returnToOriginalSlot() + if (returnSlot == -1) { - returnSlot = player.inventory.selectedSlot + returnSlot = if (!doubleBreakSwapped) { + player.inventory.selectedSlot + } else { + doubleBreakReturnSlot + } } + if (swapMethod.isSilent()) { silentSwapTo(slot, false) } else { player.inventory.selectedSlot = slot connection.sendPacket(UpdateSelectedSlotC2SPacket(slot)) } + swappedSlot = slot swapped = true } From ecef97c71361aed3e62ca88b3c175b2bf5519445 Mon Sep 17 00:00:00 2001 From: beanbag44 Date: Mon, 12 Aug 2024 16:52:51 +0100 Subject: [PATCH 91/91] - small setting fixes / improvements --- .../com/lambda/module/modules/player/PacketMine.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index c273642d0..0c6946fe8 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -52,28 +52,28 @@ object PacketMine : Module( private val breakThreshold by setting("Break Threshold", 0.70f, 0.00f..1.00f, 0.01f, "Breaks the selected block once the block breaking progress passes this value, 1 being 100%", visibility = { page == Page.General}) private val breakMode by setting("Break Mode", BreakMode.Total, "Changes the way break amount is added up. Total will choose the best tool and act as if its been using it the whole time while additive will add progress throughout the break", visibility = { page == Page.General }) private val strict by setting("Strict", false, "Resets the breaking progress at various stages to bypass generally stricter anti-cheats", visibility = { page == Page.General }) - private val range by setting("Range", 6.0f, 3.0f..6.0f, 0.1f, "The maximum distance between the players eye position and the center of the block", visibility = { page == Page.General }) + private val range by setting("Range", 6.0f, 3.0f..6.0f, 0.1f, "The maximum distance between the players eye position and the center of the block", " blocks", visibility = { page == Page.General }) private val doubleBreak by setting("Double Break", false, "This exploit only works on non strict servers or servers that run grim. It breaks two blocks at once", visibility = { page == Page.General }) private val pauseWhileUsingItems by setting("Pause While Using Items", true, "Will prevent breaking while using items like eating or aiming a bow", visibility = { page == Page.General }) private val validateBreak by setting("Validate Break", true, "Breaks blocks client side rather than waiting for a response from the server", visibility = { page == Page.General }) - private val timeoutDelay by setting("Timeout Delay", 0.20f, 0.00f..1.00f, 0.1f, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", visibility = { page == Page.General && validateBreak }) + private val timeoutDelay by setting("Timeout Delay", 0.20f, 0.00f..1.00f, 0.1f, "Will wait this amount of time (seconds) after the time to break for the block is complete before moving on", " seconds", visibility = { page == Page.General && validateBreak }) private val swingMode by setting("Swing Mode", ModeOptions.None, "Swings the players hand to simulate vanilla breaking, usually used on stricter anti-cheats", visibility = { page == Page.General }) private val swingOnManual by setting("Manual Swing", true, "Swings when the player attacks a block", visibility = { page == Page.General }) private val rotate by setting("Rotation Mode", ModeOptions.None, "Changes the method used to make the player look at the current mining block", visibility = { page == Page.General }) private val rayCast by setting("Raycast", false, "Checks if the player is directly looking at the block rather than allowing through walls", visibility = { page == Page.General && rotate.isEnabled() }) - private val rotateReleaseDelay by setting("Rotation Release Delay", 2, 0..50, 1, "The number of ticks to wait before releasing the rotation", visibility = { page == Page.General && rotate.isEnabled() }) + private val rotateReleaseDelay by setting("Rotation Release Delay", 1, 0..5, 1, "The number of ticks to wait before releasing the rotation", " ticks", visibility = { page == Page.General && rotate.isEnabled() }) private val swapMethod by setting("Swap Method", SwapMethod.StandardSilent, "Changes the swap method used. For example, silent swaps once at the beginning, and once at the end without updating client side, and constant swaps for the whole break", visibility = { page == Page.General}) private val swapMode by setting("Swap Mode", SwapMode.StartAndEnd, "The different times to swap to the best tool", visibility = { page == Page.General && swapMethod.isEnabled()}) private val packets by setting("Packet Mode", PacketMode.Vanilla, "Chooses different packets to send for each mode", visibility = { page == Page.General }) private val reBreak by setting("Re-Break", ReBreakMode.Standard, "The different modes for re-breaking the current block", visibility = { page == Page.ReBreak}) - private val reBreakDelay by setting("Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-breaking the block", visibility = { page == Page.ReBreak && (reBreak.isAutomatic() || reBreak.isFastAutomatic()) }) - private val emptyReBreakDelay by setting("Empty Re-Break Delay", 0, 0..10, 1, "The delay (in ticks) between attempting to re-break the block if the block is currently empty", visibility = { page == Page.ReBreak && reBreak.isFastAutomatic()}) + private val reBreakDelay by setting("Re-Break Delay", 0, 0..10, 1, "The delay between attempting to re-breaking the block", "ticks", visibility = { page == Page.ReBreak && (reBreak.isAutomatic() || reBreak.isFastAutomatic()) }) + private val emptyReBreakDelay by setting("Empty Re-Break Delay", 0, 0..10, 1, "The delay between attempting to re-break the block if the block is currently empty", " ticks", visibility = { page == Page.ReBreak && reBreak.isFastAutomatic()}) private val renderIfEmpty by setting("Render If Empty", false, "Draws the renders even if the re-break position is empty in the world", visibility = { page == Page.ReBreak && reBreak.isEnabled() }) private val queueBlocks by setting("Queue Blocks", false, "Queues any blocks you click for breaking", visibility = { page == Page.Queue }).apply { this.onValueSet { _, to -> if (!to) blockQueue.clear() } } private val reverseQueueOrder by setting("Reverse Queue Order", false, "Breaks the latest addition to the queue first", visibility = { page == Page.Queue && queueBlocks}) - private val queueBreakDelay by setting("Break Delay", 0, 0..5, 1, "The delay (in ticks) after breaking a block to break the next queue block", visibility = { page == Page.Queue && queueBlocks }) + private val queueBreakDelay by setting("Break Delay", 0, 0..5, 1, "The delay after breaking a block to break the next queue block", " ticks", visibility = { page == Page.Queue && queueBlocks }) private val breakingAnimation by setting("Breaking Animation", false, "Renders the block breaking animation like vanilla would to show progress", visibility = { page == Page.BlockRender }) @@ -91,7 +91,7 @@ object PacketMine : Module( private val endOutlineColour by setting("End Outline Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end outline of the box", visibility = { page == Page.BlockRender && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Dynamic }) private val outlineWidth by setting("Outline Width", 1f, 0f..3f, 0.1f, "the thickness of the outline", visibility = { page == Page.BlockRender && renderMode.isEnabled() && renderSetting != RenderSetting.Fill }) - private val renderQueueMode by setting("Render mode", RenderQueueMode.Shape, "The render type for queue blocks", visibility = { page == Page.QueueRender }) + private val renderQueueMode by setting("Render mode", RenderQueueMode.Cube, "The render type for queue blocks", visibility = { page == Page.QueueRender }) private val renderQueueSetting by setting("Render Setting", RenderSetting.Both, "The style to render queue blocks", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() }) private val renderQueueSize by setting("Render Size", 0.3f, 0f..1f, 0.01f, "The scale of the queue render blocks", visibility = { page == Page.QueueRender && renderQueueMode.isEnabled() })