chat: component trimming

Should reduce the memory usage and make testing cleaner

It also adds a failing test for leveling rewards on hypixel
This commit is contained in:
Bixilon 2023-02-26 18:10:25 +01:00
parent beb49b6d5c
commit 137c52aba6
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
5 changed files with 53 additions and 6 deletions

View File

@ -57,6 +57,7 @@ class BaseComponent : ChatComponent {
json["text"]?.nullCast<String>()?.let { json["text"]?.nullCast<String>()?.let {
if (it.indexOf(ProtocolDefinition.TEXT_COMPONENT_FORMATTING_PREFIX) != -1) { if (it.indexOf(ProtocolDefinition.TEXT_COMPONENT_FORMATTING_PREFIX) != -1) {
// TODO: That is wrong, clickEvent, hoverEvent is ignored
this += ChatComponent.of(it, translator, parent, restrictedMode) this += ChatComponent.of(it, translator, parent, restrictedMode)
parseExtra() parseExtra()
return return
@ -251,4 +252,21 @@ class BaseComponent : ChatComponent {
} }
throw IllegalArgumentException("Pointer ot of bounds!") 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<ChatComponent> = 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)
}
}
}
} }

View File

@ -79,6 +79,8 @@ interface ChatComponent {
fun cut(length: Int) fun cut(length: Int)
fun trim(): ChatComponent?
fun strikethrough(): ChatComponent fun strikethrough(): ChatComponent
fun obfuscate(): ChatComponent fun obfuscate(): ChatComponent
@ -103,13 +105,13 @@ interface ChatComponent {
} }
when (raw) { when (raw) {
is Map<*, *> -> return BaseComponent(translator, parent, raw.unsafeCast(), restrictedMode) is Map<*, *> -> return BaseComponent(translator, parent, raw.unsafeCast(), restrictedMode).trim() ?: EmptyComponent
is List<*> -> { is List<*> -> {
val component = BaseComponent() val component = BaseComponent()
for (part in raw) { 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() val string = raw.toString()
@ -124,7 +126,7 @@ interface ChatComponent {
if (codePoint == '{'.code || codePoint == '['.code) { if (codePoint == '{'.code || codePoint == '['.code) {
try { try {
val read: Any = Jackson.MAPPER.readValue(string, Any::class.java) 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) { } catch (ignored: JacksonException) {
break 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 { fun String.chat(): ChatComponent {

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * 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. * 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 val length: Int get() = 0
override fun cut(length: Int) = Unit override fun cut(length: Int) = Unit
override fun trim(): ChatComponent? = null
override fun strikethrough() = this override fun strikethrough() = this
override fun obfuscate() = this override fun obfuscate() = this

View File

@ -245,4 +245,9 @@ open class TextComponent(
} }
return message == other.message && color == other.color && formatting == other.formatting && clickEvent == other.clickEvent && hoverEvent == other.hoverEvent 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
}
} }

View File

@ -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.ChatComponent.Companion.chat
import de.bixilon.minosoft.data.text.events.click.OpenFileClickEvent 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.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.ChatColors
import de.bixilon.minosoft.data.text.formatting.color.RGBColor.Companion.asColor import de.bixilon.minosoft.data.text.formatting.color.RGBColor.Companion.asColor
import org.junit.jupiter.api.Test 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(" Hypixel Network [1.8-1.19]\n LUNAR MAPS COSMETICS | SKYBLOCK 0.17.3", component.message)
assertEquals(expected, component) 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)
}
} }