Добавление срока для оплаты счёта, по истечению - удаление счёта.

This commit is contained in:
justuser-31 2025-11-24 19:06:22 +03:00
parent be8f5e37f0
commit 0e382d8f72

View File

@ -22,6 +22,7 @@ import java.io.FileInputStream
import java.util.Properties
import kotlin.collections.mutableMapOf
import kotlin.math.abs
import java.util.Date
class Vp_server_integration() : JavaPlugin(), CommandExecutor {
companion object {
@ -38,6 +39,7 @@ 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
var INVOICE_TIMEOUT_SECONDS: Long = DEFAULT_INVOICE_TIMEOUT_SECONDS
// Default configuration values
const val DEFAULT_USERNAME: String = "test"
@ -51,6 +53,7 @@ class Vp_server_integration() : JavaPlugin(), CommandExecutor {
const val DEFAULT_COURSE_STATIC_VALUE: Double = 1000.0
const val DEFAULT_COURSE_DYNAMIC_COMMAND: String = "baltop force"
const val DEFAULT_COURSE_COMMISSION: Float = 5.0f
const val DEFAULT_INVOICE_TIMEOUT_SECONDS: Long = 300 // 5 minutes
const val PREFIX = "&9[&bVPC&7-&6I&9] &3"
@ -67,6 +70,10 @@ class Vp_server_integration() : JavaPlugin(), CommandExecutor {
var TO_PAY_INVOICES: MutableMap<String, String> = mutableMapOf() // Pair: {player: invoice_id}
@JvmStatic
var INVOICES_AMOUNT: MutableMap<String, Double> = mutableMapOf() // How many should we pay to player after invoice?
// Track invoice creation times for timeout handling
@JvmStatic
var INVOICE_CREATION_TIMES: MutableMap<String, Long> = mutableMapOf() // Pair: {invoice_id: creation_timestamp}
}
/**
@ -102,6 +109,7 @@ class Vp_server_integration() : JavaPlugin(), CommandExecutor {
COURSE_STATIC_VALUE = properties.getProperty("course_static_value", DEFAULT_COURSE_STATIC_VALUE.toString()).replace("'", "").toDouble()
COURSE_DYNAMIC_COMMAND = properties.getProperty("course_dynamic_command", DEFAULT_COURSE_DYNAMIC_COMMAND).replace("'", "")
COURSE_COMMISSION = properties.getProperty("course_commission", DEFAULT_COURSE_COMMISSION.toString()).replace("'", "").toFloat()
INVOICE_TIMEOUT_SECONDS = properties.getProperty("invoice_timeout_seconds", DEFAULT_INVOICE_TIMEOUT_SECONDS.toString()).replace("'", "").toLong()
logger.info("Configuration loaded successfully - Username: $USERNAME, API URL: $USER_API_URL")
} catch (e: Exception) {
@ -163,6 +171,11 @@ course_dynamic_command='$DEFAULT_COURSE_DYNAMIC_COMMAND'
# For dynamic course recommended 5% and higher (avoid dupe), for static course you can set 0%
course_commission=$DEFAULT_COURSE_COMMISSION
# -------------------- END ------------------------
# --------- Invoice timeout configuration ----------
# After how many seconds unpaid invoices will be deleted (default: 300 seconds = 5 minutes)
invoice_timeout_seconds=$DEFAULT_INVOICE_TIMEOUT_SECONDS
# -------------------- END ------------------------
""".trimIndent()
)
}
@ -381,6 +394,7 @@ course_commission=$DEFAULT_COURSE_COMMISSION
val invoiceId = VpcApi.create_invoice(amount).toString()
TO_PAY_INVOICES[sender.name] = invoiceId
INVOICES_AMOUNT[invoiceId] = amountLC
INVOICE_CREATION_TIMES[invoiceId] = System.currentTimeMillis()
sendPaymentPrompt(sender, amount, amountLC, invoiceId)
}
@ -437,6 +451,7 @@ course_commission=$DEFAULT_COURSE_COMMISSION
synchronized(TO_AUTH_PLAYERS) {
TO_AUTH_PLAYERS[sender.name] = vpcUsernameInput
TO_AUTH_PLAYERS_INVOICES[sender.name] = invoiceId.toString()
INVOICE_CREATION_TIMES[invoiceId.toString()] = System.currentTimeMillis()
}
LOGGER.info("Authentication lists updated")
@ -502,6 +517,7 @@ course_commission=$DEFAULT_COURSE_COMMISSION
override fun run() {
processAuthenticationInvoices()
processPaymentInvoices()
cleanupExpiredInvoices()
}
}.runTaskTimerAsynchronously(this, 0L, 20L)
}
@ -531,6 +547,7 @@ course_commission=$DEFAULT_COURSE_COMMISSION
// Clean up tracking maps
TO_AUTH_PLAYERS.remove(entry.key)
INVOICE_CREATION_TIMES.remove(entry.value)
iterator.remove()
}
} else {
@ -583,6 +600,7 @@ course_commission=$DEFAULT_COURSE_COMMISSION
// Clean up tracking maps
INVOICES_AMOUNT.remove(entry.key)
INVOICE_CREATION_TIMES.remove(entry.value)
iterator.remove()
}
} else {
@ -596,4 +614,72 @@ course_commission=$DEFAULT_COURSE_COMMISSION
}
}
}
/**
* Cleanup expired invoices based on timeout configuration
*/
private fun cleanupExpiredInvoices() {
val currentTime = System.currentTimeMillis()
val timeoutMillis = INVOICE_TIMEOUT_SECONDS * 1000
// Cleanup auth invoices
synchronized(TO_AUTH_PLAYERS_INVOICES) {
val authIterator = TO_AUTH_PLAYERS_INVOICES.iterator()
while (authIterator.hasNext()) {
val entry = authIterator.next()
val invoiceId = entry.value
val creationTime = INVOICE_CREATION_TIMES[invoiceId] ?: continue
if (currentTime - creationTime > timeoutMillis) {
LOGGER.info("Deleting expired auth invoice: $invoiceId")
try {
VpcApi.delete_invoice(invoiceId)
} catch (e: Exception) {
LOGGER.error("Error deleting expired auth invoice $invoiceId: ${e.message}")
}
// Clean up tracking maps
TO_AUTH_PLAYERS.remove(entry.key)
INVOICE_CREATION_TIMES.remove(invoiceId)
authIterator.remove()
// Notify player if online
val player = Bukkit.getPlayer(entry.key)
if (player != null && player.isOnline) {
Utils.send(player, "&cВаша авторизационная оплата истекла. Пожалуйста, попробуйте снова: /vpi auth <ник>")
}
}
}
}
// Cleanup payment invoices
synchronized(TO_PAY_INVOICES) {
val paymentIterator = TO_PAY_INVOICES.iterator()
while (paymentIterator.hasNext()) {
val entry = paymentIterator.next()
val invoiceId = entry.value
val creationTime = INVOICE_CREATION_TIMES[invoiceId] ?: continue
if (currentTime - creationTime > timeoutMillis) {
LOGGER.info("Deleting expired payment invoice: $invoiceId")
try {
VpcApi.delete_invoice(invoiceId)
} catch (e: Exception) {
LOGGER.error("Error deleting expired payment invoice $invoiceId: ${e.message}")
}
// Clean up tracking maps
INVOICES_AMOUNT.remove(invoiceId)
INVOICE_CREATION_TIMES.remove(invoiceId)
paymentIterator.remove()
// Notify player if online
val player = Bukkit.getPlayer(entry.key)
if (player != null && player.isOnline) {
Utils.send(player, "&cВаша оплата истекла. Пожалуйста, создайте новую: /vpi convert lc <сумма>")
}
}
}
}
}
}