From de5b5eae6e627bb19144d2aea9a947a002ae4258 Mon Sep 17 00:00:00 2001 From: LukynkaCZE Date: Thu, 9 Jan 2025 06:08:32 +0100 Subject: [PATCH 1/2] rewrite like everything --- .../github/dockyardmc/scroll/ClickAction.kt | 16 ++ .../io/github/dockyardmc/scroll/ClickEvent.kt | 9 + .../io/github/dockyardmc/scroll/Component.kt | 78 +++++ .../dockyardmc/scroll/ComponentColorTags.kt | 50 ---- .../scroll/ComponentSerialClasses.kt | 136 --------- .../io/github/dockyardmc/scroll/Components.kt | 11 - .../github/dockyardmc/scroll/HoverAction.kt | 12 + .../io/github/dockyardmc/scroll/HoverEvent.kt | 9 + .../dockyardmc/scroll/LegacyTextColor.kt | 22 ++ .../io/github/dockyardmc/scroll/Main.kt | 4 - .../io/github/dockyardmc/scroll/Scroll.kt | 41 +++ .../github/dockyardmc/scroll/ScrollParser.kt | 74 +++++ .../io/github/dockyardmc/scroll/ScrollUtil.kt | 102 +++++++ .../io/github/dockyardmc/scroll/Util.kt | 31 -- .../scroll/extensions/ExtendedString.kt | 53 +--- .../providers/ClosingNamedFormatProvider.kt | 20 ++ .../scroll/providers/FormatProvider.kt | 8 + .../scroll/providers/FormatProviderContext.kt | 12 + .../scroll/providers/NamedFormatProvider.kt | 10 + .../scroll/providers/default/BoldProvider.kt | 17 ++ .../providers/default/ClickEventProvider.kt | 18 ++ .../scroll/providers/default/FontProvider.kt | 19 ++ .../providers/default/HexColorProvider.kt | 18 ++ .../providers/default/HoverEventProvider.kt | 19 ++ .../providers/default/ItalicsProvider.kt | 17 ++ .../providers/default/KeybindProvider.kt | 13 + .../providers/default/NamedColorProvider.kt | 23 ++ .../providers/default/ObfuscatedProvider.kt | 17 ++ .../scroll/providers/default/ResetProvider.kt | 12 + .../default/StrikethroughProvider.kt | 17 ++ .../providers/default/TranslateProvider.kt | 13 + .../providers/default/UnderlinedProvider.kt | 17 ++ .../serializers/ComponentToJsonSerializer.kt | 1 - .../StringToComponentSerializer.kt | 271 ------------------ src/test/kotlin/NbtSerializationTests.kt | 17 +- src/test/kotlin/StringSerializationTests.kt | 200 +++++++------ 36 files changed, 765 insertions(+), 642 deletions(-) create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/ClickAction.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/ClickEvent.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/Component.kt delete mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/ComponentColorTags.kt delete mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/ComponentSerialClasses.kt delete mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/Components.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/HoverAction.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/HoverEvent.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/LegacyTextColor.kt delete mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/Main.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/Scroll.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/ScrollParser.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/ScrollUtil.kt delete mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/Util.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/ClosingNamedFormatProvider.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/FormatProvider.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/FormatProviderContext.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/NamedFormatProvider.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/default/BoldProvider.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/default/ClickEventProvider.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/default/FontProvider.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/default/HexColorProvider.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/default/HoverEventProvider.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/default/ItalicsProvider.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/default/KeybindProvider.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/default/NamedColorProvider.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/default/ObfuscatedProvider.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/default/ResetProvider.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/default/StrikethroughProvider.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/default/TranslateProvider.kt create mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/providers/default/UnderlinedProvider.kt delete mode 100644 src/main/kotlin/io/github/dockyardmc/scroll/serializers/StringToComponentSerializer.kt diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/ClickAction.kt b/src/main/kotlin/io/github/dockyardmc/scroll/ClickAction.kt new file mode 100644 index 0000000..e0a7a4a --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/ClickAction.kt @@ -0,0 +1,16 @@ +package io.github.dockyardmc.scroll + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +enum class ClickAction { + @SerialName("open_url") + OPEN_URL, + @SerialName("run_command") + RUN_COMMAND, + @SerialName("suggest_command") + SUGGEST_COMMAND, + @SerialName("copy_to_clipboard") + COPY_TO_CLIPBOARD +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/ClickEvent.kt b/src/main/kotlin/io/github/dockyardmc/scroll/ClickEvent.kt new file mode 100644 index 0000000..6468318 --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/ClickEvent.kt @@ -0,0 +1,9 @@ +package io.github.dockyardmc.scroll + +import kotlinx.serialization.Serializable + +@Serializable +class ClickEvent( + val action: ClickAction, + val value: String? = null +) \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/Component.kt b/src/main/kotlin/io/github/dockyardmc/scroll/Component.kt new file mode 100644 index 0000000..68b19ba --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/Component.kt @@ -0,0 +1,78 @@ +package io.github.dockyardmc.scroll + +import io.github.dockyardmc.scroll.serializers.ComponentToJsonSerializer +import io.github.dockyardmc.scroll.serializers.ComponentToNbtSerializer +import kotlinx.serialization.Serializable +import org.jglrxavpok.hephaistos.nbt.NBTCompound + +@Serializable +open class Component( + open var extra: MutableList? = null, + open var keybind: String? = null, + open var text: String? = null, + open var translate: String? = null, + open var color: String? = null, + open var bold: Boolean? = null, + open var italic: Boolean? = null, + open var underlined: Boolean? = null, + open var strikethrough: Boolean? = null, + open var obfuscated: Boolean? = null, + open var font: String? = null, + open var insertion: String? = null, + open var hoverEvent: HoverEvent? = null, + open var clickEvent: ClickEvent? = null +) { + companion object { + fun compound(components: MutableList): Component { + return Component( + text = "", + extra = components + ) + } + } + + fun toNBT(): NBTCompound { + return ComponentToNbtSerializer.serializeComponent(this) + } + + fun toJson(): String { + return ComponentToJsonSerializer.serialize(this) + } + + fun stripStyling(): String { + return buildString { + getAllComponents().forEach { + append(it.text) + } + } + } + + fun getAllComponents(): MutableList { + val recursiveComponentList = mutableListOf() + getComponentRecursive(this, recursiveComponentList) + return recursiveComponentList + } + + private fun getComponentRecursive(component: Component, componentList: MutableList) { + component.extra?.forEach { + componentList.add(it) + getComponentRecursive(it, componentList) + } + } + + fun resetFormatting() { + this.clickEvent = null + this.font = null + this.color = null + this.strikethrough = null + this.underlined = null + this.font = null + this.italic = null + this.bold = null + this.hoverEvent = null + this.obfuscated = null + this.insertion = null + this.keybind = null + this.translate = null + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/ComponentColorTags.kt b/src/main/kotlin/io/github/dockyardmc/scroll/ComponentColorTags.kt deleted file mode 100644 index dbed08a..0000000 --- a/src/main/kotlin/io/github/dockyardmc/scroll/ComponentColorTags.kt +++ /dev/null @@ -1,50 +0,0 @@ -package io.github.dockyardmc.scroll - -//Ordered in precise way cause text colors used to be enum in the minecraft client. It still uses that in some packets -//https://wiki.vg/Text_formatting#Colors -enum class LegacyTextColor(val hex: String) { - BLACK("#000000"), - DARK_BLUE("#0000AA"), - GREEN("#00AA00"), - CYAN("#00AAAA"), - DARK_RED("#AA0000"), - PURPLE("#AA00AA"), - ORANGE("#FFAA00"), - GRAY("#AAAAAA"), - DARK_GRAY("#555555"), - BLUE("#5555FF"), - LIME("#55FF55"), - AQUA("#55FFFF"), - RED("#FF5555"), - PINK("#FF55FF"), - YELLOW("#FFFF55"), - WHITE("#FFFFFF"), -} - -object ComponentColorTags { - - val colorTags = mutableMapOf( - "" to LegacyTextColor.RED.hex, - "" to LegacyTextColor.YELLOW.hex, - "" to LegacyTextColor.LIME.hex, - "" to LegacyTextColor.AQUA.hex, - "" to LegacyTextColor.BLUE.hex, - "" to LegacyTextColor.PINK.hex, - - "" to LegacyTextColor.DARK_RED.hex, - "" to LegacyTextColor.DARK_RED.hex, - "" to LegacyTextColor.ORANGE.hex, - "" to LegacyTextColor.ORANGE.hex, - "" to LegacyTextColor.GREEN.hex, - "" to LegacyTextColor.CYAN.hex, - "" to LegacyTextColor.DARK_BLUE.hex, - "" to LegacyTextColor.DARK_BLUE.hex, - "" to LegacyTextColor.DARK_BLUE.hex, - - "" to LegacyTextColor.WHITE.hex, - "" to LegacyTextColor.GRAY.hex, - "" to LegacyTextColor.DARK_GRAY.hex, - "" to LegacyTextColor.DARK_GRAY.hex, - "" to LegacyTextColor.BLACK.hex, - ) -} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/ComponentSerialClasses.kt b/src/main/kotlin/io/github/dockyardmc/scroll/ComponentSerialClasses.kt deleted file mode 100644 index 7306d0b..0000000 --- a/src/main/kotlin/io/github/dockyardmc/scroll/ComponentSerialClasses.kt +++ /dev/null @@ -1,136 +0,0 @@ -package io.github.dockyardmc.scroll - -import io.github.dockyardmc.scroll.serializers.ComponentToJsonSerializer -import io.github.dockyardmc.scroll.serializers.ComponentToNbtSerializer -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import org.jglrxavpok.hephaistos.nbt.NBTCompound - -@Serializable -open class Component( - open var extra: MutableList? = null, - open var keybind: String? = null, - open var text: String? = null, - open var translate: String? = null, - open var color: String? = null, - open var bold: Boolean? = null, - open var italic: Boolean? = null, - open var underlined: Boolean? = null, - open var strikethrough: Boolean? = null, - open var obfuscated: Boolean? = null, - open var font: String? = null, - open var insertion: String? = null, - open var hoverEvent: HoverEvent? = null, - open var clickEvent: ClickEvent? = null -) { - fun toNBT(): NBTCompound { - return ComponentToNbtSerializer.serializeComponent(this) - } - - fun toJson(): String { - return ComponentToJsonSerializer.serialize(this) - } - - fun stripStyling(): String { - return buildString { - getAllComponents().forEach { - append(it.text) - } - } - } - - fun getAllComponents(): MutableList { - val recursiveComponentList = mutableListOf() - getComponentRecursive(this, recursiveComponentList) - return recursiveComponentList - } - - private fun getComponentRecursive(component: Component, componentList: MutableList) { - component.extra?.forEach { - componentList.add(it) - getComponentRecursive(it, componentList) - } - } -} - - -class TextComponent( - override var text: String?, - override var extra: MutableList? = null, - override var color: String? = null, - override var bold: Boolean? = null, - override var italic: Boolean? = null, - override var underlined: Boolean? = null, - override var strikethrough: Boolean? = null, - override var obfuscated: Boolean? = null, - override var font: String? = null, - override var insertion: String? = null, - @SerialName("hoverEvent") - override var hoverEvent: HoverEvent? = null, - @SerialName("click_event") - override var clickEvent: ClickEvent? = null -): Component() - -class KeybindComponent( - override var keybind: String?, - override var extra: MutableList? = null, - override var color: String? = null, - override var bold: Boolean? = null, - override var italic: Boolean? = null, - override var underlined: Boolean? = null, - override var strikethrough: Boolean? = null, - override var obfuscated: Boolean? = null, - override var font: String? = null, - override var insertion: String? = null, - @SerialName("hoverEvent") - override var hoverEvent: HoverEvent? = null, - @SerialName("click_event") - override var clickEvent: ClickEvent? = null -): Component() - -class TranslatableComponent( - override var translate: String?, - override var extra: MutableList? = null, - override var color: String? = null, - override var bold: Boolean? = null, - override var italic: Boolean? = null, - override var underlined: Boolean? = null, - override var strikethrough: Boolean? = null, - override var obfuscated: Boolean? = null, - override var font: String? = null, - override var insertion: String? = null, - override var hoverEvent: HoverEvent? = null, - override var clickEvent: ClickEvent? = null -): Component() - -@Serializable -class ClickEvent( - val action: ClickAction, - val value: String? = null -) - -@Serializable -class HoverEvent( - val action: HoverAction, - val contents: Component? = null -) - -@Serializable -enum class ClickAction { - @SerialName("open_url") - OPEN_URL, - @SerialName("run_command") - RUN_COMMAND, - @SerialName("suggest_command") - SUGGEST_COMMAND, - @SerialName("copy_to_clipboard") - COPY_TO_CLIPBOARD -} - -@Serializable -enum class HoverAction { - @SerialName("show_text") - SHOW_TEXT, - @SerialName("show_item") - SHOW_ITEM -} diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/Components.kt b/src/main/kotlin/io/github/dockyardmc/scroll/Components.kt deleted file mode 100644 index 88d0ea3..0000000 --- a/src/main/kotlin/io/github/dockyardmc/scroll/Components.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.dockyardmc.scroll - -object Components { - - fun new(components: MutableList): Component { - return Component( - text = "", - extra = components - ) - } -} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/HoverAction.kt b/src/main/kotlin/io/github/dockyardmc/scroll/HoverAction.kt new file mode 100644 index 0000000..a840d3d --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/HoverAction.kt @@ -0,0 +1,12 @@ +package io.github.dockyardmc.scroll + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +enum class HoverAction { + @SerialName("show_text") + SHOW_TEXT, + @SerialName("show_item") + SHOW_ITEM +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/HoverEvent.kt b/src/main/kotlin/io/github/dockyardmc/scroll/HoverEvent.kt new file mode 100644 index 0000000..1e1ba25 --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/HoverEvent.kt @@ -0,0 +1,9 @@ +package io.github.dockyardmc.scroll + +import kotlinx.serialization.Serializable + +@Serializable +class HoverEvent( + val action: HoverAction, + val contents: Component? = null +) \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/LegacyTextColor.kt b/src/main/kotlin/io/github/dockyardmc/scroll/LegacyTextColor.kt new file mode 100644 index 0000000..e8f7947 --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/LegacyTextColor.kt @@ -0,0 +1,22 @@ +package io.github.dockyardmc.scroll + +//Ordered in precise way cause text colors used to be enum in the minecraft client. It still uses that in some packets +//https://wiki.vg/Text_formatting#Colors +enum class LegacyTextColor(val hex: String) { + BLACK("#000000"), + DARK_BLUE("#0000AA"), + GREEN("#00AA00"), + CYAN("#00AAAA"), + DARK_RED("#AA0000"), + PURPLE("#AA00AA"), + ORANGE("#FFAA00"), + GRAY("#AAAAAA"), + DARK_GRAY("#555555"), + BLUE("#5555FF"), + LIME("#55FF55"), + AQUA("#55FFFF"), + RED("#FF5555"), + PINK("#FF55FF"), + YELLOW("#FFFF55"), + WHITE("#FFFFFF"), +} diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/Main.kt b/src/main/kotlin/io/github/dockyardmc/scroll/Main.kt deleted file mode 100644 index 2b62944..0000000 --- a/src/main/kotlin/io/github/dockyardmc/scroll/Main.kt +++ /dev/null @@ -1,4 +0,0 @@ -package io.github.dockyardmc.scroll - -fun main() { -} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/Scroll.kt b/src/main/kotlin/io/github/dockyardmc/scroll/Scroll.kt new file mode 100644 index 0000000..d15aa4b --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/Scroll.kt @@ -0,0 +1,41 @@ +package io.github.dockyardmc.scroll + +import io.github.dockyardmc.scroll.providers.FormatProvider +import io.github.dockyardmc.scroll.providers.default.BoldProvider +import io.github.dockyardmc.scroll.providers.default.ClickEventProvider +import io.github.dockyardmc.scroll.providers.default.FontProvider +import io.github.dockyardmc.scroll.providers.default.HexColorProvider +import io.github.dockyardmc.scroll.providers.default.HoverEventProvider +import io.github.dockyardmc.scroll.providers.default.ItalicsProvider +import io.github.dockyardmc.scroll.providers.default.KeybindProvider +import io.github.dockyardmc.scroll.providers.default.NamedColorProvider +import io.github.dockyardmc.scroll.providers.default.ObfuscatedProvider +import io.github.dockyardmc.scroll.providers.default.ResetProvider +import io.github.dockyardmc.scroll.providers.default.StrikethroughProvider +import io.github.dockyardmc.scroll.providers.default.TranslateProvider +import io.github.dockyardmc.scroll.providers.default.UnderlinedProvider + +object Scroll { + + val defaultFormatProviders = listOf( + HexColorProvider(), + BoldProvider(), + ItalicsProvider(), + UnderlinedProvider(), + StrikethroughProvider(), + ObfuscatedProvider(), + NamedColorProvider(), + FontProvider(), + ResetProvider(), + TranslateProvider(), + KeybindProvider(), + ClickEventProvider(), + HoverEventProvider() + ) + + private val defaultParser = ScrollParser(defaultFormatProviders) + + fun parse(input: String): Component { + return defaultParser.parse(input) + } +} diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/ScrollParser.kt b/src/main/kotlin/io/github/dockyardmc/scroll/ScrollParser.kt new file mode 100644 index 0000000..86155e3 --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/ScrollParser.kt @@ -0,0 +1,74 @@ +package io.github.dockyardmc.scroll + +import io.github.dockyardmc.scroll.providers.FormatProvider +import io.github.dockyardmc.scroll.providers.FormatProviderContext + +data class ScrollParser(val formatProviders: Collection) { + + fun parse(input: String): Component { + val components = mutableListOf() + val tokens = ScrollUtil.splitDelimiter(input, "<", ">") + + val styleComponent = Component() + + tokens.forEach { token -> + var currentComponent = Component() + var foundProvider = false + var isInteractiveProvider = false + var isPrefilledTextProvider = false + + formatProviders.forEach { provider -> + if (token.startsWith("<") && token.endsWith(">")) { + if (provider.matches(token)) { + provider.format(FormatProviderContext(token, token, input), styleComponent) + foundProvider = true + if(styleComponent.translate != null || styleComponent.keybind != null || styleComponent.insertion != null) { + foundProvider = false + isInteractiveProvider = true + } + if(styleComponent.text != null) { + foundProvider = false + isPrefilledTextProvider = true + } + } + } + } + + if (foundProvider) return@forEach + + if (token.isEmpty()) return@forEach + currentComponent.text = token + + if(isInteractiveProvider) { + currentComponent.text = null + currentComponent.keybind = styleComponent.keybind + currentComponent.translate = styleComponent.translate + currentComponent.insertion = styleComponent.insertion + + styleComponent.keybind = null + styleComponent.translate = null + styleComponent.insertion = null + } + + if(isPrefilledTextProvider) { + currentComponent.text = styleComponent.text + styleComponent.text = null + } + + currentComponent.color = styleComponent.color + currentComponent.bold = styleComponent.bold + currentComponent.italic = styleComponent.italic + currentComponent.underlined = styleComponent.underlined + currentComponent.font = styleComponent.font + currentComponent.obfuscated = styleComponent.obfuscated + currentComponent.strikethrough = styleComponent.strikethrough + currentComponent.clickEvent = styleComponent.clickEvent + currentComponent.hoverEvent = styleComponent.hoverEvent + + + components.add(currentComponent) + } + val final = Component.compound(components) + return final + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/ScrollUtil.kt b/src/main/kotlin/io/github/dockyardmc/scroll/ScrollUtil.kt new file mode 100644 index 0000000..cab0ec1 --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/ScrollUtil.kt @@ -0,0 +1,102 @@ +package io.github.dockyardmc.scroll + +import java.util.regex.Pattern + +object ScrollUtil { + + val colorTags = mutableMapOf( + "" to LegacyTextColor.RED.hex, + "" to LegacyTextColor.YELLOW.hex, + "" to LegacyTextColor.LIME.hex, + "" to LegacyTextColor.AQUA.hex, + "" to LegacyTextColor.BLUE.hex, + "" to LegacyTextColor.PINK.hex, + + "" to LegacyTextColor.DARK_RED.hex, + "" to LegacyTextColor.DARK_RED.hex, + "" to LegacyTextColor.ORANGE.hex, + "" to LegacyTextColor.ORANGE.hex, + "" to LegacyTextColor.GREEN.hex, + "" to LegacyTextColor.CYAN.hex, + "" to LegacyTextColor.DARK_BLUE.hex, + "" to LegacyTextColor.DARK_BLUE.hex, + "" to LegacyTextColor.DARK_BLUE.hex, + + "" to LegacyTextColor.WHITE.hex, + "" to LegacyTextColor.GRAY.hex, + "" to LegacyTextColor.DARK_GRAY.hex, + "" to LegacyTextColor.DARK_GRAY.hex, + "" to LegacyTextColor.BLACK.hex, + ) + + fun splitDelimiter(string: String, start: String, end: String): MutableList { + val result = mutableListOf() + + var out = "" + var open = false + var insideQuotes = false + string.forEachIndexed { index, it -> + if (insideQuotes && it != '\'') { + out = "$out${it}"; return@forEachIndexed + } + if (out.startsWith("<")) { + if (it == '\'') { + if (insideQuotes) { + val nextChar = getCharacterAfter(string, index) + ?: throw IllegalStateException("end of quoted string unexpectedly") + insideQuotes = !(nextChar == '>' || nextChar == ':') + } else { + insideQuotes = true + } + } + } + + if (it == start[0] && getCharacterBefore(string, index).toString() != "\\") { + open = true + if (out.isNotEmpty()) { + result.add(out) + } + out = "$it" + return@forEachIndexed + } + if (it.toString() == "\\" && getCharacterAfter(string, index) == start[0]) return@forEachIndexed + out = "$out${it}" + + if (it == end[0] && open) { + open = false + if (out.isNotEmpty()) { + result.add(out) + } + out = "" + } + if (index == string.length - 1) { + result.add(out) + } + } + return result + } + + fun getCharacterBefore(string: String, currentIndex: Int): Char? { + val index = currentIndex - 1 + val value = if (index < 0) null else string[index] + return value + } + + fun getCharacterAfter(string: String, currentIndex: Int): Char? { + val index = currentIndex + 1 + val value = if (index > string.toMutableList().size) null else string[index] + return value + } + + fun getArguments(input: String): List { + val pattern = Pattern.compile("<(.*?):(.*)>") + val matcher = pattern.matcher(input) + + return if (matcher.matches()) { + matcher.group(2).split(":").map { it.removePrefix("'").removeSuffix("'") } + } else { + emptyList() + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/Util.kt b/src/main/kotlin/io/github/dockyardmc/scroll/Util.kt deleted file mode 100644 index 88f19f4..0000000 --- a/src/main/kotlin/io/github/dockyardmc/scroll/Util.kt +++ /dev/null @@ -1,31 +0,0 @@ -package io.github.dockyardmc.scroll - -fun rainbowHex(numSteps: Int, lightness: Float = 1f): List { - val colors = mutableListOf() - for (i in 0.. - (start + (end - start) * step).toInt() - } - - val interpolatedColor = StringBuilder("#") - for (value in interpolatedRGB) { - val hex = value.coerceIn(0, 255).toString(16).padStart(2, '0') - interpolatedColor.append(hex) - } - - return interpolatedColor.toString() -} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/extensions/ExtendedString.kt b/src/main/kotlin/io/github/dockyardmc/scroll/extensions/ExtendedString.kt index f7f6c56..668dd1f 100644 --- a/src/main/kotlin/io/github/dockyardmc/scroll/extensions/ExtendedString.kt +++ b/src/main/kotlin/io/github/dockyardmc/scroll/extensions/ExtendedString.kt @@ -1,16 +1,16 @@ package io.github.dockyardmc.scroll.extensions import io.github.dockyardmc.scroll.Component -import io.github.dockyardmc.scroll.serializers.StringToComponentSerializer +import io.github.dockyardmc.scroll.Scroll fun String.toComponent(): Component { - return StringToComponentSerializer().serialize(this) + return Scroll.parse(this) } fun String.scrollSanitized(): String { var out = "" this.forEachIndexed { index, char -> - out += (if(char.toString() == "<") "\\<" else char.toString()) + out += (if (char.toString() == "<") "\\<" else char.toString()) } return out } @@ -19,49 +19,14 @@ fun String.stripComponentTags(): String { return this.toComponent().stripStyling() } -fun String.split(start: String, end: String): MutableList { - val result = mutableListOf() - - var out = "" - var open = false - var insideQuotes = false - this.forEachIndexed { index, it -> - if(insideQuotes && it != '\'') { out = "$out${it}"; return@forEachIndexed } - if(it == '\'') insideQuotes = !insideQuotes - - if(it == start[0] && getCharacterBefore(this, index).toString() != "\\") { - open = true - if(out.isNotEmpty()) { - result.add(out) - } - out = "$it" - return@forEachIndexed - } - if(it.toString() == "\\" && getCharacterAfter(this, index) == start[0]) return@forEachIndexed - out = "$out${it}" - - if(it == end[0] && open) { - open = false - if(out.isNotEmpty()) { - result.add(out) - } - out = "" - } - if(index == this.length - 1) { - result.add(out) - } +fun String.replaceMultiple(delimiters: Collection, replacement: String): String { + var result = this + delimiters.forEach { delimiter -> + result = result.replace(delimiter, replacement) } return result } -fun getCharacterBefore(string: String, currentIndex: Int): Char? { - val index = currentIndex - 1 - val value = if(index < 0) null else string[index] - return value -} - -fun getCharacterAfter(string: String, currentIndex: Int): Char? { - val index = currentIndex + 1 - val value = if(index > string.toMutableList().size) null else string[index] - return value +fun String.replaceMultiple(replacement: String, vararg delimiter: String): String { + return this.replaceMultiple(delimiter.toList(), replacement) } \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/providers/ClosingNamedFormatProvider.kt b/src/main/kotlin/io/github/dockyardmc/scroll/providers/ClosingNamedFormatProvider.kt new file mode 100644 index 0000000..155abe2 --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/providers/ClosingNamedFormatProvider.kt @@ -0,0 +1,20 @@ +package io.github.dockyardmc.scroll.providers + +import io.github.dockyardmc.scroll.Component + +abstract class ClosingNamedFormatProvider(name: String, aliases: List): NamedFormatProvider(name, aliases) { + + override fun matches(token: String): Boolean { + return aliases.contains(token.replace("<", "").replace(">", "").split(":")[0]) + || aliases.contains(token.replace("", "").split(":")[0]) + || token.replace("<", "").replace(">", "").split(":")[0] == name + || token.replace("", "").split(":")[0] == name + } + + override fun format(context: FormatProviderContext, component: Component) { + if(context.token.startsWith("): FormatProvider() { + + override fun matches(token: String): Boolean { + return aliases.contains(token.replace("<", "").replace(">", "").split(":")[0]) + || token.replace("<", "").replace(">", "").split(":")[0] == name + } + constructor(name: String): this(name, listOf()) +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/BoldProvider.kt b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/BoldProvider.kt new file mode 100644 index 0000000..dc64868 --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/BoldProvider.kt @@ -0,0 +1,17 @@ +package io.github.dockyardmc.scroll.providers.default + +import io.github.dockyardmc.scroll.Component +import io.github.dockyardmc.scroll.providers.ClosingNamedFormatProvider +import io.github.dockyardmc.scroll.providers.FormatProviderContext + +class BoldProvider: ClosingNamedFormatProvider("bold", listOf("b")) { + + override fun formatNormal(context: FormatProviderContext, component: Component) { + component.bold = true + } + + override fun formatClosing(context: FormatProviderContext, component: Component) { + component.bold = null + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/ClickEventProvider.kt b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/ClickEventProvider.kt new file mode 100644 index 0000000..9781253 --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/ClickEventProvider.kt @@ -0,0 +1,18 @@ +package io.github.dockyardmc.scroll.providers.default + +import io.github.dockyardmc.scroll.ClickAction +import io.github.dockyardmc.scroll.ClickEvent +import io.github.dockyardmc.scroll.Component +import io.github.dockyardmc.scroll.providers.FormatProviderContext +import io.github.dockyardmc.scroll.providers.NamedFormatProvider + +class ClickEventProvider: NamedFormatProvider("click") { + + override fun format(context: FormatProviderContext, component: Component) { + val action = ClickAction.valueOf(context.getArgument(0).uppercase()) + val value = context.getArgument(1) + val clickEvent = ClickEvent(action, value) + + component.clickEvent = clickEvent + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/FontProvider.kt b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/FontProvider.kt new file mode 100644 index 0000000..91b1f63 --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/FontProvider.kt @@ -0,0 +1,19 @@ +package io.github.dockyardmc.scroll.providers.default + +import io.github.dockyardmc.scroll.Component +import io.github.dockyardmc.scroll.providers.ClosingNamedFormatProvider +import io.github.dockyardmc.scroll.providers.FormatProviderContext + +class FontProvider: ClosingNamedFormatProvider("font", listOf()) { + + override fun formatNormal(context: FormatProviderContext, component: Component) { + val font = context.getArgument(0) + component.font = font + + } + + override fun formatClosing(context: FormatProviderContext, component: Component) { + component.font = null + } +} + diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/HexColorProvider.kt b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/HexColorProvider.kt new file mode 100644 index 0000000..a76380a --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/HexColorProvider.kt @@ -0,0 +1,18 @@ +package io.github.dockyardmc.scroll.providers.default + +import io.github.dockyardmc.scroll.Component +import io.github.dockyardmc.scroll.extensions.replaceMultiple +import io.github.dockyardmc.scroll.providers.FormatProvider +import io.github.dockyardmc.scroll.providers.FormatProviderContext + +class HexColorProvider: FormatProvider() { + + override fun matches(token: String): Boolean { + return token.replace("<", "").replace(">", "").split(":")[0].startsWith("#") + } + + override fun format(context: FormatProviderContext, component: Component) { + component.resetFormatting() + component.color = context.token.replaceMultiple(listOf("<", ">"), "") + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/HoverEventProvider.kt b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/HoverEventProvider.kt new file mode 100644 index 0000000..9923ce2 --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/HoverEventProvider.kt @@ -0,0 +1,19 @@ +package io.github.dockyardmc.scroll.providers.default + +import io.github.dockyardmc.scroll.Component +import io.github.dockyardmc.scroll.HoverAction +import io.github.dockyardmc.scroll.HoverEvent +import io.github.dockyardmc.scroll.Scroll +import io.github.dockyardmc.scroll.providers.FormatProviderContext +import io.github.dockyardmc.scroll.providers.NamedFormatProvider + +class HoverEventProvider: NamedFormatProvider("hover") { + + override fun format(context: FormatProviderContext, component: Component) { + val action = HoverAction.valueOf(context.getArgument(0).uppercase()) + val value = Scroll.parse(context.getArgument(1)) + val hoverEvent = HoverEvent(action, value) + + component.hoverEvent = hoverEvent + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/ItalicsProvider.kt b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/ItalicsProvider.kt new file mode 100644 index 0000000..edc5260 --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/ItalicsProvider.kt @@ -0,0 +1,17 @@ +package io.github.dockyardmc.scroll.providers.default + +import io.github.dockyardmc.scroll.Component +import io.github.dockyardmc.scroll.providers.ClosingNamedFormatProvider +import io.github.dockyardmc.scroll.providers.FormatProviderContext + +class ItalicsProvider: ClosingNamedFormatProvider("italic", listOf("italic", "italics", "i")) { + + override fun formatNormal(context: FormatProviderContext, component: Component) { + component.italic = true + } + + override fun formatClosing(context: FormatProviderContext, component: Component) { + component.italic = null + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/KeybindProvider.kt b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/KeybindProvider.kt new file mode 100644 index 0000000..29a9cc1 --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/KeybindProvider.kt @@ -0,0 +1,13 @@ +package io.github.dockyardmc.scroll.providers.default + +import io.github.dockyardmc.scroll.Component +import io.github.dockyardmc.scroll.providers.FormatProviderContext +import io.github.dockyardmc.scroll.providers.NamedFormatProvider + +class KeybindProvider: NamedFormatProvider("keybind") { + + override fun format(context: FormatProviderContext, component: Component) { + val keybind = context.getArgument(0) + component.keybind = keybind + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/NamedColorProvider.kt b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/NamedColorProvider.kt new file mode 100644 index 0000000..14df5b9 --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/NamedColorProvider.kt @@ -0,0 +1,23 @@ +package io.github.dockyardmc.scroll.providers.default + +import io.github.dockyardmc.scroll.Component +import io.github.dockyardmc.scroll.ScrollUtil +import io.github.dockyardmc.scroll.extensions.replaceMultiple +import io.github.dockyardmc.scroll.providers.ClosingNamedFormatProvider +import io.github.dockyardmc.scroll.providers.FormatProviderContext + +class NamedColorProvider : + ClosingNamedFormatProvider("red", ScrollUtil.colorTags.keys.toList().map { it.replaceMultiple(listOf("<", ">"), "") }) { + + override fun formatNormal(context: FormatProviderContext, component: Component) { + component.resetFormatting() + val color = ScrollUtil.colorTags[context.token] ?: throw IllegalStateException("Invalid legacy text color: ${context.token}") + component.color = color + } + + override fun formatClosing(context: FormatProviderContext, component: Component) { + component.resetFormatting() + + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/ObfuscatedProvider.kt b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/ObfuscatedProvider.kt new file mode 100644 index 0000000..18f3e5f --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/ObfuscatedProvider.kt @@ -0,0 +1,17 @@ +package io.github.dockyardmc.scroll.providers.default + +import io.github.dockyardmc.scroll.Component +import io.github.dockyardmc.scroll.providers.ClosingNamedFormatProvider +import io.github.dockyardmc.scroll.providers.FormatProviderContext + +class ObfuscatedProvider: ClosingNamedFormatProvider("obfuscated", listOf("obf", "o")) { + + override fun formatNormal(context: FormatProviderContext, component: Component) { + component.obfuscated = true + } + + override fun formatClosing(context: FormatProviderContext, component: Component) { + component.obfuscated = null + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/ResetProvider.kt b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/ResetProvider.kt new file mode 100644 index 0000000..57a1eed --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/ResetProvider.kt @@ -0,0 +1,12 @@ +package io.github.dockyardmc.scroll.providers.default + +import io.github.dockyardmc.scroll.Component +import io.github.dockyardmc.scroll.providers.FormatProviderContext +import io.github.dockyardmc.scroll.providers.NamedFormatProvider + +class ResetProvider: NamedFormatProvider("reset", listOf("r")) { + + override fun format(context: FormatProviderContext, component: Component) { + component.resetFormatting() + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/StrikethroughProvider.kt b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/StrikethroughProvider.kt new file mode 100644 index 0000000..8b720f7 --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/StrikethroughProvider.kt @@ -0,0 +1,17 @@ +package io.github.dockyardmc.scroll.providers.default + +import io.github.dockyardmc.scroll.Component +import io.github.dockyardmc.scroll.providers.ClosingNamedFormatProvider +import io.github.dockyardmc.scroll.providers.FormatProviderContext + +class StrikethroughProvider: ClosingNamedFormatProvider("strikethrough", listOf("s", "strike")) { + + override fun formatNormal(context: FormatProviderContext, component: Component) { + component.strikethrough = true + } + + override fun formatClosing(context: FormatProviderContext, component: Component) { + component.strikethrough = null + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/TranslateProvider.kt b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/TranslateProvider.kt new file mode 100644 index 0000000..78a92e7 --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/TranslateProvider.kt @@ -0,0 +1,13 @@ +package io.github.dockyardmc.scroll.providers.default + +import io.github.dockyardmc.scroll.Component +import io.github.dockyardmc.scroll.providers.FormatProviderContext +import io.github.dockyardmc.scroll.providers.NamedFormatProvider + +class TranslateProvider: NamedFormatProvider("translate") { + + override fun format(context: FormatProviderContext, component: Component) { + val key = context.getArgument(0) + component.translate = key + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/UnderlinedProvider.kt b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/UnderlinedProvider.kt new file mode 100644 index 0000000..a9b54c6 --- /dev/null +++ b/src/main/kotlin/io/github/dockyardmc/scroll/providers/default/UnderlinedProvider.kt @@ -0,0 +1,17 @@ +package io.github.dockyardmc.scroll.providers.default + +import io.github.dockyardmc.scroll.Component +import io.github.dockyardmc.scroll.providers.ClosingNamedFormatProvider +import io.github.dockyardmc.scroll.providers.FormatProviderContext + +class UnderlinedProvider: ClosingNamedFormatProvider("underlined", listOf("underline", "u")) { + + override fun formatNormal(context: FormatProviderContext, component: Component) { + component.underlined = true + } + + override fun formatClosing(context: FormatProviderContext, component: Component) { + component.underlined = null + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/serializers/ComponentToJsonSerializer.kt b/src/main/kotlin/io/github/dockyardmc/scroll/serializers/ComponentToJsonSerializer.kt index 7567eed..afa0b91 100644 --- a/src/main/kotlin/io/github/dockyardmc/scroll/serializers/ComponentToJsonSerializer.kt +++ b/src/main/kotlin/io/github/dockyardmc/scroll/serializers/ComponentToJsonSerializer.kt @@ -5,7 +5,6 @@ import kotlinx.serialization.json.Json import kotlinx.serialization.json.encodeToJsonElement object ComponentToJsonSerializer { - fun serialize(component: Component): String { return Json.encodeToJsonElement(component).toString() } diff --git a/src/main/kotlin/io/github/dockyardmc/scroll/serializers/StringToComponentSerializer.kt b/src/main/kotlin/io/github/dockyardmc/scroll/serializers/StringToComponentSerializer.kt deleted file mode 100644 index d1d733d..0000000 --- a/src/main/kotlin/io/github/dockyardmc/scroll/serializers/StringToComponentSerializer.kt +++ /dev/null @@ -1,271 +0,0 @@ -package io.github.dockyardmc.scroll.serializers - -import io.github.dockyardmc.scroll.* -import io.github.dockyardmc.scroll.extensions.split - - -class StringToComponentSerializer(private val depth: Int = 0) { - - private var components = mutableListOf() - private var tokens = mutableListOf() - private var rainbowHex = rainbowHex(20) - private lateinit var innerStringToComponentSerializer: StringToComponentSerializer - - private var color: String? = null - private var bold: Boolean? = null - private var italic: Boolean? = null - private var underline: Boolean? = null - private var obfuscated: Boolean? = null - private var strikethrough: Boolean? = null - - private var hoverEvent: HoverEvent? = null - private var clickEvent: ClickEvent? = null - - private var font: String? = null - - private var rainbow = false - private var currentRainbowIndex = 0 - - private fun resetFormatting(includingColor: Boolean = false, includingEvents: Boolean = false) { - bold = null - italic = null - underline = null - obfuscated = null - strikethrough = null - if(includingColor) { - color = null - } - if(includingEvents) { - hoverEvent = null - clickEvent = null - } - } - - fun serialize(string: String): Component { - tokens = string.split("<", ">") - if(depth < 1) innerStringToComponentSerializer = StringToComponentSerializer(depth + 1) - - tokens.forEach { - if(it.startsWith("<") && it.endsWith(">")) { - if(tokenIsColor(it)) { - color = getTokenColor(it) - resetFormatting() - rainbow = false - } - - if(it.startsWith("<#")) { - val hex = it.replace("<", "").replace(">", "") - color = hex - resetFormatting() - rainbow = false - } - - when(it) { - "", - "" -> bold = true - "", - "" -> italic = true - "" -> italic = true - "", - "" -> underline = true - "" -> underline = true - "", - "" -> obfuscated = true - "", - "" -> strikethrough = true - "", - "" -> { - color = null - bold = null - italic = null - underline = null - obfuscated = null - strikethrough = null - rainbow = false - currentRainbowIndex = 0 - hoverEvent = null - clickEvent = null - font = null - } - "", - "", - "", - "" -> { - bold = null - italic = null - underline = null - obfuscated = null - strikethrough = null - currentRainbowIndex = 0 - } - "" -> hoverEvent = null - "" -> clickEvent = null - "" -> bold = null - "" -> bold = null - "" -> italic = null - "" -> italic = null - "" -> italic = null - "" -> underline = null - "" -> underline = null - "" -> underline = null - "" -> obfuscated = null - "" -> obfuscated = null - "" -> strikethrough = null - "" -> strikethrough = null - "" -> strikethrough = false - "" -> font = null - } - - if(it.startsWith("").toFloat() - - rainbowHex = rainbowHex(rainbowLength, lightness) - - rainbow = true - - resetFormatting() - } - - if(it.startsWith("") - components.add( - Component( - text = null, - keybind = key, - color = color, - bold = bold, - font = font, - italic = italic, - underlined = underline, - obfuscated = obfuscated, - strikethrough = strikethrough, - hoverEvent = hoverEvent, - clickEvent = clickEvent - ) - ) - return@forEach - } - - if(it.startsWith("") - components.add( - Component( - text = null, - translate = value, - color = color, - font = font, - bold = bold, - italic = italic, - underlined = underline, - obfuscated = obfuscated, - strikethrough = strikethrough, - hoverEvent = hoverEvent, - clickEvent = clickEvent - ) - ) - return@forEach - } - - if(it.startsWith("") - val comp = innerStringToComponentSerializer.serialize(hoverText) - hoverEvent = HoverEvent( - action = HoverAction.SHOW_TEXT, - contents = comp - ) - } - - if(it.startsWith("") - if(!fontValue!!.contains(":")) fontValue = "minecraft:$fontValue" - if(fontValue == "minecraft:default") fontValue = null - font = fontValue - } - - if(it.startsWith("") - clickEvent = ClickEvent( - action = ClickAction.valueOf(action), - value = value - ) - } - - if(it.startsWith("").toFloat() - - color = hexInterpolation(colorFrom, colorTo, step) - } - - return@forEach - } - - if(rainbow) { - it.forEach { letter -> - if(currentRainbowIndex > 19) currentRainbowIndex = 0 - val customColor = rainbowHex[currentRainbowIndex] - components.add( - Component( - text = letter.toString(), - color = customColor, - font = font, - bold = bold, - italic = italic, - underlined = underline, - obfuscated = obfuscated, - strikethrough = strikethrough, - hoverEvent = hoverEvent, - clickEvent = clickEvent - ) - ) - currentRainbowIndex++ - } - return@forEach - } - - components.add( - Component( - text = it, - color = color, - bold = bold, - italic = italic, - underlined = underline, - obfuscated = obfuscated, - strikethrough = strikethrough, - font = font, - hoverEvent = hoverEvent, - clickEvent = clickEvent - ) - ) - } - val outList = mutableListOf() - // Filter out empty text components created by parsing and - components.forEach { - if(it.text != null && it.text!!.isEmpty() && it.extra == null) return@forEach - outList.add(it) - } - - return Components.new(outList) - } - - - private fun tokenIsColor(token: String): Boolean { - return ComponentColorTags.colorTags.containsKey(token) - } - - private fun getTokenColor(token: String): String { - return ComponentColorTags.colorTags[token]!! - } -} \ No newline at end of file diff --git a/src/test/kotlin/NbtSerializationTests.kt b/src/test/kotlin/NbtSerializationTests.kt index e949cac..6fe5210 100644 --- a/src/test/kotlin/NbtSerializationTests.kt +++ b/src/test/kotlin/NbtSerializationTests.kt @@ -1,9 +1,8 @@ -import io.github.dockyardmc.scroll.ComponentColorTags +import io.github.dockyardmc.scroll.ScrollUtil import io.github.dockyardmc.scroll.extensions.put import io.github.dockyardmc.scroll.extensions.toComponent import org.jglrxavpok.hephaistos.nbt.NBT import kotlin.test.Test -import kotlin.test.assertContains import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -18,7 +17,7 @@ class NbtSerializationTests { hoverIn.put("extra", NBT.Compound { it.put("extra", NBT.Compound { extrahover -> extrahover.put("text", "Click to open the store URL") - extrahover.put("color", ComponentColorTags.colorTags[""]) + extrahover.put("color", ScrollUtil.colorTags[""]) }) it.put("text", "") }) @@ -32,9 +31,9 @@ class NbtSerializationTests { click.put("value", "https://store.mccisland.net") }) it.put("underline", true) - it.put("color", ComponentColorTags.colorTags[""]) + it.put("color", ScrollUtil.colorTags[""]) } - val expected = "Click to open the store URL'>CLICK HERE".toComponent() + val expected = "Click to open the store URL'>CLICK HERE".toComponent() val final = NBT.Compound { it.put("extra", mutableListOf(nbt)) it.put("text", "") @@ -54,7 +53,7 @@ class NbtSerializationTests { hoverIn.put("extra", NBT.Compound { it.put("extra", NBT.Compound { extrahover -> extrahover.put("text", "Click to open the store URL") - extrahover.put("color", ComponentColorTags.colorTags[""]) + extrahover.put("color", ScrollUtil.colorTags[""]) }) it.put("text", "") }) @@ -68,7 +67,7 @@ class NbtSerializationTests { click.put("value", "https://store.mccisland.net") }) it.put("underline", true) - it.put("color", ComponentColorTags.colorTags[""]) + it.put("color", ScrollUtil.colorTags[""]) } ) val final = NBT.Compound { @@ -83,14 +82,14 @@ class NbtSerializationTests { @Test fun testStringToNbt() { - val input = "<#ff54aa>omg haiiii bestie AsoDesu_ :3 to jump. should be advMode.mode" + val input = "<#ff54aa>omg haiiii bestie AsoDesu_ :3 to jump. should be advMode.mode" val expected = mutableListOf( NBT.Compound { it.put("text", "omg haiiii bestie AsoDesu_ ") it.put("color", "#ff54aa") }, NBT.Compound { - it.put("color", ComponentColorTags.colorTags[""]) + it.put("color", ScrollUtil.colorTags[""]) it.put("bold", true) it.put("text", ":3") }, diff --git a/src/test/kotlin/StringSerializationTests.kt b/src/test/kotlin/StringSerializationTests.kt index dd1680e..df790ee 100644 --- a/src/test/kotlin/StringSerializationTests.kt +++ b/src/test/kotlin/StringSerializationTests.kt @@ -9,203 +9,233 @@ class StringSerializationTests { @Test fun testBasicSerialization() { val input = "This text should be red" - val expected = Components.new(mutableListOf( - TextComponent("This text should be red", color = "#FF5555") + val expected = Component.compound(mutableListOf( + Component(text = "This text should be red", color = "#FF5555") )) - assertEquals(expected.toJson(), input.toComponent().toJson()) + assertEquals(expected.toJson(), Scroll.parse(input).toJson()) } @Test fun testCustomColorSerialization() { val input = "<#ff54aa>This text should be cute pink color :3" - val expected = Components.new(mutableListOf( - TextComponent("This text should be cute pink color :3", color = "#ff54aa") + val expected = Component.compound(mutableListOf( + Component(text ="This text should be cute pink color :3", color = "#ff54aa") )) - assertEquals(expected.toJson(), input.toComponent().toJson()) + assertEquals(expected.toJson(), Scroll.parse(input).toJson()) } @Test fun testMultipleSerializationComponents() { val input = "This text should be multi colored" - val expected = Components.new(mutableListOf( - TextComponent("This ", color = ComponentColorTags.colorTags[""]), - TextComponent("text ", color = ComponentColorTags.colorTags[""]), - TextComponent("should ", color = ComponentColorTags.colorTags[""]), - TextComponent("be ", color = ComponentColorTags.colorTags[""]), - TextComponent("multi ", color = ComponentColorTags.colorTags[""]), - TextComponent("colored", color = ComponentColorTags.colorTags[""]), + val expected = Component.compound(mutableListOf( + Component(text ="This ", color = ScrollUtil.colorTags[""]), + Component(text ="text ", color = ScrollUtil.colorTags[""]), + Component(text ="should ", color = ScrollUtil.colorTags[""]), + Component(text ="be ", color = ScrollUtil.colorTags[""]), + Component(text ="multi ", color = ScrollUtil.colorTags[""]), + Component(text ="colored", color = ScrollUtil.colorTags[""]), )) - assertEquals(expected.toJson(), input.toComponent().toJson()) + assertEquals(expected.toJson(), Scroll.parse(input).toJson()) } @Test fun testClosingTags() { val input = "test test test test test test" - val expected = Components.new(mutableListOf( - TextComponent("test ", bold = true, underlined = true, italic = true, strikethrough = true, obfuscated = true), - TextComponent("test ", bold = true, underlined = true, italic = true, strikethrough = true), - TextComponent("test ", bold = true, underlined = true, italic = true), - TextComponent("test ", bold = true, underlined = true), - TextComponent("test ", bold = true), - TextComponent("test"), + val expected = Component.compound(mutableListOf( + Component(text ="test ", bold = true, underlined = true, italic = true, strikethrough = true, obfuscated = true), + Component(text ="test ", bold = true, underlined = true, italic = true, strikethrough = true), + Component(text ="test ", bold = true, underlined = true, italic = true), + Component(text ="test ", bold = true, underlined = true), + Component(text ="test ", bold = true), + Component(text ="test"), )) - assertEquals(expected.toJson(), input.toComponent().toJson()) + assertEquals(expected.toJson(), Scroll.parse(input).toJson()) } @Test fun testClosingTagsMini() { val input = "test test test test test test" - val expected = Components.new(mutableListOf( - TextComponent("test ", bold = true, underlined = true, italic = true, strikethrough = true, obfuscated = true), - TextComponent("test ", bold = true, underlined = true, italic = true, strikethrough = true), - TextComponent("test ", bold = true, underlined = true, italic = true), - TextComponent("test ", bold = true, underlined = true), - TextComponent("test ", bold = true), - TextComponent("test"), + val expected = Component.compound(mutableListOf( + Component(text ="test ", bold = true, underlined = true, italic = true, strikethrough = true, obfuscated = true), + Component(text ="test ", bold = true, underlined = true, italic = true, strikethrough = true), + Component(text ="test ", bold = true, underlined = true, italic = true), + Component(text ="test ", bold = true, underlined = true), + Component(text ="test ", bold = true), + Component(text ="test"), )) - assertEquals(expected.toJson(), input.toComponent().toJson()) + assertEquals(expected.toJson(), Scroll.parse(input).toJson()) } @Test fun testFormatting() { val inputToExpectedOutput = mutableMapOf( - "test" to TextComponent("test", bold = true), - "test" to TextComponent("test", bold = true), - "test" to TextComponent("test", italic = true), - "test" to TextComponent("test", italic = true), - "test" to TextComponent("test", underlined = true), - "test" to TextComponent("test", underlined = true), - "test" to TextComponent("test", obfuscated = true), - "test" to TextComponent("test", obfuscated = true), - "test" to TextComponent("test", + "test" to Component(text ="test", bold = true), + "test" to Component(text ="test", bold = true), + "test" to Component(text ="test", italic = true), + "test" to Component(text ="test", italic = true), + "test" to Component(text ="test", underlined = true), + "test" to Component(text ="test", underlined = true), + "test" to Component(text ="test", obfuscated = true), + "test" to Component(text ="test", obfuscated = true), + "test" to Component(text ="test", bold = true, italic = true, underlined = true, obfuscated = true, ), - "test" to TextComponent("test", + "test" to Component(text ="test", bold = true, italic = true, underlined = true, obfuscated = true, ), - "test" to TextComponent("test"), - "test" to TextComponent("test"), + "test" to Component(text ="test"), + "test" to Component(text ="test"), ) - inputToExpectedOutput.forEach { assertEquals(it.key.toComponent().extra!![0].toJson(), it.value.toJson()) } + inputToExpectedOutput.forEach { assertEquals(Scroll.parse(it.key).extra!![0].toJson(), it.value.toJson()) } } @Test fun testKeybind() { - val input = "" - val expected = Components.new(mutableListOf( - KeybindComponent("key.jump") + val input = "" + val expected = Component.compound(mutableListOf( + Component(keybind = "key.jump") )) - assertEquals(expected.toJson(), input.toComponent().toJson()) + assertEquals(expected.toJson(), Scroll.parse(input).toJson()) } @Test - fun testGay() { - val input = "gayyyy" - val expected = Components.new(mutableListOf( - TextComponent("g", color = "#FF0000"), - TextComponent("a", color = "#FF4D00"), - TextComponent("y", color = "#FF9900"), - TextComponent("y", color = "#FFE600"), - TextComponent("y", color = "#CCFF00"), - TextComponent("y", color = "#80FF00"), + fun testBritish() { + val input = "bo'ohw'o'wo'er" + val expected = Component.compound(mutableListOf( + Component(text = "bo'ohw'o'wo'er", color = "#55FFFF") )) assertEquals(expected.toJson(), input.toComponent().toJson()) } + @Test + fun testClick() { + val input = "Click for Seed" + val expected = Component.compound(mutableListOf( + Component(text = "Click for Seed", clickEvent = ClickEvent(ClickAction.RUN_COMMAND, "/seed")) + )) + + assertEquals(expected.toJson(), Scroll.parse(input).toJson()) + } + + @Test + fun testHover() { + val input = "bucket o' fish'>hover over meeeee do not hover over me" + val expected = Component.compound(mutableListOf( + Component(text = "hover over meeeee ", hoverEvent = HoverEvent(HoverAction.SHOW_TEXT, "bucket o' fish".toComponent())), + Component(text = "do not hover over me") + )) + + assertEquals(expected.toJson(), Scroll.parse(input).toJson()) + } + +// @Test +// fun testGay() { +// val input = "gayyyy" +// val expected = Component.compound(mutableListOf( +// Component(text ="g", color = "#FF0000"), +// Component(text ="a", color = "#FF4D00"), +// Component(text ="y", color = "#FF9900"), +// Component(text ="y", color = "#FFE600"), +// Component(text ="y", color = "#CCFF00"), +// Component(text ="y", color = "#80FF00"), +// )) +// assertEquals(expected.toJson(), ScrollManager.toComponent(input).toJson()) +// } + @Test fun testTranslation() { - val input = "" - val expected = Components.new(mutableListOf( - TranslatableComponent("advancements.husbandry.safely_harvest_honey.description") + val input = "" + val expected = Component.compound(mutableListOf( + Component(translate = "advancements.husbandry.safely_harvest_honey.description") )) - assertEquals(expected.toJson(), input.toComponent().toJson()) + assertEquals(expected.toJson(), Scroll.parse(input).toJson()) } @Test fun testEscapes() { val input = "Missing argument \"mode\": /gamemode \\ \\test" - val expected = Components.new(mutableListOf( - TextComponent("Missing argument \"mode\": /gamemode test") + val expected = Component.compound(mutableListOf( + Component(text ="Missing argument \"mode\": /gamemode test") )) - assertEquals(expected.toJson(), input.toComponent().toJson()) + assertEquals(expected.toJson(), Scroll.parse(input).toJson()) } @Test fun testScrollSanitization() { val input = "Player123: Did you know you can type in red and bold and rainboooowww" - val expected = Components.new(mutableListOf( - TextComponent("Player123: Did you know you can type in red and bold and rainboooowww") + val expected = Component.compound(mutableListOf( + Component(text ="Player123: Did you know you can type in red and bold and rainboooowww") )) - assertEquals(expected.toJson(), input.scrollSanitized().toComponent().toJson()) + assertEquals(expected.toJson(), Scroll.parse(input.scrollSanitized()).toJson()) } @Test fun testBigBoi() { - val input = "hello hello hello hello! Welcome, <#ff54aa>LukynkaCZE! to jump. should be advMode.mode" - val expected = Components.new(mutableListOf( - TextComponent( + val input = "hello hello hello hello! Welcome, <#ff54aa>LukynkaCZE! to jump. should be advMode.mode" + val expected = Component.compound(mutableListOf( + Component( text = "hello ", - color = ComponentColorTags.colorTags[""], + color = ScrollUtil.colorTags[""], italic = true ), - TextComponent( + Component( text = "hello ", - color = ComponentColorTags.colorTags[""], + color = ScrollUtil.colorTags[""], bold = true ), - TextComponent( + Component( text = "hello ", - color = ComponentColorTags.colorTags[""], + color = ScrollUtil.colorTags[""], underlined = true ), - TextComponent( + Component( text = "hello", - color = ComponentColorTags.colorTags[""], + color = ScrollUtil.colorTags[""], obfuscated = true ), - TextComponent( + Component( text = "! Welcome, " ), - TextComponent( + Component( text = "LukynkaCZE", color = "#ff54aa" ), - TextComponent( + Component( text = "! ", ), - KeybindComponent( + Component( keybind = "key.jump" ), - TextComponent( + Component( text = " to jump. " ), - TranslatableComponent( + Component( translate = "advMode.mode" ), - TextComponent( + Component( text = " should be advMode.mode" ) )) - assertEquals(expected.toJson(), input.toComponent().toJson()) + assertEquals(expected.toJson(), Scroll.parse(input).toJson()) } @Test fun testStyleStripping() { val input = "hello there! LukynkaCZE! How are you doing this fine evening?" - val expected = "hello there! LukynkaCZE! How are you doing this fine evening?" + val expected = "hello there! LukynkaCZE! How are you doing this fine evening?" assertEquals(expected, input.toComponent().stripStyling()) } From 39cbe02090bdc1d3eebd6e2f87c61f8c7ba18c73 Mon Sep 17 00:00:00 2001 From: LukynkaCZE Date: Sat, 11 Jan 2025 20:23:29 +0100 Subject: [PATCH 2/2] fix changing color resetting font --- .profileconfig.json | 64 +++++++++++++++ .run/Run Tests.run.xml | 2 + build.gradle.kts | 81 +++++++++++++++++-- .../io/github/dockyardmc/scroll/Component.kt | 22 +++-- .../providers/default/HexColorProvider.kt | 2 +- .../providers/default/NamedColorProvider.kt | 3 +- 6 files changed, 157 insertions(+), 17 deletions(-) create mode 100644 .profileconfig.json diff --git a/.profileconfig.json b/.profileconfig.json new file mode 100644 index 0000000..b2f42d9 --- /dev/null +++ b/.profileconfig.json @@ -0,0 +1,64 @@ +{ + "jfrConfig": { + "settings": "profile" + }, + "asyncProfilerConfig": { + "jfrsync": true, + "alloc": true, + "event": "wall", + "misc": "" + }, + "file": "$PROJECT_DIR/profile.jfr", + "conversionConfig": { + "nonProjectPackagePrefixes": [ + "java.", + "javax.", + "kotlin.", + "jdk.", + "com.google.", + "org.apache.", + "org.spring.", + "sun.", + "scala." + ], + "enableMarkers": true, + "initialVisibleThreads": 10, + "initialSelectedThreads": 10, + "includeGCThreads": false, + "includeInitialSystemProperty": false, + "includeInitialEnvironmentVariables": false, + "includeSystemProcesses": false, + "ignoredEvents": [ + "jdk.ActiveSetting", + "jdk.ActiveRecording", + "jdk.BooleanFlag", + "jdk.IntFlag", + "jdk.DoubleFlag", + "jdk.LongFlag", + "jdk.NativeLibrary", + "jdk.StringFlag", + "jdk.UnsignedIntFlag", + "jdk.UnsignedLongFlag", + "jdk.InitialSystemProperty", + "jdk.InitialEnvironmentVariable", + "jdk.SystemProcess", + "jdk.ModuleExport", + "jdk.ModuleRequire" + ], + "minRequiredItemsPerThread": 3 + }, + "additionalGradleTargets": [ + { + "targetPrefix": "quarkus", + "optionForVmArgs": "-Djvm.args", + "description": "Example quarkus config, adding profiling arguments via -Djvm.args option to the Gradle task run" + } + ], + "additionalMavenTargets": [ + { + "targetPrefix": "quarkus:", + "optionForVmArgs": "-Djvm.args", + "description": "Example quarkus config, adding profiling arguments via -Djvm.args option to the Maven goal run" + } + ] +} \ No newline at end of file diff --git a/.run/Run Tests.run.xml b/.run/Run Tests.run.xml index b48f65b..2ad121e 100644 --- a/.run/Run Tests.run.xml +++ b/.run/Run Tests.run.xml @@ -1,6 +1,8 @@ +