From 4629ddcdb66e9cad00ca9c51b766f032fa4578c9 Mon Sep 17 00:00:00 2001 From: sqlerrorthing <148702857+sqlerrorthing@users.noreply.github.com> Date: Sat, 13 Sep 2025 10:09:46 +0800 Subject: [PATCH 1/3] feat/autotool-(not)-require-hold --- .../minecraft/client/MixinKeyBinding.java | 7 +++ .../liquidbounce/event/EventManager.kt | 1 + .../liquidbounce/event/events/ClientEvents.kt | 4 ++ .../module/modules/world/ModuleAutoTool.kt | 50 +++++++++++++++---- 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/client/MixinKeyBinding.java b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/client/MixinKeyBinding.java index 8e712ccf158..1fa09a912d6 100644 --- a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/client/MixinKeyBinding.java +++ b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/client/MixinKeyBinding.java @@ -23,6 +23,7 @@ import net.ccbluex.liquidbounce.event.EventManager; import net.ccbluex.liquidbounce.event.events.KeybindChangeEvent; import net.ccbluex.liquidbounce.event.events.KeybindIsPressedEvent; +import net.ccbluex.liquidbounce.event.events.MinecraftKeyPressed; import net.ccbluex.liquidbounce.utils.client.VanillaTranslationRecognizer; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.util.InputUtil; @@ -49,4 +50,10 @@ private boolean isPressed(boolean original) { return EventManager.INSTANCE.callEvent(new KeybindIsPressedEvent((KeyBinding) (Object) this, original)).isPressed(); } + @Inject(method = "setKeyPressed", at = @At("HEAD"), cancellable = true) + private static void hookSetKeyPressed(InputUtil.Key key, boolean pressed, CallbackInfo ci) { + if (EventManager.INSTANCE.callEvent(new MinecraftKeyPressed(key, pressed)).isCancelled()) { + ci.cancel(); + } + } } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/event/EventManager.kt b/src/main/kotlin/net/ccbluex/liquidbounce/event/EventManager.kt index 00edbb833b5..7cd0f853691 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/event/EventManager.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/event/EventManager.kt @@ -146,6 +146,7 @@ val ALL_EVENT_CLASSES: Array> = arrayOf( TitleEvent.Subtitle::class, TitleEvent.Fade::class, TitleEvent.Clear::class, + MinecraftKeyPressed::class ) /** diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/event/events/ClientEvents.kt b/src/main/kotlin/net/ccbluex/liquidbounce/event/events/ClientEvents.kt index 79a0a2449a0..fd247519e21 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/event/events/ClientEvents.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/event/events/ClientEvents.kt @@ -38,6 +38,7 @@ import net.ccbluex.liquidbounce.utils.inventory.InventoryAction import net.ccbluex.liquidbounce.utils.inventory.InventoryConstraints import net.ccbluex.liquidbounce.utils.kotlin.Priority import net.minecraft.client.network.ServerInfo +import net.minecraft.client.util.InputUtil import net.minecraft.world.GameMode @Deprecated( @@ -91,6 +92,9 @@ class TargetChangeEvent(val target: PlayerData?) : Event(), WebSocketEvent @Nameable("blockCountChange") class BlockCountChangeEvent(val count: Int?) : Event(), WebSocketEvent +@Nameable("minecraftKeyPressed") +class MinecraftKeyPressed(val key: InputUtil.Key, val pressed: Boolean) : CancellableEvent() + @Nameable("clientChatStateChange") class ClientChatStateChange(val state: State) : Event(), WebSocketEvent { enum class State { diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleAutoTool.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleAutoTool.kt index 52e2638f309..2d19fe19ae5 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleAutoTool.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleAutoTool.kt @@ -21,16 +21,18 @@ package net.ccbluex.liquidbounce.features.module.modules.world import net.ccbluex.liquidbounce.config.types.nesting.Choice import net.ccbluex.liquidbounce.config.types.nesting.ChoiceConfigurable import net.ccbluex.liquidbounce.config.types.nesting.ToggleableConfigurable +import net.ccbluex.liquidbounce.event.events.BlockAttackEvent import net.ccbluex.liquidbounce.event.events.BlockBreakingProgressEvent +import net.ccbluex.liquidbounce.event.events.MinecraftKeyPressed import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.features.module.Category import net.ccbluex.liquidbounce.features.module.ClientModule import net.ccbluex.liquidbounce.utils.block.bed.BedBlockTracker import net.ccbluex.liquidbounce.utils.block.getCenterDistanceSquaredEyes -import net.ccbluex.liquidbounce.utils.inventory.HotbarItemSlot import net.ccbluex.liquidbounce.utils.block.getState import net.ccbluex.liquidbounce.utils.client.SilentHotbar import net.ccbluex.liquidbounce.utils.collection.Filter +import net.ccbluex.liquidbounce.utils.inventory.HotbarItemSlot import net.ccbluex.liquidbounce.utils.inventory.ItemSlot import net.ccbluex.liquidbounce.utils.inventory.SlotGroup import net.ccbluex.liquidbounce.utils.inventory.Slots @@ -87,10 +89,34 @@ object ModuleAutoTool : ClientModule("AutoTool", Category.WORLD) { private val swapPreviousDelay by int("SwapPreviousDelay", 20, 1..100, "ticks") - private val requireSneaking by boolean("RequireSneaking", false) + private object RequireSneaking : ToggleableConfigurable( + this, "RequireSneaking", false + ) { + private val requireHold by boolean("RequireHold", false) + + private var breakStartedWithHoldingShift = false + + @Suppress("unused") + private val blockAttackHandler = handler { + if (!breakStartedWithHoldingShift) { + breakStartedWithHoldingShift = player.isSneaking + } + } + + @Suppress("unused") + private val keyHandler = handler { + if (it.key == mc.options.attackKey.boundKey && !it.pressed) { + breakStartedWithHoldingShift = false + } + } + + fun matches(): Boolean { + return player.isSneaking || (!requireHold && breakStartedWithHoldingShift) + } + } private object RequireNearBed : ToggleableConfigurable( - this, "RequireNearBed", enabled = false + this, "RequireNearBed", false ), BedBlockTracker.Subscriber { override val maxLayers: Int get() = 1 @@ -110,24 +136,26 @@ object ModuleAutoTool : ClientModule("AutoTool", Category.WORLD) { } init { - tree(RequireNearBed) + treeAll( + RequireSneaking, + RequireNearBed + ) } @Suppress("unused") private val handleBlockBreakingProgress = handler { event -> - if (!RequireNearBed.enabled || RequireNearBed.matches()) { + if ( + (!RequireNearBed.enabled || RequireNearBed.matches()) + && (!RequireSneaking.enabled || RequireSneaking.matches()) + ) { switchToBreakBlock(event.pos) } } fun switchToBreakBlock(pos: BlockPos) { - if (requireSneaking && !player.isSneaking) { - return - } - val blockState = pos.getState()!! - val slot = toolSelector.activeChoice.getTool(blockState) ?: return - SilentHotbar.selectSlotSilently(this, slot, swapPreviousDelay) + val bestSlot = toolSelector.activeChoice.getTool(blockState) ?: return + SilentHotbar.selectSlotSilently(this, bestSlot, swapPreviousDelay) } fun SlotGroup.findBestToolToMineBlock( From 96c31733278d1800ff042ffb43a8a2f0673a2291 Mon Sep 17 00:00:00 2001 From: sqlerrorthing <148702857+sqlerrorthing@users.noreply.github.com> Date: Sat, 13 Sep 2025 10:38:21 +0800 Subject: [PATCH 2/3] use key --- .../features/module/modules/world/ModuleAutoTool.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleAutoTool.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleAutoTool.kt index 2d19fe19ae5..c7b1f299ada 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleAutoTool.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleAutoTool.kt @@ -99,7 +99,7 @@ object ModuleAutoTool : ClientModule("AutoTool", Category.WORLD) { @Suppress("unused") private val blockAttackHandler = handler { if (!breakStartedWithHoldingShift) { - breakStartedWithHoldingShift = player.isSneaking + breakStartedWithHoldingShift = mc.options.sneakKey.isPressed } } @@ -111,7 +111,7 @@ object ModuleAutoTool : ClientModule("AutoTool", Category.WORLD) { } fun matches(): Boolean { - return player.isSneaking || (!requireHold && breakStartedWithHoldingShift) + return mc.options.sneakKey.isPressed || (!requireHold && breakStartedWithHoldingShift) } } From 453c016848824b3a494219aa260863cdda7d85bb Mon Sep 17 00:00:00 2001 From: sqlerrorthing <148702857+sqlerrorthing@users.noreply.github.com> Date: Sat, 13 Sep 2025 10:39:31 +0800 Subject: [PATCH 3/3] naming --- .../injection/mixins/minecraft/client/MixinKeyBinding.java | 4 ++-- .../kotlin/net/ccbluex/liquidbounce/event/EventManager.kt | 2 +- .../net/ccbluex/liquidbounce/event/events/ClientEvents.kt | 2 +- .../features/module/modules/world/ModuleAutoTool.kt | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/client/MixinKeyBinding.java b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/client/MixinKeyBinding.java index 1fa09a912d6..8ebcb5f7437 100644 --- a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/client/MixinKeyBinding.java +++ b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/client/MixinKeyBinding.java @@ -23,7 +23,7 @@ import net.ccbluex.liquidbounce.event.EventManager; import net.ccbluex.liquidbounce.event.events.KeybindChangeEvent; import net.ccbluex.liquidbounce.event.events.KeybindIsPressedEvent; -import net.ccbluex.liquidbounce.event.events.MinecraftKeyPressed; +import net.ccbluex.liquidbounce.event.events.SetKeyPressedEvent; import net.ccbluex.liquidbounce.utils.client.VanillaTranslationRecognizer; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.util.InputUtil; @@ -52,7 +52,7 @@ private boolean isPressed(boolean original) { @Inject(method = "setKeyPressed", at = @At("HEAD"), cancellable = true) private static void hookSetKeyPressed(InputUtil.Key key, boolean pressed, CallbackInfo ci) { - if (EventManager.INSTANCE.callEvent(new MinecraftKeyPressed(key, pressed)).isCancelled()) { + if (EventManager.INSTANCE.callEvent(new SetKeyPressedEvent(key, pressed)).isCancelled()) { ci.cancel(); } } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/event/EventManager.kt b/src/main/kotlin/net/ccbluex/liquidbounce/event/EventManager.kt index 7cd0f853691..b51a353594f 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/event/EventManager.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/event/EventManager.kt @@ -146,7 +146,7 @@ val ALL_EVENT_CLASSES: Array> = arrayOf( TitleEvent.Subtitle::class, TitleEvent.Fade::class, TitleEvent.Clear::class, - MinecraftKeyPressed::class + SetKeyPressedEvent::class ) /** diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/event/events/ClientEvents.kt b/src/main/kotlin/net/ccbluex/liquidbounce/event/events/ClientEvents.kt index fd247519e21..fba21e60688 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/event/events/ClientEvents.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/event/events/ClientEvents.kt @@ -93,7 +93,7 @@ class TargetChangeEvent(val target: PlayerData?) : Event(), WebSocketEvent class BlockCountChangeEvent(val count: Int?) : Event(), WebSocketEvent @Nameable("minecraftKeyPressed") -class MinecraftKeyPressed(val key: InputUtil.Key, val pressed: Boolean) : CancellableEvent() +class SetKeyPressedEvent(val key: InputUtil.Key, val pressed: Boolean) : CancellableEvent() @Nameable("clientChatStateChange") class ClientChatStateChange(val state: State) : Event(), WebSocketEvent { diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleAutoTool.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleAutoTool.kt index c7b1f299ada..62c621d1045 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleAutoTool.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleAutoTool.kt @@ -23,7 +23,7 @@ import net.ccbluex.liquidbounce.config.types.nesting.ChoiceConfigurable import net.ccbluex.liquidbounce.config.types.nesting.ToggleableConfigurable import net.ccbluex.liquidbounce.event.events.BlockAttackEvent import net.ccbluex.liquidbounce.event.events.BlockBreakingProgressEvent -import net.ccbluex.liquidbounce.event.events.MinecraftKeyPressed +import net.ccbluex.liquidbounce.event.events.SetKeyPressedEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.features.module.Category import net.ccbluex.liquidbounce.features.module.ClientModule @@ -104,7 +104,7 @@ object ModuleAutoTool : ClientModule("AutoTool", Category.WORLD) { } @Suppress("unused") - private val keyHandler = handler { + private val keyHandler = handler { if (it.key == mc.options.attackKey.boundKey && !it.pressed) { breakStartedWithHoldingShift = false }