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 1/7] 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 2/7] 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 3/7] 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 4/7] 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 5/7] 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 6/7] 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 7/7] 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") }