rework multiline

This commit is contained in:
alexcrea 2026-08-15 16:15:49 +02:00
parent 703bf40449
commit ded892f2ec
Signed by: alexcrea
GPG key ID: E59DF23EE2A2266C
18 changed files with 147 additions and 144 deletions

View file

@ -22,6 +22,8 @@ import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog
import xyz.alexcrea.cuanvil.enchant.CAEnchantment
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe
import xyz.alexcrea.cuanvil.util.CasedStringUtil
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializeLegacy
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain
import xyz.alexcrea.cuanvil.util.CustomRecipeUtil
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
import xyz.alexcrea.cuanvil.util.MiniMessageUtil
@ -151,7 +153,7 @@ object AnvilMergeLogic {
)
if (component != null) {
renameText = MiniMessageUtil.legacy_mm.serialize(component)
renameText = component.serializeLegacy()
sumCost += ConfigOptions.useOfColorCost
useColor = true

View file

@ -3,7 +3,7 @@ package xyz.alexcrea.cuanvil.command
import org.bukkit.command.Command
import org.bukkit.command.CommandSender
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry
import xyz.alexcrea.cuanvil.lang.MessageLike
import xyz.alexcrea.cuanvil.lang.Message
interface CASubCommand {
@ -22,7 +22,7 @@ interface CASubCommand {
list: MutableList<String>
)
fun description(): MessageLike
fun description(): Message
fun allEnchantmentsByName(): Collection<String> {
val names = mutableSetOf<String>()

View file

@ -9,13 +9,13 @@ import net.md_5.bungee.api.chat.hover.content.Text
import org.bukkit.command.Command
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.lang.MessageLike
import xyz.alexcrea.cuanvil.lang.Message
import xyz.alexcrea.cuanvil.lang.MsgCommand
import xyz.alexcrea.cuanvil.util.MiniMessageUtil
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain
class DebugToggleExecutor : CASubCommand {
override fun description(): MessageLike {
override fun description(): Message {
return MsgCommand.DEBUG_DESCRIPTION
}
@ -88,7 +88,7 @@ class DebugToggleExecutor : CASubCommand {
val stb = StringBuilder(MsgCommand.DEBUG_DATA_HEADER.unformatted()).append(' ')
stb.append(MsgCommand.DEBUG_DATA_LINE_COUNT.unformatted(CustomAnvil.debugStorageQueue.size))
for(log in CustomAnvil.debugStorageQueue) {
stb.append('\n').append(MiniMessageUtil.plain_text_mm.serialize(log))
stb.append('\n').append(log.serializePlain())
}
if(sender is Player) {

View file

@ -24,7 +24,7 @@ import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.packet.NoPacketManager
import xyz.alexcrea.cuanvil.dependency.packet.ProtocoLibWrapper
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry
import xyz.alexcrea.cuanvil.lang.MessageLike
import xyz.alexcrea.cuanvil.lang.Message
import xyz.alexcrea.cuanvil.lang.MsgCommand
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
import xyz.alexcrea.cuanvil.util.MetricsUtil
@ -214,7 +214,7 @@ class DiagnosticExecutor : CASubCommand {
return this.name + " v" + this.description.version
}
override fun description(): MessageLike {
override fun description(): Message {
return MsgCommand.DIAGNOSTIC_DESCRIPTION
}

View file

@ -11,7 +11,7 @@ import xyz.alexcrea.cuanvil.gui.config.MainConfigGui
import xyz.alexcrea.cuanvil.gui.config.global.EnchantConfigGui
import xyz.alexcrea.cuanvil.gui.config.global.ItemConfigGui
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions
import xyz.alexcrea.cuanvil.lang.MessageLike
import xyz.alexcrea.cuanvil.lang.Message
import xyz.alexcrea.cuanvil.lang.MsgCommand
import xyz.alexcrea.cuanvil.util.MaterialUtil.customType
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
@ -22,7 +22,7 @@ class EditConfigExecutor : CASubCommand {
return sender.hasPermission(CustomAnvil.editConfigPermission)
}
override fun description(): MessageLike {
override fun description(): Message {
return MsgCommand.CONFIG_DESCRIPTION
}

View file

@ -10,7 +10,7 @@ import org.bukkit.command.CommandSender
import org.bukkit.entity.HumanEntity
import xyz.alexcrea.cuanvil.api.EnchantmentApi
import xyz.alexcrea.cuanvil.enchant.CAEnchantment
import xyz.alexcrea.cuanvil.lang.MessageLike
import xyz.alexcrea.cuanvil.lang.Message
import xyz.alexcrea.cuanvil.lang.MsgCommand
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
@ -21,7 +21,7 @@ class EnchantExecutor : CASubCommand {
return sender.hasPermission(CustomAnvil.giveEnchantmentPermission)
}
override fun description(): MessageLike {
override fun description(): Message {
return MsgCommand.ENCHANT_DESCRIPTION
}

View file

@ -2,16 +2,15 @@ package xyz.alexcrea.cuanvil.command
import com.google.common.collect.ImmutableMap
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.TextComponent
import org.bukkit.command.Command
import org.bukkit.command.CommandSender
import xyz.alexcrea.cuanvil.lang.MessageLike
import xyz.alexcrea.cuanvil.lang.Message
import xyz.alexcrea.cuanvil.lang.MsgCommand
import xyz.alexcrea.cuanvil.util.ComponentUtil.send
class HelpExecutor : CASubCommand {
override fun description(): MessageLike {
override fun description(): Message {
return MsgCommand.HELP_DESCRIPTION
}
@ -23,7 +22,7 @@ class HelpExecutor : CASubCommand {
cmdstr: String,
args: Array<out String>,
): Boolean {
var text = MsgCommand.HELP_HEADER.formatted()
var text = MsgCommand.HELP_HEADER.formatted().first()
for((key, cmd) in commands) {
if(!cmd.allowed(sender)) continue

View file

@ -9,13 +9,13 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.gui.config.global.*
import xyz.alexcrea.cuanvil.lang.Lang
import xyz.alexcrea.cuanvil.lang.MessageLike
import xyz.alexcrea.cuanvil.lang.Message
import xyz.alexcrea.cuanvil.lang.MsgCommand
import xyz.alexcrea.cuanvil.update.UpdateHandler
class ReloadExecutor : CASubCommand {
override fun description(): MessageLike {
override fun description(): Message {
return MsgCommand.RELOAD_DESCRIPTION
}

View file

@ -1,6 +1,7 @@
package xyz.alexcrea.cuanvil.lang
import io.delilaheve.CustomAnvil
import org.bukkit.configuration.ConfigurationSection
import xyz.alexcrea.cuanvil.config.ConfigHolder
object Lang {
@ -27,6 +28,13 @@ object Lang {
return default.get(key) ?: key
}
fun getSection(key: String): ConfigurationSection? {
val value = lang.getSection(key)
if(value != null) return value
return default.getSection(key)
}
/*
* Config Options & get
*/

View file

@ -1,6 +1,7 @@
package xyz.alexcrea.cuanvil.lang
import io.delilaheve.CustomAnvil
import org.bukkit.configuration.ConfigurationSection
import org.bukkit.configuration.file.FileConfiguration
import org.bukkit.configuration.file.YamlConfiguration
import java.io.File
@ -50,6 +51,10 @@ class Language(private val id: String, private val default: Boolean = false) {
return conf.getString(key)
}
fun getSection(key: String): ConfigurationSection? {
return conf.getConfigurationSection(key)
}
val name: String
get() = conf.getString("name", id)!!
}

View file

@ -3,32 +3,15 @@ package xyz.alexcrea.cuanvil.lang
import io.delilaheve.CustomAnvil
import net.kyori.adventure.text.Component
import org.bukkit.command.CommandSender
import org.bukkit.configuration.ConfigurationSection
import xyz.alexcrea.cuanvil.util.ComponentUtil.send
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializeLegacy
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain
import xyz.alexcrea.cuanvil.util.MiniMessageUtil
import java.util.logging.Level
import kotlin.math.min
interface MessageLike {
fun log(vararg params: Any)
fun send(destination: CommandSender, vararg params: Any)
fun unformatted(vararg params: Any): String
fun formatted(vararg params: Any): Component
fun legacy(vararg params: Any): String {
val formated = formatted(*params)
return MiniMessageUtil.legacy_mm.serialize(formated)
}
}
enum class MessageType {
DEFAULT, WARNING, ERROR, COMMAND, UI,
}
open class Message(val key: String, vararg val params: String) : MessageLike {
open class Message(val key: String, vararg val params: String) {
protected fun replaceParameters(stb: StringBuilder, vararg values: Any) {
// replace all placeholder thingy %key -> value
@ -52,7 +35,7 @@ open class Message(val key: String, vararg val params: String) : MessageLike {
}
}
override fun unformatted(vararg params: Any): String {
private fun unformattedMonoline(vararg params: Any): String {
val translated = Lang.getTranslated(key)
if(params.isEmpty() && this.params.isEmpty()) return translated
@ -61,19 +44,71 @@ open class Message(val key: String, vararg val params: String) : MessageLike {
return stb.toString()
}
override fun formatted(vararg params: Any): Component {
val unformatted = unformatted(*params)
private fun unformattedMultiline(section: ConfigurationSection, vararg params: Any): String {
val stb = StringBuilder()
return MiniMessageUtil.mm.deserialize(unformatted)
for(key in section.getKeys(false)) {
if(!section.isString(key)) continue
if(!stb.isEmpty()) stb.append('\n')
stb.append(section.getString(key))
}
replaceParameters(stb, *params)
return stb.toString()
}
override fun log(vararg params: Any) {
val text = unformatted(*params)
fun unformatted(vararg params: Any): String {
val section = Lang.getSection(key)
if(section != null) return unformattedMultiline(section, *params)
CustomAnvil.instance.logger.info(text)
return unformattedMonoline(*params)
}
override fun send(destination: CommandSender, vararg params: Any) {
private fun formattedMultiline(section: ConfigurationSection, vararg params: Any): List<Component> {
val result = ArrayList<Component>()
for(key in section.getKeys(false)) {
if(!section.isString(key)) continue
val stb = StringBuilder(section.getString(key))
replaceParameters(stb, *params)
result.add(MiniMessageUtil.mm.deserialize(stb.toString()))
}
return result
}
fun formatted(vararg params: Any): List<Component> {
val section = Lang.getSection(key)
if(section != null) return formattedMultiline(section, *params)
val translated = unformattedMonoline(key, *params)
return listOf(MiniMessageUtil.mm.deserialize(translated))
}
fun legacy(vararg params: Any): String {
val formated = formatted(*params)
val stb = StringBuilder()
for(component in formated) {
if(!stb.isEmpty()) stb.append('\n')
stb.append(component.serializeLegacy())
}
return stb.toString()
}
open fun log(vararg params: Any) {
val texts = formatted(*params)
for(component in texts) {
CustomAnvil.instance.logger.info(component.serializePlain())
}
}
open fun send(destination: CommandSender, vararg params: Any) {
formatted(*params).send(destination)
}
}
@ -81,83 +116,32 @@ open class Message(val key: String, vararg val params: String) : MessageLike {
class WarningMessage(key: String, vararg params: String) : Message("warning.$key", *params) {
override fun log(vararg params: Any) {
val text = unformatted(*params)
val texts = formatted(*params)
CustomAnvil.instance.logger.warning(text)
for(component in texts) {
CustomAnvil.instance.logger.warning(component.serializePlain())
}
}
}
class ErrorMessage(key: String, vararg params: String) : Message("error.$key", *params) {
override fun log(vararg params: Any) {
val text = unformatted(*params)
val texts = formatted(*params)
CustomAnvil.logError(text)
for(component in texts) {
CustomAnvil.logError(component.serializePlain())
}
}
fun log(e: Throwable, vararg params: Any, level: Level = Level.SEVERE, track: Boolean = true) {
val text = unformatted(*params)
val texts = formatted(*params)
CustomAnvil.logError(text, e, track, level)
for(component in texts) {
CustomAnvil.logError(component.serializePlain(), e, track, level)
}
}
}
class CommandMessage(key: String, vararg params: String) : Message("command.$key", *params)
class UIMessage(key: String, vararg params: String) : Message("ui.$key", *params)
class MultiLineMessage(type: MessageType, baseKey: String, count: Int, vararg params: String) : MessageLike {
private val messages = ArrayList<MessageLike>()
init {
for(i in 1 until count + 1) {
val message = createNew(type, "$baseKey.$i", *params)
messages.add(message)
}
}
private fun createNew(type: MessageType, key: String, vararg params: String): MessageLike {
return when(type) {
MessageType.DEFAULT -> Message(key, *params)
MessageType.WARNING -> WarningMessage(key, *params)
MessageType.ERROR -> ErrorMessage(key, *params)
MessageType.COMMAND -> CommandMessage(key, *params)
MessageType.UI -> UIMessage(key, *params)
}
}
override fun log(vararg params: Any) {
for(message in messages) {
message.log(*params)
}
}
override fun send(destination: CommandSender, vararg params: Any) {
for(message in messages) {
message.send(destination, *params)
}
}
override fun unformatted(vararg params: Any): String {
val stb = StringBuilder()
stb.append(messages[0].unformatted(*params))
for(i in 1 until messages.size) {
stb.append('\n').append(messages[i].unformatted(*params))
}
return stb.toString()
}
override fun formatted(vararg params: Any): Component {
val component = messages[0].formatted(*params)
for(i in 1 until messages.size) {
component.appendNewline().append(messages[i].formatted(*params))
}
return component
}
}

View file

@ -4,12 +4,6 @@ import xyz.alexcrea.cuanvil.lang.CommandMessage as Message
object MsgCommand {
fun multiLine(basekey: String, count: Int): MultiLineMessage {
return MultiLineMessage(
MessageType.COMMAND, basekey, count
)
}
// Root
val ROOT_UNKNOWN_SUBCOMMAND = Message("root.warning.unknown-sub", "command")
val ROOT_ERROR_SUBCOMMAND = Message("root.error.generic")
@ -42,7 +36,7 @@ object MsgCommand {
// Config
val CONFIG_DESCRIPTION = Message("config.description")
val CONFIG_LEGACY_NAME_WARNING = Message("config.warning.legacy-name")
val CONFIG_FOLIA_ISSUE = multiLine("config.folia-issue", 5)
val CONFIG_FOLIA_ISSUE = Message("config.folia-issue")
val CONFIG_ENCHANTMENT_NO_IN_HAND = Message("config.enchantment.no_hand")
val CONFIG_ENCHANTMENT_NO_NAME = Message("config.enchantment.no_name", "name")

View file

@ -4,14 +4,6 @@ import xyz.alexcrea.cuanvil.lang.WarningMessage as Message
object MsgWarning {
fun multiLine(basekey: String, count: Int): MultiLineMessage {
return MultiLineMessage(
MessageType.WARNING,
basekey,
count
)
}
/*
* -----------------
* Load and reload
@ -19,8 +11,8 @@ object MsgWarning {
*/
val LOAD_UPDATE_AVAILABLE = Message("load.update.available", "version")
val LOAD_LEGACY_OLD_NAME = multiLine("load.legacy.old-name", 2)
val LOAD_LEGACY_SPIGOT = multiLine("load.legacy.spigot", 2)
val LOAD_LEGACY_SPIGOT_OLD = multiLine("load.legacy.spigot", 2)
val LOAD_LEGACY_OLD_NAME = Message("load.legacy.old-name")
val LOAD_LEGACY_SPIGOT = Message("load.legacy.spigot")
val LOAD_LEGACY_SPIGOT_OLD = Message("load.legacy.spigot-old")
}

View file

@ -30,6 +30,7 @@ import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentDisplayName
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_LEFT
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_RIGHT
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain
import xyz.alexcrea.cuanvil.util.CustomRecipeUtil
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
import xyz.alexcrea.cuanvil.util.MiniMessageUtil
@ -536,7 +537,7 @@ class AnvilResultListener : Listener {
if (bookPage.isNotEmpty()) bookPage.append('\n')
if (it == null) return@forEach
bookPage.append(MiniMessageUtil.plain_text_mm.serialize(it))
bookPage.append(it.serializePlain())
}
val resultPage = bookPage.toString()

View file

@ -8,7 +8,26 @@ object ComponentUtil {
fun Component.send(destination: CommandSender) {
if(!destination.sendPaperMessage(this))
destination.sendMessage(MiniMessageUtil.legacy_mm.serialize(this))
destination.sendMessage(this.serializeLegacy())
}
fun List<Component>.send(destination: CommandSender) {
for(component in this)
component.send(destination)
}
fun Component.serializeMM(): String {
return MiniMessageUtil.mm.serialize(this)
}
fun Component.serializeMMColor(): String {
return MiniMessageUtil.color_only_mm.serialize(this)
}
fun Component.serializeLegacy(): String {
return MiniMessageUtil.legacy_mm.serialize(this)
}
fun Component.serializePlain(): String {
return MiniMessageUtil.plain_text_mm.serialize(this)
}
}

View file

@ -25,9 +25,4 @@ object MiniMessageUtil {
val legacy_mm = LegacyComponentSerializer.legacySection()
val plain_text_mm = PlainTextComponentSerializer.plainText()
// Keeping track of this as most use of this can be replaced later on v2 with pure component alternative
fun fromLegacy(legacyText: String): TextComponent {
return legacy_mm.deserialize(legacyText)
}
}

View file

@ -3,6 +3,9 @@ package xyz.alexcrea.cuanvil.util.anvil
import io.delilaheve.util.ConfigOptions
import net.kyori.adventure.text.Component
import org.bukkit.permissions.Permissible
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializeLegacy
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializeMM
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain
import xyz.alexcrea.cuanvil.util.MiniMessageUtil
import java.util.regex.Matcher
import java.util.regex.Pattern
@ -103,10 +106,10 @@ object AnvilColorUtil {
var result: Component = MiniMessageUtil.legacy_mm.deserialize(previousStr)
if (permission.canUseMinimessage) {
// we dance with formats here
val toMinimessage = MiniMessageUtil.mm.serialize(result)
val toMinimessage = result.serializeMM()
val hackySolution = toMinimessage.replace("\\<", "<")
val fromMinimessage = MiniMessageUtil.mm.deserialize(hackySolution)
val asPlain = MiniMessageUtil.plain_text_mm.serialize(fromMinimessage)
val asPlain = fromMinimessage.serializePlain()
if (previousStr != asPlain) {
useColor = true
@ -145,8 +148,8 @@ object AnvilColorUtil {
): String? {
if (!permission.allowed() || component == null) return null
val transformed = MiniMessageUtil.mm.serialize(component)
val plainTransform = MiniMessageUtil.plain_text_mm.serialize(component)
val transformed = component.serializeMM()
val plainTransform = component.serializePlain()
if (transformed == plainTransform) return null
if (permission.onlyMinimessage()) {
return transformed
@ -154,7 +157,7 @@ object AnvilColorUtil {
// smol dance so we transform the component that may contain other tag into only decoration & color for legacy
val coloredMessage = MiniMessageUtil.color_only_mm.deserialize(transformed)
val legacyMessage = StringBuilder(MiniMessageUtil.legacy_mm.serialize(coloredMessage))
val legacyMessage = StringBuilder(coloredMessage.serializeLegacy())
// Reverse hex pattern
if (permission.canUseHexColor) {

View file

@ -10,6 +10,7 @@ import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.LoreEditResult
import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.componentLore
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentLore
import xyz.alexcrea.cuanvil.util.ComponentUtil.serializePlain
import xyz.alexcrea.cuanvil.util.MiniMessageUtil
import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil
import xyz.alexcrea.cuanvil.util.config.LoreEditType
@ -320,7 +321,7 @@ object AnvilLoreEditUtil {
hasUndidColor = true
result = clearedLine
} else {
result = MiniMessageUtil.plain_text_mm.serialize(line)
result = line.serializePlain()
}
lines[index] = MiniMessageUtil.plain_text_mm.deserialize(result)
@ -354,7 +355,7 @@ object AnvilLoreEditUtil {
result = clearedLine
} else {
// Remove extra tags
result = MiniMessageUtil.plain_text_mm.serialize(coloredComponent)
result = coloredComponent.serializePlain()
}
line.set(MiniMessageUtil.plain_text_mm.deserialize(result))