Добавление покупки по табличке.

This commit is contained in:
justuser-31 2025-11-30 15:40:38 +03:00
parent 79d21942bb
commit 5bd184ec2a
2 changed files with 841 additions and 563 deletions

View File

@ -0,0 +1,163 @@
package main.VpcSpigotIntegration
import main.VpcSpigotIntegration.VpcServerIntegration.Companion.INVOICE_CREATION_TIMES
import main.VpcSpigotIntegration.VpcServerIntegration.Companion.LOGGER
import main.VpcSpigotIntegration.VpcServerIntegration.Companion.PAY_BY_SIGN
import main.VpcSpigotIntegration.VpcServerIntegration.Companion.PLUGIN
import main.VpcSpigotIntegration.VpcServerIntegration.Companion.PREFIX
import main.VpcSpigotIntegration.VpcServerIntegration.Companion.SIGN_PAYMENT_INFO
import main.VpcSpigotIntegration.VpcServerIntegration.Companion.TO_PAY_SIGN_INVOICES
import main.VpcSpigotIntegration.VpcServerIntegration.Companion.USERNAME
import net.md_5.bungee.api.chat.ClickEvent
import net.md_5.bungee.api.chat.ComponentBuilder
import net.md_5.bungee.api.chat.HoverEvent
import net.md_5.bungee.api.chat.TextComponent
import org.bukkit.Bukkit
import org.bukkit.Bukkit.getWorld
import org.bukkit.ChatColor
import org.bukkit.Location
import org.bukkit.event.EventHandler
import org.bukkit.event.block.BlockEvent
import org.bukkit.event.player.PlayerInteractEvent
import org.bukkit.Material
import org.bukkit.block.Chest
import org.bukkit.block.Container
import org.bukkit.block.Sign
import org.bukkit.entity.Player
import org.bukkit.event.Listener
import org.bukkit.event.block.Action
import org.bukkit.event.block.BlockPlaceEvent
import org.bukkit.event.block.SignChangeEvent
import org.bukkit.inventory.Inventory
import org.bukkit.inventory.ItemStack
import org.bukkit.plugin.java.JavaPlugin
import java.util.Locale
import java.util.Locale.getDefault
class SignPaymentInfo(
public val amount: Int,
public val type: Material,
public val container: Chest,
public val player: Player,
public val cost: Double,
public val dst_username: String
)
class SignHandler: Listener {
@EventHandler
fun onClick(event: PlayerInteractEvent) {
// Check if feature enabled
if (!PAY_BY_SIGN) return
// Check if clicked block is a sign
val block = event.clickedBlock!!
if (block.type != Material.SIGN_POST && block.type != Material.WALL_SIGN) return
// Verify it's actually a sign state
val state = block.state
if (state !is Sign) return
// Check if it is RIGHT CLICK
if (event.action != Action.RIGHT_CLICK_BLOCK) return
// Check if this is good formatted sign
val sign = block.state as Sign
val clearFirstLine = ChatColor.stripColor(sign.getLine(0)).trim()
val clearPrefix = ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', PREFIX)).trim()
if (clearFirstLine != clearPrefix) return
// Check if player already have open invoices
if (TO_PAY_SIGN_INVOICES.contains(event.player.name)) {
Utils.send(event.player, "&cУ вас уже есть открытый счёт, сначала оплатите его.")
return
}
val blockFace = event.blockFace.toString()
LOGGER.info("Block face: $blockFace")
var cordX: Int = event.clickedBlock.location.x.toInt()
var cordY: Int = event.clickedBlock.location.y.toInt()
var cordZ: Int = event.clickedBlock.location.z.toInt()
LOGGER.info("Cords: $cordX $cordY $cordZ")
when {
blockFace == "EAST" -> {
cordX -= 1
}
blockFace == "NORTH" -> {
cordZ += 1
}
blockFace == "WEST" -> {
cordX += 1
}
blockFace == "SOUTH" -> {
cordZ -= 1
}
}
val containerBlock = getWorld(event.clickedBlock.world.uid).getBlockAt(cordX, cordY, cordZ)
LOGGER.info("Container block: $cordX $cordY $cordZ")
val container: Chest = containerBlock.state as Chest
val firstItem = container.blockInventory.contents[0]
LOGGER.info("firstItem: ${firstItem.type} | amount: ${firstItem.amount}")
// Get info
val vpcUsername = sign.getLine(1)
val costPerItem: Double? = sign.getLine(2).toDoubleOrNull()
val amount: Int? = sign.getLine(3).toIntOrNull()
if (vpcUsername.isEmpty() || costPerItem == null || amount == null) return
LOGGER.info("vpcUsername: $vpcUsername")
LOGGER.info("costPerItem: $costPerItem")
LOGGER.info("amount: $amount")
// Fixed: Properly check if there are enough items of the required type
val availableAmount = container.inventory.all(firstItem.type).values.sumOf { it.amount }
if (availableAmount < amount) {
LOGGER.info("Not enough items: [type: ${firstItem.type}, requested: $amount, available: $availableAmount]")
Utils.send(event.player,"&cВ контейнере не хватает предметов для покупки.")
return
}
// Generate invoice etc.
Bukkit.getScheduler().runTaskAsynchronously(PLUGIN, Runnable {
val cost = costPerItem*amount
val invoiceId = VpcApi.create_invoice(cost).toString()
LOGGER.info("Invoice id: $invoiceId")
if (invoiceId == "null") {
Utils.send(event.player,"&cПроизошла ошибка при генерации счёта. Обратитесь к администратору или повторите позже.")
return@Runnable
}
// Add data to map
TO_PAY_SIGN_INVOICES[event.player.name] = invoiceId
INVOICE_CREATION_TIMES[invoiceId] = System.currentTimeMillis()
SIGN_PAYMENT_INFO[invoiceId] = SignPaymentInfo(amount, firstItem.type, container, event.player, cost, vpcUsername)
val colored = ChatColor.translateAlternateColorCodes('&',
"${PREFIX}Нажмите здесь, оплатить &6$cost VPC")
val message = TextComponent(colored)
message.clickEvent = ClickEvent(ClickEvent.Action.RUN_COMMAND, "/vpc pay $USERNAME $cost $invoiceId")
message.hoverEvent = HoverEvent(HoverEvent.Action.SHOW_TEXT,
ComponentBuilder("/vpc pay $USERNAME $cost $invoiceId").create())
event.player.spigot().sendMessage(message)
})
}
@EventHandler
fun onSignChange(event: SignChangeEvent) {
// Check if feature enabled
if (!PAY_BY_SIGN) return
if (event.getLine(0).contains("[VPC]")) {
val vpcUsername = event.getLine(1)
val cost: Double? = event.getLine(2).toDoubleOrNull()
val amount: Int? = event.getLine(3).toIntOrNull()
var coloredLine: String
// Check if some data is missing
if (vpcUsername.isEmpty() || cost == null || amount == null) {
coloredLine = ChatColor.translateAlternateColorCodes('&', "$PREFIX&cError")
event.setLine(0, coloredLine)
return
}
coloredLine = ChatColor.translateAlternateColorCodes('&', PREFIX)
event.setLine(0, coloredLine)
}
}
}