Skip to content

Commit

Permalink
feat(AutoQueue): custom mode (#5699)
Browse files Browse the repository at this point in the history
Supports Trigger and Action selection, as well as Control and Wait until world change.
  • Loading branch information
1zun4 authored Feb 24, 2025
1 parent fddbe3d commit 7195e2e
Show file tree
Hide file tree
Showing 12 changed files with 362 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,14 @@ package net.ccbluex.liquidbounce.features.module.modules.player.autoqueue

import net.ccbluex.liquidbounce.features.module.Category
import net.ccbluex.liquidbounce.features.module.ClientModule
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.modes.AutoQueueGommeDuels
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.modes.AutoQueueHypixelSW
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.modes.AutoQueueMessage
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.modes.AutoQueuePaper
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.presets.AutoQueueCustom
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.presets.AutoQueueGommeDuels
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.presets.AutoQueueHypixelSW

object ModuleAutoQueue : ClientModule("AutoQueue", Category.PLAYER, aliases = arrayOf("AutoPlay")) {
val modes = choices("Mode", AutoQueuePaper, arrayOf(
AutoQueueMessage,
AutoQueuePaper,
val presets = choices("Presets", AutoQueueHypixelSW, arrayOf(
AutoQueueHypixelSW,
AutoQueueGommeDuels,
AutoQueueCustom
)).apply(::tagBy)
}
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.player.autoqueue.actions

import net.ccbluex.liquidbounce.config.types.Choice
import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable
import net.ccbluex.liquidbounce.event.Sequence
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.presets.AutoQueueCustom.triggers

abstract class AutoQueueAction(name: String) : Choice(name) {
override val parent: ChoiceConfigurable<*>
get() = triggers
abstract suspend fun execute(sequence: Sequence)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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.player.autoqueue.actions

import net.ccbluex.liquidbounce.event.Sequence

object AutoQueueActionChat : AutoQueueAction("Chat") {

private val message by text("Message", "/play solo_normal")

override suspend fun execute(sequence: Sequence) {
if (message.startsWith("/")) {
network.sendCommand(message.substring(1))
} else {
network.sendChatMessage(message)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,31 @@
*
*
*/
package net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.actions

package net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.modes

import net.ccbluex.liquidbounce.config.types.Choice
import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable
import net.ccbluex.liquidbounce.event.tickHandler
import net.ccbluex.liquidbounce.event.Sequence
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.ModuleAutoQueue
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.ModuleAutoQueue.modes
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.actions.AutoQueueActionUseItem.itemName
import net.ccbluex.liquidbounce.utils.client.SilentHotbar
import net.ccbluex.liquidbounce.utils.client.convertToString
import net.ccbluex.liquidbounce.utils.inventory.Slots
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
import net.minecraft.util.Hand

/**
* Can be used for different server that use paper to join a game
*/
object AutoQueuePaper : Choice("Paper") {
object AutoQueueActionUseItem : AutoQueueAction("UseItem") {

override val parent: ChoiceConfigurable<Choice>
get() = modes
/**
* The [itemName] of the item to click in order to queue.
*/
private val itemName by text("Name", "Paper")

val repeatable = tickHandler {
val paper = Slots.Hotbar.findSlotIndex(Items.PAPER) ?: return@tickHandler
override suspend fun execute(sequence: Sequence) {
val item = Slots.Hotbar.findSlotIndex { itemStack ->
itemStack.name.convertToString().contains(itemName)
} ?: return

SilentHotbar.selectSlotSilently(ModuleAutoQueue, paper)
waitTicks(1)
SilentHotbar.selectSlotSilently(ModuleAutoQueue, item)
sequence.waitTicks(1)
interaction.interactItem(player, Hand.MAIN_HAND)

waitTicks(20)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* 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.player.autoqueue.presets

import net.ccbluex.liquidbounce.config.types.Choice
import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable
import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable
import net.ccbluex.liquidbounce.event.events.WorldChangeEvent
import net.ccbluex.liquidbounce.event.handler
import net.ccbluex.liquidbounce.event.tickHandler
import net.ccbluex.liquidbounce.features.module.modules.combat.killaura.ModuleKillAura
import net.ccbluex.liquidbounce.features.module.modules.movement.speed.ModuleSpeed
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.ModuleAutoQueue
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.actions.AutoQueueAction
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.actions.AutoQueueActionChat
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.actions.AutoQueueActionUseItem
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.trigger.*

object AutoQueueCustom : Choice("Custom") {

override val parent: ChoiceConfigurable<*>
get() = ModuleAutoQueue.presets

internal val triggers = choices<AutoQueueTrigger>("Trigger", 0) {
arrayOf(
AutoQueueTriggerMessage,
AutoQueueTriggerItem,
AutoQueueTriggerTabHeader,
AutoQueueTriggerTabFooter
)
}

internal val actions = choices<AutoQueueAction>("Action", 0) {
arrayOf(
AutoQueueActionChat,
AutoQueueActionUseItem
)
}

object Control : ToggleableConfigurable(this, "Control", true) {

val killAura by boolean("KillAura", true)
val speed by boolean("Speed", false)

fun changeGameState(isInGame: Boolean) {
if (!enabled) {
return
}

if (killAura) ModuleKillAura.enabled = isInGame
if (speed) ModuleSpeed.enabled = isInGame
}

}

init {
tree(Control)
}

private val waitUntilWorldChange by boolean("WaitUntilWorldChange", true)
private var worldChangeOccurred = false

@Suppress("unused")
private val tickHandler = tickHandler {
val trigger = triggers.activeChoice

if (trigger.isTriggered) {
Control.changeGameState(false)

actions.activeChoice.execute(this)
onCancellation { Control.changeGameState(true) }

if (waitUntilWorldChange) {
waitUntil { worldChangeOccurred }
worldChangeOccurred = false
}

waitTicks(20)
Control.changeGameState(true)
}
}

@Suppress("unused")
private val worldChange = handler<WorldChangeEvent> { event ->
worldChangeOccurred = true
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*
*
*/
package net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.modes
package net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.presets

import net.ccbluex.liquidbounce.config.types.Choice
import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable
Expand All @@ -28,7 +28,7 @@ import net.ccbluex.liquidbounce.event.events.NotificationEvent
import net.ccbluex.liquidbounce.event.sequenceHandler
import net.ccbluex.liquidbounce.event.tickHandler
import net.ccbluex.liquidbounce.features.module.modules.combat.killaura.ModuleKillAura
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.ModuleAutoQueue.modes
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.ModuleAutoQueue.presets
import net.ccbluex.liquidbounce.utils.client.*
import net.ccbluex.liquidbounce.utils.entity.boxedDistanceTo
import net.ccbluex.liquidbounce.utils.inventory.Slots
Expand All @@ -48,7 +48,7 @@ object AutoQueueGommeDuels : Choice("GommeDuels") {
private var controlKillAura by boolean("ControlKillAura", true)

override val parent: ChoiceConfigurable<*>
get() = modes
get() = presets

override fun enable() {
chat(regular("Please set your server language to German (DE) to use AutoPlay"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@
*
*/

package net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.modes
package net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.presets

import net.ccbluex.liquidbounce.config.types.Choice
import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable
import net.ccbluex.liquidbounce.config.types.NamedChoice
import net.ccbluex.liquidbounce.event.tickHandler
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.ModuleAutoQueue.modes
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.ModuleAutoQueue.presets
import net.ccbluex.liquidbounce.utils.inventory.Slots
import net.minecraft.item.Items

object AutoQueueHypixelSW : Choice("HypixelSW") {

override val parent: ChoiceConfigurable<Choice>
get() = modes
get() = presets

private val gameMode by enumChoice("GameMode", SkyWarsGameMode.NORMAL, SkyWarsGameMode.values())

Expand Down
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.player.autoqueue.trigger

import net.ccbluex.liquidbounce.config.types.Choice
import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable
import net.ccbluex.liquidbounce.features.module.modules.player.autoqueue.presets.AutoQueueCustom.triggers

abstract class AutoQueueTrigger(name: String) : Choice(name) {
override val parent: ChoiceConfigurable<*>
get() = triggers
abstract val isTriggered: Boolean
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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.player.autoqueue.trigger

import net.ccbluex.liquidbounce.utils.client.convertToString
import net.ccbluex.liquidbounce.utils.inventory.Slots

/**
* Can be used for different server that use paper to join a game
*/
object AutoQueueTriggerItem : AutoQueueTrigger("Item") {

/**
* The [itemName] of the item when to trigger the queue,
* which can be a different item than we use in the [AutoQueueTriggerItem] action.
*
* The name also can be a custom name of the item and does not have to be matching,
* and only contains the text.
*/
private val itemName by text("Name", "Paper")

override val isTriggered: Boolean
get() = Slots.Hotbar.findSlot { itemStack ->
itemStack.name.convertToString().contains(itemName)
} != null

}
Loading

0 comments on commit 7195e2e

Please sign in to comment.