diff --git a/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.kt b/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.kt index 6fcd759f4..13ed4790a 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.kt @@ -57,6 +57,7 @@ class BaseComponent : ChatComponent { json["text"]?.nullCast()?.let { if (it.indexOf(ProtocolDefinition.TEXT_COMPONENT_FORMATTING_PREFIX) != -1) { + // TODO: That is wrong, clickEvent, hoverEvent is ignored this += ChatComponent.of(it, translator, parent, restrictedMode) parseExtra() return @@ -251,4 +252,21 @@ class BaseComponent : ChatComponent { } throw IllegalArgumentException("Pointer ot of bounds!") } + + override fun trim(): ChatComponent? { + return when { + parts.isEmpty() -> null + parts.size == 1 -> parts.first().trim() + else -> { + val parts: MutableList = mutableListOf() + for (part in this.parts) { + parts += part.trim() ?: continue + } + if (parts.isEmpty()) return null + if (parts.size == 1) parts.first() + if (this.parts.size == parts.size) return this + return BaseComponent(parts) + } + } + } } diff --git a/src/main/java/de/bixilon/minosoft/data/text/ChatComponent.kt b/src/main/java/de/bixilon/minosoft/data/text/ChatComponent.kt index 954927f34..2202d2019 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/ChatComponent.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/ChatComponent.kt @@ -79,6 +79,8 @@ interface ChatComponent { fun cut(length: Int) + fun trim(): ChatComponent? + fun strikethrough(): ChatComponent fun obfuscate(): ChatComponent @@ -103,13 +105,13 @@ interface ChatComponent { } when (raw) { - is Map<*, *> -> return BaseComponent(translator, parent, raw.unsafeCast(), restrictedMode) + is Map<*, *> -> return BaseComponent(translator, parent, raw.unsafeCast(), restrictedMode).trim() ?: EmptyComponent is List<*> -> { val component = BaseComponent() for (part in raw) { - component += of(part, translator, parent, restrictedMode = restrictedMode) + component += of(part, translator, parent, restrictedMode = restrictedMode).trim() ?: continue } - return component + return component.trim() ?: EmptyComponent } } val string = raw.toString() @@ -124,7 +126,7 @@ interface ChatComponent { if (codePoint == '{'.code || codePoint == '['.code) { try { val read: Any = Jackson.MAPPER.readValue(string, Any::class.java) - return of(read, translator, parent, ignoreJson = true, restrictedMode) + return of(read, translator, parent, ignoreJson = true, restrictedMode).trim() ?: EmptyComponent } catch (ignored: JacksonException) { break } @@ -133,7 +135,7 @@ interface ChatComponent { } } - return LegacyComponentReader.parse(parent, string, restrictedMode) + return LegacyComponentReader.parse(parent, string, restrictedMode).trim() ?: EmptyComponent } fun String.chat(): ChatComponent { diff --git a/src/main/java/de/bixilon/minosoft/data/text/EmptyComponent.kt b/src/main/java/de/bixilon/minosoft/data/text/EmptyComponent.kt index 56042a21d..eb0784241 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/EmptyComponent.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/EmptyComponent.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger and contributors + * Copyright (C) 2020-2023 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -32,6 +32,7 @@ object EmptyComponent : ChatComponent { override val length: Int get() = 0 override fun cut(length: Int) = Unit + override fun trim(): ChatComponent? = null override fun strikethrough() = this override fun obfuscate() = this diff --git a/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt b/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt index b60f56f54..390ae3887 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt @@ -245,4 +245,9 @@ open class TextComponent( } return message == other.message && color == other.color && formatting == other.formatting && clickEvent == other.clickEvent && hoverEvent == other.hoverEvent } + + override fun trim(): ChatComponent? { + if (message.isEmpty()) return null + return this + } } diff --git a/src/test/java/de/bixilon/minosoft/data/text/ChatComponentTest.kt b/src/test/java/de/bixilon/minosoft/data/text/ChatComponentTest.kt index 02d8d65d3..44f5083aa 100644 --- a/src/test/java/de/bixilon/minosoft/data/text/ChatComponentTest.kt +++ b/src/test/java/de/bixilon/minosoft/data/text/ChatComponentTest.kt @@ -17,6 +17,8 @@ import de.bixilon.kutil.url.URLUtil.toURL import de.bixilon.minosoft.data.text.ChatComponent.Companion.chat import de.bixilon.minosoft.data.text.events.click.OpenFileClickEvent import de.bixilon.minosoft.data.text.events.click.OpenURLClickEvent +import de.bixilon.minosoft.data.text.events.click.SendMessageClickEvent +import de.bixilon.minosoft.data.text.events.hover.TextHoverEvent import de.bixilon.minosoft.data.text.formatting.color.ChatColors import de.bixilon.minosoft.data.text.formatting.color.RGBColor.Companion.asColor import org.junit.jupiter.api.Test @@ -229,4 +231,23 @@ internal class ChatComponentTest { assertEquals(" Hypixel Network [1.8-1.19]\n LUNAR MAPS COSMETICS | SKYBLOCK 0.17.3", component.message) assertEquals(expected, component) } + + @Test + fun levelingReward() { + val string = """{"text":"§eClick here to view it!","strikethrough":false,"clickEvent":{"action":"run_command","value":"/rewards"},"hoverEvent":{"action":"show_text","value":{"text":"Click to open the §3Hypixel Leveling §emenu","color":"yellow","strikethrough":false}}}""" + val component = ChatComponent.of(string) + + val expected = TextComponent("Click here to view it!") + .color(ChatColors.YELLOW) + .clickEvent(SendMessageClickEvent("/rewards")) + .hoverEvent( + TextHoverEvent(BaseComponent( + TextComponent("Click to open the ").color(ChatColors.YELLOW), + TextComponent("Hypixel Leveling ").color(ChatColors.DARK_AQUA), + TextComponent("menu").color(ChatColors.YELLOW), + ))) + + + assertEquals(expected, component) + } }