diff --git a/src/main/java/net/ccbluex/liquidbounce/features/command/commands/SettingsCommand.kt b/src/main/java/net/ccbluex/liquidbounce/features/command/commands/SettingsCommand.kt index 5d5d3c202a0..0c5629b2630 100644 --- a/src/main/java/net/ccbluex/liquidbounce/features/command/commands/SettingsCommand.kt +++ b/src/main/java/net/ccbluex/liquidbounce/features/command/commands/SettingsCommand.kt @@ -5,10 +5,9 @@ */ package net.ccbluex.liquidbounce.features.command.commands -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import net.ccbluex.liquidbounce.LiquidBounce import net.ccbluex.liquidbounce.api.ClientApi import net.ccbluex.liquidbounce.api.Status @@ -20,12 +19,15 @@ import net.ccbluex.liquidbounce.ui.client.hud.HUD.addNotification import net.ccbluex.liquidbounce.ui.client.hud.element.elements.Notification import net.ccbluex.liquidbounce.utils.client.ClientUtils.LOGGER import net.ccbluex.liquidbounce.utils.io.HttpUtils.get +import net.ccbluex.liquidbounce.utils.kotlin.SharedScopes import net.ccbluex.liquidbounce.utils.kotlin.StringUtils import java.awt.Toolkit import java.awt.datatransfer.StringSelection object SettingsCommand : Command("autosettings", "autosetting", "settings", "setting", "config") { + private val mutex = Mutex() + /** * Execute commands with provided [args] */ @@ -37,121 +39,120 @@ object SettingsCommand : Command("autosettings", "autosetting", "settings", "set return } - GlobalScope.launch { - when (args[1].lowercase()) { - "load" -> loadSettings(args) - "report" -> reportSettings(args) - "upload" -> uploadSettings(args) - "list" -> listSettings() - else -> chatSyntax("$usedAlias ") + if (mutex.isLocked) { + chat("§cPrevious task is not finished!") + return + } + + SharedScopes.IO.launch { + mutex.withLock { + when (args[1].lowercase()) { + "load" -> loadSettings(args) + "report" -> reportSettings(args) + "upload" -> uploadSettings(args) + "list" -> listSettings() + else -> chatSyntax("$usedAlias ") + } } } } // Load subcommand - private suspend fun loadSettings(args: Array) { - withContext(Dispatchers.IO) { - if (args.size < 3) { - chatSyntax("${args[0].lowercase()} load ") - return@withContext - } - - try { - val settings = if (args[2].startsWith("http")) { - val (text, code) = get(args[2]) - if (code != 200) { - error(text) - } + private fun loadSettings(args: Array) { + if (args.size < 3) { + chatSyntax("${args[0].lowercase()} load ") + return + } - text - } else { - ClientApi.requestSettingsScript(args[2]) + try { + val settings = if (args[2].startsWith("http")) { + val (text, code) = get(args[2]) + if (code != 200) { + error(text) } - chat("Applying settings...") - SettingsUtils.applyScript(settings) - chat("§6Settings applied successfully") - addNotification(Notification("Updated Settings")) - playEdit() - } catch (e: Exception) { - LOGGER.error("Failed to load settings", e) - chat("Failed to load settings: ${e.message}") + text + } else { + ClientApi.requestSettingsScript(args[2]) } + + chat("Applying settings...") + SettingsUtils.applyScript(settings) + chat("§6Settings applied successfully") + addNotification(Notification("Updated Settings")) + playEdit() + } catch (e: Exception) { + LOGGER.error("Failed to load settings", e) + chat("Failed to load settings: ${e.message}") } } // Report subcommand - private suspend fun reportSettings(args: Array) { - withContext(Dispatchers.IO) { - if (args.size < 3) { - chatSyntax("${args[0].lowercase()} report ") - return@withContext - } + private fun reportSettings(args: Array) { + if (args.size < 3) { + chatSyntax("${args[0].lowercase()} report ") + return + } - try { - val response = ClientApi.reportSettings(args[2]) - when (response.status) { - Status.SUCCESS -> chat("§6${response.message}") - Status.ERROR -> chat("§c${response.message}") - } - } catch (e: Exception) { - LOGGER.error("Failed to report settings", e) - chat("Failed to report settings: ${e.message}") + try { + val response = ClientApi.reportSettings(args[2]) + when (response.status) { + Status.SUCCESS -> chat("§6${response.message}") + Status.ERROR -> chat("§c${response.message}") } + } catch (e: Exception) { + LOGGER.error("Failed to report settings", e) + chat("Failed to report settings: ${e.message}") } } // Upload subcommand - private suspend fun uploadSettings(args: Array) { - withContext(Dispatchers.IO) { - val option = if (args.size > 3) StringUtils.toCompleteString(args, 3).lowercase() else "all" - val all = "all" in option - val values = all || "values" in option - val binds = all || "binds" in option - val states = all || "states" in option - - if (!values && !binds && !states) { - chatSyntax("${args[0].lowercase()} upload [all/values/binds/states]...") - return@withContext - } - - try { - chat("§9Creating settings...") - val settingsScript = SettingsUtils.generateScript(values, binds, states) - chat("§9Uploading settings...") + private fun uploadSettings(args: Array) { + val option = if (args.size > 3) StringUtils.toCompleteString(args, 3).lowercase() else "all" + val all = "all" in option + val values = all || "values" in option + val binds = all || "binds" in option + val states = all || "states" in option + + if (!values && !binds && !states) { + chatSyntax("${args[0].lowercase()} upload [all/values/binds/states]...") + return + } - val serverData = mc.currentServerData ?: error("You need to be on a server to upload settings.") + try { + chat("§9Creating settings...") + val settingsScript = SettingsUtils.generateScript(values, binds, states) + chat("§9Uploading settings...") - val name = "${LiquidBounce.clientCommit}-${serverData.serverIP.replace(".", "_")}" - val response = ClientApi.uploadSettings(name, mc.session.username, settingsScript) + val serverData = mc.currentServerData ?: error("You need to be on a server to upload settings.") - when (response.status) { - Status.SUCCESS -> { - chat("§6${response.message}") - chat("§9Token: §6${response.token}") + val name = "${LiquidBounce.clientCommit}-${serverData.serverIP.replace(".", "_")}" + val response = ClientApi.uploadSettings(name, mc.session.username, settingsScript) - // Store token in clipboard - val stringSelection = StringSelection(response.token) - Toolkit.getDefaultToolkit().systemClipboard.setContents(stringSelection, stringSelection) - } + when (response.status) { + Status.SUCCESS -> { + chat("§6${response.message}") + chat("§9Token: §6${response.token}") - Status.ERROR -> chat("§c${response.message}") + // Store token in clipboard + val stringSelection = StringSelection(response.token) + Toolkit.getDefaultToolkit().systemClipboard.setContents(stringSelection, stringSelection) } - } catch (e: Exception) { - LOGGER.error("Failed to upload settings", e) - chat("Failed to upload settings: ${e.message}") + + Status.ERROR -> chat("§c${response.message}") } + } catch (e: Exception) { + LOGGER.error("Failed to upload settings", e) + chat("Failed to upload settings: ${e.message}") } } // List subcommand - private suspend fun listSettings() { - withContext(Dispatchers.IO) { - chat("Loading settings...") - loadSettings(false) { - for (setting in it) { - chat("> ${setting.settingId} (Last updated: ${setting.date}, Status: ${setting.statusType.displayName})") - } + private fun listSettings() { + chat("Loading settings...") + loadSettings(false) { + for (setting in it) { + chat("> ${setting.settingId} (Last updated: ${setting.date}, Status: ${setting.statusType.displayName})") } } }