Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(PacketMine): switch method option in tool mode on stop #5558

Merged
merged 1 commit into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,11 @@ enum class FailProcedure {
mode.activeChoice.onCannotLookAtTarget(mineTarget)

// if required, we already switch
switch(switchMode.activeChoice.getSlot(mineTarget.blockState), mineTarget)
interaction.syncSelectedSlot()
val switchMode = switchMode.activeChoice
switch(switchMode.getSlot(mineTarget.blockState), mineTarget)
if (switchMode.getSwitchingMethod().shouldSync) {
interaction.syncSelectedSlot()
}
}

return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ import net.ccbluex.liquidbounce.event.handler
import net.ccbluex.liquidbounce.event.tickHandler
import net.ccbluex.liquidbounce.features.module.Category
import net.ccbluex.liquidbounce.features.module.ClientModule
import net.ccbluex.liquidbounce.features.module.modules.world.ModuleAutoTool
import net.ccbluex.liquidbounce.features.module.modules.world.packetmine.mode.CivMineMode
import net.ccbluex.liquidbounce.features.module.modules.world.packetmine.mode.ImmediateMineMode
import net.ccbluex.liquidbounce.features.module.modules.world.packetmine.mode.NormalMineMode
import net.ccbluex.liquidbounce.features.module.modules.world.packetmine.tool.AlwaysToolMode
import net.ccbluex.liquidbounce.features.module.modules.world.packetmine.tool.NeverToolMode
import net.ccbluex.liquidbounce.features.module.modules.world.packetmine.tool.OnStopToolMode
import net.ccbluex.liquidbounce.features.module.modules.world.packetmine.tool.PostStartToolMode
import net.ccbluex.liquidbounce.render.engine.Color4b
import net.ccbluex.liquidbounce.utils.aiming.Rotation
import net.ccbluex.liquidbounce.utils.aiming.RotationManager
Expand All @@ -37,7 +40,6 @@ import net.ccbluex.liquidbounce.utils.block.SwingMode
import net.ccbluex.liquidbounce.utils.block.getState
import net.ccbluex.liquidbounce.utils.block.outlineBox
import net.ccbluex.liquidbounce.utils.client.Chronometer
import net.ccbluex.liquidbounce.utils.client.SilentHotbar
import net.ccbluex.liquidbounce.utils.kotlin.Priority
import net.ccbluex.liquidbounce.utils.render.placement.PlacementRenderer
import net.minecraft.block.BlockState
Expand Down Expand Up @@ -225,15 +227,19 @@ object ModulePacketMine : ClientModule("PacketMine", Category.WORLD) {
return
}

val slot = switchMode.activeChoice.getSlot(mineTarget.blockState)
val switchMode = switchMode.activeChoice
val slot = switchMode.getSlot(mineTarget.blockState)
if (!mineTarget.started) {
startBreaking(slot, mineTarget)
} else if (mode.activeChoice.shouldUpdate(mineTarget, slot)) {
updateBreakingProgress(mineTarget, slot)
if (mineTarget.progress >= breakDamage && !mineTarget.finished) {
mode.activeChoice.finish(mineTarget)
switchMode.getSwitchingMethod().switchBack()
}
}

switchMode.getSwitchingMethod().reset()
}

private fun startBreaking(slot: IntObjectImmutablePair<ItemStack>?, mineTarget: MineTarget) {
Expand All @@ -247,14 +253,17 @@ object ModulePacketMine : ClientModule("PacketMine", Category.WORLD) {
}

private fun updateBreakingProgress(mineTarget: MineTarget, slot: IntObjectImmutablePair<ItemStack>?) {
mineTarget.progress += switchMode.activeChoice.getBlockBreakingDelta(
val switchMode = switchMode.activeChoice
mineTarget.progress += switchMode.getBlockBreakingDelta(
mineTarget.targetPos,
mineTarget.blockState,
slot?.second()
)

switch(slot, mineTarget)
interaction.syncSelectedSlot()
if (switchMode.getSwitchingMethod().shouldSync) {
interaction.syncSelectedSlot()
}

val f = if (breakDamage > 0f) {
val breakDamageD = breakDamage.toDouble()
Expand Down Expand Up @@ -282,11 +291,9 @@ object ModulePacketMine : ClientModule("PacketMine", Category.WORLD) {
return
}

val shouldSwitch = switchMode.activeChoice.shouldSwitch(mineTarget)
if (shouldSwitch && ModuleAutoTool.running) {
ModuleAutoTool.switchToBreakBlock(mineTarget.targetPos)
} else if (shouldSwitch) {
SilentHotbar.selectSlotSilently(this, slot.firstInt(), 1)
val switchMode = switchMode.activeChoice
if (switchMode.shouldSwitch(mineTarget)) {
switchMode.getSwitchingMethod().switch(slot, mineTarget)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
*
* Copyright (c) 2015 - 2025 CCBlueX
*
* LiquidBounce is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LiquidBounce is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
*/
package net.ccbluex.liquidbounce.features.module.modules.world.packetmine.tool

import net.ccbluex.liquidbounce.event.events.PacketEvent
import net.ccbluex.liquidbounce.event.events.SelectHotbarSlotSilentlyEvent
import net.ccbluex.liquidbounce.event.handler
import net.ccbluex.liquidbounce.features.module.modules.world.ModuleAutoTool
import net.ccbluex.liquidbounce.features.module.modules.world.packetmine.MineTarget
import net.ccbluex.liquidbounce.features.module.modules.world.packetmine.ModulePacketMine
import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket
import net.minecraft.network.packet.s2c.play.UpdateSelectedSlotS2CPacket

object AlwaysToolMode : MineToolMode("Always", syncOnStart = true) {

private val abortOnSwitch by boolean("AbortOnSwitch", true)
private val cancelAutomaticSwitching by boolean("CancelAutomaticSwitching", true)

@Suppress("unused")
private val packetHandler = handler<PacketEvent> { event ->
mc.execute {
val target = ModulePacketMine._target ?: return@execute
if (!abortOnSwitch || !target.started) {
return@execute
}

val packet = event.packet
val serverInitiatedSwitch = packet is UpdateSelectedSlotS2CPacket &&
packet.slot == getSlot(target.blockState)?.firstInt()
val clientInitiatedSwitch = packet is UpdateSelectedSlotC2SPacket &&
packet.selectedSlot == getSlot(target.blockState)?.firstInt()
if (serverInitiatedSwitch || clientInitiatedSwitch) {
ModulePacketMine._resetTarget()
}
}
}

@Suppress("unused")
private val silentSwitchHandler = handler<SelectHotbarSlotSilentlyEvent> { event ->
val target = ModulePacketMine._target ?: return@handler

val requester = event.requester
val fromPacketMine = requester == ModulePacketMine
val fromAutoTool = requester == ModuleAutoTool && event.slot == getSlot(target.blockState)?.firstInt()
if (cancelAutomaticSwitching && target.started && !fromPacketMine && !fromAutoTool) {
event.cancelEvent()
}
}

override fun shouldSwitch(mineTarget: MineTarget) = true

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,15 @@
* You should have received a copy of the GNU General Public License
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
*/
package net.ccbluex.liquidbounce.features.module.modules.world.packetmine
package net.ccbluex.liquidbounce.features.module.modules.world.packetmine.tool

import it.unimi.dsi.fastutil.ints.IntObjectImmutablePair
import net.ccbluex.liquidbounce.config.types.Choice
import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable
import net.ccbluex.liquidbounce.event.events.PacketEvent
import net.ccbluex.liquidbounce.event.events.SelectHotbarSlotSilentlyEvent
import net.ccbluex.liquidbounce.event.handler
import net.ccbluex.liquidbounce.features.module.MinecraftShortcuts
import net.ccbluex.liquidbounce.features.module.modules.world.ModuleAutoTool
import net.ccbluex.liquidbounce.features.module.modules.world.packetmine.MineTarget
import net.ccbluex.liquidbounce.features.module.modules.world.packetmine.ModulePacketMine
import net.ccbluex.liquidbounce.utils.client.player
import net.ccbluex.liquidbounce.utils.client.world
import net.ccbluex.liquidbounce.utils.item.getEnchantment
Expand All @@ -36,69 +35,9 @@ import net.minecraft.entity.attribute.EntityAttributes
import net.minecraft.entity.effect.StatusEffectUtil
import net.minecraft.entity.effect.StatusEffects
import net.minecraft.item.ItemStack
import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket
import net.minecraft.network.packet.s2c.play.UpdateSelectedSlotS2CPacket
import net.minecraft.registry.tag.FluidTags
import net.minecraft.util.math.BlockPos

object AlwaysToolMode : MineToolMode("Always", syncOnStart = true) {

private val abortOnSwitch by boolean("AbortOnSwitch", true)
private val cancelAutomaticSwitching by boolean("CancelAutomaticSwitching", true)

@Suppress("unused")
private val packetHandler = handler<PacketEvent> { event ->
mc.execute {
val target = ModulePacketMine._target ?: return@execute
if (!abortOnSwitch || !target.started) {
return@execute
}

val packet = event.packet
val serverInitiatedSwitch = packet is UpdateSelectedSlotS2CPacket &&
packet.slot == getSlot(target.blockState)?.firstInt()
val clientInitiatedSwitch = packet is UpdateSelectedSlotC2SPacket &&
packet.selectedSlot == getSlot(target.blockState)?.firstInt()
if (serverInitiatedSwitch || clientInitiatedSwitch) {
ModulePacketMine._resetTarget()
}
}
}

@Suppress("unused")
private val silentSwitchHandler = handler<SelectHotbarSlotSilentlyEvent> { event ->
val target = ModulePacketMine._target ?: return@handler

val requester = event.requester
val fromPacketMine = requester == ModulePacketMine
val fromAutoTool = requester == ModuleAutoTool && event.slot == getSlot(target.blockState)?.firstInt()
if (cancelAutomaticSwitching && target.started && !fromPacketMine && !fromAutoTool) {
event.cancelEvent()
}
}

override fun shouldSwitch(mineTarget: MineTarget) = true

}

object PostStartToolMode : MineToolMode("PostStart") {

override fun shouldSwitch(mineTarget: MineTarget) = true

}

object OnStopToolMode : MineToolMode("OnStop") {

override fun shouldSwitch(mineTarget: MineTarget) = mineTarget.progress >= ModulePacketMine.breakDamage

}

object NeverToolMode : MineToolMode("Never", switchesNever = true) {

override fun shouldSwitch(mineTarget: MineTarget) = false

}

/**
* Determines when to switch to a tool and calculates the breaking process delta.
*/
Expand All @@ -111,6 +50,8 @@ abstract class MineToolMode(

abstract fun shouldSwitch(mineTarget: MineTarget): Boolean

open fun getSwitchingMethod() = SwitchMethod.NORMAL

fun getBlockBreakingDelta(pos: BlockPos, state: BlockState, itemStack: ItemStack?): Float {
if (switchesNever || itemStack == null) {
return state.calcBlockBreakingDelta(player, world, pos)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
*
* Copyright (c) 2015 - 2025 CCBlueX
*
* LiquidBounce is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LiquidBounce is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
*/
package net.ccbluex.liquidbounce.features.module.modules.world.packetmine.tool

import net.ccbluex.liquidbounce.features.module.modules.world.packetmine.MineTarget

object NeverToolMode : MineToolMode("Never", switchesNever = true) {

override fun shouldSwitch(mineTarget: MineTarget) = false

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
*
* Copyright (c) 2015 - 2025 CCBlueX
*
* LiquidBounce is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LiquidBounce is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
*/
package net.ccbluex.liquidbounce.features.module.modules.world.packetmine.tool

import net.ccbluex.liquidbounce.features.module.modules.world.packetmine.MineTarget
import net.ccbluex.liquidbounce.features.module.modules.world.packetmine.ModulePacketMine

object OnStopToolMode : MineToolMode("OnStop") {

private val switchMethod by enumChoice("SwitchMethod", SwitchMethod.NORMAL)

override fun shouldSwitch(mineTarget: MineTarget) = mineTarget.progress >= ModulePacketMine.breakDamage

override fun getSwitchingMethod() = switchMethod

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
*
* Copyright (c) 2015 - 2025 CCBlueX
*
* LiquidBounce is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LiquidBounce is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
*/
package net.ccbluex.liquidbounce.features.module.modules.world.packetmine.tool

import net.ccbluex.liquidbounce.features.module.modules.world.packetmine.MineTarget

object PostStartToolMode : MineToolMode("PostStart") {

override fun shouldSwitch(mineTarget: MineTarget) = true

}
Loading
Loading