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: restore-command and improve value-command #4003

Draft
wants to merge 7 commits into
base: nextgen
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion config/detekt/baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
<ID>LongMethod:ServerListRest.kt$ServerListRest$internal fun RestNode.serverListRest()</ID>
<ID>LongMethod:Value.kt$Value$open fun setByString(string: String)</ID>
<ID>LongMethod:WorldListRest.kt$internal fun RestNode.worldListRest()</ID>
<ID>LongParameterList:Command.kt$Command$( val name: String, val aliases: Array&lt;out String>, val parameters: Array&lt;Parameter&lt;*>>, val subcommands: Array&lt;Command>, val executable: Boolean, val handler: CommandHandler?, private var parentCommand: Command? = null )</ID>
<ID>LongParameterList:Command.kt$Command$( val name: String, val aliases: Array&lt;out String>, val parameters: Array&lt;Parameter&lt;*>>, var subcommands: Array&lt;Command>, val hub: Boolean, val handler: CommandHandler?, private var parentCommand: Command? = null )</ID>
<ID>LongParameterList:FallingPlayer.kt$FallingPlayer$( private val player: ClientPlayerEntity, var x: Double, var y: Double, var z: Double, private var motionX: Double, private var motionY: Double, private var motionZ: Double, private val yaw: Float )</ID>
<ID>LongParameterList:FontRenderer.kt$FontRenderer$( x0: Float, x: Float, y: Float, z: Float, color: Color4b, through: Boolean )</ID>
<ID>LongParameterList:JsNetworkUtil.kt$JsNetworkUtil$(x: Double, y: Double, z: Double, yaw: Float, pitch: Float, onGround: Boolean)</ID>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ class ChoiceConfigurable<T : Choice>(
}
}

override fun getCompletion(begin: String): List<String> {
return choices.map { it.choiceName }.filter { it.startsWith(begin) }
}

@ScriptApi
fun getChoicesStrings(): Array<String> = this.choices.map { it.name }.toTypedArray()

Expand Down
46 changes: 41 additions & 5 deletions src/main/kotlin/net/ccbluex/liquidbounce/config/Value.kt
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,40 @@ open class Value<T : Any>(
}
}

open fun getCompletion(begin: String): List<String> {
val results = mutableListOf<String>()

when (this.valueType) {
ValueType.BOOLEAN -> {
results.add("true")
results.add("false")
}

ValueType.BLOCK -> {
results.addAll(Registries.BLOCK.map {
it.translationKey
.removePrefix("block.")
.replace('.', ':')
})
}

ValueType.ITEM -> {
results.addAll(Registries.ITEM.map {
it.translationKey
.removePrefix("item.")
.removePrefix("block.")
.replace('.', ':')
})
}

else -> {
/* no special completion */
}
}

return results.filter { it.startsWith(begin) }
}

}

/**
Expand Down Expand Up @@ -409,16 +443,18 @@ class ChooseListValue<T : NamedChoice>(
override fun setByString(string: String) {
val newValue = choices.firstOrNull { it.choiceName == string }

if (newValue == null) {
throw IllegalArgumentException(
"ChooseListValue `${this.name}` has no option named $string" +
" (available options are ${this.choices.joinToString { it.choiceName }})"
)
requireNotNull(newValue) {
"ChooseListValue `${this.name}` has no option named $string" +
" (available options are ${this.choices.joinToString { it.choiceName }})"
}

set(newValue)
}

override fun getCompletion(begin: String): List<String> {
return choices.map { it.choiceName }.filter { it.startsWith(begin) }
}

@ScriptApi
fun getChoicesStrings(): Array<String> {
return this.choices.map { it.choiceName }.toTypedArray()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ val ALL_EVENT_CLASSES: Array<KClass<out Event>> = arrayOf(
ClickGuiScaleChangeEvent::class,
BrowserUrlChangeEvent::class,
TagEntityEvent::class,
RegistryChangeEvent::class,
MouseScrollInHotbarEvent::class,
PlayerFluidCollisionCheckEvent::class
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import net.ccbluex.liquidbounce.config.Value
import net.ccbluex.liquidbounce.event.Event
import net.ccbluex.liquidbounce.features.chat.packet.User
import net.ccbluex.liquidbounce.features.misc.ProxyManager
import net.ccbluex.liquidbounce.features.module.Module
import net.ccbluex.liquidbounce.utils.client.Nameable
import net.ccbluex.liquidbounce.utils.entity.SimulatedPlayer
import net.ccbluex.liquidbounce.utils.inventory.InventoryAction
Expand Down Expand Up @@ -180,6 +181,9 @@ class SimulatedTickEvent(val movementEvent: MovementInputEvent, val simulatedPla
@Nameable("resourceReload")
class ResourceReloadEvent : Event()

@Nameable("moduleRegistry")
class RegistryChangeEvent(val change: RegistryChange, val module: Module) : Event()

@Nameable("scaleFactorChange")
@WebSocketEvent
class ScaleFactorChangeEvent(val scaleFactor: Double) : Event()
Expand All @@ -201,3 +205,8 @@ class ScheduleInventoryActionEvent(
@Nameable("browserUrlChange")
@WebSocketEvent
class BrowserUrlChangeEvent(val index: Int, val url: String) : Event()

enum class RegistryChange {
ADD,
REMOVE
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ class Command(
val name: String,
val aliases: Array<out String>,
val parameters: Array<Parameter<*>>,
val subcommands: Array<Command>,
val executable: Boolean,
var subcommands: Array<Command>,
val hub: Boolean,
val handler: CommandHandler?,
private var parentCommand: Command? = null
) : QuickImports {
Expand Down Expand Up @@ -110,7 +110,7 @@ class Command(
val output = ArrayList<String>()

// Don't show non-executable commands as executable
if (executable) {
if (handler != null) {
val joiner = StringJoiner(" ")

for (parameter in parameters) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ object CommandManager : Iterable<Command> {
addCommand(CommandFakePlayer.createCommand())
addCommand(CommandAutoAccount.createCommand())
addCommand(CommandDebug.createCommand())
addCommand(CommandRestore.createCommand())

// creative commands
addCommand(CommandItemRename.createCommand())
Expand Down Expand Up @@ -251,11 +252,14 @@ object CommandManager : Iterable<Command> {
val command = pair.first

// If the command is not executable, don't allow it to be executed
if (!command.executable) {
if (command.handler == null) {
throw CommandException(
translation("liquidbounce.commandManager.invalidUsage", args[0]),
usageInfo = command.usage()
)
} else if (command.hub) {
command.handler!!(command, emptyArray());
return
}

// The index the command is in
Expand Down Expand Up @@ -326,7 +330,7 @@ object CommandManager : Iterable<Command> {
}
}

if (!command.executable) {
if (command.handler == null) {
throw CommandException(
translation("liquidbounce.commandManager.commandNotExecutable", command.name),
usageInfo = command.usage()
Expand Down Expand Up @@ -523,8 +527,6 @@ object CommandManager : Iterable<Command> {
// return builder.buildFuture()
}



operator fun plusAssign(command: Command) {
addCommand(command)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class CommandBuilder private constructor(val name: String) {
private var parameters: ArrayList<Parameter<*>> = ArrayList()
private var subcommands: ArrayList<Command> = ArrayList()
private var handler: CommandHandler? = null
private var executable = true
private var hub = false

companion object {
fun begin(name: String): CommandBuilder = CommandBuilder(name)
Expand Down Expand Up @@ -60,24 +60,26 @@ class CommandBuilder private constructor(val name: String) {
}

/**
* If a command is marked as a hub command, it is impossible to execute it.
* If a command is marked as a hub command, it can't have parameters.
* Furthermore, hubs are not required to be executable.
*
* For example: <code>.friend</code>
*
* The command _friend_ would not be executable since it just acts as a
* hub for its subcommands
* The command _friend_ would not be able to have parameters since it just acts as a
* hub for its subcommands.
*/
fun hub(): CommandBuilder {
this.executable = false
this.hub = true

return this
}

fun build(): Command {
require(executable || this.handler == null) {
"The command is marked as not executable (hub), but no handler was specified"
require(hub && parameters.isEmpty() || !hub) {
"The command is marked as hub, but parameters were specified"
}
require(!executable || this.handler != null) {

require(!hub && handler != null || hub) {
"The command is marked as executable, but no handler was specified."
}

Expand All @@ -103,7 +105,7 @@ class CommandBuilder private constructor(val name: String) {
this.subcommands.toArray(
emptyArray()
),
executable,
this.hub,
this.handler
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
*
* Copyright (c) 2015 - 2024 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.command.commands.client

import net.ccbluex.liquidbounce.config.Configurable
import net.ccbluex.liquidbounce.config.Value
import net.ccbluex.liquidbounce.event.Listenable
import net.ccbluex.liquidbounce.event.events.RegistryChange
import net.ccbluex.liquidbounce.event.events.RegistryChangeEvent
import net.ccbluex.liquidbounce.event.handler
import net.ccbluex.liquidbounce.features.command.Command
import net.ccbluex.liquidbounce.features.command.builder.CommandBuilder
import net.ccbluex.liquidbounce.lang.translation
import net.ccbluex.liquidbounce.utils.client.MessageMetadata
import net.ccbluex.liquidbounce.utils.client.chat
import net.ccbluex.liquidbounce.utils.client.regular
import net.ccbluex.liquidbounce.utils.client.variable

/**
* Restore Command
*
* Allows you to restore original configurations.
*/
object CommandRestore : Listenable {

var command = CommandBuilder.begin("restore").hub().build()

fun createCommand() = command

@Suppress("unused")
val handleModules = handler<RegistryChangeEvent> { event ->
when (event.change) {
RegistryChange.ADD -> registerCommands(null, command, event.module, event.module)
RegistryChange.REMOVE -> {
val newSubCommands = command.subcommands.filter { it.name != event.module.name }.toTypedArray()
command.subcommands = newSubCommands
}
}
}

private fun registerCommands(
commandBuilder: CommandBuilder?,
command: Command?,
configurable: Configurable,
module: Configurable
) {
val commandBuilder1 = CommandBuilder
.begin(configurable.name)
.handler { _, _ -> handle(module, configurable) }
.hub()

configurable.inner.forEach { value ->
if (value is Configurable) {
registerCommands(commandBuilder1, null, value, module)
} else {
commandBuilder1.subcommand(
CommandBuilder
.begin(value.name)
.handler { _, _ -> handle(module, value) }
.build()
)
}
}

val command1 = commandBuilder1.build()
commandBuilder?.subcommand(command1)
command?.let { it.subcommands += command1 }
}

private fun handle(module: Configurable, value: Value<*>) {
value.restore()

if (value is Configurable) {
chat(
regular(
translation("liquidbounce.command.restore.configurable.result.success", variable(value.name))
), metadata = MessageMetadata(id = "${module.name}#restored")
)
} else {
chat(
regular(
translation(
"liquidbounce.command.restore.result.success",
variable(value.name),
variable(module.name)
)
), metadata = MessageMetadata(id = "${module.name}#restored")
)
}
}

}
Loading
Loading