Skip to content
This repository has been archived by the owner on Aug 14, 2024. It is now read-only.

Commit

Permalink
reimplement configs
Browse files Browse the repository at this point in the history
  • Loading branch information
ManInMyVan committed Jan 4, 2024
1 parent a32b0a0 commit a7e04a8
Show file tree
Hide file tree
Showing 4 changed files with 309 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ object CommandManager {
fun registerCommands() {
commands.clear()

registerCommand(ConfigCommand)
registerCommand(BindCommand)
registerCommand(VClipCommand)
registerCommand(HClipCommand)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
* LiquidBounce Hacked Client
* A free open source mixin-based injection hacked client for Minecraft using Minecraft Forge.
* https://github.com/CCBlueX/LiquidBounce/
*/
package net.ccbluex.liquidbounce.features.command.commands


import net.ccbluex.liquidbounce.features.command.Command
import net.ccbluex.liquidbounce.file.FileManager.settingsDir
import net.ccbluex.liquidbounce.ui.client.hud.HUD.addNotification
import net.ccbluex.liquidbounce.ui.client.hud.element.elements.Notification
import net.ccbluex.liquidbounce.utils.ClientUtils.LOGGER
import net.ccbluex.liquidbounce.utils.SettingsUtils
import java.awt.Desktop
import java.io.File
import java.io.IOException

object ConfigCommand : Command("config", "settings", "c", "cfg") {
/**
* Execute commands with provided [args]
*/
override fun execute(args: Array<String>) {
val usedAlias = args[0].lowercase().removePrefix(".")
if (args.size <= 1) {
chatSyntax("$usedAlias <load/save/list/delete/folder/rename>")
return
}
when (args[1].lowercase()) {
"load" -> {
if (args.size <= 2) {
chatSyntax("$usedAlias load <name>")
return
}
val file = File(settingsDir, args[2])
try {
val settings = file.readText()
SettingsUtils.applyScript(settings)
chat("§6Config §a${args[2]} §6loaded successfully.")
addNotification(Notification("Updated Settings"))
playEdit()
} catch (e: IOException) {
e.printStackTrace()
}
}

"rename" -> {
if (args.size <= 3) {
chatSyntax("$usedAlias rename <oldName> <newName>")
return
}

val oldFile = File(settingsDir, args[2])
val newFile = File(settingsDir, args[3])

if (!oldFile.exists()) {
chat("§cConfig §a${args[2]} §cdoes not exist!")
return
}
if (newFile.exists()) newFile.delete()

oldFile.renameTo(newFile)
chat("§6Config §a${args[2]} §6renamed to §a${args[3]} §6successfully.")

}
"save" -> {
if (args.size <= 2) {
chatSyntax("$usedAlias save <name>")
return
}

val file = File(settingsDir, args[2])

try {
if (file.exists()) file.delete()

file.createNewFile()
val settingsScript = SettingsUtils.generateScript()
file.writeText(settingsScript)

chat("§6Config §a${args[2]} §6saved successfully.")
} catch (throwable: Throwable) {
chat("§cFailed to create config: §3${throwable.message}")
LOGGER.error("Failed to create config.", throwable)
}
}

"delete" -> {
if (args.size <= 2) {
chatSyntax("$usedAlias delete <name>")
return
}

val file = File(settingsDir, args[2])

if (!file.exists()) {
chat("§cConfig §a${args[2]} §cdoes not exist!")
return
}

file.delete()

chat("§6Config §a${args[2]} §6deleted successfully.")
}

"list" -> {
val settings = getLocalSettings() ?: return
if (settings.isEmpty()) {
chat("§6No Configs Found.")
return
}
chat("§6Configs:")
for (file in settings)
chat(" §a${file.name}")
}

"folder" -> Desktop.getDesktop().open(settingsDir)

else -> chatSyntax("$usedAlias <load/save/list/delete/folder/rename>")
}
}

override fun tabComplete(args: Array<String>): List<String> {
if (args.isEmpty()) return emptyList()

return when (args.size) {
1 -> listOf("delete", "folder", "list", "load", "rename", "save").filter { it.startsWith(args[0], true) }

2 ->
when (args[0].lowercase()) {
"delete", "load", "rename" -> {
val settings = getLocalSettings() ?: return emptyList()

settings
.map { it.name }
.filter { it.startsWith(args[1], true) }
}

else -> emptyList()
}

else -> emptyList()
}
}

private fun getLocalSettings() = settingsDir.listFiles()
}
2 changes: 1 addition & 1 deletion src/main/java/net/ccbluex/liquidbounce/file/FileManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ object FileManager : MinecraftInstance() {

val dir = File(mc.mcDataDir, CLIENT_NAME)
val fontsDir = File(dir, "fonts")
val settingsDir = File(dir, "settings")
val settingsDir = File(dir, "configs")
val modulesConfig = ModulesConfig(File(dir, "modules.json"))
val valuesConfig = ValuesConfig(File(dir, "values.json"))
val clickGuiConfig = ClickGuiConfig(File(dir, "clickgui.json"))
Expand Down
160 changes: 160 additions & 0 deletions src/main/java/net/ccbluex/liquidbounce/utils/SettingsUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/*
* LiquidBounce Hacked Client
* A free open source mixin-based injection hacked client for Minecraft using Minecraft Forge.
* https://github.com/CCBlueX/LiquidBounce/
*/
package net.ccbluex.liquidbounce.utils

import net.ccbluex.liquidbounce.LiquidBounce.moduleManager
import net.ccbluex.liquidbounce.api.ClientApi
import net.ccbluex.liquidbounce.features.module.Module
import net.ccbluex.liquidbounce.file.FileManager
import net.ccbluex.liquidbounce.utils.ClientUtils.displayChatMessage
import net.ccbluex.liquidbounce.utils.misc.HttpUtils
import net.ccbluex.liquidbounce.utils.misc.StringUtils
import net.ccbluex.liquidbounce.utils.render.ColorUtils.translateAlternateColorCodes
import net.ccbluex.liquidbounce.value.*
import org.lwjgl.input.Keyboard
import kotlin.reflect.KMutableProperty0

/**
* Utility class for handling settings and scripts in LiquidBounce.
*/
object SettingsUtils {

/**
* Execute settings script.
* @param script The script to apply.
*/
fun applyScript(script: String) {
script.lines().forEachIndexed { index, s ->
if (s.isEmpty() || s.startsWith('#')) {
return@forEachIndexed
}

val args = s.split(" ").toTypedArray()

if (args.size <= 1) {
displayChatMessage("§cSyntax error at line '$index' in setting script.\n§8§lLine: §7$s")
return@forEachIndexed
}

when (args[0]) {
"chat" -> displayChatMessage(
"§e${
translateAlternateColorCodes(
StringUtils.toCompleteString(
args,
1
)
)
}"
)

"unchat" -> displayChatMessage(
translateAlternateColorCodes(
StringUtils.toCompleteString(
args,
1
)
)
)

"load" -> {
val url = StringUtils.toCompleteString(args, 1)
runCatching {
val settings = if (url.startsWith("http")) {
val (text, code) = HttpUtils.get(url)

if (code != 200) {
error(text)
}

text
} else {
ClientApi.requestSettingsScript(url)
}

applyScript(settings)
}.onSuccess {
displayChatMessage("§7[§3§lAutoSettings§7] §7Loaded settings §a§l$url§7.")
}.onFailure {
displayChatMessage("§7Failed to load settings §c§l$url§7.")
}
}

else -> {
if (args.size < 3) {
displayChatMessage("§cSyntax error at line '$index' in setting script.\n§8§lLine: §7$s")
return@forEachIndexed
}

val moduleName = args[0]
val valueName = args[1]
val value = args[2]
val module = moduleManager[moduleName]

if (module == null) {
displayChatMessage("§cModule §a$moduleName§c does not exist!")
return@forEachIndexed
}

when (valueName) {
"toggle" -> setToggle(module, value)
"bind" -> setBind(module, value)
else -> setValue(module, valueName, value, args)
}
}
}
}

FileManager.saveConfig(FileManager.valuesConfig)
}
private fun setToggle(module: Module, value: String) {
module.state = value.equals("true", ignoreCase = true)
}
private fun setBind(module: Module, value: String) {
module.keyBind = Keyboard.getKeyIndex(value)
}

// Utility functions for setting values
private fun setValue(module: Module, valueName: String, value: String, args: Array<String>) {
val moduleValue = module[valueName]

if (moduleValue == null) {
displayChatMessage("§7[§3§lAutoSettings§7] §cValue §a§l$valueName§c wasn't found in module §a§l${module.getName()}§c.")
return
}

try {
when (moduleValue) {
is BoolValue -> moduleValue.changeValue(value.toBoolean())
is FloatValue -> moduleValue.changeValue(value.toFloat())
is IntegerValue -> moduleValue.changeValue(value.toInt())
is TextValue -> moduleValue.changeValue(StringUtils.toCompleteString(args, 2))
is ListValue -> moduleValue.changeValue(value)
}
} catch (e: Exception) {
displayChatMessage("§7[§3§lAutoSettings§7] §a§l${e.javaClass.name}§7(${e.message}) §cAn Exception occurred while setting §a§l$value§c to §a§l${moduleValue.name}§c in §a§l${module.getName()}§c.")
}
}

/**
* Generate settings script.
* @return The generated script.
*/
fun generateScript(): String {
return moduleManager.modules
.joinToString("\n") { module ->
buildString {
val vals = module.values
if (vals.isNotEmpty()) {
vals.joinTo(this, separator = "\n") { "${module.name} ${it.name} ${it.get()}" }
appendLine()
}
appendLine("${module.name} toggle ${module.state}")
appendLine("${module.name} bind ${Keyboard.getKeyName(module.keyBind)}")
}
}.lines().filter { it.isNotBlank() }.joinToString("\n")
}
}

0 comments on commit a7e04a8

Please sign in to comment.