From 542d71165de11143b06cd073e178999e67c45db5 Mon Sep 17 00:00:00 2001 From: Rui Pereira Date: Thu, 26 Mar 2026 15:35:31 +0000 Subject: [PATCH] Improve Adventure support and use native components on Paper Allows the usage of more advanced MiniMessage tags such as font and head. --- .../modern/chat/WrappedChatComponent.kt | 7 +++- .../bukkit/scoreboard/VarReplacer.kt | 2 - .../simplescore/bukkit/util/Adventure.kt | 37 +++++++++++++------ 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/bukkit/src/main/kotlin/com/r4g3baby/simplescore/bukkit/protocol/modern/chat/WrappedChatComponent.kt b/bukkit/src/main/kotlin/com/r4g3baby/simplescore/bukkit/protocol/modern/chat/WrappedChatComponent.kt index d61fc2c..006c3cb 100644 --- a/bukkit/src/main/kotlin/com/r4g3baby/simplescore/bukkit/protocol/modern/chat/WrappedChatComponent.kt +++ b/bukkit/src/main/kotlin/com/r4g3baby/simplescore/bukkit/protocol/modern/chat/WrappedChatComponent.kt @@ -1,10 +1,11 @@ package com.r4g3baby.simplescore.bukkit.protocol.modern.chat +import com.r4g3baby.simplescore.bukkit.util.Adventure import com.r4g3baby.simplescore.bukkit.util.NMS import com.r4g3baby.simplescore.bukkit.util.OBC import com.r4g3baby.simplescore.core.util.Reflection -class WrappedChatComponent(val handle: Any) { +class WrappedChatComponent private constructor(val handle: Any) { companion object { val clazz: Class<*> @@ -27,6 +28,10 @@ class WrappedChatComponent(val handle: Any) { } fun fromString(message: String): WrappedChatComponent { + val component = Adventure.parseToComponent(message) + if (component != null) return WrappedChatComponent(component) + + val message = Adventure.parseToString(message) ?: message val components = fromString.invoke(null, message) as Array<*> return WrappedChatComponent(components[0]!!) } diff --git a/bukkit/src/main/kotlin/com/r4g3baby/simplescore/bukkit/scoreboard/VarReplacer.kt b/bukkit/src/main/kotlin/com/r4g3baby/simplescore/bukkit/scoreboard/VarReplacer.kt index 3e36856..ac9fd4f 100644 --- a/bukkit/src/main/kotlin/com/r4g3baby/simplescore/bukkit/scoreboard/VarReplacer.kt +++ b/bukkit/src/main/kotlin/com/r4g3baby/simplescore/bukkit/scoreboard/VarReplacer.kt @@ -2,7 +2,6 @@ package com.r4g3baby.simplescore.bukkit.scoreboard import com.r4g3baby.simplescore.BukkitPlugin import com.r4g3baby.simplescore.api.scoreboard.VarReplacer -import com.r4g3baby.simplescore.bukkit.util.Adventure import com.r4g3baby.simplescore.bukkit.util.getPlayerPing import com.r4g3baby.simplescore.bukkit.util.lazyReplace import com.r4g3baby.simplescore.core.util.translateColorCodes @@ -36,7 +35,6 @@ class VarReplacer(plugin: BukkitPlugin) : VarReplacer { .lazyReplace("%server_online%") { viewer.server.onlinePlayers.size.toString() } .lazyReplace("%server_maxplayers%") { viewer.server.maxPlayers.toString() } - result = Adventure.parseToString(result) return translateColorCodes(result) } diff --git a/bukkit/src/main/kotlin/com/r4g3baby/simplescore/bukkit/util/Adventure.kt b/bukkit/src/main/kotlin/com/r4g3baby/simplescore/bukkit/util/Adventure.kt index 5d89893..c84149b 100644 --- a/bukkit/src/main/kotlin/com/r4g3baby/simplescore/bukkit/util/Adventure.kt +++ b/bukkit/src/main/kotlin/com/r4g3baby/simplescore/bukkit/util/Adventure.kt @@ -1,5 +1,6 @@ package com.r4g3baby.simplescore.bukkit.util +import com.r4g3baby.simplescore.core.util.Reflection import com.r4g3baby.simplescore.core.util.Reflection.classExists import net.kyori.adventure.text.minimessage.MiniMessage import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer @@ -8,31 +9,43 @@ import org.bukkit.ChatColor.COLOR_CHAR object Adventure { private val miniMessage: MiniMessage? private val textSerializer: LegacyComponentSerializer? + private val componentConstructor: Reflection.ConstructorInvoker? init { - val isAdventureSupported = classExists("net.kyori.adventure.text.minimessage.MiniMessage") - && classExists("net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer") - - if (isAdventureSupported) { - miniMessage = MiniMessage.builder().strict(false).build() + val isMiniMessageSupported = classExists("net.kyori.adventure.text.minimessage.MiniMessage") + miniMessage = if (isMiniMessageSupported) MiniMessage.miniMessage() else null + val isLegacyTextSupported = classExists("net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer") + textSerializer = if (isLegacyTextSupported) { val legacySerializerBuilder = LegacyComponentSerializer.builder().character(COLOR_CHAR) val hexColorsSupported = ServerVersion.atOrAbove(ServerVersion.netherUpdate) - textSerializer = if (hexColorsSupported) { + + if (hexColorsSupported) { legacySerializerBuilder.useUnusualXRepeatedCharacterHexFormat().hexColors().build() } else legacySerializerBuilder.build() - } else { - miniMessage = null - textSerializer = null - } + } else null + + componentConstructor = try { + val component = Reflection.getClass("net.kyori.adventure.text.Component") + val adventureComponent = Reflection.getClass("io.papermc.paper.adventure.AdventureComponent") + Reflection.getConstructor(adventureComponent, component) + } catch (_: IllegalArgumentException) { null } } - fun parseToString(text: String): String { + fun parseToString(text: String): String? { return if (textSerializer != null && miniMessage != null) { textSerializer.serialize( miniMessage.deserialize(vanillaToMini(text)) ) - } else text + } else null + } + + fun parseToComponent(text: String): Any? { + return if (componentConstructor != null && miniMessage != null) { + componentConstructor.invoke( + miniMessage.deserialize(vanillaToMini(text)) + ) + } else null } private val namedToMiniTag = mapOf(