From 820bfaaab3756f857c6e8a19d582cd3c111ef57e Mon Sep 17 00:00:00 2001 From: WieszczY Date: Fri, 28 Aug 2026 12:17:12 +0200 Subject: [PATCH 1/5] Use Adventure components directly in GUI item factory --- .../kotlin/pl/syntaxdevteam/plotsx/gui/GUIHandler.kt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/GUIHandler.kt b/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/GUIHandler.kt index 8d2e835..f8b882e 100644 --- a/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/GUIHandler.kt +++ b/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/GUIHandler.kt @@ -1,6 +1,6 @@ package pl.syntaxdevteam.plotsx.gui -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver +import net.kyori.adventure.text.Component import org.bukkit.Material import org.bukkit.entity.Player import org.bukkit.event.EventHandler @@ -10,10 +10,9 @@ import org.bukkit.inventory.ItemStack import pl.syntaxdevteam.plotsx.PlotsX import java.util.* -class GUIHandler(plugin: PlotsX) : Listener { +class GUIHandler(@Suppress("UNUSED_PARAMETER") plugin: PlotsX) : Listener { private val openGuis: MutableMap = mutableMapOf() - private val message = plugin.messageHandler fun registerGui(player: Player, gui: GUI) { openGuis[player.uniqueId] = gui @@ -36,10 +35,10 @@ class GUIHandler(plugin: PlotsX) : Listener { gui.handleClick(event) } - fun createItem(material: Material, name: String): ItemStack { + fun createItem(material: Material, name: Component): ItemStack { val item = ItemStack(material) val meta = item.itemMeta!! - meta.displayName(message.formatMixedTextToMiniMessage(name, TagResolver.empty())) + meta.displayName(name) item.itemMeta = meta return item } From 0bbb9997086f4577d3348333d78d8bbfb91d8fa6 Mon Sep 17 00:00:00 2001 From: WieszczY Date: Fri, 28 Aug 2026 12:17:22 +0200 Subject: [PATCH 2/5] Avoid string round-trip in claim confirmation GUI --- .../plotsx/gui/ClaimConfirmGUI.kt | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/ClaimConfirmGUI.kt b/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/ClaimConfirmGUI.kt index 385e96f..6e316a0 100644 --- a/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/ClaimConfirmGUI.kt +++ b/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/ClaimConfirmGUI.kt @@ -18,13 +18,19 @@ class ClaimConfirmGUI( private val cancelIndex = 15 init { - inventory.setItem(confirmIndex, - plugin.guiHandler.createItem(Material.EMERALD_BLOCK, - message.stringMessageToStringNoPrefix("GUI", "claim.material_name.confirm")) + inventory.setItem( + confirmIndex, + plugin.guiHandler.createItem( + Material.EMERALD_BLOCK, + message.stringMessageToComponentNoPrefix("GUI", "claim.material_name.confirm") + ) ) - inventory.setItem(cancelIndex, - plugin.guiHandler.createItem(Material.REDSTONE_BLOCK, - message.stringMessageToStringNoPrefix("GUI", "claim.material_name.cancel")) + inventory.setItem( + cancelIndex, + plugin.guiHandler.createItem( + Material.REDSTONE_BLOCK, + message.stringMessageToComponentNoPrefix("GUI", "claim.material_name.cancel") + ) ) } From ffeeea4e82f0dd4eebdc29c30ab0e0b1b9c9e26c Mon Sep 17 00:00:00 2001 From: WieszczY Date: Fri, 28 Aug 2026 12:17:30 +0200 Subject: [PATCH 3/5] Avoid string round-trip in unclaim confirmation GUI --- .../plotsx/gui/UnclaimConfirmGUI.kt | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/UnclaimConfirmGUI.kt b/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/UnclaimConfirmGUI.kt index 9ec51ee..ce9e1c2 100644 --- a/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/UnclaimConfirmGUI.kt +++ b/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/UnclaimConfirmGUI.kt @@ -18,13 +18,19 @@ class UnclaimConfirmGUI( private val cancelIndex = 15 init { - inventory.setItem(confirmIndex, - plugin.guiHandler.createItem(Material.EMERALD_BLOCK, - message.stringMessageToStringNoPrefix("GUI", "unclaim.material_name.confirm")) + inventory.setItem( + confirmIndex, + plugin.guiHandler.createItem( + Material.EMERALD_BLOCK, + message.stringMessageToComponentNoPrefix("GUI", "unclaim.material_name.confirm") + ) ) - inventory.setItem(cancelIndex, - plugin.guiHandler.createItem(Material.REDSTONE_BLOCK, - message.stringMessageToStringNoPrefix("GUI", "unclaim.material_name.cancel")) + inventory.setItem( + cancelIndex, + plugin.guiHandler.createItem( + Material.REDSTONE_BLOCK, + message.stringMessageToComponentNoPrefix("GUI", "unclaim.material_name.cancel") + ) ) } @@ -43,4 +49,4 @@ class UnclaimConfirmGUI( } } } -} \ No newline at end of file +} From 7cc9014c97bba7a8e035172fd30e548f39827958 Mon Sep 17 00:00:00 2001 From: WieszczY Date: Fri, 28 Aug 2026 12:17:49 +0200 Subject: [PATCH 4/5] Keep plot GUI labels as Adventure components --- .../pl/syntaxdevteam/plotsx/gui/PlotGUI.kt | 121 ++++++++++-------- 1 file changed, 71 insertions(+), 50 deletions(-) diff --git a/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/PlotGUI.kt b/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/PlotGUI.kt index b8a3fc0..810ff9a 100644 --- a/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/PlotGUI.kt +++ b/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/PlotGUI.kt @@ -1,6 +1,6 @@ package pl.syntaxdevteam.plotsx.gui -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver +import net.kyori.adventure.text.Component import org.bukkit.Material import org.bukkit.entity.Player import org.bukkit.event.inventory.InventoryClickEvent @@ -9,31 +9,29 @@ import org.bukkit.inventory.meta.SkullMeta import pl.syntaxdevteam.plotsx.PlotsX import pl.syntaxdevteam.plotsx.databases.Helpers import pl.syntaxdevteam.plotsx.databases.PlotData -import net.kyori.adventure.text.Component +import pl.syntaxdevteam.plotsx.protection.SafeTeleportUtil import java.text.SimpleDateFormat import java.util.* -import pl.syntaxdevteam.plotsx.protection.SafeTeleportUtil class PlotGUI( private val plugin: PlotsX, - private val plot: PlotData? = null , + private val plot: PlotData? = null, private val ownerUuid: UUID ) : AbstractGUI( title = plugin.messageHandler.stringMessageToComponentNoPrefix("GUI", "plot.title_plot"), - size = 45 + size = 45 ) { private val message = plugin.messageHandler private val helpers = Helpers(plugin) - private val plotIndex = 4 + private val plotIndex = 4 private val flagsIndex = 11 - private val tpaIndex = 15 + private val tpaIndex = 15 private val renameIndex = 29 - private val listIndex = 31 + private val listIndex = 31 private val expandIndex = 33 override fun open(player: Player) { - val targetPlot = plot ?: plugin.databaseHandler.getPlotAtLocation( player.location.world!!.name, player.location.blockX, @@ -45,27 +43,42 @@ class PlotGUI( return } - inventory.setItem(plotIndex, createPlotHead(player, targetPlot)) - inventory.setItem(flagsIndex, createItem( - Material.CALIBRATED_SCULK_SENSOR, - message.stringMessageToStringNoPrefix("GUI", "plot.material_name.flags") - )) - inventory.setItem(tpaIndex, createItem( - Material.MINECART, - message.stringMessageToStringNoPrefix("GUI", "plot.material_name.teleport") - )) - inventory.setItem(renameIndex, createItem( - Material.NAME_TAG, - message.stringMessageToStringNoPrefix("GUI", "plot.material_name.rename") - )) - inventory.setItem(listIndex, createItem( - Material.GRASS_BLOCK, - message.stringMessageToStringNoPrefix("GUI", "plot.material_name.list") - )) - inventory.setItem(expandIndex, createItem( - Material.DIAMOND_PICKAXE, - message.stringMessageToStringNoPrefix("GUI", "plot.material_name.expand") - )) + inventory.setItem(plotIndex, createPlotHead(player, targetPlot)) + inventory.setItem( + flagsIndex, + createItem( + Material.CALIBRATED_SCULK_SENSOR, + message.stringMessageToComponentNoPrefix("GUI", "plot.material_name.flags") + ) + ) + inventory.setItem( + tpaIndex, + createItem( + Material.MINECART, + message.stringMessageToComponentNoPrefix("GUI", "plot.material_name.teleport") + ) + ) + inventory.setItem( + renameIndex, + createItem( + Material.NAME_TAG, + message.stringMessageToComponentNoPrefix("GUI", "plot.material_name.rename") + ) + ) + inventory.setItem( + listIndex, + createItem( + Material.GRASS_BLOCK, + message.stringMessageToComponentNoPrefix("GUI", "plot.material_name.list") + ) + ) + inventory.setItem( + expandIndex, + createItem( + Material.DIAMOND_PICKAXE, + message.stringMessageToComponentNoPrefix("GUI", "plot.material_name.expand") + ) + ) super.open(player) } @@ -92,6 +105,7 @@ class PlotGUI( plugin.guiHandler.registerGui(player, FlagsGUI(plugin, pd)) } } + tpaIndex -> { if (pd == null) { player.sendMessage(message.stringMessageToComponent("error", "no_in_plot")) @@ -106,6 +120,7 @@ class PlotGUI( }) } } + renameIndex -> { if (pd == null) { player.sendMessage(message.stringMessageToComponent("error", "no_in_plot")) @@ -114,6 +129,7 @@ class PlotGUI( plugin.renamePlotChatListener.startRenameProcess(player, pd.id) } } + listIndex -> { val playerPlots = plugin.databaseHandler.getPlayerPlots(ownerUuid) if (playerPlots.isNotEmpty()) { @@ -123,6 +139,7 @@ class PlotGUI( player.closeInventory() } } + expandIndex -> { if (pd == null) { player.sendMessage(message.stringMessageToComponent("error", "no_in_plot")) @@ -131,6 +148,7 @@ class PlotGUI( player.sendMessage("Feature not implemented yet.") } } + plotIndex -> { if (pd == null) { player.sendMessage(message.stringMessageToComponent("error", "no_in_plot")) @@ -138,23 +156,23 @@ class PlotGUI( } plugin.server.scheduler.runTask(plugin, Runnable { helpers.visualizePlotBorder3D( - player = player, - centerX = pd.x, - centerZ = pd.z, - radius = pd.radius, + player = player, + centerX = pd.x, + centerZ = pd.z, + radius = pd.radius, durationSec = 20, - stepXZ = 2, - stepY = 4 + stepXZ = 2, + stepY = 4 ) }) } } } - private fun createItem(material: Material, name: String): ItemStack { + private fun createItem(material: Material, name: Component): ItemStack { val item = ItemStack(material) val meta = item.itemMeta!! - meta.displayName(message.formatMixedTextToMiniMessage(name, TagResolver.empty())) + meta.displayName(name) item.itemMeta = meta return item } @@ -164,24 +182,27 @@ class PlotGUI( val meta = skull.itemMeta as SkullMeta meta.owningPlayer = player - meta.displayName(message.stringMessageToComponentNoPrefix( - "GUI", "plot.material_name.info", - mapOf("plot" to plot.name) - )) + meta.displayName( + message.stringMessageToComponentNoPrefix( + "GUI", "plot.material_name.info", + mapOf("plot" to plot.name) + ) + ) - val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm") + val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm") val creationTime = dateFormat.format(Date(plot.creationTime)) plugin.logger.debug("plot.ownerUuid.toString() to ${plot.ownerUuid}") - // Name resolution may legitimately fail (offline-mode data, unavailable - // profile service, or an owner who has never joined this server). The GUI - // must still open instead of throwing from owner!!. val owner = plugin.uuidManager.getPlayerName(plot.ownerUuid) ?: plot.ownerUuid.toString() val lore = listOf( - message.stringMessageToComponentNoPrefix("GUI", "plot.info.owner", mapOf("owner" to owner)), - message.stringMessageToComponentNoPrefix("GUI", "plot.info.plot_name", mapOf("plot" to plot.name)), - message.stringMessageToComponentNoPrefix("GUI", "plot.info.id", mapOf("id" to plot.id.toString())), - message.stringMessageToComponentNoPrefix("GUI", "plot.info.creation_time",mapOf("time" to creationTime)), + message.stringMessageToComponentNoPrefix("GUI", "plot.info.owner", mapOf("owner" to owner)), + message.stringMessageToComponentNoPrefix("GUI", "plot.info.plot_name", mapOf("plot" to plot.name)), + message.stringMessageToComponentNoPrefix("GUI", "plot.info.id", mapOf("id" to plot.id.toString())), + message.stringMessageToComponentNoPrefix( + "GUI", + "plot.info.creation_time", + mapOf("time" to creationTime) + ), Component.text(" "), message.stringMessageToComponentNoPrefix("GUI", "plot.info.click") ) From 4bf0b6ec560da0103833de8c55bfc61bb71e41b9 Mon Sep 17 00:00:00 2001 From: WieszczY Date: Fri, 28 Aug 2026 12:18:10 +0200 Subject: [PATCH 5/5] Build flags GUI directly from Adventure components --- .../pl/syntaxdevteam/plotsx/gui/FlagsGUI.kt | 90 +++++++++++++------ 1 file changed, 65 insertions(+), 25 deletions(-) diff --git a/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/FlagsGUI.kt b/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/FlagsGUI.kt index a644bbd..8e046c5 100644 --- a/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/FlagsGUI.kt +++ b/src/main/kotlin/pl/syntaxdevteam/plotsx/gui/FlagsGUI.kt @@ -1,7 +1,8 @@ package pl.syntaxdevteam.plotsx.gui import net.kyori.adventure.text.Component -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver +import net.kyori.adventure.text.format.NamedTextColor +import net.kyori.adventure.text.format.TextDecoration import org.bukkit.Material import org.bukkit.NamespacedKey import org.bukkit.entity.Player @@ -19,7 +20,7 @@ class FlagsGUI( private val plot: PlotData ) : AbstractGUI( title = plugin.messageHandler.stringMessageToComponentNoPrefix("GUI", "flags.title"), - size = 54 + size = 54 ) { private val message = plugin.messageHandler @@ -36,32 +37,68 @@ class FlagsGUI( val flagData = flags.firstOrNull { it.name == flagMeta.name } val current = flagData?.value?.toBooleanStrictOrNull() ?: flagMeta.defaultValue - val name = message.stringMessageToStringNoPrefix("flags", flagMeta.displayKey) - val desc = message.stringMessageToStringNoPrefix("flags", flagMeta.descriptionKey) - val descTl = message.stringMessageToStringNoPrefix("flags", "desc_title") - val valTl = message.stringMessageToStringNoPrefix("flags", "value_title") - val valStr = if (current) - "✔ ${message.stringMessageToStringNoPrefix("flags", "value_true")}" - else - "✘ ${message.stringMessageToStringNoPrefix("flags", "value_false")}" + val name = message.stringMessageToComponentNoPrefix("flags", flagMeta.displayKey) + val desc = message.stringMessageToComponentNoPrefix("flags", flagMeta.descriptionKey) + val descTitle = message.stringMessageToComponentNoPrefix("flags", "desc_title") + val valueTitle = message.stringMessageToComponentNoPrefix("flags", "value_title") + val valueText = message.stringMessageToComponentNoPrefix( + "flags", + if (current) "value_true" else "value_false" + ) + val valueComponent = Component.text() + .color(if (current) NamedTextColor.GREEN else NamedTextColor.RED) + .append( + Component.text(if (current) "✔" else "✘") + .decorate(TextDecoration.BOLD) + ) + .append(Component.space()) + .append(valueText) + .build() - // Item val item = ItemStack(flagMeta.material) val meta = item.itemMeta!! meta.persistentDataContainer.set(keyFlag, PersistentDataType.STRING, flagMeta.name) meta.displayName( - message.formatMixedTextToMiniMessage("=> $name <=", TagResolver.empty()) + Component.text() + .color(NamedTextColor.GOLD) + .append(Component.text("=> ")) + .append(name.decorate(TextDecoration.BOLD)) + .append(Component.text(" <=")) + .build() + ) + meta.lore( + listOf( + Component.text() + .color(NamedTextColor.AQUA) + .append(Component.text(" ")) + .append(valueTitle) + .append(Component.text(": ")) + .append(valueComponent) + .build(), + Component.empty(), + Component.text() + .color(NamedTextColor.AQUA) + .append(descTitle) + .append( + Component.text() + .color(NamedTextColor.GRAY) + .append(desc) + .build() + ) + .build() + ) ) - meta.lore(listOf( - message.formatMixedTextToMiniMessage(" $valTl: $valStr", TagResolver.empty()), - Component.empty(), - message.formatMixedTextToMiniMessage("$descTl$desc", TagResolver.empty()) - )) item.itemMeta = meta inventory.setItem(idx, item) } - inventory.setItem(49, plugin.guiHandler.createItem(Material.BARRIER, message.stringMessageToStringNoPrefix("GUI", "flags.back"))) + inventory.setItem( + 49, + plugin.guiHandler.createItem( + Material.BARRIER, + message.stringMessageToComponentNoPrefix("GUI", "flags.back") + ) + ) super.open(player) } @@ -72,7 +109,7 @@ class FlagsGUI( event.isCancelled = true val player = event.whoClicked as? Player ?: return val clicked = event.currentItem ?: return - val meta = clicked.itemMeta ?: return + val meta = clicked.itemMeta ?: return plugin.guiHandler.unregisterGui(player) player.closeInventory() @@ -80,7 +117,6 @@ class FlagsGUI( val flagKey = meta.persistentDataContainer .get(keyFlag, PersistentDataType.STRING) - // Obsługa przycisku "back" (slot 49) if (event.slot == 49) { plugin.guiHandler.registerGui(player, PlotGUI(plugin, plot, plot.ownerUuid)) return @@ -96,10 +132,14 @@ class FlagsGUI( val updated = !current if (plugin.databaseHandler.updatePlotFlag(plot.id, flagKey, updated)) { - player.sendMessage(message.stringMessageToComponent("flags", "toggle", mapOf( - "flag" to flagKey, - "value" to updated.toString() - ))) + player.sendMessage( + message.stringMessageToComponent( + "flags", "toggle", mapOf( + "flag" to flagKey, + "value" to updated.toString() + ) + ) + ) plugin.cacheManager.updateFlagCacheAsync(plot.id) { plugin.server.scheduler.runTask(plugin, Runnable { @@ -113,7 +153,7 @@ class FlagsGUI( timestamp = System.currentTimeMillis() ) ) - if(plugin.config.getBoolean("debug", false)){ + if (plugin.config.getBoolean("debug", false)) { val cacheFlags = plugin.cacheManager.getFlags(plot.id) ?: emptyList() val dbFlags = plugin.databaseHandler.getPlotFlags(plot.id) val table = formatFlagComparison(cacheFlags, dbFlags)