diff --git a/src/main/kotlin/main/vp_server_integration/TotalBalanceModules.kt b/src/main/kotlin/main/vp_server_integration/TotalBalanceModules.kt index 14b0359..9b41c0a 100644 --- a/src/main/kotlin/main/vp_server_integration/TotalBalanceModules.kt +++ b/src/main/kotlin/main/vp_server_integration/TotalBalanceModules.kt @@ -1,27 +1,38 @@ package main.vp_server_integration +// ----------------- VPC API -------------------- +// Here is modules for check global balance (for further using in DYNAMIC course) +// ---------------------------------------------- + import main.vp_server_integration.Vp_server_integration.Companion.LOGGER class TotalBalanceModules { companion object { fun getEssentialsBalance(): Float { - val output: List = CommandCapture.execute("baltop") - LOGGER.info("output $output") - var total: Float = 0.0f - var startOfList: Boolean = false + val output = CommandCapture.execute("baltop") + LOGGER.info("Balance top command output: $output") + + var total = 0.0f + var startOfList = false + for (el in output) { - LOGGER.info("el: $el") + LOGGER.info("Processing line: $el") + if (startOfList) { - LOGGER.info("EL ELEMENT!!!") - LOGGER.info(el.split(" ")[2].replace(Regex("[^0-9.]"), "")) - total += el.split(" ")[2].replace(Regex("[^0-9.]"), "").toFloat() + LOGGER.info("Parsing balance entry") + val balance = el.split(" ")[2].replace(Regex("[^0-9.]"), "") + LOGGER.info("Extracted balance: $balance") + total += balance.toFloat() } else if (el.contains("1.")) { startOfList = true - LOGGER.info("EL START!!!") - LOGGER.info(el.split(" ")[2].replace(Regex("[^0-9.]"), "")) - total += el.split(" ")[2].replace(Regex("[^0-9.]"), "").toFloat() + LOGGER.info("Found first entry, starting balance calculation") + val balance = el.split(" ")[2].replace(Regex("[^0-9.]"), "") + LOGGER.info("First balance extracted: $balance") + total += balance.toFloat() } } + + LOGGER.info("Total balance calculated: $total") return total } } diff --git a/src/main/kotlin/main/vp_server_integration/Utils.kt b/src/main/kotlin/main/vp_server_integration/Utils.kt new file mode 100644 index 0000000..aa19358 --- /dev/null +++ b/src/main/kotlin/main/vp_server_integration/Utils.kt @@ -0,0 +1,45 @@ +package main.vp_server_integration + +// ----------------- VPC API -------------------- +// Here is utils help for working with some stuff +// ---------------------------------------------- + +import main.vp_server_integration.Vp_server_integration.Companion.PREFIX +import org.bukkit.ChatColor +import org.bukkit.command.CommandSender + +import java.util.logging.Logger + +class MyLogger(debugEnabled: Boolean, private val loggerOriginal: java.util.logging.Logger) { + private val debug_enabled = debugEnabled + private val loggerSpigot = loggerOriginal + + fun info(message: String) { + if (debug_enabled) { + loggerSpigot.info(message) + } + } + + fun error(message: String) { + if (debug_enabled) { + loggerSpigot.severe(message) + } + } +} + +class Utils { + companion object { + fun send(source: CommandSender, message: String, prefix: String = PREFIX) { + var first = true + message.split("\n").forEach { line -> + val trimmedLine = line.trimStart() + if (first) { + source.sendMessage(ChatColor.translateAlternateColorCodes('&', "$prefix$trimmedLine")) + first = false + } else { + source.sendMessage(ChatColor.translateAlternateColorCodes('&', "&3$trimmedLine")) + } + } + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/main/vp_server_integration/Vp_server_integration.kt b/src/main/kotlin/main/vp_server_integration/Vp_server_integration.kt index 0df6f3c..7d18e60 100644 --- a/src/main/kotlin/main/vp_server_integration/Vp_server_integration.kt +++ b/src/main/kotlin/main/vp_server_integration/Vp_server_integration.kt @@ -16,7 +16,6 @@ import net.md_5.bungee.api.chat.HoverEvent import net.md_5.bungee.api.chat.ClickEvent import net.md_5.bungee.api.chat.TextComponent import org.bukkit.ChatColor -import org.bukkit.plugin.java.JavaPluginLoader import org.bukkit.scheduler.BukkitRunnable import java.io.File import java.io.FileInputStream @@ -26,7 +25,8 @@ import kotlin.math.abs class Vp_server_integration() : JavaPlugin(), CommandExecutor { companion object { - // A lot of needed configurations + // Configuration settings + var DEBUG_FLAG: Boolean = false lateinit var USERNAME: String lateinit var USER_TOKEN: String lateinit var USER_API_URL: String @@ -38,7 +38,8 @@ class Vp_server_integration() : JavaPlugin(), CommandExecutor { var COURSE_STATIC_VALUE: Double = DEFAULT_COURSE_STATIC_VALUE lateinit var COURSE_DYNAMIC_COMMAND: String var COURSE_COMMISSION: Float = DEFAULT_COURSE_COMMISSION - // A lot of needed configurations + + // Default configuration values const val DEFAULT_USERNAME: String = "test" const val DEFAULT_USER_TOKEN: String = "test" const val DEFAULT_USER_API_URL: String = "http://127.0.0.1:8010/api/" @@ -53,9 +54,10 @@ class Vp_server_integration() : JavaPlugin(), CommandExecutor { const val PREFIX = "&9[&bVPC&7-&6I&9] &3" - // Helpful variables - lateinit var LOGGER: Logger + // Utility instances + lateinit var LOGGER: MyLogger lateinit var SERVER: org.bukkit.Server + // For background checks @JvmStatic var TO_AUTH_PLAYERS: MutableMap = mutableMapOf() // Pair: {player: vpc_username} @@ -64,11 +66,12 @@ class Vp_server_integration() : JavaPlugin(), CommandExecutor { @JvmStatic var TO_PAY_INVOICES: MutableMap = mutableMapOf() // Pair: {player: invoice_id} @JvmStatic - var INVOICES_AMOUNT: MutableMap = mutableMapOf() // To re-send message when user rejoin/etc. - @JvmStatic - var INVOICES_REWARDS: MutableMap = mutableMapOf() // How many should we pay to player after invoice? + var INVOICES_AMOUNT: MutableMap = mutableMapOf() // How many should we pay to player after invoice? } + /** + * Load configuration from config.properties file + */ private fun loadConfiguration() { try { // In Spigot, we use getDataFolder() instead of dataDirectory @@ -83,6 +86,8 @@ class Vp_server_integration() : JavaPlugin(), CommandExecutor { configFile.writeText( """ # VPC Integration Configuration +# For get extra output +debug=false # ---------- Part for work with UserAPI ----------- # Username from your VPC wallet @@ -135,6 +140,7 @@ course_commission=$DEFAULT_COURSE_COMMISSION val properties = Properties() FileInputStream(configFile).use { properties.load(it) } + DEBUG_FLAG = properties.getProperty("debug", false.toString()).replace("'", "").toBoolean() USERNAME = properties.getProperty("username", DEFAULT_USERNAME).replace("'", "") USER_TOKEN = properties.getProperty("user_token", DEFAULT_USER_TOKEN).replace("'", "") USER_API_URL = properties.getProperty("user_api_url", DEFAULT_USER_API_URL).replace("'", "") @@ -158,14 +164,15 @@ course_commission=$DEFAULT_COURSE_COMMISSION } override fun onEnable() { - // Initialize logger - LOGGER = this.logger // Get server instance SERVER = Bukkit.getServer() // Load configuration loadConfiguration() + // Initialize logger + LOGGER = MyLogger(DEBUG_FLAG, this.logger) + getCommand("vpi")?.setExecutor(this) // Background checks such a auth, invoice check, ... @@ -188,54 +195,51 @@ course_commission=$DEFAULT_COURSE_COMMISSION sender.sendMessage("&cТолько игроки могут выполнять команды.") return true } -// val mess = CommandCapture.execute("baltop") -// VpcApi.send(sender, TotalBalanceModules.getEssentialsBalance().toString()) -// return true if ((args.size == 3 || args.size == 4) && args[0] == "convert") { - logger.severe("Step 1") + LOGGER.error("Step 1") val vpcUsername = DataManager.getPlayerVPCUsername(sender.name) if (vpcUsername == null) { - VpcApi.send(sender, "&cНеобходимо авторизоваться через: /vpi auth") + Utils.send(sender, "&cНеобходимо авторизоваться через: /vpi auth") return true } - logger.severe("Step 2") + LOGGER.error("Step 2") val direction = args[1] val amount = abs(args[2].toDouble()) if (!listOf("vpc", "lc").contains(direction)) { - VpcApi.send(sender, "&cНе существует такого направление, правильные: vpc/lc") + Utils.send(sender, "&cНе существует такого направление, правильные: vpc/lc") return true } - logger.severe("Step 3") + LOGGER.error("Step 3") val course: Double // VPC to LC if (COURSE_MODE == "static") { course = COURSE_STATIC_VALUE } else { if (COURSE_DYNAMIC_COMMAND == "baltop force") { - logger.severe("Step 4.1") + LOGGER.error("Step 4.1") CommandCapture.execute("baltop force") val globalBalance = TotalBalanceModules.getEssentialsBalance() - logger.info("globalBalance PRE CHECK: $globalBalance") - logger.severe("Step 4.1.2") + LOGGER.info("globalBalance PRE CHECK: $globalBalance") + LOGGER.error("Step 4.1.2") val vpcUser = VpcApi.user_in_db(username=USERNAME) - logger.severe("Step 4.1.3") + LOGGER.error("Step 4.1.3") val vpcBalance: Double - logger.severe("Step 4.1.4") + LOGGER.error("Step 4.1.4") if (vpcUser == null) { throw Exception("null vpcUser") } - logger.severe("Step 4.1.6") - logger.info(vpcUser["balance"].toString()) + LOGGER.error("Step 4.1.6") + LOGGER.info(vpcUser["balance"].toString()) vpcBalance = vpcUser["balance"].toString().toDouble() - logger.severe("Step 4.1.7") - logger.info("globalBalance: $globalBalance") - logger.info("vpcBalance: $vpcBalance") + LOGGER.error("Step 4.1.7") + LOGGER.info("globalBalance: $globalBalance") + LOGGER.info("vpcBalance: $vpcBalance") course = globalBalance/vpcBalance - logger.info("course: $course") + LOGGER.info("course: $course") } else { - logger.severe("Step 4.2") + LOGGER.error("Step 4.2") val globalBalance = CommandCapture.execute(COURSE_DYNAMIC_COMMAND).toString().toDouble() - logger.severe("$globalBalance") + LOGGER.error("$globalBalance") val vpcUser = VpcApi.user_in_db(username=USERNAME) val vpcBalance: Double if (vpcUser == null) { @@ -249,14 +253,14 @@ course_commission=$DEFAULT_COURSE_COMMISSION if (direction == "vpc") { val amountVPC: Double = amount/course * (1 - COURSE_COMMISSION/100) if (args.size == 4) { - logger.severe("Step 5") + LOGGER.error("Step 5") val result: String = CommandCapture.execute(COMMAND_REMOVE_COINS.replace("%player%", sender.name).replace("%amount%", amount.toString()))[0] - logger.severe("Step 6") + LOGGER.error("Step 6") if (result.contains(COMMAND_REMOVE_ERROR)) { - VpcApi.send(sender, "&cОшибка, возможно недостаточно средств.") + Utils.send(sender, "&cОшибка, возможно недостаточно средств.") return true } - logger.severe("Step 8") + LOGGER.error("Step 8") VpcApi.transfer_coins(vpcUsername, amountVPC) } else { val colored = ChatColor.translateAlternateColorCodes('&', "${PREFIX}Кликните здесь, чтобы конвертировать &6$amount&3 в &6${String.format("%.4f", amountVPC)} VPC") @@ -278,10 +282,10 @@ course_commission=$DEFAULT_COURSE_COMMISSION sender.spigot().sendMessage(message) return true } - logger.severe("amount: $amount") - logger.severe("course: $course") + LOGGER.error("amount: $amount") + LOGGER.error("course: $course") val amountLC: Double = amount*course * (1 + COURSE_COMMISSION/100) - logger.severe("amountLC: $amountLC") + LOGGER.error("amountLC: $amountLC") val invoice_id = VpcApi.create_invoice(amount).toString() TO_PAY_INVOICES[sender.name] = invoice_id INVOICES_AMOUNT[invoice_id] = amountLC @@ -293,12 +297,12 @@ course_commission=$DEFAULT_COURSE_COMMISSION sender.spigot().sendMessage(message) } } else if (args.isNotEmpty() && args[0] == "convert") { - VpcApi.send(sender, "/vpi convert <сумма>") + Utils.send(sender, "/vpi convert <сумма>") } else if (args.size == 2 && args[0] == "auth") { val vpcUsername = DataManager.getPlayerVPCUsername(sender.name) if (vpcUsername != null) { - VpcApi.send(sender, "Вы уже авторизованы!") + Utils.send(sender, "Вы уже авторизованы!") return true } if (sender.name in TO_AUTH_PLAYERS) { @@ -311,13 +315,13 @@ course_commission=$DEFAULT_COURSE_COMMISSION } val invoice_id = VpcApi.create_invoice(0.001) val vpc_username = args[1] - logger.severe("Adding to lists") + LOGGER.error("Adding to lists") synchronized(TO_AUTH_PLAYERS) { TO_AUTH_PLAYERS[sender.name] = vpc_username TO_AUTH_PLAYERS_INVOICES[sender.name] = invoice_id.toString() } - logger.severe("TO_AUTH_PLAYERS: $TO_AUTH_PLAYERS") - logger.severe("TO_AUTH_PLAYERS_INVOICES: $TO_AUTH_PLAYERS_INVOICES") + LOGGER.error("TO_AUTH_PLAYERS: $TO_AUTH_PLAYERS") + LOGGER.error("TO_AUTH_PLAYERS_INVOICES: $TO_AUTH_PLAYERS_INVOICES") val colored = ChatColor.translateAlternateColorCodes('&', "${PREFIX}Кликните здесь, чтобы перевести 0.001 VPC") val message = TextComponent(colored) message.clickEvent = ClickEvent(ClickEvent.Action.RUN_COMMAND, "/vpc pay $USERNAME 0.001 $invoice_id") @@ -325,31 +329,10 @@ course_commission=$DEFAULT_COURSE_COMMISSION sender.spigot().sendMessage(message) } else if (args.isNotEmpty() && args[0] == "auth") { - VpcApi.send(sender, "/vpi auth <ник>") + Utils.send(sender, "/vpi auth <ник>") } else { -// val messages = listOf( -// "Использование команд:", -// "/vpi auth <ник> - Авторизация", -// "/vpi convert <куда: vpc/lc> <сумма> - Обмен VPC на локальную валюту или наоборот", -// "", -// "Почему 'VPC-I'? Потому что это интеграция на конечном сервере - 'VPC Integration'", -// "", -// "Соглашение: voidproject.del.pw/vpc_agreement", -// "Группа ТГ: @void_project_mc", -// "Группа ДС: discord.gg/zwNt5DJj6J" -// ) -// -// var first: Boolean = true -// messages.forEach { message -> -// if (first) { -// VpcApi.send(sender, message) -// first = false -// } else { -// VpcApi.send(sender, message, "&3") -// } -// } - VpcApi.send(sender, """Использование команд: + Utils.send(sender, """Использование команд: /vpi auth <ник> - Авторизация /vpi convert <куда: vpc/lc> <сумма> - Обмен VPC на локальную валюту или наоборот @@ -361,15 +344,6 @@ course_commission=$DEFAULT_COURSE_COMMISSION } return true - - // Create a clickable message that runs /help when clicked -// val message = TextComponent("Click here to execute command") -// val colored = ChatColor.translateAlternateColorCodes('&', "&6Testing") -// val message = TextComponent(colored) -// message.clickEvent = ClickEvent(ClickEvent.Action.RUN_COMMAND, "/vpc bal") -// message.hoverEvent = HoverEvent(HoverEvent.Action.SHOW_TEXT, ComponentBuilder("Click here to execute command").create()) -// -// sender.spigot().sendMessage(message) } return false } @@ -413,14 +387,14 @@ course_commission=$DEFAULT_COURSE_COMMISSION // Add null safety checks if (result != null) { val status = result["status"] - logger.severe("Invoice ${entry.value} status: $status") + LOGGER.error("Invoice ${entry.value} status: $status") if (status != null && status.toString() == "true") { - logger.severe("DELETE!!!!!!!!!!!!!!!!") + LOGGER.error("DELETE!!!!!!!!!!!!!!!!") VpcApi.delete_invoice(entry.value) DataManager.setPlayerVPCUsername(entry.key, TO_AUTH_PLAYERS[entry.key].toString()) - VpcApi.send(Bukkit.getPlayer(entry.key.toString()), "&aВы успешно авторизованы!") + Utils.send(Bukkit.getPlayer(entry.key.toString()), "&aВы успешно авторизованы!") // Safely remove from both maps TO_AUTH_PLAYERS.remove(entry.key) @@ -430,7 +404,7 @@ course_commission=$DEFAULT_COURSE_COMMISSION logger.warning("Received null result for invoice ${entry.value}") } } catch (e: Exception) { - logger.severe("Error processing invoice ${entry.value}: ${e.message}") + LOGGER.error("Error processing invoice ${entry.value}: ${e.message}") e.printStackTrace() } } @@ -449,10 +423,10 @@ course_commission=$DEFAULT_COURSE_COMMISSION // Add null safety checks if (result != null) { val status = result["status"] - logger.severe("Invoice ${entry.value} status: $status") + LOGGER.error("Invoice ${entry.value} status: $status") if (status != null && status.toString() == "true") { - logger.severe("DELETE!!!!!!!!!!!!!!!!") + LOGGER.error("DELETE!!!!!!!!!!!!!!!!") VpcApi.delete_invoice(entry.value) val amountLC = INVOICES_AMOUNT[entry.value] @@ -463,7 +437,7 @@ course_commission=$DEFAULT_COURSE_COMMISSION try { CommandCapture.execute(commandToAddCoins) } catch (e: Exception) { - logger.severe("Error executing command: ${e.message}") + LOGGER.error("Error executing command: ${e.message}") e.printStackTrace() } }) @@ -476,7 +450,7 @@ course_commission=$DEFAULT_COURSE_COMMISSION logger.warning("Received null result for invoice ${entry.value}") } } catch (e: Exception) { - logger.severe("Error processing invoice ${entry.value}: ${e.message}") + LOGGER.error("Error processing invoice ${entry.value}: ${e.message}") e.printStackTrace() } } diff --git a/src/main/kotlin/main/vp_server_integration/VpcApi.kt b/src/main/kotlin/main/vp_server_integration/VpcApi.kt index 26a6e45..01d85f8 100644 --- a/src/main/kotlin/main/vp_server_integration/VpcApi.kt +++ b/src/main/kotlin/main/vp_server_integration/VpcApi.kt @@ -156,46 +156,9 @@ class VpcApi { } } - fun send(source: CommandSender, message: String, prefix: String = PREFIX) { - var first: Boolean = true - var mess: String - message.split("\n").forEach { el -> - mess = el.trimStart() - if (first) { - source.sendMessage(ChatColor.translateAlternateColorCodes('&', prefix + mess)) - first = false - } else { - source.sendMessage(ChatColor.translateAlternateColorCodes('&', "&3$mess")) - } - } - // Translate color codes for Spigot -// val coloredMessage = ChatColor.translateAlternateColorCodes('&', prefix + message) -// source.sendMessage(coloredMessage) - } - - fun get_super_UUID(source: CommandSender): String { - if (source is Player) { - val uuid = source.uniqueId - val username = source.name - val address = source.address?.hostString ?: "unknown" - // Note: Some properties don't exist in 1.12.2, using available alternatives - val merged = "$uuid$username$address" - return hash(merged) - } else { - return "None" - } - } - // Simple hash function (you might want to replace this with a proper hashing algorithm) - private fun hash(input: String): String { - return UUID.nameUUIDFromBytes(input.toByteArray()).toString() - } - fun user_in_db(source: CommandSender? = null, username: String? = null): Map? { - var mine_uuid: String? = null - // Determine which parameter to use val userParam = when { username != null -> "username" to username - source is Player -> "mine_name" to source.name else -> throw IllegalArgumentException("Either source or username must be provided") } @@ -218,14 +181,13 @@ class VpcApi { fun transfer_coins(dst_username: String, amount: Double): Any? { val response = sendPost( - "transfer_coins/", jsonify( - listOf( - "username", USERNAME, - "user_token", USER_TOKEN, - "dst_username", dst_username, - "amount", amount.toString() - ) - ) + "transfer_coins/", + jsonify(listOf( + "username", USERNAME, + "user_token", USER_TOKEN, + "dst_username", dst_username, + "amount", amount.toString() + )) ) return if (response.status == 200) { @@ -237,13 +199,12 @@ class VpcApi { fun create_invoice(amount: Double): Any? { val response = sendPost( - "create_invoice/", jsonify( - listOf( - "username", USERNAME, - "user_token", USER_TOKEN, - "amount", amount.toString() - ) - ) + "create_invoice/", + jsonify(listOf( + "username", USERNAME, + "user_token", USER_TOKEN, + "amount", amount.toString() + )) ) return if (response.status == 200) { @@ -255,13 +216,12 @@ class VpcApi { fun delete_invoice(invoice_id: String): Any? { val response = sendPost( - "delete_invoice/", jsonify( - listOf( - "username", USERNAME, - "user_token", USER_TOKEN, - "invoice_id", invoice_id - ) - ) + "delete_invoice/", + jsonify(listOf( + "username", USERNAME, + "user_token", USER_TOKEN, + "invoice_id", invoice_id + )) ) return if (response.status == 200) { @@ -273,13 +233,12 @@ class VpcApi { fun get_invoice(invoice_id: String): Any? { val response = sendPost( - "get_invoice/", jsonify( - listOf( - "username", USERNAME, - "user_token", USER_TOKEN, - "invoice_id", invoice_id - ) - ) + "get_invoice/", + jsonify(listOf( + "username", USERNAME, + "user_token", USER_TOKEN, + "invoice_id", invoice_id + )) ) // response["someKey"] (map-like access)