From 0357245e88be4b8cd3d0681340d9a7065361ea74 Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Thu, 24 Oct 2024 14:49:21 +0200 Subject: Add getLegacyFormatString method [no changelog] --- src/main/kotlin/commands/rome.kt | 15 ++- src/main/kotlin/util/textutil.kt | 25 ++++ src/test/kotlin/testutil/ItemResources.kt | 7 ++ src/test/kotlin/util/TextUtilText.kt | 15 +++ src/test/resources/testdata/chat/all-chat.snbt | 162 +++++++++++++++++++++++++ 5 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 src/test/kotlin/util/TextUtilText.kt create mode 100644 src/test/resources/testdata/chat/all-chat.snbt (limited to 'src') diff --git a/src/main/kotlin/commands/rome.kt b/src/main/kotlin/commands/rome.kt index 4f54872..8fcbd77 100644 --- a/src/main/kotlin/commands/rome.kt +++ b/src/main/kotlin/commands/rome.kt @@ -30,6 +30,8 @@ import moe.nea.firmament.util.SkyblockId import moe.nea.firmament.util.accessors.messages import moe.nea.firmament.util.collections.InstanceList import moe.nea.firmament.util.collections.WeakCache +import moe.nea.firmament.util.mc.SNbtFormatter +import moe.nea.firmament.util.unformattedString fun firmamentCommand() = literal("firmament") { @@ -44,7 +46,8 @@ fun firmamentCommand() = literal("firmament") { } thenArgument("property", string()) { property -> suggestsList { - (ManagedConfig.allManagedConfigs.getAll().find { it.name == this[config] } ?: return@suggestsList listOf()) + (ManagedConfig.allManagedConfigs.getAll().find { it.name == this[config] } + ?: return@suggestsList listOf()) .allOptions.entries.asSequence().filter { it.value.handler is BooleanHandler } .map { it.key } .asIterable() @@ -216,6 +219,16 @@ fun firmamentCommand() = literal("firmament") { println(nbt) } } + thenArgument("search", string()) { search -> + thenExecute { + MC.inGameHud.chatHud.messages + .filter { this[search] in it.content.unformattedString } + .forEach { + val nbt = TextCodecs.CODEC.encodeStart(NbtOps.INSTANCE, it.content).orThrow + println(SNbtFormatter.prettify(nbt)) + } + } + } } thenLiteral("sbdata") { thenExecute { diff --git a/src/main/kotlin/util/textutil.kt b/src/main/kotlin/util/textutil.kt index 1cef5d4..252f708 100644 --- a/src/main/kotlin/util/textutil.kt +++ b/src/main/kotlin/util/textutil.kt @@ -3,6 +3,7 @@ package moe.nea.firmament.util import net.minecraft.text.MutableText import net.minecraft.text.PlainTextContent import net.minecraft.text.Text +import net.minecraft.text.TextColor import net.minecraft.text.TranslatableTextContent import net.minecraft.util.Formatting import moe.nea.firmament.Firmament @@ -92,6 +93,30 @@ val Text.unformattedString: String val Text.directLiteralStringContent: String? get() = (this.content as? PlainTextContent)?.string() +fun Text.getLegacyFormatString() = + run { + val sb = StringBuilder() + for (component in iterator()) { + sb.append(component.style.color?.toChatFormatting()?.toString() ?: "§r") + sb.append(component.directLiteralStringContent) + sb.append("§r") + } + sb.toString() + } + +private val textColorLUT = Formatting.entries + .mapNotNull { formatting -> formatting.colorValue?.let { it to formatting } } + .toMap() + +fun TextColor.toChatFormatting(): Formatting? { + return textColorLUT[this.rgb] +} + +fun Text.iterator(): Sequence { + return sequenceOf(this) + siblings.asSequence() + .flatMap { it.iterator() } // TODO: in theory we want to properly inherit styles here +} + fun Text.allSiblings(): List = listOf(this) + siblings.flatMap { it.allSiblings() } fun MutableText.withColor(formatting: Formatting) = this.styled { it.withColor(formatting).withItalic(false) } diff --git a/src/test/kotlin/testutil/ItemResources.kt b/src/test/kotlin/testutil/ItemResources.kt index bd3c438..ee2a322 100644 --- a/src/test/kotlin/testutil/ItemResources.kt +++ b/src/test/kotlin/testutil/ItemResources.kt @@ -4,6 +4,8 @@ import net.minecraft.item.ItemStack import net.minecraft.nbt.NbtCompound import net.minecraft.nbt.NbtOps import net.minecraft.nbt.StringNbtReader +import net.minecraft.text.Text +import net.minecraft.text.TextCodecs import moe.nea.firmament.test.FirmTestBootstrap object ItemResources { @@ -22,6 +24,11 @@ object ItemResources { return StringNbtReader.parse(loadString(path)) } + fun loadText(name: String): Text { + return TextCodecs.CODEC.parse(NbtOps.INSTANCE, loadSNbt("testdata/chat/$name.snbt")) + .getOrThrow { IllegalStateException("Could not load test chat '$name': $it") } + } + fun loadItem(name: String): ItemStack { // TODO: make the load work with enchantments return ItemStack.CODEC.parse(NbtOps.INSTANCE, loadSNbt("testdata/items/$name.snbt")) diff --git a/src/test/kotlin/util/TextUtilText.kt b/src/test/kotlin/util/TextUtilText.kt new file mode 100644 index 0000000..7091f4e --- /dev/null +++ b/src/test/kotlin/util/TextUtilText.kt @@ -0,0 +1,15 @@ +package moe.nea.firmament.test.util + +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import moe.nea.firmament.test.testutil.ItemResources +import moe.nea.firmament.util.getLegacyFormatString + +class TextUtilText { + @Test + fun testThing() { + // TODO: add more tests that are directly validated with 1.8.9 code + val text = ItemResources.loadText("all-chat") + Assertions.assertEquals("§r§r§8[§r§9302§r§8] §r§6♫ §r§b[MVP§r§d+§r§b] lrg89§r§f: test§r", text.getLegacyFormatString()) + } +} diff --git a/src/test/resources/testdata/chat/all-chat.snbt b/src/test/resources/testdata/chat/all-chat.snbt new file mode 100644 index 0000000..15cc2de --- /dev/null +++ b/src/test/resources/testdata/chat/all-chat.snbt @@ -0,0 +1,162 @@ +{ + extra: [ + { + bold: 0b, + color: "#555555", + hoverEvent: { + action: "show_text", + contents: { + clickEvent: { + action: "run_command", + value: "command" + }, + strikethrough: 0b, + text: "§b[MVP§d+§b] lrg89§f + +§7SkyBlock Level: §8[§9302§8] +§7Skill Average: §648.1 + +§7Emblem: §6♫ +§8Harp Master + +§7§8Unlocked for All Harp Songs Perfected. + +§7Perfect Completions: §b37" + } + }, + italic: 0b, + obfuscated: 0b, + strikethrough: 0b, + text: "[", + underlined: 0b + }, + { + bold: 0b, + color: "#5555FF", + hoverEvent: { + action: "show_text", + contents: { + clickEvent: { + action: "run_command", + value: "command" + }, + strikethrough: 0b, + text: "§b[MVP§d+§b] lrg89§f + +§7SkyBlock Level: §8[§9302§8] +§7Skill Average: §648.1 + +§7Emblem: §6♫ +§8Harp Master + +§7§8Unlocked for All Harp Songs Perfected. + +§7Perfect Completions: §b37" + } + }, + italic: 0b, + obfuscated: 0b, + strikethrough: 0b, + text: "302", + underlined: 0b + }, + { + bold: 0b, + color: "#555555", + hoverEvent: { + action: "show_text", + contents: { + clickEvent: { + action: "run_command", + value: "command" + }, + strikethrough: 0b, + text: "§b[MVP§d+§b] lrg89§f + +§7SkyBlock Level: §8[§9302§8] +§7Skill Average: §648.1 + +§7Emblem: §6♫ +§8Harp Master + +§7§8Unlocked for All Harp Songs Perfected. + +§7Perfect Completions: §b37" + } + }, + italic: 0b, + obfuscated: 0b, + strikethrough: 0b, + text: "] ", + underlined: 0b + }, + { + bold: 0b, + color: "#FFAA00", + hoverEvent: { + action: "show_text", + contents: { + clickEvent: { + action: "run_command", + value: "command" + }, + strikethrough: 0b, + text: "§b[MVP§d+§b] lrg89§f + +§7SkyBlock Level: §8[§9302§8] +§7Skill Average: §648.1 + +§7Emblem: §6♫ +§8Harp Master + +§7§8Unlocked for All Harp Songs Perfected. + +§7Perfect Completions: §b37" + } + }, + italic: 0b, + obfuscated: 0b, + strikethrough: 0b, + text: "♫ ", + underlined: 0b + }, + { + bold: 0b, + color: "#55FFFF", + italic: 0b, + obfuscated: 0b, + strikethrough: 0b, + text: "[MVP", + underlined: 0b + }, + { + bold: 0b, + color: "#FF55FF", + italic: 0b, + obfuscated: 0b, + strikethrough: 0b, + text: "+", + underlined: 0b + }, + { + bold: 0b, + color: "#55FFFF", + italic: 0b, + obfuscated: 0b, + strikethrough: 0b, + text: "] lrg89", + underlined: 0b + }, + { + bold: 0b, + color: "#FFFFFF", + italic: 0b, + obfuscated: 0b, + strikethrough: 0b, + text: ": test", + underlined: 0b + } + ], + strikethrough: 0b, + text: "" +} -- cgit