From 29c997adf0cffcbe65e1462a42d9a90397d5a0b6 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 8 Jun 2024 11:56:16 +0200 Subject: [PATCH 01/86] feat: basic component serializing to nbt (without styling) --- settings.gradle.kts | 1 + text-serializer-nbt/build.gradle.kts | 11 ++ .../nbt/NBTComponentSerializer.java | 8 + .../nbt/NBTComponentSerializerImpl.java | 142 ++++++++++++++++++ .../nbt/NBTComponentSerializerOptions.java | 4 + .../serializer/nbt/NBTSerializerOptions.java | 15 ++ 6 files changed, 181 insertions(+) create mode 100644 text-serializer-nbt/build.gradle.kts create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerOptions.java create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java diff --git a/settings.gradle.kts b/settings.gradle.kts index 85bcd13339..6368001ed9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -47,6 +47,7 @@ sequenceOf( "text-serializer-legacy", "text-serializer-plain", "text-serializer-ansi", + "text-serializer-nbt" ).forEach { include("adventure-$it") project(":adventure-$it").projectDir = file(it) diff --git a/text-serializer-nbt/build.gradle.kts b/text-serializer-nbt/build.gradle.kts new file mode 100644 index 0000000000..a7e7bbe317 --- /dev/null +++ b/text-serializer-nbt/build.gradle.kts @@ -0,0 +1,11 @@ +plugins { + id("adventure.common-conventions") +} + +dependencies { + api(libs.option) + api(projects.adventureApi) + api(projects.adventureNbt) +} + +applyJarMetadata("net.kyori.adventure.text.serializer.nbt") diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java new file mode 100644 index 0000000000..4db02d56e6 --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java @@ -0,0 +1,8 @@ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.ComponentSerializer; + +public interface NBTComponentSerializer extends ComponentSerializer { +} diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java new file mode 100644 index 0000000000..b95fc47f72 --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -0,0 +1,142 @@ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; +import net.kyori.adventure.nbt.StringBinaryTag; +import net.kyori.adventure.text.BlockNBTComponent; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.EntityNBTComponent; +import net.kyori.adventure.text.KeybindComponent; +import net.kyori.adventure.text.NBTComponent; +import net.kyori.adventure.text.ScoreComponent; +import net.kyori.adventure.text.SelectorComponent; +import net.kyori.adventure.text.StorageNBTComponent; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.TranslatableComponent; +import net.kyori.adventure.text.TranslationArgument; +import net.kyori.option.OptionState; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +final class NBTComponentSerializerImpl implements NBTComponentSerializer { + + private static final String TEXT = "text"; + + private static final String TRANSLATE_KEY = "translate"; + private static final String TRANSLATE_WITH = "with"; + private static final String TRANSLATE_FALLBACK = "fallback"; + + private static final String KEYBIND = "keybind"; + + private static final String SCORE = "score"; + private static final String SCORE_NAME = "name"; + private static final String SCORE_OBJECTIVE = "objective"; + @Deprecated + private static final String SCORE_VALUE = "value"; + + private static final String SELECTOR = "selector"; + private static final String SELECTOR_SEPARATOR = "separator"; + + private static final String NBT = "nbt"; + private static final String NBT_INTERPRET = "interpret"; + private static final String NBT_SEPARATOR = "separator"; + private static final String NBT_BLOCK = "block"; + private static final String NBT_ENTITY = "entity"; + private static final String NBT_STORAGE = "storage"; + + private final OptionState flags; + + @Override + public @NotNull Component deserialize(@NotNull BinaryTag input) { + return null; + } + + @Override + public @NotNull BinaryTag serialize(@NotNull Component component) { + if (this.flags.value(NBTSerializerOptions.EMIT_COMPACT_TEXT_COMPONENT) && component instanceof TextComponent + && !component.hasStyling()) { + return StringBinaryTag.stringBinaryTag(((TextComponent) component).content()); + } + + CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder(); + + if (component instanceof TextComponent) { + builder.putString(TEXT, ((TextComponent) component).content()); + } else if (component instanceof TranslatableComponent) { + TranslatableComponent translatable = (TranslatableComponent) component; + builder.putString(TRANSLATE_KEY, translatable.key()); + + List arguments = translatable.arguments(); + + if (!arguments.isEmpty()) { + List argumentsTags = new ArrayList<>(); + + for (TranslationArgument argument : arguments) { + argumentsTags.add(this.serialize(argument.asComponent())); + } + + builder.put(TRANSLATE_WITH, ListBinaryTag.from(argumentsTags)); + } + + + String fallback = translatable.fallback(); + if (fallback != null) { + builder.putString(TRANSLATE_FALLBACK, fallback); + } + } else if (component instanceof KeybindComponent) { + builder.putString(KEYBIND, ((KeybindComponent) component).keybind()); + } else if (component instanceof ScoreComponent) { + ScoreComponent score = (ScoreComponent) component; + + CompoundBinaryTag.Builder scoreBuilder = CompoundBinaryTag.builder() + .putString(SCORE_NAME, score.name()) + .putString(SCORE_OBJECTIVE, score.objective()); + + String value = score.value(); + if (value != null) { + scoreBuilder.putString(SCORE_VALUE, value); + } + + builder.put(SCORE, scoreBuilder.build()); + } else if (component instanceof SelectorComponent) { + SelectorComponent selector = (SelectorComponent) component; + builder.putString(SELECTOR, selector.pattern()); + + Component separator = selector.separator(); + if (separator != null) { + builder.put(SELECTOR_SEPARATOR, serialize(separator)); + } + } else if (component instanceof NBTComponent) { + NBTComponent nbt = (NBTComponent) component; + builder.putString(NBT, nbt.nbtPath()); + builder.putBoolean(NBT_INTERPRET, nbt.interpret()); + + Component separator = nbt.separator(); + if (separator != null) { + builder.put(NBT_SEPARATOR, serialize(separator)); + } + + if (nbt instanceof BlockNBTComponent) { + builder.putString(NBT_BLOCK, ((BlockNBTComponent) nbt).pos().asString()); + } else if (nbt instanceof EntityNBTComponent) { + builder.putString(NBT_ENTITY, ((EntityNBTComponent) nbt).selector()); + } else if (nbt instanceof StorageNBTComponent) { + builder.putString(NBT_STORAGE, ((StorageNBTComponent) nbt).storage().asString()) + } else { + throw notSureHowToSerialize(component); + } + } else { + throw notSureHowToSerialize(component); + } + + + return builder.build(); + } + + private static IllegalArgumentException notSureHowToSerialize(final Component component) { + return new IllegalArgumentException("Don't know how to serialize " + component + " as a Component"); + } +} diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerOptions.java new file mode 100644 index 0000000000..adadbd6d3b --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerOptions.java @@ -0,0 +1,4 @@ +package net.kyori.adventure.text.serializer.nbt; + +public class NBTComponentSerializerOptions { +} diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java new file mode 100644 index 0000000000..a8087323cf --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -0,0 +1,15 @@ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.option.Option; + +public final class NBTSerializerOptions { + + public static final Option EMIT_COMPACT_TEXT_COMPONENT = Option.booleanOption(key("emit/compact_text_component"), true); + + private NBTSerializerOptions() { + } + + private static String key(final String value) { + return "adventure:nbt/" + value; + } +} From 34a381a95765d89c7ba48cb67b96f95d5d9d4fc1 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 8 Jun 2024 13:03:41 +0200 Subject: [PATCH 02/86] feat: serialize component children and types --- .../nbt/NBTComponentSerializerImpl.java | 41 +++++++++++++++++++ .../nbt/NBTComponentSerializerOptions.java | 4 -- .../serializer/nbt/NBTSerializerOptions.java | 1 + 3 files changed, 42 insertions(+), 4 deletions(-) delete mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerOptions.java diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index b95fc47f72..61f1e35a04 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -23,6 +23,17 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { + private static final String TYPE = "type"; + + private static final String TYPE_TEXT = "text"; + private static final String TYPE_TRANSLATABLE = "translatable"; + private static final String TYPE_KEYBIND = "keybind"; + private static final String TYPE_SCORE = "score"; + private static final String TYPE_SELECTOR = "selector"; + private static final String TYPE_NBT = "nbt"; + + private static final String EXTRA = "extra"; + private static final String TEXT = "text"; private static final String TRANSLATE_KEY = "translate"; @@ -49,6 +60,10 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { private final OptionState flags; + NBTComponentSerializerImpl(@NotNull OptionState flags) { + this.flags = flags; + } + @Override public @NotNull Component deserialize(@NotNull BinaryTag input) { return null; @@ -64,8 +79,11 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder(); if (component instanceof TextComponent) { + this.writeComponentType(TYPE_TEXT, builder); builder.putString(TEXT, ((TextComponent) component).content()); } else if (component instanceof TranslatableComponent) { + this.writeComponentType(TYPE_TRANSLATABLE, builder); + TranslatableComponent translatable = (TranslatableComponent) component; builder.putString(TRANSLATE_KEY, translatable.key()); @@ -87,8 +105,10 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { builder.putString(TRANSLATE_FALLBACK, fallback); } } else if (component instanceof KeybindComponent) { + this.writeComponentType(TYPE_KEYBIND, builder); builder.putString(KEYBIND, ((KeybindComponent) component).keybind()); } else if (component instanceof ScoreComponent) { + this.writeComponentType(TYPE_SCORE, builder); ScoreComponent score = (ScoreComponent) component; CompoundBinaryTag.Builder scoreBuilder = CompoundBinaryTag.builder() @@ -102,6 +122,8 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { builder.put(SCORE, scoreBuilder.build()); } else if (component instanceof SelectorComponent) { + this.writeComponentType(TYPE_SELECTOR, builder); + SelectorComponent selector = (SelectorComponent) component; builder.putString(SELECTOR, selector.pattern()); @@ -110,6 +132,8 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { builder.put(SELECTOR_SEPARATOR, serialize(separator)); } } else if (component instanceof NBTComponent) { + this.writeComponentType(TYPE_NBT, builder); + NBTComponent nbt = (NBTComponent) component; builder.putString(NBT, nbt.nbtPath()); builder.putBoolean(NBT_INTERPRET, nbt.interpret()); @@ -132,10 +156,27 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { throw notSureHowToSerialize(component); } + List children = component.children(); + + if (!children.isEmpty()) { + List serializedChildren = new ArrayList<>(); + + for (Component child : children) { + serializedChildren.add(this.serialize(child)); + } + + builder.put(EXTRA, ListBinaryTag.from(serializedChildren)); + } return builder.build(); } + private void writeComponentType(final String componentType, final CompoundBinaryTag.Builder builder) { + if (this.flags.value(NBTSerializerOptions.SERIALIZE_COMPONENT_TYPES)) { + builder.putString(TYPE, componentType); + } + } + private static IllegalArgumentException notSureHowToSerialize(final Component component) { return new IllegalArgumentException("Don't know how to serialize " + component + " as a Component"); } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerOptions.java deleted file mode 100644 index adadbd6d3b..0000000000 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerOptions.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.kyori.adventure.text.serializer.nbt; - -public class NBTComponentSerializerOptions { -} diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index a8087323cf..144941edde 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -5,6 +5,7 @@ public final class NBTSerializerOptions { public static final Option EMIT_COMPACT_TEXT_COMPONENT = Option.booleanOption(key("emit/compact_text_component"), true); + public static final Option SERIALIZE_COMPONENT_TYPES = Option.booleanOption(key("serialize/component-types"), true); private NBTSerializerOptions() { } From 5bb4c5a4b686a641bbf8be1886fc88855bf91e42 Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 9 Jun 2024 11:11:31 +0200 Subject: [PATCH 03/86] misc: i'm too lazy to name this commit, but it fixes and adds a lot of stuff after spigotting (looking at nms code decompiled and mapped with build tools) --- text-serializer-nbt/build.gradle.kts | 1 + .../serializer/nbt/ClickEventSerializer.java | 90 ++++++++++++++++++ .../serializer/nbt/HoverEventSerializer.java | 91 +++++++++++++++++++ .../nbt/NBTComponentSerializerImpl.java | 87 +++++++++++++++++- .../serializer/nbt/NBTDataComponentValue.java | 11 +++ .../nbt/NBTDataComponentValueImpl.java | 18 ++++ 6 files changed, 296 insertions(+), 2 deletions(-) create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java diff --git a/text-serializer-nbt/build.gradle.kts b/text-serializer-nbt/build.gradle.kts index a7e7bbe317..c0da57576d 100644 --- a/text-serializer-nbt/build.gradle.kts +++ b/text-serializer-nbt/build.gradle.kts @@ -6,6 +6,7 @@ dependencies { api(libs.option) api(projects.adventureApi) api(projects.adventureNbt) + api(projects.adventureTextSerializerGson) } applyJarMetadata("net.kyori.adventure.text.serializer.nbt") diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java new file mode 100644 index 0000000000..77579d17b7 --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java @@ -0,0 +1,90 @@ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.text.event.ClickEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +final class ClickEventSerializer { + + private static final String ACTION = "action"; + private static final String VALUE = "value"; + + private static final String CLICK_EVENT_OPEN_URL = "open_url"; + private static final String CLICK_EVENT_OPEN_FILE = "open_file"; + private static final String CLICK_EVENT_RUN_COMMAND = "run_command"; + private static final String CLICK_EVENT_SUGGEST_COMMAND = "suggest_command"; + private static final String CLICK_EVENT_CHANGE_PAGE = "change_page"; + private static final String CLICK_EVENT_COPY_TO_CLIPBOARD = "copy_to_clipboard"; + + private ClickEventSerializer() { + } + + static @Nullable ClickEvent deserialize(@NotNull CompoundBinaryTag tag) { + ClickEvent.Action action; + String actionString = tag.getString(ACTION); + + if (actionString.isEmpty()) { + return null; + } + + switch (actionString) { + case CLICK_EVENT_OPEN_URL: + action = ClickEvent.Action.OPEN_URL; + break; + case CLICK_EVENT_OPEN_FILE: + action = ClickEvent.Action.OPEN_FILE; + break; + case CLICK_EVENT_RUN_COMMAND: + action = ClickEvent.Action.RUN_COMMAND; + break; + case CLICK_EVENT_SUGGEST_COMMAND: + action = ClickEvent.Action.SUGGEST_COMMAND; + break; + case CLICK_EVENT_CHANGE_PAGE: + action = ClickEvent.Action.CHANGE_PAGE; + break; + case CLICK_EVENT_COPY_TO_CLIPBOARD: + action = ClickEvent.Action.COPY_TO_CLIPBOARD; + break; + default: + return null; + } + + return ClickEvent.clickEvent(action, tag.getString(VALUE)); + } + + static @NotNull CompoundBinaryTag serialize(@NotNull ClickEvent event) { + ClickEvent.Action action = event.action(); + String actionString; + + switch (action) { + case OPEN_URL: + actionString = CLICK_EVENT_OPEN_URL; + break; + case OPEN_FILE: + actionString = CLICK_EVENT_OPEN_FILE; + break; + case RUN_COMMAND: + actionString = CLICK_EVENT_RUN_COMMAND; + break; + case SUGGEST_COMMAND: + actionString = CLICK_EVENT_SUGGEST_COMMAND; + break; + case CHANGE_PAGE: + actionString = CLICK_EVENT_CHANGE_PAGE; + break; + case COPY_TO_CLIPBOARD: + actionString = CLICK_EVENT_COPY_TO_CLIPBOARD; + break; + default: + // Never called, but needed for proper compilation + throw new IllegalStateException("Unknown click event action: " + action); + } + + return CompoundBinaryTag.builder() + .putString(ACTION, actionString) + .putString(VALUE, event.value()) + .build(); + } +} diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java new file mode 100644 index 0000000000..24ab796a60 --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -0,0 +1,91 @@ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.StringBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.HoverEvent; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; + +final class HoverEventSerializer { + + private static final String HOVER_EVENT_ACTION = "action"; + private static final String HOVER_EVENT_CONTENTS = "contents"; + + private static final String HOVER_EVENT_SHOW_TEXT = "show_text"; + private static final String HOVER_EVENT_SHOW_ITEM = "show_item"; + private static final String HOVER_EVENT_SHOW_ENTITY = "show_entity"; + @Deprecated + private static final String HOVER_EVENT_SHOW_ACHIEVEMENT = "show_achievement"; + + private static final String SHOW_ITEM_ID = "id"; + private static final String SHOW_ITEM_COUNT = "count"; + private static final String SHOW_ITEM_COMPONENTS = "components"; + + private static final String SHOW_ENTITY_TYPE = "type"; + private static final String SHOW_ENTITY_ID = "id"; + private static final String SHOW_ENTITY_NAME = "name"; + + private HoverEventSerializer() { + } + + static @NotNull CompoundBinaryTag serialize(@NotNull HoverEvent event, @NotNull NBTComponentSerializerImpl serializer) { + HoverEvent.Action action = event.action(); + + BinaryTag tag; + String actionString; + + if (action == HoverEvent.Action.SHOW_TEXT) { + tag = serializer.serialize((Component) event.value()); + actionString = HOVER_EVENT_SHOW_TEXT; + } else if (action == HoverEvent.Action.SHOW_ITEM) { + HoverEvent.ShowItem item = (HoverEvent.ShowItem) event.value(); + + CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() + .putString(SHOW_ITEM_ID, item.item().asString()) + .putInt(SHOW_ITEM_COUNT, item.count()); + + Map components = item.dataComponentsAs(NBTDataComponentValue.class); + + if (!components.isEmpty()) { + CompoundBinaryTag.Builder dataComponentsBuilder = CompoundBinaryTag.builder(); + + for (Map.Entry entry : components.entrySet()) { + dataComponentsBuilder.put(entry.getKey().asString(), entry.getValue().binaryTag()); + } + + builder.put(SHOW_ITEM_COMPONENTS, dataComponentsBuilder.build()); + } + + tag = builder.build(); + actionString = HOVER_EVENT_SHOW_ITEM; + } else if (action == HoverEvent.Action.SHOW_ENTITY) { + HoverEvent.ShowEntity item = (HoverEvent.ShowEntity) event.value(); + + CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() + .putString(SHOW_ENTITY_TYPE, item.type().asString()) + .putString(SHOW_ENTITY_ID, item.id().toString()); + + Component customName = item.name(); + if (customName != null) { + builder.put(SHOW_ENTITY_NAME, serializer.serialize(customName)); + } + + tag = builder.build(); + actionString = HOVER_EVENT_SHOW_ENTITY; + } else if (action == HoverEvent.Action.SHOW_ACHIEVEMENT) { + tag = StringBinaryTag.stringBinaryTag((String) event.value()); + actionString = HOVER_EVENT_SHOW_ACHIEVEMENT; + } else { + throw new IllegalArgumentException("Don't know how to serialize " + event + " as a HoverEvent"); + } + + return CompoundBinaryTag.builder() + .putString(HOVER_EVENT_ACTION, actionString) + .put(HOVER_EVENT_CONTENTS, tag) + .build(); + } +} diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 61f1e35a04..fc2282927c 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -1,5 +1,6 @@ package net.kyori.adventure.text.serializer.nbt; +import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.ListBinaryTag; @@ -15,6 +16,11 @@ import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TranslatableComponent; import net.kyori.adventure.text.TranslationArgument; +import net.kyori.adventure.text.event.ClickEvent; +import net.kyori.adventure.text.event.HoverEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.TextDecoration; import net.kyori.option.OptionState; import org.jetbrains.annotations.NotNull; @@ -34,6 +40,17 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { private static final String EXTRA = "extra"; + private static final String COLOR = "color"; + private static final String BOLD = "bold"; + private static final String ITALIC = "italic"; + private static final String UNDERLINED = "underlined"; + private static final String STRIKETHROUGH = "strikethrough"; + private static final String OBFUSCATED = "obfuscated"; + private static final String FONT = "font"; + private static final String INSERTION = "insertion"; + private static final String CLICK_EVENT = "clickEvent"; + private static final String HOVER_EVENT = "hoverEvent"; + private static final String TEXT = "text"; private static final String TRANSLATE_KEY = "translate"; @@ -75,9 +92,75 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { && !component.hasStyling()) { return StringBinaryTag.stringBinaryTag(((TextComponent) component).content()); } + return writeCompoundComponent(component); + } + private @NotNull CompoundBinaryTag writeCompoundComponent(@NotNull Component component) { CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder(); + TextColor color = component.color(); + + if (color != null) { + if (color instanceof NamedTextColor) { + builder.putString(COLOR, color.toString()); + } else { + builder.putString(COLOR, color.asHexString()); + } + } + + component.decorations().forEach((decoration, state) -> { + if (state != TextDecoration.State.NOT_SET) { + String decorationName; + + switch (decoration) { + case OBFUSCATED: + decorationName = OBFUSCATED; + break; + case BOLD: + decorationName = BOLD; + break; + case STRIKETHROUGH: + decorationName = STRIKETHROUGH; + break; + case UNDERLINED: + decorationName = UNDERLINED; + break; + case ITALIC: + decorationName = ITALIC; + break; + default: + // Never called, but needed for proper compilation + throw new IllegalStateException("Unknown text decoration: " + decoration); + } + + builder.putBoolean(decorationName, state == TextDecoration.State.TRUE); + } + }); + + Key font = component.font(); + + if (font != null) { + builder.putString(FONT, font.asString()); + } + + String insertion = component.insertion(); + + if (insertion != null) { + builder.putString(INSERTION, insertion); + } + + ClickEvent clickEvent = component.clickEvent(); + + if (clickEvent != null) { + builder.put(CLICK_EVENT, ClickEventSerializer.serialize(clickEvent)); + } + + HoverEvent hoverEvent = component.hoverEvent(); + + if (hoverEvent != null) { + builder.put(HOVER_EVENT, HoverEventSerializer.serialize(hoverEvent, this)); + } + if (component instanceof TextComponent) { this.writeComponentType(TYPE_TEXT, builder); builder.putString(TEXT, ((TextComponent) component).content()); @@ -93,7 +176,7 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { List argumentsTags = new ArrayList<>(); for (TranslationArgument argument : arguments) { - argumentsTags.add(this.serialize(argument.asComponent())); + argumentsTags.add(this.writeCompoundComponent(argument.asComponent())); } builder.put(TRANSLATE_WITH, ListBinaryTag.from(argumentsTags)); @@ -148,7 +231,7 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { } else if (nbt instanceof EntityNBTComponent) { builder.putString(NBT_ENTITY, ((EntityNBTComponent) nbt).selector()); } else if (nbt instanceof StorageNBTComponent) { - builder.putString(NBT_STORAGE, ((StorageNBTComponent) nbt).storage().asString()) + builder.putString(NBT_STORAGE, ((StorageNBTComponent) nbt).storage().asString()); } else { throw notSureHowToSerialize(component); } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java new file mode 100644 index 0000000000..6778cf1471 --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java @@ -0,0 +1,11 @@ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.text.event.DataComponentValue; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +@ApiStatus.NonExtendable +public interface NBTDataComponentValue extends DataComponentValue { + @NotNull BinaryTag binaryTag(); +} diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java new file mode 100644 index 0000000000..48b600aa25 --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java @@ -0,0 +1,18 @@ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.BinaryTag; +import org.jetbrains.annotations.NotNull; + +final class NBTDataComponentValueImpl implements NBTDataComponentValue { + + private final BinaryTag binaryTag; + + NBTDataComponentValueImpl(@NotNull BinaryTag binaryTag) { + this.binaryTag = binaryTag; + } + + @Override + public @NotNull BinaryTag binaryTag() { + return this.binaryTag; + } +} From 97809cf503d98eeed54e418001d4217c274a3467 Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 9 Jun 2024 11:17:36 +0200 Subject: [PATCH 04/86] chore: remove useless gson serializer --- text-serializer-nbt/build.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/text-serializer-nbt/build.gradle.kts b/text-serializer-nbt/build.gradle.kts index c0da57576d..a7e7bbe317 100644 --- a/text-serializer-nbt/build.gradle.kts +++ b/text-serializer-nbt/build.gradle.kts @@ -6,7 +6,6 @@ dependencies { api(libs.option) api(projects.adventureApi) api(projects.adventureNbt) - api(projects.adventureTextSerializerGson) } applyJarMetadata("net.kyori.adventure.text.serializer.nbt") From 1c750c32931e0102d0823807fd7ced77987c2592 Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 9 Jun 2024 12:52:55 +0200 Subject: [PATCH 05/86] chore: add support for legacy item tags --- .../serializer/nbt/HoverEventSerializer.java | 11 +++++- .../nbt/NBTComponentSerializerImpl.java | 4 +++ .../serializer/nbt/NBTDataComponentValue.java | 4 +++ .../serializer/nbt/NBTSerializerOptions.java | 34 +++++++++++++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java index 24ab796a60..8567ae9b70 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -4,6 +4,7 @@ import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.StringBinaryTag; +import net.kyori.adventure.nbt.api.BinaryTagHolder; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.HoverEvent; import org.jetbrains.annotations.NotNull; @@ -24,6 +25,8 @@ final class HoverEventSerializer { private static final String SHOW_ITEM_ID = "id"; private static final String SHOW_ITEM_COUNT = "count"; private static final String SHOW_ITEM_COMPONENTS = "components"; + @Deprecated + private static final String SHOW_ITEM_TAG = "tag"; private static final String SHOW_ENTITY_TYPE = "type"; private static final String SHOW_ENTITY_ID = "id"; @@ -49,8 +52,9 @@ private HoverEventSerializer() { .putInt(SHOW_ITEM_COUNT, item.count()); Map components = item.dataComponentsAs(NBTDataComponentValue.class); + NBTSerializerOptions.ShowItemHoverDataMode dataMode = serializer.flags().value(NBTSerializerOptions.SHOW_ITEM_HOVER_DATA_MODE); - if (!components.isEmpty()) { + if (!components.isEmpty() && dataMode != NBTSerializerOptions.ShowItemHoverDataMode.EMIT_LEGACY_NBT) { CompoundBinaryTag.Builder dataComponentsBuilder = CompoundBinaryTag.builder(); for (Map.Entry entry : components.entrySet()) { @@ -58,6 +62,11 @@ private HoverEventSerializer() { } builder.put(SHOW_ITEM_COMPONENTS, dataComponentsBuilder.build()); + } else if (dataMode != NBTSerializerOptions.ShowItemHoverDataMode.EMIT_DATA_COMPONENTS) { + BinaryTagHolder holder = item.nbt(); + if (holder != null) { + builder.putString(SHOW_ITEM_TAG, holder.string()); + } } tag = builder.build(); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index fc2282927c..791ccf2f84 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -254,6 +254,10 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { return builder.build(); } + @NotNull OptionState flags() { + return this.flags; + } + private void writeComponentType(final String componentType, final CompoundBinaryTag.Builder builder) { if (this.flags.value(NBTSerializerOptions.SERIALIZE_COMPONENT_TYPES)) { builder.putString(TYPE, componentType); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java index 6778cf1471..e736965543 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java @@ -8,4 +8,8 @@ @ApiStatus.NonExtendable public interface NBTDataComponentValue extends DataComponentValue { @NotNull BinaryTag binaryTag(); + + static @NotNull NBTDataComponentValue nbtDataComponentValue(@NotNull BinaryTag binaryTag) { + return new NBTDataComponentValueImpl(binaryTag); + } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index 144941edde..b5d90db76e 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -5,6 +5,14 @@ public final class NBTSerializerOptions { public static final Option EMIT_COMPACT_TEXT_COMPONENT = Option.booleanOption(key("emit/compact_text_component"), true); + + /** + * How to emit the item data on {@code show_item} hover events. + * + * @since 4.18.0 + */ + public static final Option SHOW_ITEM_HOVER_DATA_MODE = Option.enumOption(key("emit/show_item_hover_data"), ShowItemHoverDataMode.class, ShowItemHoverDataMode.EMIT_EITHER); + public static final Option SERIALIZE_COMPONENT_TYPES = Option.booleanOption(key("serialize/component-types"), true); private NBTSerializerOptions() { @@ -13,4 +21,30 @@ private NBTSerializerOptions() { private static String key(final String value) { return "adventure:nbt/" + value; } + + /** + * Configure how to emit show_item hovers. + * + * @since 4.18.0 + */ + public enum ShowItemHoverDataMode { + /** + * Only emit the pre-1.20.5 item nbt. + * + * @since 4.18.0 + */ + EMIT_LEGACY_NBT, + /** + * Only emit modern data components. + * + * @since 4.18.0 + */ + EMIT_DATA_COMPONENTS, + /** + * Emit whichever of legacy or modern data the item has. + * + * @since 4.18.0 + */ + EMIT_EITHER, + } } From 92ea88106aa846ed9c1ab3d3c2f1b81f7b87c502 Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 9 Jun 2024 17:09:16 +0200 Subject: [PATCH 06/86] feat: component deserialization --- .../serializer/nbt/HoverEventSerializer.java | 74 ++++++- .../nbt/NBTComponentSerializerImpl.java | 203 +++++++++++++++++- 2 files changed, 268 insertions(+), 9 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java index 8567ae9b70..1b11ddd7d0 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -6,10 +6,13 @@ import net.kyori.adventure.nbt.StringBinaryTag; import net.kyori.adventure.nbt.api.BinaryTagHolder; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.DataComponentValue; import net.kyori.adventure.text.event.HoverEvent; import org.jetbrains.annotations.NotNull; +import java.util.HashMap; import java.util.Map; +import java.util.UUID; final class HoverEventSerializer { @@ -35,14 +38,73 @@ final class HoverEventSerializer { private HoverEventSerializer() { } + static @NotNull HoverEvent deserialize(@NotNull CompoundBinaryTag compound, @NotNull NBTComponentSerializerImpl serializer) { + String actionString = compound.getString(HOVER_EVENT_ACTION); + HoverEvent.Action action = HoverEvent.Action.NAMES.valueOrThrow(actionString); + Class actionType = action.type(); + + BinaryTag contents = compound.get(HOVER_EVENT_CONTENTS); + if (contents == null) { + throw new IllegalArgumentException("The hover event doesn't contain any contents"); + } + + if (Component.class.isAssignableFrom(actionType)) { + return HoverEvent.showText(serializer.deserialize(contents)); + } else if (HoverEvent.ShowItem.class.isAssignableFrom(actionType)) { + CompoundBinaryTag showItemContents = (CompoundBinaryTag) contents; + + Key itemId = Key.key(showItemContents.getString(SHOW_ITEM_ID)); + int itemCount = showItemContents.getInt(SHOW_ITEM_COUNT); + + BinaryTag components = showItemContents.get(SHOW_ITEM_COMPONENTS); + BinaryTag tag = showItemContents.get(SHOW_ITEM_TAG); + + if (components != null) { + CompoundBinaryTag componentsCompound = (CompoundBinaryTag) components; + Map componentValues = new HashMap<>(); + + for (String string : componentsCompound.keySet()) { + BinaryTag value = componentsCompound.get(string); + if (value == null) continue; + componentValues.put(Key.key(string), NBTDataComponentValue.nbtDataComponentValue(value)); + } + + return HoverEvent.showItem(itemId, itemCount, componentValues); + } else if (tag != null) { + BinaryTagHolder holder = BinaryTagHolder.binaryTagHolder(((StringBinaryTag) tag).value()); + return HoverEvent.showItem(itemId, itemCount, holder); + } else { + return HoverEvent.showItem(itemId, itemCount); + } + } else if (HoverEvent.ShowEntity.class.isAssignableFrom(actionType)) { + CompoundBinaryTag showEntityContents = (CompoundBinaryTag) contents; + + Key entityType = Key.key(showEntityContents.getString(SHOW_ENTITY_TYPE)); + UUID entityId = UUID.fromString(showEntityContents.getString(SHOW_ENTITY_ID)); + + BinaryTag entityName = showEntityContents.get(SHOW_ENTITY_NAME); + + if (entityName != null) { + return HoverEvent.showEntity(entityType, entityId, serializer.deserialize(entityName)); + } else { + return HoverEvent.showEntity(entityType, entityId); + } + } else if (String.class.isAssignableFrom(actionType)) { + return HoverEvent.showAchievement(((StringBinaryTag) contents).value()); + } else { + // Never called, but needed for proper compilation + throw new IllegalArgumentException("Unknown hover event"); + } + } + static @NotNull CompoundBinaryTag serialize(@NotNull HoverEvent event, @NotNull NBTComponentSerializerImpl serializer) { HoverEvent.Action action = event.action(); - BinaryTag tag; + BinaryTag contents; String actionString; if (action == HoverEvent.Action.SHOW_TEXT) { - tag = serializer.serialize((Component) event.value()); + contents = serializer.serialize((Component) event.value()); actionString = HOVER_EVENT_SHOW_TEXT; } else if (action == HoverEvent.Action.SHOW_ITEM) { HoverEvent.ShowItem item = (HoverEvent.ShowItem) event.value(); @@ -69,7 +131,7 @@ private HoverEventSerializer() { } } - tag = builder.build(); + contents = builder.build(); actionString = HOVER_EVENT_SHOW_ITEM; } else if (action == HoverEvent.Action.SHOW_ENTITY) { HoverEvent.ShowEntity item = (HoverEvent.ShowEntity) event.value(); @@ -83,10 +145,10 @@ private HoverEventSerializer() { builder.put(SHOW_ENTITY_NAME, serializer.serialize(customName)); } - tag = builder.build(); + contents = builder.build(); actionString = HOVER_EVENT_SHOW_ENTITY; } else if (action == HoverEvent.Action.SHOW_ACHIEVEMENT) { - tag = StringBinaryTag.stringBinaryTag((String) event.value()); + contents = StringBinaryTag.stringBinaryTag((String) event.value()); actionString = HOVER_EVENT_SHOW_ACHIEVEMENT; } else { throw new IllegalArgumentException("Don't know how to serialize " + event + " as a HoverEvent"); @@ -94,7 +156,7 @@ private HoverEventSerializer() { return CompoundBinaryTag.builder() .putString(HOVER_EVENT_ACTION, actionString) - .put(HOVER_EVENT_CONTENTS, tag) + .put(HOVER_EVENT_CONTENTS, contents) .build(); } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 791ccf2f84..8041a614cc 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -2,6 +2,8 @@ import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.BinaryTagTypes; +import net.kyori.adventure.nbt.ByteBinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.ListBinaryTag; import net.kyori.adventure.nbt.StringBinaryTag; @@ -19,6 +21,7 @@ import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextDecoration; import net.kyori.option.OptionState; @@ -83,13 +86,199 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { @Override public @NotNull Component deserialize(@NotNull BinaryTag input) { - return null; + if (input instanceof StringBinaryTag) { + return Component.text(((StringBinaryTag) input).value()); + } + + if (!(input instanceof CompoundBinaryTag)) { + throw new IllegalArgumentException("The input isn't a compound or string binary tag"); + } + + CompoundBinaryTag compound = (CompoundBinaryTag) input; + String type = compound.getString(TYPE); + + if (type.isEmpty()) { + if (compound.get(TEXT) != null) { + type = TYPE_TEXT; + } else if (compound.get(TRANSLATE_KEY) != null) { + type = TYPE_TRANSLATABLE; + } else if (compound.get(KEYBIND) != null) { + type = TYPE_KEYBIND; + } else if (compound.get(SCORE) != null) { + type = TYPE_SCORE; + } else if (compound.get(SELECTOR) != null) { + type = TYPE_SELECTOR; + } else if (compound.get(NBT) != null && (compound.get(NBT_BLOCK) != null + || compound.get(NBT_STORAGE) != null || compound.get(NBT_ENTITY) != null)) { + type = TYPE_NBT; + } else { + throw new IllegalArgumentException("Could not guess type of the component"); + } + } + + Style.Builder styleBuilder = Style.style(); + + String colorString = compound.getString(COLOR); + if (!colorString.isEmpty()) { + if (colorString.startsWith(TextColor.HEX_PREFIX)) { + styleBuilder.color(TextColor.fromHexString(colorString)); + } else { + styleBuilder.color(NamedTextColor.NAMES.value(colorString)); + } + } + + styleBuilder.decoration(TextDecoration.BOLD, readOptionalState(BOLD, compound)) + .decoration(TextDecoration.ITALIC, readOptionalState(ITALIC, compound)) + .decoration(TextDecoration.UNDERLINED, readOptionalState(UNDERLINED, compound)) + .decoration(TextDecoration.STRIKETHROUGH, readOptionalState(STRIKETHROUGH, compound)) + .decoration(TextDecoration.OBFUSCATED, readOptionalState(OBFUSCATED, compound)); + + String fontString = compound.getString(FONT); + if (!fontString.isEmpty()) { + styleBuilder.font(Key.key(fontString)); + } + + BinaryTag binaryInsertion = compound.get(INSERTION); + if (binaryInsertion != null) { + styleBuilder.insertion(((StringBinaryTag) binaryInsertion).value()); + } + + BinaryTag binaryClickEvent = compound.get(CLICK_EVENT); + if (binaryClickEvent != null) { + styleBuilder.clickEvent(ClickEventSerializer.deserialize((CompoundBinaryTag) binaryClickEvent)); + } + + BinaryTag binaryHoverEvent = compound.get(HOVER_EVENT); + if (binaryHoverEvent != null) { + styleBuilder.hoverEvent(HoverEventSerializer.deserialize((CompoundBinaryTag) binaryHoverEvent, this)); + } + + Style style = styleBuilder.build(); + + List children = new ArrayList<>(); + ListBinaryTag binaryChildren = compound.getList(EXTRA); + binaryChildren.forEach(child -> children.add(this.deserialize(child))); + + switch (type) { + case TYPE_TEXT: + return Component.text() + .content(compound.getString(TEXT)) + .style(style) + .append(children) + .build(); + case TYPE_TRANSLATABLE: + ListBinaryTag binaryArguments = compound.getList(TRANSLATE_WITH, BinaryTagTypes.STRING); + String fallback = compound.getString(TRANSLATE_FALLBACK); + + if (fallback.isEmpty()) { + fallback = null; + } + + List arguments = new ArrayList<>(); + for (BinaryTag argument : binaryArguments) { + arguments.add(this.deserialize(argument)); + } + + return Component.translatable() + .key(compound.getString(TRANSLATE_KEY)) + .fallback(fallback) + .arguments(arguments) + .style(style) + .append(children) + .build(); + case TYPE_KEYBIND: + return Component.keybind() + .keybind(compound.getString(KEYBIND)) + .style(style) + .append(children) + .build(); + case TYPE_SCORE: + CompoundBinaryTag binaryScore = compound.getCompound(SCORE); + + String scoreName = binaryScore.getString(SCORE_NAME); + String scoreObjective = binaryScore.getString(SCORE_OBJECTIVE); + + String scoreValue = null; + BinaryTag binaryScoreValue = binaryScore.get(SCORE_VALUE); + + if (binaryScoreValue != null) { + scoreValue = ((StringBinaryTag) binaryScoreValue).value(); + } + + return Component.score() + .name(scoreName) + .objective(scoreObjective) + .value(scoreValue) + .style(style) + .append(children) + .build(); + case TYPE_SELECTOR: + String selector = compound.getString(SELECTOR); + Component selectorSeparator = null; + + BinaryTag binarySelectorSeparator = compound.get(SELECTOR_SEPARATOR); + if (binarySelectorSeparator != null) { + selectorSeparator = this.deserialize(binarySelectorSeparator); + } + + return Component.selector() + .pattern(selector) + .separator(selectorSeparator) + .style(style) + .append(children) + .build(); + case TYPE_NBT: + String nbtPath = compound.getString(NBT); + boolean nbtInterpret = compound.getBoolean(NBT_INTERPRET); + Component nbtSeparator = null; + + BinaryTag binaryNbtSeparator = compound.get(NBT_SEPARATOR); + if (binaryNbtSeparator != null) { + nbtSeparator = this.deserialize(binaryNbtSeparator); + } + + BinaryTag binaryBlock = compound.get(NBT_BLOCK); + BinaryTag binaryEntity = compound.get(NBT_ENTITY); + BinaryTag binaryStorage = compound.get(NBT_STORAGE); + + if (binaryBlock != null) { + BlockNBTComponent.Pos pos = BlockNBTComponent.Pos.fromString(((StringBinaryTag) binaryBlock).value()); + return Component.blockNBT() + .nbtPath(nbtPath) + .interpret(nbtInterpret) + .separator(nbtSeparator) + .pos(pos) + .style(style) + .append(children) + .build(); + } else if (binaryEntity != null) { + return Component.entityNBT() + .nbtPath(nbtPath) + .interpret(nbtInterpret) + .separator(nbtSeparator) + .selector(((StringBinaryTag) binaryEntity).value()) + .style(style) + .append(children) + .build(); + } else if (binaryStorage != null) { + return Component.storageNBT() + .nbtPath(nbtPath) + .interpret(nbtInterpret) + .separator(nbtSeparator) + .storage(Key.key(((StringBinaryTag) binaryStorage).value())) + .style(style) + .append(children) + .build(); + } + default: + throw new IllegalArgumentException("Unknown component type " + type); + } } @Override public @NotNull BinaryTag serialize(@NotNull Component component) { if (this.flags.value(NBTSerializerOptions.EMIT_COMPACT_TEXT_COMPONENT) && component instanceof TextComponent - && !component.hasStyling()) { + && !component.hasStyling() && component.children().isEmpty()) { return StringBinaryTag.stringBinaryTag(((TextComponent) component).content()); } return writeCompoundComponent(component); @@ -245,7 +434,7 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { List serializedChildren = new ArrayList<>(); for (Component child : children) { - serializedChildren.add(this.serialize(child)); + serializedChildren.add(this.writeCompoundComponent(child)); } builder.put(EXTRA, ListBinaryTag.from(serializedChildren)); @@ -267,4 +456,12 @@ private void writeComponentType(final String componentType, final CompoundBinary private static IllegalArgumentException notSureHowToSerialize(final Component component) { return new IllegalArgumentException("Don't know how to serialize " + component + " as a Component"); } + + private static TextDecoration.@NotNull State readOptionalState(@NotNull String key, @NotNull CompoundBinaryTag compound) { + BinaryTag tag = compound.get(key); + if (tag == null) { + return TextDecoration.State.NOT_SET; + } + return TextDecoration.State.byBoolean(((ByteBinaryTag) tag).value() != 0); + } } From 9858a9f6b9ba0c90c842d97ed5a54f0059dee11b Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 9 Jun 2024 17:39:05 +0200 Subject: [PATCH 07/86] fix: translatable component arguments aren't deserializing --- .../text/serializer/nbt/NBTComponentSerializerImpl.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 8041a614cc..140a8f4322 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -2,7 +2,6 @@ import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.BinaryTag; -import net.kyori.adventure.nbt.BinaryTagTypes; import net.kyori.adventure.nbt.ByteBinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.ListBinaryTag; @@ -167,7 +166,7 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { .append(children) .build(); case TYPE_TRANSLATABLE: - ListBinaryTag binaryArguments = compound.getList(TRANSLATE_WITH, BinaryTagTypes.STRING); + ListBinaryTag binaryArguments = compound.getList(TRANSLATE_WITH); String fallback = compound.getString(TRANSLATE_FALLBACK); if (fallback.isEmpty()) { @@ -371,7 +370,6 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { builder.put(TRANSLATE_WITH, ListBinaryTag.from(argumentsTags)); } - String fallback = translatable.fallback(); if (fallback != null) { builder.putString(TRANSLATE_FALLBACK, fallback); From 4c7b00c7da1d0b8b293e8daa07b467af1b83193c Mon Sep 17 00:00:00 2001 From: codestech Date: Wed, 12 Jun 2024 16:11:35 +0200 Subject: [PATCH 08/86] fix: legacy hover events aren't serialized properly --- .../serializer/nbt/HoverEventSerializer.java | 34 ++++++++++++++----- .../nbt/NBTComponentSerializerImpl.java | 5 ++- .../serializer/nbt/NBTSerializerOptions.java | 3 ++ 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java index 1b11ddd7d0..746b09eb05 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -8,7 +8,9 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.DataComponentValue; import net.kyori.adventure.text.event.HoverEvent; +import net.kyori.option.OptionState; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; @@ -18,6 +20,8 @@ final class HoverEventSerializer { private static final String HOVER_EVENT_ACTION = "action"; private static final String HOVER_EVENT_CONTENTS = "contents"; + @Deprecated + private static final String HOVER_EVENT_VALUE = "value"; private static final String HOVER_EVENT_SHOW_TEXT = "show_text"; private static final String HOVER_EVENT_SHOW_ITEM = "show_item"; @@ -45,7 +49,10 @@ private HoverEventSerializer() { BinaryTag contents = compound.get(HOVER_EVENT_CONTENTS); if (contents == null) { - throw new IllegalArgumentException("The hover event doesn't contain any contents"); + contents = compound.get(HOVER_EVENT_VALUE); + if (contents == null) { + throw new IllegalArgumentException("The hover event doesn't contain any contents"); + } } if (Component.class.isAssignableFrom(actionType)) { @@ -97,12 +104,26 @@ private HoverEventSerializer() { } } - static @NotNull CompoundBinaryTag serialize(@NotNull HoverEvent event, @NotNull NBTComponentSerializerImpl serializer) { + static @Nullable CompoundBinaryTag serialize(@NotNull HoverEvent event, @NotNull NBTComponentSerializerImpl serializer) { + OptionState flags = serializer.flags(); HoverEvent.Action action = event.action(); + if (action == HoverEvent.Action.SHOW_ACHIEVEMENT) { + if (!flags.value(NBTSerializerOptions.EMIT_LEGACY_HOVER)) { + return null; + } + + return CompoundBinaryTag.builder() + .putString(HOVER_EVENT_ACTION, HOVER_EVENT_SHOW_ACHIEVEMENT) + .putString(HOVER_EVENT_VALUE, (String) event.value()) + .build(); + } + BinaryTag contents; String actionString; + boolean emitsModern = flags.value(NBTSerializerOptions.EMIT_MODERN_HOVER); + if (action == HoverEvent.Action.SHOW_TEXT) { contents = serializer.serialize((Component) event.value()); actionString = HOVER_EVENT_SHOW_TEXT; @@ -114,7 +135,7 @@ private HoverEventSerializer() { .putInt(SHOW_ITEM_COUNT, item.count()); Map components = item.dataComponentsAs(NBTDataComponentValue.class); - NBTSerializerOptions.ShowItemHoverDataMode dataMode = serializer.flags().value(NBTSerializerOptions.SHOW_ITEM_HOVER_DATA_MODE); + NBTSerializerOptions.ShowItemHoverDataMode dataMode = flags.value(NBTSerializerOptions.SHOW_ITEM_HOVER_DATA_MODE); if (!components.isEmpty() && dataMode != NBTSerializerOptions.ShowItemHoverDataMode.EMIT_LEGACY_NBT) { CompoundBinaryTag.Builder dataComponentsBuilder = CompoundBinaryTag.builder(); @@ -133,7 +154,7 @@ private HoverEventSerializer() { contents = builder.build(); actionString = HOVER_EVENT_SHOW_ITEM; - } else if (action == HoverEvent.Action.SHOW_ENTITY) { + } else if (action == HoverEvent.Action.SHOW_ENTITY && emitsModern) { HoverEvent.ShowEntity item = (HoverEvent.ShowEntity) event.value(); CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() @@ -147,16 +168,13 @@ private HoverEventSerializer() { contents = builder.build(); actionString = HOVER_EVENT_SHOW_ENTITY; - } else if (action == HoverEvent.Action.SHOW_ACHIEVEMENT) { - contents = StringBinaryTag.stringBinaryTag((String) event.value()); - actionString = HOVER_EVENT_SHOW_ACHIEVEMENT; } else { throw new IllegalArgumentException("Don't know how to serialize " + event + " as a HoverEvent"); } return CompoundBinaryTag.builder() .putString(HOVER_EVENT_ACTION, actionString) - .put(HOVER_EVENT_CONTENTS, contents) + .put(emitsModern ? HOVER_EVENT_CONTENTS : HOVER_EVENT_VALUE, contents) .build(); } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 140a8f4322..623bb99b8a 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -346,7 +346,10 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { HoverEvent hoverEvent = component.hoverEvent(); if (hoverEvent != null) { - builder.put(HOVER_EVENT, HoverEventSerializer.serialize(hoverEvent, this)); + CompoundBinaryTag binaryHoverEvent = HoverEventSerializer.serialize(hoverEvent, this); + if (binaryHoverEvent != null) { + builder.put(HOVER_EVENT, binaryHoverEvent); + } } if (component instanceof TextComponent) { diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index b5d90db76e..22984d9168 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -13,6 +13,9 @@ public final class NBTSerializerOptions { */ public static final Option SHOW_ITEM_HOVER_DATA_MODE = Option.enumOption(key("emit/show_item_hover_data"), ShowItemHoverDataMode.class, ShowItemHoverDataMode.EMIT_EITHER); + public static final Option EMIT_MODERN_HOVER = Option.booleanOption(key("emit/modern_hover"), true); + public static final Option EMIT_LEGACY_HOVER = Option.booleanOption(key("emit/legacy_hover"), false); + public static final Option SERIALIZE_COMPONENT_TYPES = Option.booleanOption(key("serialize/component-types"), true); private NBTSerializerOptions() { From 0a52c019c6a275c96a9c8b5df2d9b8581ff682be Mon Sep 17 00:00:00 2001 From: codestech Date: Wed, 12 Jun 2024 16:20:48 +0200 Subject: [PATCH 09/86] fix: serializing show entity as a legacy hover event throws an exception instead of returning null --- .../adventure/text/serializer/nbt/HoverEventSerializer.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java index 746b09eb05..baa2cd5de1 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -154,7 +154,11 @@ private HoverEventSerializer() { contents = builder.build(); actionString = HOVER_EVENT_SHOW_ITEM; - } else if (action == HoverEvent.Action.SHOW_ENTITY && emitsModern) { + } else if (action == HoverEvent.Action.SHOW_ENTITY) { + if (!emitsModern) { + return null; + } + HoverEvent.ShowEntity item = (HoverEvent.ShowEntity) event.value(); CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() From a020c0a2bebc15cec14c04e96a543d7b04e02216 Mon Sep 17 00:00:00 2001 From: codestech Date: Thu, 13 Jun 2024 13:12:55 +0200 Subject: [PATCH 10/86] misc: split the style serialization and deserialization to other class --- .../nbt/NBTComponentSerializerImpl.java | 131 +-------------- .../text/serializer/nbt/StyleSerializer.java | 149 ++++++++++++++++++ 2 files changed, 151 insertions(+), 129 deletions(-) create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 623bb99b8a..a7eedcbf7e 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -2,7 +2,6 @@ import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.BinaryTag; -import net.kyori.adventure.nbt.ByteBinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.ListBinaryTag; import net.kyori.adventure.nbt.StringBinaryTag; @@ -17,12 +16,7 @@ import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TranslatableComponent; import net.kyori.adventure.text.TranslationArgument; -import net.kyori.adventure.text.event.ClickEvent; -import net.kyori.adventure.text.event.HoverEvent; -import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; -import net.kyori.adventure.text.format.TextColor; -import net.kyori.adventure.text.format.TextDecoration; import net.kyori.option.OptionState; import org.jetbrains.annotations.NotNull; @@ -42,17 +36,6 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { private static final String EXTRA = "extra"; - private static final String COLOR = "color"; - private static final String BOLD = "bold"; - private static final String ITALIC = "italic"; - private static final String UNDERLINED = "underlined"; - private static final String STRIKETHROUGH = "strikethrough"; - private static final String OBFUSCATED = "obfuscated"; - private static final String FONT = "font"; - private static final String INSERTION = "insertion"; - private static final String CLICK_EVENT = "clickEvent"; - private static final String HOVER_EVENT = "hoverEvent"; - private static final String TEXT = "text"; private static final String TRANSLATE_KEY = "translate"; @@ -115,44 +98,7 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { } } - Style.Builder styleBuilder = Style.style(); - - String colorString = compound.getString(COLOR); - if (!colorString.isEmpty()) { - if (colorString.startsWith(TextColor.HEX_PREFIX)) { - styleBuilder.color(TextColor.fromHexString(colorString)); - } else { - styleBuilder.color(NamedTextColor.NAMES.value(colorString)); - } - } - - styleBuilder.decoration(TextDecoration.BOLD, readOptionalState(BOLD, compound)) - .decoration(TextDecoration.ITALIC, readOptionalState(ITALIC, compound)) - .decoration(TextDecoration.UNDERLINED, readOptionalState(UNDERLINED, compound)) - .decoration(TextDecoration.STRIKETHROUGH, readOptionalState(STRIKETHROUGH, compound)) - .decoration(TextDecoration.OBFUSCATED, readOptionalState(OBFUSCATED, compound)); - - String fontString = compound.getString(FONT); - if (!fontString.isEmpty()) { - styleBuilder.font(Key.key(fontString)); - } - - BinaryTag binaryInsertion = compound.get(INSERTION); - if (binaryInsertion != null) { - styleBuilder.insertion(((StringBinaryTag) binaryInsertion).value()); - } - - BinaryTag binaryClickEvent = compound.get(CLICK_EVENT); - if (binaryClickEvent != null) { - styleBuilder.clickEvent(ClickEventSerializer.deserialize((CompoundBinaryTag) binaryClickEvent)); - } - - BinaryTag binaryHoverEvent = compound.get(HOVER_EVENT); - if (binaryHoverEvent != null) { - styleBuilder.hoverEvent(HoverEventSerializer.deserialize((CompoundBinaryTag) binaryHoverEvent, this)); - } - - Style style = styleBuilder.build(); + Style style = StyleSerializer.deserialize(compound, this); List children = new ArrayList<>(); ListBinaryTag binaryChildren = compound.getList(EXTRA); @@ -285,72 +231,7 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { private @NotNull CompoundBinaryTag writeCompoundComponent(@NotNull Component component) { CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder(); - - TextColor color = component.color(); - - if (color != null) { - if (color instanceof NamedTextColor) { - builder.putString(COLOR, color.toString()); - } else { - builder.putString(COLOR, color.asHexString()); - } - } - - component.decorations().forEach((decoration, state) -> { - if (state != TextDecoration.State.NOT_SET) { - String decorationName; - - switch (decoration) { - case OBFUSCATED: - decorationName = OBFUSCATED; - break; - case BOLD: - decorationName = BOLD; - break; - case STRIKETHROUGH: - decorationName = STRIKETHROUGH; - break; - case UNDERLINED: - decorationName = UNDERLINED; - break; - case ITALIC: - decorationName = ITALIC; - break; - default: - // Never called, but needed for proper compilation - throw new IllegalStateException("Unknown text decoration: " + decoration); - } - - builder.putBoolean(decorationName, state == TextDecoration.State.TRUE); - } - }); - - Key font = component.font(); - - if (font != null) { - builder.putString(FONT, font.asString()); - } - - String insertion = component.insertion(); - - if (insertion != null) { - builder.putString(INSERTION, insertion); - } - - ClickEvent clickEvent = component.clickEvent(); - - if (clickEvent != null) { - builder.put(CLICK_EVENT, ClickEventSerializer.serialize(clickEvent)); - } - - HoverEvent hoverEvent = component.hoverEvent(); - - if (hoverEvent != null) { - CompoundBinaryTag binaryHoverEvent = HoverEventSerializer.serialize(hoverEvent, this); - if (binaryHoverEvent != null) { - builder.put(HOVER_EVENT, binaryHoverEvent); - } - } + StyleSerializer.serialize(component.style(), builder, this); if (component instanceof TextComponent) { this.writeComponentType(TYPE_TEXT, builder); @@ -457,12 +338,4 @@ private void writeComponentType(final String componentType, final CompoundBinary private static IllegalArgumentException notSureHowToSerialize(final Component component) { return new IllegalArgumentException("Don't know how to serialize " + component + " as a Component"); } - - private static TextDecoration.@NotNull State readOptionalState(@NotNull String key, @NotNull CompoundBinaryTag compound) { - BinaryTag tag = compound.get(key); - if (tag == null) { - return TextDecoration.State.NOT_SET; - } - return TextDecoration.State.byBoolean(((ByteBinaryTag) tag).value() != 0); - } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java new file mode 100644 index 0000000000..45f550fc4a --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java @@ -0,0 +1,149 @@ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.ByteBinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.StringBinaryTag; +import net.kyori.adventure.text.event.ClickEvent; +import net.kyori.adventure.text.event.HoverEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.jetbrains.annotations.NotNull; + +final class StyleSerializer { + + private static final String COLOR = "color"; + private static final String BOLD = "bold"; + private static final String ITALIC = "italic"; + private static final String UNDERLINED = "underlined"; + private static final String STRIKETHROUGH = "strikethrough"; + private static final String OBFUSCATED = "obfuscated"; + private static final String FONT = "font"; + private static final String INSERTION = "insertion"; + private static final String CLICK_EVENT = "clickEvent"; + private static final String HOVER_EVENT = "hoverEvent"; + + private StyleSerializer() { + } + + static @NotNull Style deserialize(@NotNull CompoundBinaryTag compound, @NotNull NBTComponentSerializerImpl serializer) { + Style.Builder styleBuilder = Style.style(); + + String colorString = compound.getString(COLOR); + if (!colorString.isEmpty()) { + if (colorString.startsWith(TextColor.HEX_PREFIX)) { + styleBuilder.color(TextColor.fromHexString(colorString)); + } else { + styleBuilder.color(NamedTextColor.NAMES.value(colorString)); + } + } + + styleBuilder.decoration(TextDecoration.BOLD, readOptionalState(BOLD, compound)) + .decoration(TextDecoration.ITALIC, readOptionalState(ITALIC, compound)) + .decoration(TextDecoration.UNDERLINED, readOptionalState(UNDERLINED, compound)) + .decoration(TextDecoration.STRIKETHROUGH, readOptionalState(STRIKETHROUGH, compound)) + .decoration(TextDecoration.OBFUSCATED, readOptionalState(OBFUSCATED, compound)); + + String fontString = compound.getString(FONT); + if (!fontString.isEmpty()) { + styleBuilder.font(Key.key(fontString)); + } + + BinaryTag binaryInsertion = compound.get(INSERTION); + if (binaryInsertion != null) { + styleBuilder.insertion(((StringBinaryTag) binaryInsertion).value()); + } + + BinaryTag binaryClickEvent = compound.get(CLICK_EVENT); + if (binaryClickEvent != null) { + styleBuilder.clickEvent(ClickEventSerializer.deserialize((CompoundBinaryTag) binaryClickEvent)); + } + + BinaryTag binaryHoverEvent = compound.get(HOVER_EVENT); + if (binaryHoverEvent != null) { + styleBuilder.hoverEvent(HoverEventSerializer.deserialize((CompoundBinaryTag) binaryHoverEvent, serializer)); + } + + return styleBuilder.build(); + } + + static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder builder, + @NotNull NBTComponentSerializerImpl serializer) { + TextColor color = style.color(); + + if (color != null) { + if (color instanceof NamedTextColor) { + builder.putString(COLOR, color.toString()); + } else { + builder.putString(COLOR, color.asHexString()); + } + } + + style.decorations().forEach((decoration, state) -> { + if (state != TextDecoration.State.NOT_SET) { + String decorationName; + + switch (decoration) { + case OBFUSCATED: + decorationName = OBFUSCATED; + break; + case BOLD: + decorationName = BOLD; + break; + case STRIKETHROUGH: + decorationName = STRIKETHROUGH; + break; + case UNDERLINED: + decorationName = UNDERLINED; + break; + case ITALIC: + decorationName = ITALIC; + break; + default: + // Never called, but needed for proper compilation + throw new IllegalStateException("Unknown text decoration: " + decoration); + } + + builder.putBoolean(decorationName, state == TextDecoration.State.TRUE); + } + }); + + Key font = style.font(); + + if (font != null) { + builder.putString(FONT, font.asString()); + } + + String insertion = style.insertion(); + + if (insertion != null) { + builder.putString(INSERTION, insertion); + } + + ClickEvent clickEvent = style.clickEvent(); + + if (clickEvent != null) { + builder.put(CLICK_EVENT, ClickEventSerializer.serialize(clickEvent)); + } + + HoverEvent hoverEvent = style.hoverEvent(); + + if (hoverEvent != null) { + CompoundBinaryTag binaryHoverEvent = HoverEventSerializer.serialize(hoverEvent, serializer); + if (binaryHoverEvent != null) { + builder.put(HOVER_EVENT, binaryHoverEvent); + } + } + } + + private static TextDecoration.@NotNull State readOptionalState(@NotNull String key, @NotNull CompoundBinaryTag compound) { + BinaryTag tag = compound.get(key); + if (tag == null) { + return TextDecoration.State.NOT_SET; + } + return TextDecoration.State.byBoolean(((ByteBinaryTag) tag).value() != 0); + } +} From a39a1016d84bce39f0deda6f42c5759b7f3bb03c Mon Sep 17 00:00:00 2001 From: codestech Date: Thu, 13 Jun 2024 13:16:36 +0200 Subject: [PATCH 11/86] feat: add an emit rgb flag --- .../adventure/text/serializer/nbt/NBTSerializerOptions.java | 2 ++ .../kyori/adventure/text/serializer/nbt/StyleSerializer.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index 22984d9168..7f68cadfb3 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -13,6 +13,8 @@ public final class NBTSerializerOptions { */ public static final Option SHOW_ITEM_HOVER_DATA_MODE = Option.enumOption(key("emit/show_item_hover_data"), ShowItemHoverDataMode.class, ShowItemHoverDataMode.EMIT_EITHER); + public static final Option EMIT_RGB = Option.booleanOption(key("emit/rgb"), true); + public static final Option EMIT_MODERN_HOVER = Option.booleanOption(key("emit/modern_hover"), true); public static final Option EMIT_LEGACY_HOVER = Option.booleanOption(key("emit/legacy_hover"), false); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java index 45f550fc4a..0d83440ece 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java @@ -77,7 +77,7 @@ static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder b if (color != null) { if (color instanceof NamedTextColor) { builder.putString(COLOR, color.toString()); - } else { + } else if (serializer.flags().value(NBTSerializerOptions.EMIT_RGB)) { builder.putString(COLOR, color.asHexString()); } } From 8e7408822776866ca7a5618be157a84e0f8cbdc6 Mon Sep 17 00:00:00 2001 From: codestech Date: Thu, 13 Jun 2024 14:40:38 +0200 Subject: [PATCH 12/86] feat: add a builder for the nbt component serializer --- .../nbt/NBTComponentSerializer.java | 33 +++++++++++++++++++ .../nbt/NBTComponentSerializerImpl.java | 28 ++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java index 4db02d56e6..363f19d228 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java @@ -1,8 +1,41 @@ package net.kyori.adventure.text.serializer.nbt; +import net.kyori.adventure.builder.AbstractBuilder; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.ComponentSerializer; +import net.kyori.option.OptionState; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Consumer; public interface NBTComponentSerializer extends ComponentSerializer { + + static @NotNull Builder builder() { + return new NBTComponentSerializerImpl.BuilderImpl(); + } + + interface Builder extends AbstractBuilder { + @NotNull Builder options(final @NotNull OptionState flags); + @NotNull Builder editOptions(final @NotNull Consumer optionEditor); + + default @NotNull Builder downsampleColors() { + return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_RGB, false)); + } + + default @NotNull Builder emitModernHoverEvent(final boolean emit) { + return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_MODERN_HOVER, emit)); + } + + default @NotNull Builder emitLegacyHoverEvent(final boolean emit) { + return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_LEGACY_HOVER, emit)); + } + + default @NotNull Builder serializeComponentTypes(final boolean serialize) { + return this.editOptions(builder -> builder.value(NBTSerializerOptions.SERIALIZE_COMPONENT_TYPES, serialize)); + } + + @Override + @NotNull NBTComponentSerializer build(); + } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index a7eedcbf7e..586d7ab530 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -22,6 +22,9 @@ import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; + +import static java.util.Objects.requireNonNull; final class NBTComponentSerializerImpl implements NBTComponentSerializer { @@ -338,4 +341,29 @@ private void writeComponentType(final String componentType, final CompoundBinary private static IllegalArgumentException notSureHowToSerialize(final Component component) { return new IllegalArgumentException("Don't know how to serialize " + component + " as a Component"); } + + static final class BuilderImpl implements NBTComponentSerializer.Builder { + + private OptionState flags = OptionState.emptyOptionState(); + + @Override + public @NotNull Builder options(@NotNull OptionState flags) { + this.flags = flags; + return this; + } + + @Override + public @NotNull Builder editOptions(@NotNull Consumer optionEditor) { + final OptionState.Builder builder = OptionState.optionState() + .values(this.flags); + requireNonNull(optionEditor, "optionEditor").accept(builder); + this.flags = builder.build(); + return this; + } + + @Override + public @NotNull NBTComponentSerializer build() { + return new NBTComponentSerializerImpl(this.flags); + } + } } From f96ca385625238646db0df19c6d07ba568aafef7 Mon Sep 17 00:00:00 2001 From: codestech Date: Thu, 13 Jun 2024 14:42:31 +0200 Subject: [PATCH 13/86] chore: add a non-null requirement to NBTComponentSerializerImpl.BuilderImpl#options --- .../text/serializer/nbt/NBTComponentSerializerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 586d7ab530..25dbb8d25e 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -348,7 +348,7 @@ static final class BuilderImpl implements NBTComponentSerializer.Builder { @Override public @NotNull Builder options(@NotNull OptionState flags) { - this.flags = flags; + this.flags = requireNonNull(flags, "flags"); return this; } From bba80fb41db2661dcd6aac2ad5fcca43589cb3f2 Mon Sep 17 00:00:00 2001 From: codestech Date: Thu, 13 Jun 2024 15:26:17 +0200 Subject: [PATCH 14/86] feat: nbt component providers --- .../nbt/NBTComponentSerializer.java | 39 ++++++++++++++++++- .../nbt/NBTComponentSerializerImpl.java | 20 ++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java index 363f19d228..a420589d59 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java @@ -4,13 +4,19 @@ import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.ComponentSerializer; +import net.kyori.adventure.util.PlatformAPI; import net.kyori.option.OptionState; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import java.util.function.Consumer; public interface NBTComponentSerializer extends ComponentSerializer { + static @NotNull NBTComponentSerializer nbt() { + return NBTComponentSerializerImpl.Instances.INSTANCE; + } + static @NotNull Builder builder() { return new NBTComponentSerializerImpl.BuilderImpl(); } @@ -19,8 +25,8 @@ interface Builder extends AbstractBuilder { @NotNull Builder options(final @NotNull OptionState flags); @NotNull Builder editOptions(final @NotNull Consumer optionEditor); - default @NotNull Builder downsampleColors() { - return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_RGB, false)); + default @NotNull Builder downsampleColors(final boolean downsampleColors) { + return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_RGB, downsampleColors)); } default @NotNull Builder emitModernHoverEvent(final boolean emit) { @@ -38,4 +44,33 @@ interface Builder extends AbstractBuilder { @Override @NotNull NBTComponentSerializer build(); } + + /** + * A {@link NBTComponentSerializer} service provider. + * + * @since 4.18.0 + */ + @ApiStatus.Internal + @PlatformAPI + interface Provider { + /** + * Provides a standard {@link NBTComponentSerializer}. + * + * @return a {@link NBTComponentSerializer} + * @since 4.18.0 + */ + @ApiStatus.Internal + @PlatformAPI + @NotNull NBTComponentSerializer nbt(); + + /** + * Completes the building process of {@link Builder}. + * + * @return a {@link Consumer} + * @since 4.18.0 + */ + @ApiStatus.Internal + @PlatformAPI + @NotNull Consumer builder(); + } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 25dbb8d25e..daf0fbbb20 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -17,17 +17,33 @@ import net.kyori.adventure.text.TranslatableComponent; import net.kyori.adventure.text.TranslationArgument; import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.util.Services; import net.kyori.option.OptionState; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.function.Consumer; import static java.util.Objects.requireNonNull; final class NBTComponentSerializerImpl implements NBTComponentSerializer { + private static final Optional SERVICE = Services.service(Provider.class); + private static final Consumer BUILDER = SERVICE + .map(Provider::builder) + .orElse(builder -> { + // NOOP + }); + + // We cannot store these fields in NBTComponentSerializerImpl directly due to class initialisation issues. + static final class Instances { + static final NBTComponentSerializer INSTANCE = SERVICE + .map(Provider::nbt) + .orElseGet(() -> new NBTComponentSerializerImpl(OptionState.emptyOptionState())); + } + private static final String TYPE = "type"; private static final String TYPE_TEXT = "text"; @@ -346,6 +362,10 @@ static final class BuilderImpl implements NBTComponentSerializer.Builder { private OptionState flags = OptionState.emptyOptionState(); + BuilderImpl() { + BUILDER.accept(this); // let service provider touch the builder before anybody else touches it + } + @Override public @NotNull Builder options(@NotNull OptionState flags) { this.flags = requireNonNull(flags, "flags"); From 0ec4d53e0d87f894f3dd34fb750fd37f79be694f Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 15 Jun 2024 03:00:55 +0200 Subject: [PATCH 15/86] chore: add remaining serializer options to builder --- .../text/serializer/nbt/NBTComponentSerializer.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java index a420589d59..3b2cba3a78 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java @@ -25,8 +25,8 @@ interface Builder extends AbstractBuilder { @NotNull Builder options(final @NotNull OptionState flags); @NotNull Builder editOptions(final @NotNull Consumer optionEditor); - default @NotNull Builder downsampleColors(final boolean downsampleColors) { - return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_RGB, downsampleColors)); + default @NotNull Builder emitRgb(final boolean emit) { + return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_RGB, emit)); } default @NotNull Builder emitModernHoverEvent(final boolean emit) { @@ -41,6 +41,14 @@ interface Builder extends AbstractBuilder { return this.editOptions(builder -> builder.value(NBTSerializerOptions.SERIALIZE_COMPONENT_TYPES, serialize)); } + default @NotNull Builder showItemHoverDataMode(final @NotNull NBTSerializerOptions.ShowItemHoverDataMode mode) { + return this.editOptions(builder -> builder.value(NBTSerializerOptions.SHOW_ITEM_HOVER_DATA_MODE, mode)); + } + + default @NotNull Builder emitCompactTextComponent(final boolean emit) { + return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_COMPACT_TEXT_COMPONENT, emit)); + } + @Override @NotNull NBTComponentSerializer build(); } From e8b5efdb330984a7bc750be3f1069c0e996a9766 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 15 Jun 2024 10:15:05 +0200 Subject: [PATCH 16/86] chore: cleanup --- .../text/serializer/nbt/NBTComponentSerializerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index daf0fbbb20..0b86a09eea 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -302,7 +302,7 @@ static final class Instances { Component separator = selector.separator(); if (separator != null) { - builder.put(SELECTOR_SEPARATOR, serialize(separator)); + builder.put(SELECTOR_SEPARATOR, this.serialize(separator)); } } else if (component instanceof NBTComponent) { this.writeComponentType(TYPE_NBT, builder); @@ -313,7 +313,7 @@ static final class Instances { Component separator = nbt.separator(); if (separator != null) { - builder.put(NBT_SEPARATOR, serialize(separator)); + builder.put(NBT_SEPARATOR, this.serialize(separator)); } if (nbt instanceof BlockNBTComponent) { From f8427a0abd1fc9648f77eadbab8a13c6859a3475 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 15 Jun 2024 13:52:39 +0200 Subject: [PATCH 17/86] chore: add javadocs to and simplify NBTSerializerOptions and add license headers --- .../serializer/nbt/ClickEventSerializer.java | 23 +++++ .../serializer/nbt/HoverEventSerializer.java | 33 +++++-- .../nbt/NBTComponentSerializer.java | 31 +++++-- .../nbt/NBTComponentSerializerImpl.java | 23 +++++ .../serializer/nbt/NBTDataComponentValue.java | 23 +++++ .../nbt/NBTDataComponentValueImpl.java | 23 +++++ .../serializer/nbt/NBTSerializerOptions.java | 87 ++++++++++++++++++- .../text/serializer/nbt/StyleSerializer.java | 23 +++++ 8 files changed, 251 insertions(+), 15 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java index 77579d17b7..f1b7226314 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java @@ -1,3 +1,26 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.nbt.CompoundBinaryTag; diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java index baa2cd5de1..0c113e3459 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -1,3 +1,26 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.key.Key; @@ -108,8 +131,10 @@ private HoverEventSerializer() { OptionState flags = serializer.flags(); HoverEvent.Action action = event.action(); + NBTSerializerOptions.HoverEventValueMode hoverMode = flags.value(NBTSerializerOptions.EMIT_HOVER_EVENT_TYPE); + if (action == HoverEvent.Action.SHOW_ACHIEVEMENT) { - if (!flags.value(NBTSerializerOptions.EMIT_LEGACY_HOVER)) { + if (hoverMode == NBTSerializerOptions.HoverEventValueMode.MODERN_ONLY) { return null; } @@ -122,8 +147,6 @@ private HoverEventSerializer() { BinaryTag contents; String actionString; - boolean emitsModern = flags.value(NBTSerializerOptions.EMIT_MODERN_HOVER); - if (action == HoverEvent.Action.SHOW_TEXT) { contents = serializer.serialize((Component) event.value()); actionString = HOVER_EVENT_SHOW_TEXT; @@ -155,7 +178,7 @@ private HoverEventSerializer() { contents = builder.build(); actionString = HOVER_EVENT_SHOW_ITEM; } else if (action == HoverEvent.Action.SHOW_ENTITY) { - if (!emitsModern) { + if (hoverMode != NBTSerializerOptions.HoverEventValueMode.LEGACY_ONLY) { return null; } @@ -178,7 +201,7 @@ private HoverEventSerializer() { return CompoundBinaryTag.builder() .putString(HOVER_EVENT_ACTION, actionString) - .put(emitsModern ? HOVER_EVENT_CONTENTS : HOVER_EVENT_VALUE, contents) + .put(hoverMode == NBTSerializerOptions.HoverEventValueMode.LEGACY_ONLY ? HOVER_EVENT_VALUE : HOVER_EVENT_CONTENTS, contents) .build(); } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java index 3b2cba3a78..117b7e4c4f 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java @@ -1,3 +1,26 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.builder.AbstractBuilder; @@ -29,12 +52,8 @@ interface Builder extends AbstractBuilder { return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_RGB, emit)); } - default @NotNull Builder emitModernHoverEvent(final boolean emit) { - return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_MODERN_HOVER, emit)); - } - - default @NotNull Builder emitLegacyHoverEvent(final boolean emit) { - return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_LEGACY_HOVER, emit)); + default @NotNull Builder emitHoverEventValueMode(final NBTSerializerOptions.HoverEventValueMode mode) { + return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_HOVER_EVENT_TYPE, mode)); } default @NotNull Builder serializeComponentTypes(final boolean serialize) { diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 0b86a09eea..8657e9f9c5 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -1,3 +1,26 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.key.Key; diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java index e736965543..b81631b3d5 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java @@ -1,3 +1,26 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.nbt.BinaryTag; diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java index 48b600aa25..869b909d2b 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java @@ -1,3 +1,26 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.nbt.BinaryTag; diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index 7f68cadfb3..089a569dca 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -1,9 +1,44 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package net.kyori.adventure.text.serializer.nbt; import net.kyori.option.Option; +/** + * Options that can apply to {@linkplain NBTComponentSerializer NBT serializers}. + * + *

See serializer documentation for specific details on which flags are supported.

+ * + * @since 4.18.0 + */ public final class NBTSerializerOptions { - + /** + * Whether to emit text components with no style and no children as plain text. + * + * @since 4.18.0 + * @sinceMinecraft 1.20.3 + */ public static final Option EMIT_COMPACT_TEXT_COMPONENT = Option.booleanOption(key("emit/compact_text_component"), true); /** @@ -13,13 +48,31 @@ public final class NBTSerializerOptions { */ public static final Option SHOW_ITEM_HOVER_DATA_MODE = Option.enumOption(key("emit/show_item_hover_data"), ShowItemHoverDataMode.class, ShowItemHoverDataMode.EMIT_EITHER); + /** + * Whether to emit RGB text. + * + *

If this attribute is disabled, colors in styles will be downsampled to the classic 16 colors.

+ * + * @since 4.18.0 + * @sinceMinecraft 1.16 + */ public static final Option EMIT_RGB = Option.booleanOption(key("emit/rgb"), true); - public static final Option EMIT_MODERN_HOVER = Option.booleanOption(key("emit/modern_hover"), true); - public static final Option EMIT_LEGACY_HOVER = Option.booleanOption(key("emit/legacy_hover"), false); - + /** + * Whether to serialize the types of {@linkplain net.kyori.adventure.text.Component components}. + * + * @since 4.18.0 + */ public static final Option SERIALIZE_COMPONENT_TYPES = Option.booleanOption(key("serialize/component-types"), true); + + /** + * Control how hover event values should be emitted. + * + * @since 4.18.0 + */ + public static final Option EMIT_HOVER_EVENT_TYPE = Option.enumOption(key("emit/hover_value_mode"), HoverEventValueMode.class, HoverEventValueMode.MODERN_ONLY); + private NBTSerializerOptions() { } @@ -52,4 +105,30 @@ public enum ShowItemHoverDataMode { */ EMIT_EITHER, } + + /** + * Configure how to emit hover event values. + * + * @since 4.18.0 + */ + public enum HoverEventValueMode { + /** + * Only emit the 1.16+ modern hover events. + * + * @since 4.18.0 + */ + MODERN_ONLY, + /** + * Only emit the pre-1.16 hover event {@code value} field. + * + * @since 4.18.0 + */ + LEGACY_ONLY, + /** + * Include both modern and legacy hover event fields, for maximum compatibility. + * + * @since 4.18.0 + */ + BOTH, + } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java index 0d83440ece..0ca5f20dc3 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java @@ -1,3 +1,26 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.key.Key; From 8c43bac962691d6c3c92c3965ef2d08707c388af Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 15 Jun 2024 14:05:03 +0200 Subject: [PATCH 18/86] chore: add javadocs for public classes --- .../nbt/NBTComponentSerializer.java | 91 ++++++++++++++++++- .../serializer/nbt/NBTDataComponentValue.java | 20 ++++ 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java index 117b7e4c4f..c27e59709c 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java @@ -34,40 +34,127 @@ import java.util.function.Consumer; +/** + * A NBT component serializer. + * + *

Use {@link Builder#emitRgb(boolean)} to support platforms + * that do not understand hex colors that were introduced in Minecraft 1.16.

+ * + * @since 4.18.0 + */ public interface NBTComponentSerializer extends ComponentSerializer { - + /** + * Gets a component serializer for NBT serialization and deserialization. + * + * @return a NBT component serializer + * @since 4.18.0 + */ static @NotNull NBTComponentSerializer nbt() { return NBTComponentSerializerImpl.Instances.INSTANCE; } + /** + * Creates a new {@link NBTComponentSerializer.Builder}. + * + * @return a builder + * @since 4.18.0 + */ static @NotNull Builder builder() { return new NBTComponentSerializerImpl.BuilderImpl(); } + /** + * A builder for {@link NBTComponentSerializer}. + * + * @since 4.18.0 + */ interface Builder extends AbstractBuilder { + /** + * Set the option state to apply on this serializer. + * + *

This controls how the serializer emits and interprets components.

+ * + * @param flags the flag set to use + * @return this builder + * @see NBTSerializerOptions + * @since 4.18.0 + */ @NotNull Builder options(final @NotNull OptionState flags); + + /** + * Edit the active set of serializer options. + * + * @param optionEditor the consumer operating on the existing flag set + * @return this builder + * @see NBTSerializerOptions + * @since 4.18.0 + */ @NotNull Builder editOptions(final @NotNull Consumer optionEditor); + /** + * Sets whether the serializer should downsample hex colors to named colors. + * + * @param emit true if the serializer should downsample hex colors to named colors, false otherwise + * @return this builder + * @since 4.18.0 + */ default @NotNull Builder emitRgb(final boolean emit) { return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_RGB, emit)); } - default @NotNull Builder emitHoverEventValueMode(final NBTSerializerOptions.HoverEventValueMode mode) { + /** + * Sets a {@linkplain NBTSerializerOptions.HoverEventValueMode hover event value mode} of the serializer. + * + * @param mode the mode + * @return this builder + * @since 4.18.0 + */ + default @NotNull Builder emitHoverEventValueMode(final @NotNull NBTSerializerOptions.HoverEventValueMode mode) { return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_HOVER_EVENT_TYPE, mode)); } + /** + * Sets whether the serializer should serialize types of the components. + * + * @param serialize true if the serializer should serialize types of the components, false otherwise + * @return this builder + * @since 4.18.0 + */ default @NotNull Builder serializeComponentTypes(final boolean serialize) { return this.editOptions(builder -> builder.value(NBTSerializerOptions.SERIALIZE_COMPONENT_TYPES, serialize)); } + /** + * Sets a {@linkplain NBTSerializerOptions.ShowItemHoverDataMode show item hover data mode} of the serializer. + * + * @param mode the mode + * @return this builder + * @since 4.18.0 + */ default @NotNull Builder showItemHoverDataMode(final @NotNull NBTSerializerOptions.ShowItemHoverDataMode mode) { return this.editOptions(builder -> builder.value(NBTSerializerOptions.SHOW_ITEM_HOVER_DATA_MODE, mode)); } + /** + * Sets whether the serializer should serialize text components without styling as + * {@linkplain net.kyori.adventure.nbt.StringBinaryTag string binary tags} instead of + * {@linkplain net.kyori.adventure.nbt.CompoundBinaryTag compound binary tags}. + * + * @param emit true if the serializer should serialize text components without styling + * as string binary tags, false otherwise + * @return this builder + * @since 4.18.0 + */ default @NotNull Builder emitCompactTextComponent(final boolean emit) { return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_COMPACT_TEXT_COMPONENT, emit)); } + /** + * Builds the serializer. + * + * @return the built serializer + * @since 4.18.0 + */ @Override @NotNull NBTComponentSerializer build(); } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java index b81631b3d5..69c346ac5c 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java @@ -28,10 +28,30 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +/** + * An {@link DataComponentValue} implementation that holds a {@linkplain BinaryTag binary tag}. + * + *

This holder is exposed to allow conversions to/from NBT data holders.

+ * + * @since 4.18.0 + */ @ApiStatus.NonExtendable public interface NBTDataComponentValue extends DataComponentValue { + /** + * The contained element, intended for read-only use. + * + * @return a copy of the contained element + * @since 4.18.0 + */ @NotNull BinaryTag binaryTag(); + /** + * Create a box for item data that can be understood by the NBT serializer. + * + * @param binaryTag the item data to hold + * @return a newly created item data holder instance + * @since 4.18.0 + */ static @NotNull NBTDataComponentValue nbtDataComponentValue(@NotNull BinaryTag binaryTag) { return new NBTDataComponentValueImpl(binaryTag); } From 2f4c78c8f98eab6c145a1677a764c1c1f7cc327d Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 15 Jun 2024 14:39:27 +0200 Subject: [PATCH 19/86] chore: add tests --- .../serializer/nbt/BlockNBTComponentTest.java | 54 +++++++++++++++++++ .../nbt/EntityNBTComponentTest.java | 46 ++++++++++++++++ .../serializer/nbt/KeybindComponentTest.java | 42 +++++++++++++++ .../text/serializer/nbt/NBTComponentTest.java | 46 ++++++++++++++++ .../serializer/nbt/ScoreComponentTest.java | 39 ++++++++++++++ .../serializer/nbt/SelectorComponentTest.java | 43 +++++++++++++++ .../nbt/StorageNBTComponentTest.java | 47 ++++++++++++++++ .../serializer/nbt/TextComponentTest.java | 42 +++++++++++++++ .../nbt/TranslatableComponentTest.java | 42 +++++++++++++++ 9 files changed, 401 insertions(+) create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/NBTComponentTest.java create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java new file mode 100644 index 0000000000..ee66aeed49 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java @@ -0,0 +1,54 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.text.BlockNBTComponent; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.junit.jupiter.api.Test; + +import static net.kyori.adventure.text.BlockNBTComponent.WorldPos.Coordinate.absolute; + +final class BlockNBTComponentTest implements NBTComponentTest { + @Test + public void testNoStyling() { + this.test(Component.blockNBT( + "abc", + true, + Component.text("separator?"), + BlockNBTComponent.WorldPos.worldPos(absolute(435), absolute(512), absolute(4243))) + ); + } + + @Test + public void testWithStyling() { + this.test(Component.blockNBT() + .nbtPath("cab") + .interpret(false) + .separator(Component.text("another-separator", NamedTextColor.RED, TextDecoration.OBFUSCATED)) + .worldPos(absolute(44), absolute(51), absolute(42)) + .build()); + } +} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java new file mode 100644 index 0000000000..d42756db14 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java @@ -0,0 +1,46 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.junit.jupiter.api.Test; + +final class EntityNBTComponentTest implements NBTComponentTest { + @Test + public void testNoStyling() { + this.test(Component.entityNBT("abc", "@a")); + } + + @Test + public void testWithStyling() { + this.test(Component.entityNBT() + .nbtPath("cab") + .interpret(true) + .separator(Component.text("another-separator", NamedTextColor.RED, TextDecoration.OBFUSCATED)) + .selector("@p") + .build()); + } +} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java new file mode 100644 index 0000000000..22e26b2a7e --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java @@ -0,0 +1,42 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.junit.jupiter.api.Test; + +final class KeybindComponentTest implements NBTComponentTest { + @Test + public void testNoStyling() { + this.test(Component.translatable("some.translation")); + } + + @Test + public void testWithStyling() { + this.test(Component.translatable("another-translation", NamedTextColor.GOLD, TextDecoration.STRIKETHROUGH) + .decoration(TextDecoration.ITALIC, false)); + } +} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/NBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/NBTComponentTest.java new file mode 100644 index 0000000000..226e657f7a --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/NBTComponentTest.java @@ -0,0 +1,46 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; + +interface NBTComponentTest { + default void test(@NotNull Component component) { + this.test(component, CompoundBinaryTag.class); + } + + default void test(@NotNull Component component, @NotNull Class expectedTag) { + NBTComponentSerializer serializer = NBTComponentSerializer.nbt(); + + BinaryTag serialized = serializer.serialize(component); + Assertions.assertInstanceOf(expectedTag, serialized); + + Component deserialized = serializer.deserialize(serialized); + Assertions.assertEquals(component, deserialized); + } +} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java new file mode 100644 index 0000000000..bbb5fa8cdc --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java @@ -0,0 +1,39 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.text.Component; +import org.junit.jupiter.api.Test; + +final class ScoreComponentTest implements NBTComponentTest { + @Test + public void testNoStyling() { + this.test(Component.score("a-score", "dummy", "idk-what-to-put-here")); + } + + @Test + public void testWithStyling() { + this.test(Component.score("some-score", "another-dummy-objective", "a-value")); + } +} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java new file mode 100644 index 0000000000..505abc8b06 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java @@ -0,0 +1,43 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.junit.jupiter.api.Test; + +final class SelectorComponentTest implements NBTComponentTest { + @Test + public void testNoStyling() { + this.test(Component.selector("@p", Component.text("a-separator"))); + } + + @Test + public void testWithStyling() { + this.test(Component.selector("@e", Component.text("some-separator", NamedTextColor.RED, TextDecoration.STRIKETHROUGH)) + .color(NamedTextColor.GOLD) + .decorate(TextDecoration.BOLD)); + } +} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java new file mode 100644 index 0000000000..b25ad81af6 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java @@ -0,0 +1,47 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.junit.jupiter.api.Test; + +final class StorageNBTComponentTest implements NBTComponentTest { + @Test + public void testNoStyling() { + this.test(Component.storageNBT("dsa", true, Component.text("separator?"), Key.key("minecraft", "chest"))); + } + + @Test + public void testWithStyling() { + this.test(Component.storageNBT() + .nbtPath("rsaby") + .interpret(false) + .separator(Component.text("another-separator", NamedTextColor.RED, TextDecoration.OBFUSCATED)) + .storage(Key.key("dummy", "storage")) + .build()); + } +} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java new file mode 100644 index 0000000000..f30b47dbea --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java @@ -0,0 +1,42 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.StringBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.junit.jupiter.api.Test; + +final class TextComponentTest implements NBTComponentTest { + @Test + public void testNoStyling() { + this.test(Component.text("Codestech was here!"), StringBinaryTag.class); + } + + @Test + public void testWithStyling() { + this.test(Component.text("A component with style!", NamedTextColor.RED, TextDecoration.BOLD)); + } +} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java new file mode 100644 index 0000000000..acb291996c --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java @@ -0,0 +1,42 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.junit.jupiter.api.Test; + +final class TranslatableComponentTest implements NBTComponentTest { + @Test + public void testNoStyling() { + this.test(Component.translatable("some.translation")); + } + + @Test + public void testWithStyling() { + this.test(Component.translatable("another-translation", NamedTextColor.GOLD, TextDecoration.STRIKETHROUGH) + .decoration(TextDecoration.ITALIC, false)); + } +} From 20217079835578c8087459f3d6532cf65e11f734 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 15 Jun 2024 15:18:00 +0200 Subject: [PATCH 20/86] fix: hover events are not serialized properly, feat: add a test for hover event --- .../serializer/nbt/HoverEventSerializer.java | 2 +- .../nbt/NBTDataComponentValueImpl.java | 15 +++++ .../text/serializer/nbt/HoverEventTest.java | 63 +++++++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/HoverEventTest.java diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java index 0c113e3459..c8b621a165 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -178,7 +178,7 @@ private HoverEventSerializer() { contents = builder.build(); actionString = HOVER_EVENT_SHOW_ITEM; } else if (action == HoverEvent.Action.SHOW_ENTITY) { - if (hoverMode != NBTSerializerOptions.HoverEventValueMode.LEGACY_ONLY) { + if (hoverMode == NBTSerializerOptions.HoverEventValueMode.LEGACY_ONLY) { return null; } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java index 869b909d2b..bd94d5558d 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java @@ -26,6 +26,8 @@ import net.kyori.adventure.nbt.BinaryTag; import org.jetbrains.annotations.NotNull; +import java.util.Objects; + final class NBTDataComponentValueImpl implements NBTDataComponentValue { private final BinaryTag binaryTag; @@ -38,4 +40,17 @@ final class NBTDataComponentValueImpl implements NBTDataComponentValue { public @NotNull BinaryTag binaryTag() { return this.binaryTag; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof NBTDataComponentValueImpl)) return false; + NBTDataComponentValueImpl that = (NBTDataComponentValueImpl) o; + return Objects.equals(this.binaryTag, that.binaryTag); + } + + @Override + public int hashCode() { + return Objects.hashCode(this.binaryTag); + } } diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/HoverEventTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/HoverEventTest.java new file mode 100644 index 0000000000..1f44bbca5f --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/HoverEventTest.java @@ -0,0 +1,63 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import com.google.common.collect.ImmutableMap; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.IntBinaryTag; +import net.kyori.adventure.nbt.StringBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.HoverEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.junit.jupiter.api.Test; + +import java.util.UUID; + +final class HoverEventTest implements NBTComponentTest { + @Test + public void testShowText() { + this.test(Component.empty().hoverEvent( + HoverEvent.showText(Component.text("Hi!", NamedTextColor.RED, TextDecoration.STRIKETHROUGH)) + )); + } + + @Test + public void testShowItem() { + this.test(Component.empty().hoverEvent(HoverEvent.showItem(Key.key("netherite_chestplate"), 2, ImmutableMap.of( + Key.key("count"), NBTDataComponentValue.nbtDataComponentValue(IntBinaryTag.intBinaryTag(2)), + Key.key("display_name"), NBTDataComponentValue.nbtDataComponentValue(StringBinaryTag.stringBinaryTag("test")) + )))); + } + + @Test + public void testShowEntity() { + this.test(Component.empty().hoverEvent( + HoverEvent.showEntity( + Key.key("enderman"), + UUID.randomUUID(), + Component.text("An entity name", NamedTextColor.RED, TextDecoration.STRIKETHROUGH)) + )); + } +} From 9021233f956eb0fadc8e60a1789f27a4979f52c6 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 15 Jun 2024 15:23:04 +0200 Subject: [PATCH 21/86] feat: add a test for click event --- .../text/serializer/nbt/ClickEventTest.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ClickEventTest.java diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ClickEventTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ClickEventTest.java new file mode 100644 index 0000000000..926e481ba4 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ClickEventTest.java @@ -0,0 +1,60 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2024 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.ClickEvent; +import org.junit.jupiter.api.Test; + +final class ClickEventTest implements NBTComponentTest { + @Test + public void testUrl() { + this.test(Component.empty().clickEvent(ClickEvent.openUrl("https://docs.advntr.dev/"))); + } + + @Test + public void testFile() { + this.test(Component.empty().clickEvent(ClickEvent.openFile("/root/some-file.extension"))); + } + + @Test + public void testRunCommand() { + this.test(Component.empty().clickEvent(ClickEvent.runCommand("/help"))); + } + + @Test + public void testSuggestCommand() { + this.test(Component.empty().clickEvent(ClickEvent.suggestCommand("/?"))); + } + + @Test + public void testChangePage() { + this.test(Component.empty().clickEvent(ClickEvent.changePage(6))); + } + + @Test + public void testCopyToClipboard() { + this.test(Component.empty().clickEvent(ClickEvent.copyToClipboard("abcdxyz"))); + } +} From c7f406a221c20e55a08a40e6b30990a98248873e Mon Sep 17 00:00:00 2001 From: codestech Date: Wed, 19 Jun 2024 13:09:17 +0200 Subject: [PATCH 22/86] chore: resolve requested changes --- .../serializer/nbt/ClickEventSerializer.java | 72 +++-------------- .../serializer/nbt/HoverEventSerializer.java | 56 ++----------- .../nbt/NBTComponentSerializer.java | 61 --------------- .../nbt/NBTComponentSerializerImpl.java | 15 ---- .../serializer/nbt/NBTSerializerOptions.java | 78 ------------------- .../text/serializer/nbt/StyleSerializer.java | 12 +-- .../serializer/nbt/ScoreComponentTest.java | 8 +- .../nbt/StorageNBTComponentTest.java | 2 + 8 files changed, 25 insertions(+), 279 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java index f1b7226314..4218dffa7d 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java @@ -23,90 +23,36 @@ */ package net.kyori.adventure.text.serializer.nbt; +import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.StringBinaryTag; import net.kyori.adventure.text.event.ClickEvent; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; final class ClickEventSerializer { private static final String ACTION = "action"; private static final String VALUE = "value"; - private static final String CLICK_EVENT_OPEN_URL = "open_url"; - private static final String CLICK_EVENT_OPEN_FILE = "open_file"; - private static final String CLICK_EVENT_RUN_COMMAND = "run_command"; - private static final String CLICK_EVENT_SUGGEST_COMMAND = "suggest_command"; - private static final String CLICK_EVENT_CHANGE_PAGE = "change_page"; - private static final String CLICK_EVENT_COPY_TO_CLIPBOARD = "copy_to_clipboard"; - private ClickEventSerializer() { } - static @Nullable ClickEvent deserialize(@NotNull CompoundBinaryTag tag) { - ClickEvent.Action action; - String actionString = tag.getString(ACTION); + static @NotNull ClickEvent deserialize(@NotNull CompoundBinaryTag tag) { + BinaryTag actionTag = tag.get(ACTION); - if (actionString.isEmpty()) { - return null; + if (actionTag == null) { + throw new IllegalArgumentException("The serialized click event doesn't contain an action"); } - switch (actionString) { - case CLICK_EVENT_OPEN_URL: - action = ClickEvent.Action.OPEN_URL; - break; - case CLICK_EVENT_OPEN_FILE: - action = ClickEvent.Action.OPEN_FILE; - break; - case CLICK_EVENT_RUN_COMMAND: - action = ClickEvent.Action.RUN_COMMAND; - break; - case CLICK_EVENT_SUGGEST_COMMAND: - action = ClickEvent.Action.SUGGEST_COMMAND; - break; - case CLICK_EVENT_CHANGE_PAGE: - action = ClickEvent.Action.CHANGE_PAGE; - break; - case CLICK_EVENT_COPY_TO_CLIPBOARD: - action = ClickEvent.Action.COPY_TO_CLIPBOARD; - break; - default: - return null; - } + String actionString = ((StringBinaryTag) actionTag).value(); + ClickEvent.Action action = ClickEvent.Action.NAMES.valueOrThrow(actionString); return ClickEvent.clickEvent(action, tag.getString(VALUE)); } static @NotNull CompoundBinaryTag serialize(@NotNull ClickEvent event) { - ClickEvent.Action action = event.action(); - String actionString; - - switch (action) { - case OPEN_URL: - actionString = CLICK_EVENT_OPEN_URL; - break; - case OPEN_FILE: - actionString = CLICK_EVENT_OPEN_FILE; - break; - case RUN_COMMAND: - actionString = CLICK_EVENT_RUN_COMMAND; - break; - case SUGGEST_COMMAND: - actionString = CLICK_EVENT_SUGGEST_COMMAND; - break; - case CHANGE_PAGE: - actionString = CLICK_EVENT_CHANGE_PAGE; - break; - case COPY_TO_CLIPBOARD: - actionString = CLICK_EVENT_COPY_TO_CLIPBOARD; - break; - default: - // Never called, but needed for proper compilation - throw new IllegalStateException("Unknown click event action: " + action); - } - return CompoundBinaryTag.builder() - .putString(ACTION, actionString) + .putString(ACTION, ClickEvent.Action.NAMES.keyOrThrow(event.action())) .putString(VALUE, event.value()) .build(); } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java index c8b621a165..adf20b5408 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -26,14 +26,10 @@ import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; -import net.kyori.adventure.nbt.StringBinaryTag; -import net.kyori.adventure.nbt.api.BinaryTagHolder; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.DataComponentValue; import net.kyori.adventure.text.event.HoverEvent; -import net.kyori.option.OptionState; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; @@ -43,20 +39,14 @@ final class HoverEventSerializer { private static final String HOVER_EVENT_ACTION = "action"; private static final String HOVER_EVENT_CONTENTS = "contents"; - @Deprecated - private static final String HOVER_EVENT_VALUE = "value"; private static final String HOVER_EVENT_SHOW_TEXT = "show_text"; private static final String HOVER_EVENT_SHOW_ITEM = "show_item"; private static final String HOVER_EVENT_SHOW_ENTITY = "show_entity"; - @Deprecated - private static final String HOVER_EVENT_SHOW_ACHIEVEMENT = "show_achievement"; private static final String SHOW_ITEM_ID = "id"; private static final String SHOW_ITEM_COUNT = "count"; private static final String SHOW_ITEM_COMPONENTS = "components"; - @Deprecated - private static final String SHOW_ITEM_TAG = "tag"; private static final String SHOW_ENTITY_TYPE = "type"; private static final String SHOW_ENTITY_ID = "id"; @@ -72,10 +62,7 @@ private HoverEventSerializer() { BinaryTag contents = compound.get(HOVER_EVENT_CONTENTS); if (contents == null) { - contents = compound.get(HOVER_EVENT_VALUE); - if (contents == null) { - throw new IllegalArgumentException("The hover event doesn't contain any contents"); - } + throw new IllegalArgumentException("The hover event doesn't contain any contents"); } if (Component.class.isAssignableFrom(actionType)) { @@ -87,7 +74,6 @@ private HoverEventSerializer() { int itemCount = showItemContents.getInt(SHOW_ITEM_COUNT); BinaryTag components = showItemContents.get(SHOW_ITEM_COMPONENTS); - BinaryTag tag = showItemContents.get(SHOW_ITEM_TAG); if (components != null) { CompoundBinaryTag componentsCompound = (CompoundBinaryTag) components; @@ -100,9 +86,6 @@ private HoverEventSerializer() { } return HoverEvent.showItem(itemId, itemCount, componentValues); - } else if (tag != null) { - BinaryTagHolder holder = BinaryTagHolder.binaryTagHolder(((StringBinaryTag) tag).value()); - return HoverEvent.showItem(itemId, itemCount, holder); } else { return HoverEvent.showItem(itemId, itemCount); } @@ -119,31 +102,14 @@ private HoverEventSerializer() { } else { return HoverEvent.showEntity(entityType, entityId); } - } else if (String.class.isAssignableFrom(actionType)) { - return HoverEvent.showAchievement(((StringBinaryTag) contents).value()); } else { - // Never called, but needed for proper compilation - throw new IllegalArgumentException("Unknown hover event"); + throw new IllegalArgumentException("Don't know how to deserialize a hoverEvent with action of " + actionString + " from a binary tag"); } } - static @Nullable CompoundBinaryTag serialize(@NotNull HoverEvent event, @NotNull NBTComponentSerializerImpl serializer) { - OptionState flags = serializer.flags(); + static @NotNull CompoundBinaryTag serialize(@NotNull HoverEvent event, @NotNull NBTComponentSerializerImpl serializer) { HoverEvent.Action action = event.action(); - NBTSerializerOptions.HoverEventValueMode hoverMode = flags.value(NBTSerializerOptions.EMIT_HOVER_EVENT_TYPE); - - if (action == HoverEvent.Action.SHOW_ACHIEVEMENT) { - if (hoverMode == NBTSerializerOptions.HoverEventValueMode.MODERN_ONLY) { - return null; - } - - return CompoundBinaryTag.builder() - .putString(HOVER_EVENT_ACTION, HOVER_EVENT_SHOW_ACHIEVEMENT) - .putString(HOVER_EVENT_VALUE, (String) event.value()) - .build(); - } - BinaryTag contents; String actionString; @@ -158,9 +124,8 @@ private HoverEventSerializer() { .putInt(SHOW_ITEM_COUNT, item.count()); Map components = item.dataComponentsAs(NBTDataComponentValue.class); - NBTSerializerOptions.ShowItemHoverDataMode dataMode = flags.value(NBTSerializerOptions.SHOW_ITEM_HOVER_DATA_MODE); - if (!components.isEmpty() && dataMode != NBTSerializerOptions.ShowItemHoverDataMode.EMIT_LEGACY_NBT) { + if (!components.isEmpty()) { CompoundBinaryTag.Builder dataComponentsBuilder = CompoundBinaryTag.builder(); for (Map.Entry entry : components.entrySet()) { @@ -168,20 +133,11 @@ private HoverEventSerializer() { } builder.put(SHOW_ITEM_COMPONENTS, dataComponentsBuilder.build()); - } else if (dataMode != NBTSerializerOptions.ShowItemHoverDataMode.EMIT_DATA_COMPONENTS) { - BinaryTagHolder holder = item.nbt(); - if (holder != null) { - builder.putString(SHOW_ITEM_TAG, holder.string()); - } } contents = builder.build(); actionString = HOVER_EVENT_SHOW_ITEM; } else if (action == HoverEvent.Action.SHOW_ENTITY) { - if (hoverMode == NBTSerializerOptions.HoverEventValueMode.LEGACY_ONLY) { - return null; - } - HoverEvent.ShowEntity item = (HoverEvent.ShowEntity) event.value(); CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() @@ -196,12 +152,12 @@ private HoverEventSerializer() { contents = builder.build(); actionString = HOVER_EVENT_SHOW_ENTITY; } else { - throw new IllegalArgumentException("Don't know how to serialize " + event + " as a HoverEvent"); + throw new IllegalArgumentException("Don't know how to serialize " + event + " as a binary tag"); } return CompoundBinaryTag.builder() .putString(HOVER_EVENT_ACTION, actionString) - .put(hoverMode == NBTSerializerOptions.HoverEventValueMode.LEGACY_ONLY ? HOVER_EVENT_VALUE : HOVER_EVENT_CONTENTS, contents) + .put(HOVER_EVENT_CONTENTS, contents) .build(); } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java index c27e59709c..2dc88d0767 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java @@ -37,9 +37,6 @@ /** * A NBT component serializer. * - *

Use {@link Builder#emitRgb(boolean)} to support platforms - * that do not understand hex colors that were introduced in Minecraft 1.16.

- * * @since 4.18.0 */ public interface NBTComponentSerializer extends ComponentSerializer { @@ -91,64 +88,6 @@ interface Builder extends AbstractBuilder { */ @NotNull Builder editOptions(final @NotNull Consumer optionEditor); - /** - * Sets whether the serializer should downsample hex colors to named colors. - * - * @param emit true if the serializer should downsample hex colors to named colors, false otherwise - * @return this builder - * @since 4.18.0 - */ - default @NotNull Builder emitRgb(final boolean emit) { - return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_RGB, emit)); - } - - /** - * Sets a {@linkplain NBTSerializerOptions.HoverEventValueMode hover event value mode} of the serializer. - * - * @param mode the mode - * @return this builder - * @since 4.18.0 - */ - default @NotNull Builder emitHoverEventValueMode(final @NotNull NBTSerializerOptions.HoverEventValueMode mode) { - return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_HOVER_EVENT_TYPE, mode)); - } - - /** - * Sets whether the serializer should serialize types of the components. - * - * @param serialize true if the serializer should serialize types of the components, false otherwise - * @return this builder - * @since 4.18.0 - */ - default @NotNull Builder serializeComponentTypes(final boolean serialize) { - return this.editOptions(builder -> builder.value(NBTSerializerOptions.SERIALIZE_COMPONENT_TYPES, serialize)); - } - - /** - * Sets a {@linkplain NBTSerializerOptions.ShowItemHoverDataMode show item hover data mode} of the serializer. - * - * @param mode the mode - * @return this builder - * @since 4.18.0 - */ - default @NotNull Builder showItemHoverDataMode(final @NotNull NBTSerializerOptions.ShowItemHoverDataMode mode) { - return this.editOptions(builder -> builder.value(NBTSerializerOptions.SHOW_ITEM_HOVER_DATA_MODE, mode)); - } - - /** - * Sets whether the serializer should serialize text components without styling as - * {@linkplain net.kyori.adventure.nbt.StringBinaryTag string binary tags} instead of - * {@linkplain net.kyori.adventure.nbt.CompoundBinaryTag compound binary tags}. - * - * @param emit true if the serializer should serialize text components without styling - * as string binary tags, false otherwise - * @return this builder - * @since 4.18.0 - */ - default @NotNull Builder emitCompactTextComponent(final boolean emit) { - return this.editOptions(builder -> builder.value(NBTSerializerOptions.EMIT_COMPACT_TEXT_COMPONENT, emit)); - } - /** * Builds the serializer. * diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 8657e9f9c5..a7837e90e9 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -89,8 +89,6 @@ static final class Instances { private static final String SCORE = "score"; private static final String SCORE_NAME = "name"; private static final String SCORE_OBJECTIVE = "objective"; - @Deprecated - private static final String SCORE_VALUE = "value"; private static final String SELECTOR = "selector"; private static final String SELECTOR_SEPARATOR = "separator"; @@ -185,17 +183,9 @@ static final class Instances { String scoreName = binaryScore.getString(SCORE_NAME); String scoreObjective = binaryScore.getString(SCORE_OBJECTIVE); - String scoreValue = null; - BinaryTag binaryScoreValue = binaryScore.get(SCORE_VALUE); - - if (binaryScoreValue != null) { - scoreValue = ((StringBinaryTag) binaryScoreValue).value(); - } - return Component.score() .name(scoreName) .objective(scoreObjective) - .value(scoreValue) .style(style) .append(children) .build(); @@ -311,11 +301,6 @@ static final class Instances { .putString(SCORE_NAME, score.name()) .putString(SCORE_OBJECTIVE, score.objective()); - String value = score.value(); - if (value != null) { - scoreBuilder.putString(SCORE_VALUE, value); - } - builder.put(SCORE, scoreBuilder.build()); } else if (component instanceof SelectorComponent) { this.writeComponentType(TYPE_SELECTOR, builder); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index 089a569dca..d32eab1abc 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -40,24 +40,6 @@ public final class NBTSerializerOptions { * @sinceMinecraft 1.20.3 */ public static final Option EMIT_COMPACT_TEXT_COMPONENT = Option.booleanOption(key("emit/compact_text_component"), true); - - /** - * How to emit the item data on {@code show_item} hover events. - * - * @since 4.18.0 - */ - public static final Option SHOW_ITEM_HOVER_DATA_MODE = Option.enumOption(key("emit/show_item_hover_data"), ShowItemHoverDataMode.class, ShowItemHoverDataMode.EMIT_EITHER); - - /** - * Whether to emit RGB text. - * - *

If this attribute is disabled, colors in styles will be downsampled to the classic 16 colors.

- * - * @since 4.18.0 - * @sinceMinecraft 1.16 - */ - public static final Option EMIT_RGB = Option.booleanOption(key("emit/rgb"), true); - /** * Whether to serialize the types of {@linkplain net.kyori.adventure.text.Component components}. * @@ -65,70 +47,10 @@ public final class NBTSerializerOptions { */ public static final Option SERIALIZE_COMPONENT_TYPES = Option.booleanOption(key("serialize/component-types"), true); - - /** - * Control how hover event values should be emitted. - * - * @since 4.18.0 - */ - public static final Option EMIT_HOVER_EVENT_TYPE = Option.enumOption(key("emit/hover_value_mode"), HoverEventValueMode.class, HoverEventValueMode.MODERN_ONLY); - private NBTSerializerOptions() { } private static String key(final String value) { return "adventure:nbt/" + value; } - - /** - * Configure how to emit show_item hovers. - * - * @since 4.18.0 - */ - public enum ShowItemHoverDataMode { - /** - * Only emit the pre-1.20.5 item nbt. - * - * @since 4.18.0 - */ - EMIT_LEGACY_NBT, - /** - * Only emit modern data components. - * - * @since 4.18.0 - */ - EMIT_DATA_COMPONENTS, - /** - * Emit whichever of legacy or modern data the item has. - * - * @since 4.18.0 - */ - EMIT_EITHER, - } - - /** - * Configure how to emit hover event values. - * - * @since 4.18.0 - */ - public enum HoverEventValueMode { - /** - * Only emit the 1.16+ modern hover events. - * - * @since 4.18.0 - */ - MODERN_ONLY, - /** - * Only emit the pre-1.16 hover event {@code value} field. - * - * @since 4.18.0 - */ - LEGACY_ONLY, - /** - * Include both modern and legacy hover event fields, for maximum compatibility. - * - * @since 4.18.0 - */ - BOTH, - } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java index 0ca5f20dc3..a94af0a523 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java @@ -98,11 +98,7 @@ static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder b TextColor color = style.color(); if (color != null) { - if (color instanceof NamedTextColor) { - builder.putString(COLOR, color.toString()); - } else if (serializer.flags().value(NBTSerializerOptions.EMIT_RGB)) { - builder.putString(COLOR, color.asHexString()); - } + builder.putString(COLOR, color instanceof NamedTextColor ? color.toString() : color.asHexString()); } style.decorations().forEach((decoration, state) -> { @@ -153,12 +149,8 @@ static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder b } HoverEvent hoverEvent = style.hoverEvent(); - if (hoverEvent != null) { - CompoundBinaryTag binaryHoverEvent = HoverEventSerializer.serialize(hoverEvent, serializer); - if (binaryHoverEvent != null) { - builder.put(HOVER_EVENT, binaryHoverEvent); - } + builder.put(HOVER_EVENT, HoverEventSerializer.serialize(hoverEvent, serializer)); } } diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java index bbb5fa8cdc..1277fe63d0 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java @@ -24,16 +24,20 @@ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; import org.junit.jupiter.api.Test; final class ScoreComponentTest implements NBTComponentTest { @Test public void testNoStyling() { - this.test(Component.score("a-score", "dummy", "idk-what-to-put-here")); + this.test(Component.score("a-score", "dummy")); } @Test public void testWithStyling() { - this.test(Component.score("some-score", "another-dummy-objective", "a-value")); + this.test(Component.score("some-score", "another-dummy-objective") + .decorate(TextDecoration.BOLD) + .color(NamedTextColor.RED)); } } diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java index b25ad81af6..ef386d8b8b 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java @@ -42,6 +42,8 @@ public void testWithStyling() { .interpret(false) .separator(Component.text("another-separator", NamedTextColor.RED, TextDecoration.OBFUSCATED)) .storage(Key.key("dummy", "storage")) + .color(NamedTextColor.YELLOW) + .decorate(TextDecoration.BOLD) .build()); } } From cc298cbcf34b1346b38c2f78f90232d9db586cfb Mon Sep 17 00:00:00 2001 From: codestech Date: Wed, 19 Jun 2024 17:07:36 +0200 Subject: [PATCH 23/86] feat: add a possibility to (de)-serialize a style without a component --- .../nbt/NBTComponentSerializer.java | 20 +++++++++++++++++++ .../nbt/NBTComponentSerializerImpl.java | 12 +++++++++++ 2 files changed, 32 insertions(+) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java index 2dc88d0767..82b1eac070 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java @@ -25,7 +25,9 @@ import net.kyori.adventure.builder.AbstractBuilder; import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.serializer.ComponentSerializer; import net.kyori.adventure.util.PlatformAPI; import net.kyori.option.OptionState; @@ -40,6 +42,24 @@ * @since 4.18.0 */ public interface NBTComponentSerializer extends ComponentSerializer { + /** + * Deserializes a {@linkplain Style style} from a {@linkplain BinaryTag binary tag}. + * + * @param tag the binary tag + * @return the style + * @since 4.18.0 + */ + @NotNull Style deserializeStyle(@NotNull CompoundBinaryTag tag); + + /** + * Serializes a {@linkplain Style style} to a {@linkplain BinaryTag binary tag}. + * + * @param style the style + * @return the binary tag + * @since 4.18.0 + */ + @NotNull CompoundBinaryTag serializeStyle(@NotNull Style style); + /** * Gets a component serializer for NBT serialization and deserialization. * diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index a7837e90e9..ac30ae1027 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -60,6 +60,18 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { // NOOP }); + @Override + public @NotNull Style deserializeStyle(@NotNull CompoundBinaryTag tag) { + return StyleSerializer.deserialize(tag, this); + } + + @Override + public @NotNull CompoundBinaryTag serializeStyle(@NotNull Style style) { + CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder(); + StyleSerializer.serialize(style, builder, this); + return builder.build(); + } + // We cannot store these fields in NBTComponentSerializerImpl directly due to class initialisation issues. static final class Instances { static final NBTComponentSerializer INSTANCE = SERVICE From 8996ab0d6bc3a44714895dd2442e425f3997bdf2 Mon Sep 17 00:00:00 2001 From: codestech Date: Fri, 21 Jun 2024 15:53:54 +0200 Subject: [PATCH 24/86] chore: simplify serializing text colors with TextColor#toString --- .../kyori/adventure/text/serializer/nbt/StyleSerializer.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java index a94af0a523..ad0ab12cb1 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java @@ -96,9 +96,8 @@ private StyleSerializer() { static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder builder, @NotNull NBTComponentSerializerImpl serializer) { TextColor color = style.color(); - if (color != null) { - builder.putString(COLOR, color instanceof NamedTextColor ? color.toString() : color.asHexString()); + builder.putString(COLOR, color.toString()); } style.decorations().forEach((decoration, state) -> { From c5e3525ce87fad5bb2f2a5999eb758e8446d6514 Mon Sep 17 00:00:00 2001 From: codestech Date: Fri, 20 Jun 2025 17:32:20 +0200 Subject: [PATCH 25/86] feat: shadow color serializing --- text-serializer-nbt/build.gradle.kts | 1 + .../serializer/nbt/NBTSerializerOptions.java | 32 ++++++++++ .../serializer/nbt/ShadowColorSerializer.java | 61 +++++++++++++++++++ .../text/serializer/nbt/StyleSerializer.java | 15 +++++ 4 files changed, 109 insertions(+) create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java diff --git a/text-serializer-nbt/build.gradle.kts b/text-serializer-nbt/build.gradle.kts index a7e7bbe317..88320bdde3 100644 --- a/text-serializer-nbt/build.gradle.kts +++ b/text-serializer-nbt/build.gradle.kts @@ -6,6 +6,7 @@ dependencies { api(libs.option) api(projects.adventureApi) api(projects.adventureNbt) + implementation(projects.adventureTextSerializerCommons) } applyJarMetadata("net.kyori.adventure.text.serializer.nbt") diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index d32eab1abc..c13bc7ffac 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -46,6 +46,13 @@ public final class NBTSerializerOptions { * @since 4.18.0 */ public static final Option SERIALIZE_COMPONENT_TYPES = Option.booleanOption(key("serialize/component-types"), true); + /** + * How to emit shadow colour data. + * + * @since 4.18.0 + * @sinceMinecraft 1.21.4 + */ + public static final Option SHADOW_COLOR_MODE = Option.enumOption(key("emit/shadow_color"), ShadowColorEmitMode.class, ShadowColorEmitMode.EMIT_INTEGER); private NBTSerializerOptions() { } @@ -53,4 +60,29 @@ private NBTSerializerOptions() { private static String key(final String value) { return "adventure:nbt/" + value; } + + /** + * How text shadow colors should be emitted. + * + * @since 4.18.0 + * @sinceMinecraft 1.21.4 + */ + public enum ShadowColorEmitMode { + /** + * Do not emit shadow colours. + */ + NONE, + /** + * Emit as a single packed integer value containing, in order, ARGB bytes. + * + * @since 4.18.0 + */ + EMIT_INTEGER, + /** + * Emit a colour as 4-element float array of the RGBA components of the colour. + * + * @since 4.18.0 + */ + EMIT_ARRAY + } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java new file mode 100644 index 0000000000..dcb2da2ed1 --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java @@ -0,0 +1,61 @@ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.BinaryTagTypes; +import net.kyori.adventure.nbt.FloatBinaryTag; +import net.kyori.adventure.nbt.IntBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; +import net.kyori.adventure.text.format.ShadowColor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +final class ShadowColorSerializer { + + private ShadowColorSerializer() { + } + + static @Nullable BinaryTag serialize(@NotNull ShadowColor color, @NotNull NBTComponentSerializerImpl serializer) { + NBTSerializerOptions.ShadowColorEmitMode emitMode = serializer.flags().value(NBTSerializerOptions.SHADOW_COLOR_MODE); + switch (emitMode) { + case NONE: + return null; + case EMIT_INTEGER: + return IntBinaryTag.intBinaryTag(color.value()); + case EMIT_ARRAY: + ListBinaryTag.Builder shadowColorTagBuilder = ListBinaryTag.builder(BinaryTagTypes.FLOAT); + addShadowColorComponent(shadowColorTagBuilder, color.red()); + addShadowColorComponent(shadowColorTagBuilder, color.green()); + addShadowColorComponent(shadowColorTagBuilder, color.blue()); + addShadowColorComponent(shadowColorTagBuilder, color.alpha()); + return shadowColorTagBuilder.build(); + default: + // Never called, but needed for proper compilation + throw new IllegalArgumentException("Unknown shadow color emit mode: " + emitMode); + } + } + + static @NotNull ShadowColor deserialize(@NotNull BinaryTag tag) { + if (tag instanceof IntBinaryTag) { + IntBinaryTag castShadowColorTag = (IntBinaryTag) tag; + return ShadowColor.shadowColor(castShadowColorTag.value()); + } else if (tag instanceof ListBinaryTag) { + ListBinaryTag castShadowColorTag = (ListBinaryTag) tag; + return ShadowColor.shadowColor( + getShadowColorComponent(castShadowColorTag, 0), + getShadowColorComponent(castShadowColorTag, 1), + getShadowColorComponent(castShadowColorTag, 2), + getShadowColorComponent(castShadowColorTag, 3) + ); + } else { + throw new IllegalArgumentException("The binary tag representing the shadow color is of an invalid type"); + } + } + + private static int getShadowColorComponent(@NotNull ListBinaryTag tag, int index) { + return (int) (tag.getFloat(index) * 0xff); + } + + private static void addShadowColorComponent(@NotNull ListBinaryTag.Builder builder, int element) { + builder.add(FloatBinaryTag.floatBinaryTag((float) element / 0xff)); + } +} diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java index ad0ab12cb1..645a475199 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java @@ -31,9 +31,11 @@ import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.ShadowColor; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; import org.jetbrains.annotations.NotNull; final class StyleSerializer { @@ -90,6 +92,11 @@ private StyleSerializer() { styleBuilder.hoverEvent(HoverEventSerializer.deserialize((CompoundBinaryTag) binaryHoverEvent, serializer)); } + BinaryTag shadowColorTag = compound.get(ComponentTreeConstants.SHADOW_COLOR); + if (shadowColorTag != null) { + styleBuilder.shadowColor(ShadowColorSerializer.deserialize(shadowColorTag)); + } + return styleBuilder.build(); } @@ -151,6 +158,14 @@ static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder b if (hoverEvent != null) { builder.put(HOVER_EVENT, HoverEventSerializer.serialize(hoverEvent, serializer)); } + + ShadowColor shadowColor = style.shadowColor(); + if (shadowColor != null) { + BinaryTag serializedShadowColor = ShadowColorSerializer.serialize(shadowColor, serializer); + if (serializedShadowColor != null) { + builder.put(ComponentTreeConstants.SHADOW_COLOR, serializedShadowColor); + } + } } private static TextDecoration.@NotNull State readOptionalState(@NotNull String key, @NotNull CompoundBinaryTag compound) { From 6e77a335825367d3b78c422e6a07b935dec06090 Mon Sep 17 00:00:00 2001 From: codestech Date: Fri, 20 Jun 2025 17:44:12 +0200 Subject: [PATCH 26/86] chore: update all `@since` tags to use version 4.24.0 --- .../nbt/NBTComponentSerializer.java | 24 +++++++++---------- .../serializer/nbt/NBTDataComponentValue.java | 6 ++--- .../serializer/nbt/NBTSerializerOptions.java | 14 +++++------ 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java index 82b1eac070..28435bdec8 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java @@ -39,7 +39,7 @@ /** * A NBT component serializer. * - * @since 4.18.0 + * @since 4.24.0 */ public interface NBTComponentSerializer extends ComponentSerializer { /** @@ -47,7 +47,7 @@ public interface NBTComponentSerializer extends ComponentSerializer { /** @@ -94,7 +94,7 @@ interface Builder extends AbstractBuilder { * @param flags the flag set to use * @return this builder * @see NBTSerializerOptions - * @since 4.18.0 + * @since 4.24.0 */ @NotNull Builder options(final @NotNull OptionState flags); @@ -104,7 +104,7 @@ interface Builder extends AbstractBuilder { * @param optionEditor the consumer operating on the existing flag set * @return this builder * @see NBTSerializerOptions - * @since 4.18.0 + * @since 4.24.0 */ @NotNull Builder editOptions(final @NotNull Consumer optionEditor); @@ -112,7 +112,7 @@ interface Builder extends AbstractBuilder { * Builds the serializer. * * @return the built serializer - * @since 4.18.0 + * @since 4.24.0 */ @Override @NotNull NBTComponentSerializer build(); @@ -121,7 +121,7 @@ interface Builder extends AbstractBuilder { /** * A {@link NBTComponentSerializer} service provider. * - * @since 4.18.0 + * @since 4.24.0 */ @ApiStatus.Internal @PlatformAPI @@ -130,7 +130,7 @@ interface Provider { * Provides a standard {@link NBTComponentSerializer}. * * @return a {@link NBTComponentSerializer} - * @since 4.18.0 + * @since 4.24.0 */ @ApiStatus.Internal @PlatformAPI @@ -140,7 +140,7 @@ interface Provider { * Completes the building process of {@link Builder}. * * @return a {@link Consumer} - * @since 4.18.0 + * @since 4.24.0 */ @ApiStatus.Internal @PlatformAPI diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java index 69c346ac5c..62640291de 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java @@ -33,7 +33,7 @@ * *

This holder is exposed to allow conversions to/from NBT data holders.

* - * @since 4.18.0 + * @since 4.24.0 */ @ApiStatus.NonExtendable public interface NBTDataComponentValue extends DataComponentValue { @@ -41,7 +41,7 @@ public interface NBTDataComponentValue extends DataComponentValue { * The contained element, intended for read-only use. * * @return a copy of the contained element - * @since 4.18.0 + * @since 4.24.0 */ @NotNull BinaryTag binaryTag(); @@ -50,7 +50,7 @@ public interface NBTDataComponentValue extends DataComponentValue { * * @param binaryTag the item data to hold * @return a newly created item data holder instance - * @since 4.18.0 + * @since 4.24.0 */ static @NotNull NBTDataComponentValue nbtDataComponentValue(@NotNull BinaryTag binaryTag) { return new NBTDataComponentValueImpl(binaryTag); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index c13bc7ffac..d9d8b5f4d1 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -30,26 +30,26 @@ * *

See serializer documentation for specific details on which flags are supported.

* - * @since 4.18.0 + * @since 4.24.0 */ public final class NBTSerializerOptions { /** * Whether to emit text components with no style and no children as plain text. * - * @since 4.18.0 + * @since 4.24.0 * @sinceMinecraft 1.20.3 */ public static final Option EMIT_COMPACT_TEXT_COMPONENT = Option.booleanOption(key("emit/compact_text_component"), true); /** * Whether to serialize the types of {@linkplain net.kyori.adventure.text.Component components}. * - * @since 4.18.0 + * @since 4.24.0 */ public static final Option SERIALIZE_COMPONENT_TYPES = Option.booleanOption(key("serialize/component-types"), true); /** * How to emit shadow colour data. * - * @since 4.18.0 + * @since 4.24.0 * @sinceMinecraft 1.21.4 */ public static final Option SHADOW_COLOR_MODE = Option.enumOption(key("emit/shadow_color"), ShadowColorEmitMode.class, ShadowColorEmitMode.EMIT_INTEGER); @@ -64,7 +64,7 @@ private static String key(final String value) { /** * How text shadow colors should be emitted. * - * @since 4.18.0 + * @since 4.24.0 * @sinceMinecraft 1.21.4 */ public enum ShadowColorEmitMode { @@ -75,13 +75,13 @@ public enum ShadowColorEmitMode { /** * Emit as a single packed integer value containing, in order, ARGB bytes. * - * @since 4.18.0 + * @since 4.24.0 */ EMIT_INTEGER, /** * Emit a colour as 4-element float array of the RGBA components of the colour. * - * @since 4.18.0 + * @since 4.24.0 */ EMIT_ARRAY } From 95bd14653bbf1911a3e351ef86cfaf18f9577346 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 21 Jun 2025 11:05:50 +0200 Subject: [PATCH 27/86] chore: update ClickEventSerializer to support the latest format --- .../serializer/nbt/ClickEventSerializer.java | 110 +++++++++++++++--- .../serializer/nbt/NBTSerializerUtils.java | 42 +++++++ 2 files changed, 136 insertions(+), 16 deletions(-) create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java index 4218dffa7d..2f70b3cb39 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java @@ -23,37 +23,115 @@ */ package net.kyori.adventure.text.serializer.nbt; -import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.BinaryTagTypes; import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.IntBinaryTag; import net.kyori.adventure.nbt.StringBinaryTag; +import net.kyori.adventure.nbt.api.BinaryTagHolder; import net.kyori.adventure.text.event.ClickEvent; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -final class ClickEventSerializer { +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_ACTION; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_COMMAND; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_ID; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_PAGE; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_PAYLOAD; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_URL; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_VALUE; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getRequiredTag; - private static final String ACTION = "action"; - private static final String VALUE = "value"; +final class ClickEventSerializer { private ClickEventSerializer() { } - static @NotNull ClickEvent deserialize(@NotNull CompoundBinaryTag tag) { - BinaryTag actionTag = tag.get(ACTION); + static @Nullable ClickEvent deserializeCamel(@NotNull CompoundBinaryTag tag) { + StringBinaryTag actionTag = getRequiredTag(tag, CLICK_EVENT_ACTION, BinaryTagTypes.STRING); + StringBinaryTag valueTag = getRequiredTag(tag, CLICK_EVENT_VALUE, BinaryTagTypes.STRING); - if (actionTag == null) { - throw new IllegalArgumentException("The serialized click event doesn't contain an action"); + ClickEvent.Action action = ClickEvent.Action.NAMES.valueOrThrow(actionTag.value()); + if (!action.readable()) { + return null; } - String actionString = ((StringBinaryTag) actionTag).value(); - ClickEvent.Action action = ClickEvent.Action.NAMES.valueOrThrow(actionString); + return ClickEvent.clickEvent(action, valueTag.value()); + } + + static @Nullable ClickEvent deserializeSnake(@NotNull CompoundBinaryTag tag) { + StringBinaryTag actionTag = getRequiredTag(tag, CLICK_EVENT_ACTION, BinaryTagTypes.STRING); + ClickEvent.Action action = ClickEvent.Action.NAMES.valueOrThrow(actionTag.value()); + + if (!action.readable()) { + return null; + } - return ClickEvent.clickEvent(action, tag.getString(VALUE)); + switch (action) { + case OPEN_URL: + StringBinaryTag urlTag = getRequiredTag(tag, CLICK_EVENT_URL, BinaryTagTypes.STRING); + return ClickEvent.openUrl(urlTag.value()); + case RUN_COMMAND: + case SUGGEST_COMMAND: + StringBinaryTag commandTag = getRequiredTag(tag, CLICK_EVENT_COMMAND, BinaryTagTypes.STRING); + String command = commandTag.value(); + return action == ClickEvent.Action.RUN_COMMAND ? ClickEvent.runCommand(command) : ClickEvent.suggestCommand(command); + case CHANGE_PAGE: + IntBinaryTag pageTag = getRequiredTag(tag, CLICK_EVENT_PAGE, BinaryTagTypes.INT); + return ClickEvent.changePage(pageTag.value()); + case COPY_TO_CLIPBOARD: + StringBinaryTag valueTag = getRequiredTag(tag, CLICK_EVENT_VALUE, BinaryTagTypes.STRING); + return ClickEvent.copyToClipboard(valueTag.value()); + case CUSTOM: + StringBinaryTag clickEventIdTag = getRequiredTag(tag, CLICK_EVENT_ID, BinaryTagTypes.STRING); + StringBinaryTag payloadTag = getRequiredTag(tag, CLICK_EVENT_PAYLOAD, BinaryTagTypes.STRING); + return ClickEvent.custom(Key.key(clickEventIdTag.value()), BinaryTagHolder.binaryTagHolder(payloadTag.value())); + default: + // Never called, but needed for proper compilation + throw new IllegalArgumentException("Unknown click event action: " + action); + } } - static @NotNull CompoundBinaryTag serialize(@NotNull ClickEvent event) { - return CompoundBinaryTag.builder() - .putString(ACTION, ClickEvent.Action.NAMES.keyOrThrow(event.action())) - .putString(VALUE, event.value()) - .build(); + static @Nullable CompoundBinaryTag serialize(@NotNull ClickEvent event, boolean snakeCase) { + CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() + .putString(CLICK_EVENT_ACTION, ClickEvent.Action.NAMES.keyOrThrow(event.action())); + + if (snakeCase) { + ClickEvent.Action action = event.action(); + if (!action.readable()) { + return null; + } + + ClickEvent.Payload payload = event.payload(); + if (payload instanceof ClickEvent.Payload.Text) { + String payloadFieldName; + switch (action) { + case OPEN_URL: + payloadFieldName = CLICK_EVENT_URL; + break; + case RUN_COMMAND: + case SUGGEST_COMMAND: + payloadFieldName = CLICK_EVENT_COMMAND; + break; + case COPY_TO_CLIPBOARD: + payloadFieldName = CLICK_EVENT_VALUE; + break; + default: + // Never called, but needed for proper compilation + throw new IllegalArgumentException("Unknown click event action: " + action); + } + builder.putString(payloadFieldName, ((ClickEvent.Payload.Text) payload).value()); + } else if (payload instanceof ClickEvent.Payload.Custom) { + ClickEvent.Payload.Custom castPayload = (ClickEvent.Payload.Custom) payload; + builder.putString(CLICK_EVENT_ID, castPayload.key().asString()); + builder.putString(CLICK_EVENT_PAYLOAD, castPayload.nbt().string()); + } else if (payload instanceof ClickEvent.Payload.Int) { + builder.putInt(CLICK_EVENT_PAGE, ((ClickEvent.Payload.Int) payload).integer()); + } + } else { + builder.putString(CLICK_EVENT_VALUE, event.value()); + } + + return builder.build(); } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java new file mode 100644 index 0000000000..291c612c0c --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java @@ -0,0 +1,42 @@ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.BinaryTagType; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +final class NBTSerializerUtils { + + private NBTSerializerUtils() { + } + + static @NotNull B getRequiredTag(@NotNull CompoundBinaryTag compoundTag, + @NotNull String name, @NotNull BinaryTagType tagType) { + B tag = getOptionalTag(compoundTag, name, tagType); + if (tag == null) { + throw new IllegalArgumentException("The specified compound tag does not contain a \"" + name + "\" field"); + } + return (B) tag; + } + + + static @Nullable B getOptionalTag(@NotNull CompoundBinaryTag compoundTag, + @NotNull String name, @NotNull BinaryTagType tagType) { + BinaryTag tag = compoundTag.get(name); + if (tag == null) { + return null; + } + + BinaryTagType actualTagType = tag.type(); + if (actualTagType != tagType) { + throw new IllegalArgumentException( + "A type of the tag is different than expected." + + " Expected: " + tagType.getClass().getSimpleName() + + " Actual: " + actualTagType.getClass().getSimpleName() + ); + } + + return (B) tag; + } +} From 847b477bc680be633c63da21f61aa57a12ea6ce5 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 21 Jun 2025 15:01:32 +0200 Subject: [PATCH 28/86] chore: create ShowItemSerializer for future use in StyleSerializer to support the latest format --- .../serializer/nbt/NBTDataComponentValue.java | 17 ++-- .../nbt/NBTDataComponentValueImpl.java | 12 ++- .../serializer/nbt/ShowItemSerializer.java | 87 +++++++++++++++++++ 3 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java index 62640291de..67da72a64d 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java @@ -24,10 +24,13 @@ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.EndBinaryTag; import net.kyori.adventure.text.event.DataComponentValue; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +import static java.util.Objects.requireNonNull; + /** * An {@link DataComponentValue} implementation that holds a {@linkplain BinaryTag binary tag}. * @@ -38,9 +41,9 @@ @ApiStatus.NonExtendable public interface NBTDataComponentValue extends DataComponentValue { /** - * The contained element, intended for read-only use. + * The contained element. * - * @return a copy of the contained element + * @return the contained element * @since 4.24.0 */ @NotNull BinaryTag binaryTag(); @@ -48,11 +51,15 @@ public interface NBTDataComponentValue extends DataComponentValue { /** * Create a box for item data that can be understood by the NBT serializer. * - * @param binaryTag the item data to hold + * @param data the item data to hold * @return a newly created item data holder instance * @since 4.24.0 */ - static @NotNull NBTDataComponentValue nbtDataComponentValue(@NotNull BinaryTag binaryTag) { - return new NBTDataComponentValueImpl(binaryTag); + static @NotNull NBTDataComponentValue nbtDataComponentValue(final @NotNull BinaryTag data) { + if (data instanceof EndBinaryTag) { + return NBTDataComponentValueImpl.RemovedNBTComponentValueImpl.INSTANCE; + } else { + return new NBTDataComponentValueImpl(requireNonNull(data, "data")); + } } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java index bd94d5558d..01bb00f1bd 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java @@ -24,11 +24,13 @@ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.EndBinaryTag; +import net.kyori.adventure.text.event.DataComponentValue; import org.jetbrains.annotations.NotNull; import java.util.Objects; -final class NBTDataComponentValueImpl implements NBTDataComponentValue { +class NBTDataComponentValueImpl implements NBTDataComponentValue { private final BinaryTag binaryTag; @@ -53,4 +55,12 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hashCode(this.binaryTag); } + + static final class RemovedNBTComponentValueImpl extends NBTDataComponentValueImpl implements DataComponentValue.Removed { + static final RemovedNBTComponentValueImpl INSTANCE = new RemovedNBTComponentValueImpl(); + + RemovedNBTComponentValueImpl() { + super(EndBinaryTag.endBinaryTag()); + } + } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java new file mode 100644 index 0000000000..79067afc5e --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java @@ -0,0 +1,87 @@ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.BinaryTagTypes; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.EndBinaryTag; +import net.kyori.adventure.nbt.IntBinaryTag; +import net.kyori.adventure.text.event.DataComponentValue; +import net.kyori.adventure.text.event.HoverEvent; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ITEM_COMPONENTS; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ITEM_COUNT; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ITEM_ID; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getOptionalTag; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getRequiredTag; + +final class ShowItemSerializer { + + private static final String DATA_COMPONENT_REMOVAL_PREFIX = "!"; + + private ShowItemSerializer() { + } + + static HoverEvent.@NotNull ShowItem deserialize(@NotNull CompoundBinaryTag compound) { + Key itemId = Key.key(getRequiredTag(compound, SHOW_ITEM_ID, BinaryTagTypes.STRING).value()); + + IntBinaryTag countTag = getOptionalTag(compound, SHOW_ITEM_COUNT, BinaryTagTypes.INT); + int itemCount = countTag == null ? 1 : countTag.value(); + + CompoundBinaryTag components = getOptionalTag(compound, SHOW_ITEM_COMPONENTS, BinaryTagTypes.COMPOUND); + if (components == null) { + return HoverEvent.ShowItem.showItem(itemId, itemCount); + } else { + Map componentValues = new HashMap<>(); + + for (String string : components.keySet()) { + boolean removed = string.startsWith(DATA_COMPONENT_REMOVAL_PREFIX); + + BinaryTag value = components.get(string); + if (value == null) continue; + + if (removed) { + string = string.substring(1); + } + + componentValues.put(Key.key(string), removed ? DataComponentValue.removed() : NBTDataComponentValue.nbtDataComponentValue(value)); + } + + return HoverEvent.ShowItem.showItem(itemId, itemCount, componentValues); + } + } + + static @NotNull CompoundBinaryTag serialize(HoverEvent.@NotNull ShowItem showItem, @NotNull NBTComponentSerializerImpl serializer) { + CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() + .putString(SHOW_ITEM_ID, showItem.item().asString()); + + int count = showItem.count(); + if (count != 1 || serializer.flags().value(NBTSerializerOptions.EMIT_DEFAULT_ITEM_HOVER_QUANTITY)) { + builder.putInt(SHOW_ITEM_COUNT, count); + } + + if (!showItem.dataComponents().isEmpty()) { + CompoundBinaryTag.Builder dataComponentsBuilder = CompoundBinaryTag.builder(); + + Map components = showItem.dataComponentsAs(NBTDataComponentValue.class); + for (Map.Entry entry : components.entrySet()) { + String key = entry.getKey().asString(); + BinaryTag value = entry.getValue().binaryTag(); + + if (value instanceof EndBinaryTag) { // removed + key = DATA_COMPONENT_REMOVAL_PREFIX + key; + } + + dataComponentsBuilder.put(key, value); + } + + builder.put(SHOW_ITEM_COMPONENTS, dataComponentsBuilder.build()); + } + + return builder.build(); + } +} From 8cc7c47647958f58b8c07dbd0bf88b3b497ba0de Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 21 Jun 2025 15:01:56 +0200 Subject: [PATCH 29/86] misc: fix double colon in JSON ShowItemSerializer --- .../adventure/text/serializer/gson/ShowItemSerializer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/ShowItemSerializer.java b/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/ShowItemSerializer.java index 58fd90125d..0025850ea8 100644 --- a/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/ShowItemSerializer.java +++ b/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/ShowItemSerializer.java @@ -149,7 +149,7 @@ public void write(final JsonWriter out, final HoverEvent.ShowItem value) throws out.name(SHOW_ITEM_COMPONENTS); out.beginObject(); for (final Map.Entry entry : value.dataComponentsAs(GsonDataComponentValue.class).entrySet()) { - final JsonElement el = entry.getValue().element();; + final JsonElement el = entry.getValue().element(); if (el instanceof JsonNull) { // removed out.name(DATA_COMPONENT_REMOVAL_PREFIX + entry.getKey().asString()); out.beginObject().endObject(); From 5591b4281f21f83062277818dc314fb45810b7a7 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 21 Jun 2025 17:22:13 +0200 Subject: [PATCH 30/86] chore: update ShowEntitySerializer to support the latest format --- .../serializer/nbt/ShowEntitySerializer.java | 63 ++++++++++++++ .../text/serializer/nbt/UUIDSerializer.java | 85 +++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java new file mode 100644 index 0000000000..bf12a1d5a5 --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java @@ -0,0 +1,63 @@ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.BinaryTagTypes; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.HoverEvent; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ENTITY_ID; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ENTITY_NAME; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ENTITY_TYPE; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ENTITY_UUID; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getRequiredTag; + +final class ShowEntitySerializer { + + private ShowEntitySerializer() { + } + + static HoverEvent.@NotNull ShowEntity deserialize(@NotNull CompoundBinaryTag compound, boolean snakeCase, + @NotNull NBTComponentSerializerImpl serializer) { + Key entityType = Key.key(getRequiredTag(compound, snakeCase ? SHOW_ENTITY_ID : SHOW_ENTITY_TYPE, BinaryTagTypes.STRING).value()); + + BinaryTag entityIdTag = compound.get(snakeCase ? SHOW_ENTITY_UUID : SHOW_ENTITY_ID); + if (entityIdTag == null) { + throw new IllegalArgumentException("The show entity compound tag does not contain an entity id field"); + } + + UUID entityId = UUIDSerializer.deserialize(entityIdTag); + BinaryTag entityName = compound.get(SHOW_ENTITY_NAME); + + if (entityName == null) { + return HoverEvent.ShowEntity.showEntity(entityType, entityId); + } else { + return HoverEvent.ShowEntity.showEntity(entityType, entityId, serializer.deserialize(entityName)); + } + } + + static @NotNull CompoundBinaryTag serialize(HoverEvent.@NotNull ShowEntity showEntity, boolean snakeCase, + @NotNull NBTComponentSerializerImpl serializer) { + CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() + .putString(snakeCase ? SHOW_ENTITY_ID : SHOW_ENTITY_TYPE, showEntity.type().asString()); + + UUID entityId = showEntity.id(); + if (snakeCase) { + NBTSerializerOptions.ShowEntityUUIDEmitMode uuidEmitMode = serializer.flags().value(NBTSerializerOptions.EMIT_SHOW_ENTITY_UUID_TYPE); + builder.put(SHOW_ENTITY_UUID, UUIDSerializer.serialize(entityId, uuidEmitMode)); + } else { + builder.put(SHOW_ENTITY_ID, UUIDSerializer.serialize(entityId, NBTSerializerOptions.ShowEntityUUIDEmitMode.EMIT_STRING)); + } + + Component customName = showEntity.name(); + if (customName != null) { + builder.put(SHOW_ENTITY_NAME, serializer.serialize(customName)); + } + + return builder.build(); + } +} diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java new file mode 100644 index 0000000000..a159a5ecd9 --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java @@ -0,0 +1,85 @@ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.BinaryTagTypes; +import net.kyori.adventure.nbt.IntArrayBinaryTag; +import net.kyori.adventure.nbt.IntBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; +import net.kyori.adventure.nbt.StringBinaryTag; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +final class UUIDSerializer { + + private static final long LONG_HALF = 0xffffffffL; + + private UUIDSerializer() { + } + + static @NotNull UUID deserialize(@NotNull BinaryTag tag) { + if (tag instanceof StringBinaryTag) { + return UUID.fromString(((StringBinaryTag) tag).value()); + } else if (tag instanceof IntArrayBinaryTag) { + return createUUIDFromArray(((IntArrayBinaryTag) tag).value()); + } else if (tag instanceof ListBinaryTag) { + ListBinaryTag castTag = (ListBinaryTag) tag; + int[] array = new int[castTag.size()]; + + for (int index = 0; index < array.length; index++) { + array[index] = castTag.getInt(index); + } + + return createUUIDFromArray(array); + } else { + throw new IllegalArgumentException("Don't know how to deserialize an UUID from the specified binary tag: " + tag.getClass().getSimpleName()); + } + } + + static @NotNull BinaryTag serialize(@NotNull UUID uuid, NBTSerializerOptions.@NotNull ShowEntityUUIDEmitMode emitMode) { + switch (emitMode) { + case EMIT_STRING: + return StringBinaryTag.stringBinaryTag(uuid.toString()); + case EMIT_INT_ARRAY: + return IntArrayBinaryTag.intArrayBinaryTag(createArrayFromUUID(uuid)); + case EMIT_LIST: + List tags = new ArrayList<>(); + for (int value : createArrayFromUUID(uuid)) { + tags.add(IntBinaryTag.intBinaryTag(value)); + } + return ListBinaryTag.listBinaryTag(BinaryTagTypes.INT, tags); + default: + // Never called, but needed for proper compilation + throw new IllegalStateException("Unknown emit mode: " + emitMode); + } + } + + private static @NotNull UUID createUUIDFromArray(int @NotNull [] array) { + long mostSignificantBits = binaryConcat(array[0], array[1]); + long leastSignificantBits = binaryConcat(array[2], array[3]); + return new UUID(mostSignificantBits, leastSignificantBits); + } + + private static int @NotNull [] createArrayFromUUID(@NotNull UUID uuid) { + long mostSignificantBits = uuid.getMostSignificantBits(); + long leastSignificantBits = uuid.getLeastSignificantBits(); + return new int[] { + mostSignificantBits(mostSignificantBits), leastSignificantBits(mostSignificantBits), + mostSignificantBits(leastSignificantBits), leastSignificantBits(leastSignificantBits) + }; + } + + private static long binaryConcat(int mostSignificantBits, int leastSignificantBits) { + return ((long) mostSignificantBits << Integer.SIZE) | ((long) leastSignificantBits & LONG_HALF); + } + + private static int mostSignificantBits(long value) { + return (int) ((value >> Integer.SIZE) & LONG_HALF); + } + + private static int leastSignificantBits(long value) { + return (int) (value & LONG_HALF); + } +} From f955ef635a066338970f3387755c8250d3a71ecc Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 21 Jun 2025 17:31:41 +0200 Subject: [PATCH 31/86] chore: update HoverEventSerializer to support the latest format --- .../serializer/nbt/HoverEventSerializer.java | 151 ++++++------------ 1 file changed, 49 insertions(+), 102 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java index adf20b5408..843bf0b0ed 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -23,141 +23,88 @@ */ package net.kyori.adventure.text.serializer.nbt; -import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.BinaryTagTypes; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.event.DataComponentValue; import net.kyori.adventure.text.event.HoverEvent; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.HOVER_EVENT_ACTION; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.HOVER_EVENT_CONTENTS; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.HOVER_EVENT_VALUE; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getRequiredTag; final class HoverEventSerializer { - private static final String HOVER_EVENT_ACTION = "action"; - private static final String HOVER_EVENT_CONTENTS = "contents"; - - private static final String HOVER_EVENT_SHOW_TEXT = "show_text"; - private static final String HOVER_EVENT_SHOW_ITEM = "show_item"; - private static final String HOVER_EVENT_SHOW_ENTITY = "show_entity"; - - private static final String SHOW_ITEM_ID = "id"; - private static final String SHOW_ITEM_COUNT = "count"; - private static final String SHOW_ITEM_COMPONENTS = "components"; - - private static final String SHOW_ENTITY_TYPE = "type"; - private static final String SHOW_ENTITY_ID = "id"; - private static final String SHOW_ENTITY_NAME = "name"; - private HoverEventSerializer() { } - static @NotNull HoverEvent deserialize(@NotNull CompoundBinaryTag compound, @NotNull NBTComponentSerializerImpl serializer) { + static @Nullable HoverEvent deserialize(@NotNull CompoundBinaryTag compound, boolean snakeCase, + @NotNull NBTComponentSerializerImpl serializer) { String actionString = compound.getString(HOVER_EVENT_ACTION); HoverEvent.Action action = HoverEvent.Action.NAMES.valueOrThrow(actionString); - Class actionType = action.type(); - BinaryTag contents = compound.get(HOVER_EVENT_CONTENTS); - if (contents == null) { - throw new IllegalArgumentException("The hover event doesn't contain any contents"); + if (!action.readable()) { + return null; } - if (Component.class.isAssignableFrom(actionType)) { - return HoverEvent.showText(serializer.deserialize(contents)); - } else if (HoverEvent.ShowItem.class.isAssignableFrom(actionType)) { - CompoundBinaryTag showItemContents = (CompoundBinaryTag) contents; - - Key itemId = Key.key(showItemContents.getString(SHOW_ITEM_ID)); - int itemCount = showItemContents.getInt(SHOW_ITEM_COUNT); - - BinaryTag components = showItemContents.get(SHOW_ITEM_COMPONENTS); - - if (components != null) { - CompoundBinaryTag componentsCompound = (CompoundBinaryTag) components; - Map componentValues = new HashMap<>(); - - for (String string : componentsCompound.keySet()) { - BinaryTag value = componentsCompound.get(string); - if (value == null) continue; - componentValues.put(Key.key(string), NBTDataComponentValue.nbtDataComponentValue(value)); - } - - return HoverEvent.showItem(itemId, itemCount, componentValues); - } else { - return HoverEvent.showItem(itemId, itemCount); - } - } else if (HoverEvent.ShowEntity.class.isAssignableFrom(actionType)) { - CompoundBinaryTag showEntityContents = (CompoundBinaryTag) contents; - - Key entityType = Key.key(showEntityContents.getString(SHOW_ENTITY_TYPE)); - UUID entityId = UUID.fromString(showEntityContents.getString(SHOW_ENTITY_ID)); - - BinaryTag entityName = showEntityContents.get(SHOW_ENTITY_NAME); - - if (entityName != null) { - return HoverEvent.showEntity(entityType, entityId, serializer.deserialize(entityName)); + CompoundBinaryTag contentsTag = snakeCase ? compound : getRequiredTag(compound, HOVER_EVENT_CONTENTS, BinaryTagTypes.COMPOUND); + if (action == HoverEvent.Action.SHOW_TEXT) { + BinaryTag textTag; + if (snakeCase) { + textTag = compound.get(HOVER_EVENT_VALUE); + if (textTag == null) + throw new IllegalArgumentException("The show text hover event action tag does not contain a text field"); } else { - return HoverEvent.showEntity(entityType, entityId); + textTag = contentsTag; } + return HoverEvent.showText(serializer.deserialize(textTag)); + } else if (action == HoverEvent.Action.SHOW_ITEM) { + return HoverEvent.showItem(ShowItemSerializer.deserialize(contentsTag)); + } else if (action == HoverEvent.Action.SHOW_ENTITY) { + return HoverEvent.showEntity(ShowEntitySerializer.deserialize(contentsTag, snakeCase, serializer)); } else { throw new IllegalArgumentException("Don't know how to deserialize a hoverEvent with action of " + actionString + " from a binary tag"); } } - static @NotNull CompoundBinaryTag serialize(@NotNull HoverEvent event, @NotNull NBTComponentSerializerImpl serializer) { + static @Nullable CompoundBinaryTag serialize(@NotNull HoverEvent event, boolean snakeCase, + @NotNull NBTComponentSerializerImpl serializer) { HoverEvent.Action action = event.action(); + if (!action.readable()) { + return null; + } - BinaryTag contents; - String actionString; - + BinaryTag contentsTag; if (action == HoverEvent.Action.SHOW_TEXT) { - contents = serializer.serialize((Component) event.value()); - actionString = HOVER_EVENT_SHOW_TEXT; - } else if (action == HoverEvent.Action.SHOW_ITEM) { - HoverEvent.ShowItem item = (HoverEvent.ShowItem) event.value(); - - CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() - .putString(SHOW_ITEM_ID, item.item().asString()) - .putInt(SHOW_ITEM_COUNT, item.count()); - - Map components = item.dataComponentsAs(NBTDataComponentValue.class); - - if (!components.isEmpty()) { - CompoundBinaryTag.Builder dataComponentsBuilder = CompoundBinaryTag.builder(); - - for (Map.Entry entry : components.entrySet()) { - dataComponentsBuilder.put(entry.getKey().asString(), entry.getValue().binaryTag()); - } - - builder.put(SHOW_ITEM_COMPONENTS, dataComponentsBuilder.build()); + BinaryTag serializedComponent = serializer.serialize((Component) event.value()); + if (snakeCase) { + contentsTag = CompoundBinaryTag.builder() + .put(HOVER_EVENT_VALUE, serializedComponent) + .build(); + } else { + contentsTag = serializedComponent; } - - contents = builder.build(); - actionString = HOVER_EVENT_SHOW_ITEM; + } else if (action == HoverEvent.Action.SHOW_ITEM) { + contentsTag = ShowItemSerializer.serialize((HoverEvent.ShowItem) event.value(), serializer); } else if (action == HoverEvent.Action.SHOW_ENTITY) { - HoverEvent.ShowEntity item = (HoverEvent.ShowEntity) event.value(); - - CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() - .putString(SHOW_ENTITY_TYPE, item.type().asString()) - .putString(SHOW_ENTITY_ID, item.id().toString()); + contentsTag = ShowEntitySerializer.serialize((HoverEvent.ShowEntity) event.value(), snakeCase, serializer); + } else { + throw new IllegalArgumentException("Don't know how to serialize " + event + " as a binary tag"); + } - Component customName = item.name(); - if (customName != null) { - builder.put(SHOW_ENTITY_NAME, serializer.serialize(customName)); - } + CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() + .putString(HOVER_EVENT_ACTION, HoverEvent.Action.NAMES.keyOrThrow(action)); - contents = builder.build(); - actionString = HOVER_EVENT_SHOW_ENTITY; + if (snakeCase) { + CompoundBinaryTag castContentsTag = (CompoundBinaryTag) contentsTag; + castContentsTag.forEach(entry -> builder.put(entry.getKey(), entry.getValue())); } else { - throw new IllegalArgumentException("Don't know how to serialize " + event + " as a binary tag"); + builder.put(HOVER_EVENT_CONTENTS, contentsTag); } - return CompoundBinaryTag.builder() - .putString(HOVER_EVENT_ACTION, actionString) - .put(HOVER_EVENT_CONTENTS, contents) - .build(); + return builder.build(); } } From 473e1996bcff560cfa1ef752c1e30c2b9c35d73b Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 21 Jun 2025 17:49:40 +0200 Subject: [PATCH 32/86] chore: add missing options to the NBTSerializerOptions --- .../serializer/nbt/NBTSerializerOptions.java | 112 +++++++++++++++++- 1 file changed, 111 insertions(+), 1 deletion(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index d9d8b5f4d1..0508f8716a 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -33,6 +33,7 @@ * @since 4.24.0 */ public final class NBTSerializerOptions { + /** * Whether to emit text components with no style and no children as plain text. * @@ -40,20 +41,51 @@ public final class NBTSerializerOptions { * @sinceMinecraft 1.20.3 */ public static final Option EMIT_COMPACT_TEXT_COMPONENT = Option.booleanOption(key("emit/compact_text_component"), true); + /** * Whether to serialize the types of {@linkplain net.kyori.adventure.text.Component components}. * * @since 4.24.0 */ public static final Option SERIALIZE_COMPONENT_TYPES = Option.booleanOption(key("serialize/component-types"), true); + /** * How to emit shadow colour data. * * @since 4.24.0 - * @sinceMinecraft 1.21.4 */ public static final Option SHADOW_COLOR_MODE = Option.enumOption(key("emit/shadow_color"), ShadowColorEmitMode.class, ShadowColorEmitMode.EMIT_INTEGER); + /** + * Control how hover event values should be emitted. + * + * @since 4.24.0 + */ + public static final Option EMIT_HOVER_EVENT_TYPE = Option.enumOption(key("emit/hover_value_mode"), HoverEventValueMode.class, HoverEventValueMode.SNAKE_CASE); + + /** + * Control how click event values should be emitted. + * + * @since 4.24.0 + */ + public static final Option EMIT_CLICK_EVENT_TYPE = Option.enumOption(key("emit/click_value_mode"), ClickEventValueMode.class, ClickEventValueMode.SNAKE_CASE); + + /** + * Whether to emit the default hover event item stack quantity of {@code 1}. + * + *

When enabled, this matches Vanilla as of 1.20.5.

+ * + * @since 4.24.0 + */ + public static final Option EMIT_DEFAULT_ITEM_HOVER_QUANTITY = Option.booleanOption(key("emit/default_item_hover_quantity"), true); + + /** + * Control how entity ids of show entity hover events should be emitted. + * + * @since 4.24.0 + */ + public static final Option EMIT_SHOW_ENTITY_UUID_TYPE = Option.enumOption(key("emit/show_entity_uuid"), ShowEntityUUIDEmitMode.class, ShowEntityUUIDEmitMode.EMIT_INT_ARRAY); + private NBTSerializerOptions() { } @@ -61,6 +93,58 @@ private static String key(final String value) { return "adventure:nbt/" + value; } + /** + * Configure how to emit hover event values. + * + * @since 4.24.0 + */ + public enum HoverEventValueMode { + /** + * Only emit the 1.21.5+ hover events using the {@code hover_event} field. + * + * @since 4.24.0 + */ + SNAKE_CASE, + /** + * Only emit the 1.16+ hover events using the {@code hoverEvent} field. + * + * @since 4.24.0 + */ + CAMEL_CASE, + /** + * Include both camel and snake case hover event fields, for maximum compatibility. + * + * @since 4.24.0 + */ + BOTH + } + + /** + * Configure how to emit click event values. + * + * @since 4.24.0 + */ + public enum ClickEventValueMode { + /** + * Only emit the 1.21.5+ click events using the {@code click_event} field. + * + * @since 4.24.0 + */ + SNAKE_CASE, + /** + * Only emit the pre-1.21.5 click events using the {@code clickEvent} field. + * + * @since 4.24.0 + */ + CAMEL_CASE, + /** + * Include both camel and snake case click event fields, for maximum compatibility. + * + * @since 4.24.0 + */ + BOTH, + } + /** * How text shadow colors should be emitted. * @@ -85,4 +169,30 @@ public enum ShadowColorEmitMode { */ EMIT_ARRAY } + + /** + * Configure how to emit entity ids of show entity hover events. + * + * @since 4.24.0 + */ + public enum ShowEntityUUIDEmitMode { + /** + * Emit as a string. + * + * @since 4.24.0 + */ + EMIT_STRING, + /** + * Emit as an int array. + * + * @since 4.24.0 + */ + EMIT_INT_ARRAY, + /** + * Emit as an int list. + * + * @since 4.24.0 + */ + EMIT_LIST + } } From 7d90b2f24653736b871c074a1192bd718376e909 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 21 Jun 2025 18:03:53 +0200 Subject: [PATCH 33/86] chore: apply new serializing system of click events and hover events in StyleSerializer --- .../text/serializer/nbt/StyleSerializer.java | 81 +++++++++++++++---- 1 file changed, 67 insertions(+), 14 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java index 645a475199..788b09f859 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java @@ -25,6 +25,7 @@ import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.BinaryTagTypes; import net.kyori.adventure.nbt.ByteBinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.StringBinaryTag; @@ -35,9 +36,16 @@ import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextDecoration; -import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; +import net.kyori.option.OptionState; import org.jetbrains.annotations.NotNull; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_CAMEL; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_SNAKE; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.HOVER_EVENT_CAMEL; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.HOVER_EVENT_SNAKE; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHADOW_COLOR; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getOptionalTag; + final class StyleSerializer { private static final String COLOR = "color"; @@ -48,8 +56,6 @@ final class StyleSerializer { private static final String OBFUSCATED = "obfuscated"; private static final String FONT = "font"; private static final String INSERTION = "insertion"; - private static final String CLICK_EVENT = "clickEvent"; - private static final String HOVER_EVENT = "hoverEvent"; private StyleSerializer() { } @@ -82,17 +88,27 @@ private StyleSerializer() { styleBuilder.insertion(((StringBinaryTag) binaryInsertion).value()); } - BinaryTag binaryClickEvent = compound.get(CLICK_EVENT); - if (binaryClickEvent != null) { - styleBuilder.clickEvent(ClickEventSerializer.deserialize((CompoundBinaryTag) binaryClickEvent)); + CompoundBinaryTag binaryClickEvent = getOptionalTag(compound, CLICK_EVENT_SNAKE, BinaryTagTypes.COMPOUND); + if (binaryClickEvent == null) { + binaryClickEvent = getOptionalTag(compound, CLICK_EVENT_CAMEL, BinaryTagTypes.COMPOUND); + if (binaryClickEvent != null) { + styleBuilder.clickEvent(ClickEventSerializer.deserializeCamel(binaryClickEvent)); + } + } else { + styleBuilder.clickEvent(ClickEventSerializer.deserializeSnake(binaryClickEvent)); } - BinaryTag binaryHoverEvent = compound.get(HOVER_EVENT); - if (binaryHoverEvent != null) { - styleBuilder.hoverEvent(HoverEventSerializer.deserialize((CompoundBinaryTag) binaryHoverEvent, serializer)); + CompoundBinaryTag binaryHoverEvent = getOptionalTag(compound, HOVER_EVENT_SNAKE, BinaryTagTypes.COMPOUND); + if (binaryHoverEvent == null) { + binaryHoverEvent = getOptionalTag(compound, HOVER_EVENT_CAMEL, BinaryTagTypes.COMPOUND); + if (binaryHoverEvent != null) { + styleBuilder.hoverEvent(HoverEventSerializer.deserialize(binaryHoverEvent, false, serializer)); + } + } else { + styleBuilder.hoverEvent(HoverEventSerializer.deserialize(binaryHoverEvent, true, serializer)); } - BinaryTag shadowColorTag = compound.get(ComponentTreeConstants.SHADOW_COLOR); + BinaryTag shadowColorTag = compound.get(SHADOW_COLOR); if (shadowColorTag != null) { styleBuilder.shadowColor(ShadowColorSerializer.deserialize(shadowColorTag)); } @@ -102,6 +118,8 @@ private StyleSerializer() { static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder builder, @NotNull NBTComponentSerializerImpl serializer) { + OptionState flags = serializer.flags(); + TextColor color = style.color(); if (color != null) { builder.putString(COLOR, color.toString()); @@ -149,21 +167,56 @@ static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder b } ClickEvent clickEvent = style.clickEvent(); - if (clickEvent != null) { - builder.put(CLICK_EVENT, ClickEventSerializer.serialize(clickEvent)); + NBTSerializerOptions.ClickEventValueMode clickEventValueMode = flags.value(NBTSerializerOptions.EMIT_CLICK_EVENT_TYPE); + + boolean emitBothClickEvents = clickEventValueMode == NBTSerializerOptions.ClickEventValueMode.BOTH; + boolean emitSnakeCaseClickEvent = clickEventValueMode == NBTSerializerOptions.ClickEventValueMode.SNAKE_CASE; + boolean emitCamelCaseClickEvent = clickEventValueMode == NBTSerializerOptions.ClickEventValueMode.CAMEL_CASE; + + if (emitBothClickEvents || emitSnakeCaseClickEvent) { + BinaryTag serializedClickEvent = ClickEventSerializer.serialize(clickEvent, true); + if (serializedClickEvent != null) { + builder.put(CLICK_EVENT_SNAKE, serializedClickEvent); + } + } + + if (emitBothClickEvents || emitCamelCaseClickEvent) { + BinaryTag serializedClickEvent = ClickEventSerializer.serialize(clickEvent, false); + if (serializedClickEvent != null) { + builder.put(CLICK_EVENT_CAMEL, serializedClickEvent); + } + } } HoverEvent hoverEvent = style.hoverEvent(); if (hoverEvent != null) { - builder.put(HOVER_EVENT, HoverEventSerializer.serialize(hoverEvent, serializer)); + NBTSerializerOptions.HoverEventValueMode hoverEventValueMode = flags.value(NBTSerializerOptions.EMIT_HOVER_EVENT_TYPE); + + boolean emitBothHoverEvents = hoverEventValueMode == NBTSerializerOptions.HoverEventValueMode.BOTH; + boolean emitSnakeCaseHoverEvent = hoverEventValueMode == NBTSerializerOptions.HoverEventValueMode.SNAKE_CASE; + boolean emitCamelCaseHoverEvent = hoverEventValueMode == NBTSerializerOptions.HoverEventValueMode.CAMEL_CASE; + + if (emitBothHoverEvents || emitSnakeCaseHoverEvent) { + BinaryTag serializedHoverEvent = HoverEventSerializer.serialize(hoverEvent, true, serializer); + if (serializedHoverEvent != null) { + builder.put(HOVER_EVENT_SNAKE, serializedHoverEvent); + } + } + + if (emitBothHoverEvents || emitCamelCaseHoverEvent) { + BinaryTag serializedHoverEvent = HoverEventSerializer.serialize(hoverEvent, false, serializer); + if (serializedHoverEvent != null) { + builder.put(HOVER_EVENT_CAMEL, serializedHoverEvent); + } + } } ShadowColor shadowColor = style.shadowColor(); if (shadowColor != null) { BinaryTag serializedShadowColor = ShadowColorSerializer.serialize(shadowColor, serializer); if (serializedShadowColor != null) { - builder.put(ComponentTreeConstants.SHADOW_COLOR, serializedShadowColor); + builder.put(SHADOW_COLOR, serializedShadowColor); } } } From 1500a1484061ea43f7a8d682b4f712d0836c208a Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 21 Jun 2025 18:35:57 +0200 Subject: [PATCH 34/86] chore: update StyleSerializer fields to support the latest format --- .../text/serializer/nbt/StyleSerializer.java | 33 +++++++----------- .../serializer/nbt/TextColorSerializer.java | 34 +++++++++++++++++++ 2 files changed, 47 insertions(+), 20 deletions(-) create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TextColorSerializer.java diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java index 788b09f859..67c35a7107 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java @@ -31,7 +31,6 @@ import net.kyori.adventure.nbt.StringBinaryTag; import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.HoverEvent; -import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.ShadowColor; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextColor; @@ -41,21 +40,21 @@ import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_CAMEL; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_SNAKE; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.COLOR; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.FONT; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.HOVER_EVENT_CAMEL; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.HOVER_EVENT_SNAKE; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.INSERTION; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHADOW_COLOR; import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getOptionalTag; final class StyleSerializer { - private static final String COLOR = "color"; private static final String BOLD = "bold"; private static final String ITALIC = "italic"; private static final String UNDERLINED = "underlined"; private static final String STRIKETHROUGH = "strikethrough"; private static final String OBFUSCATED = "obfuscated"; - private static final String FONT = "font"; - private static final String INSERTION = "insertion"; private StyleSerializer() { } @@ -63,13 +62,9 @@ private StyleSerializer() { static @NotNull Style deserialize(@NotNull CompoundBinaryTag compound, @NotNull NBTComponentSerializerImpl serializer) { Style.Builder styleBuilder = Style.style(); - String colorString = compound.getString(COLOR); - if (!colorString.isEmpty()) { - if (colorString.startsWith(TextColor.HEX_PREFIX)) { - styleBuilder.color(TextColor.fromHexString(colorString)); - } else { - styleBuilder.color(NamedTextColor.NAMES.value(colorString)); - } + StringBinaryTag colorTag = NBTSerializerUtils.getOptionalTag(compound, COLOR, BinaryTagTypes.STRING); + if (colorTag != null) { + styleBuilder.color(TextColorSerializer.deserialize(colorTag)); } styleBuilder.decoration(TextDecoration.BOLD, readOptionalState(BOLD, compound)) @@ -78,14 +73,14 @@ private StyleSerializer() { .decoration(TextDecoration.STRIKETHROUGH, readOptionalState(STRIKETHROUGH, compound)) .decoration(TextDecoration.OBFUSCATED, readOptionalState(OBFUSCATED, compound)); - String fontString = compound.getString(FONT); - if (!fontString.isEmpty()) { - styleBuilder.font(Key.key(fontString)); + StringBinaryTag fontTag = getOptionalTag(compound, FONT, BinaryTagTypes.STRING); + if (fontTag != null) { + styleBuilder.font(Key.key(fontTag.value())); } - BinaryTag binaryInsertion = compound.get(INSERTION); - if (binaryInsertion != null) { - styleBuilder.insertion(((StringBinaryTag) binaryInsertion).value()); + StringBinaryTag insertionTag = getOptionalTag(compound, INSERTION, BinaryTagTypes.STRING); + if (insertionTag != null) { + styleBuilder.insertion(insertionTag.value()); } CompoundBinaryTag binaryClickEvent = getOptionalTag(compound, CLICK_EVENT_SNAKE, BinaryTagTypes.COMPOUND); @@ -122,7 +117,7 @@ static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder b TextColor color = style.color(); if (color != null) { - builder.putString(COLOR, color.toString()); + builder.put(COLOR, TextColorSerializer.serialize(color)); } style.decorations().forEach((decoration, state) -> { @@ -155,13 +150,11 @@ static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder b }); Key font = style.font(); - if (font != null) { builder.putString(FONT, font.asString()); } String insertion = style.insertion(); - if (insertion != null) { builder.putString(INSERTION, insertion); } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TextColorSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TextColorSerializer.java new file mode 100644 index 0000000000..0dfbb5ac33 --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TextColorSerializer.java @@ -0,0 +1,34 @@ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.StringBinaryTag; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextColor; +import org.jetbrains.annotations.NotNull; + +import java.util.Locale; + +final class TextColorSerializer { + + private TextColorSerializer() { + } + + static @NotNull TextColor deserialize(@NotNull StringBinaryTag tag) { + String value = tag.value(); + if (value.startsWith(TextColor.HEX_PREFIX)) { + return TextColor.fromHexString(value); + } else { + return NamedTextColor.NAMES.value(value); + } + } + + static @NotNull StringBinaryTag serialize(@NotNull TextColor color) { + String value = color instanceof NamedTextColor + ? NamedTextColor.NAMES.keyOrThrow((NamedTextColor) color) + : asUpperCaseHexString(color); + return StringBinaryTag.stringBinaryTag(value); + } + + private static String asUpperCaseHexString(final TextColor color) { + return String.format(Locale.ROOT, "%c%06X", TextColor.HEX_CHARACTER, color.value()); // to be consistent with vanilla + } +} From 5214303e51ccdbc900b1bf7a01d3745d770ebb98 Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 22 Jun 2025 10:04:48 +0200 Subject: [PATCH 35/86] chore: serialize and deserialize text decorations in loops --- .../serializer/nbt/NBTSerializerUtils.java | 6 ++ .../text/serializer/nbt/StyleSerializer.java | 74 +++++++++---------- 2 files changed, 42 insertions(+), 38 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java index 291c612c0c..648336ca6f 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java @@ -3,6 +3,7 @@ import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.BinaryTagType; import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.NumberBinaryTag; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,4 +40,9 @@ private NBTSerializerUtils() { return (B) tag; } + + static boolean asBoolean(@NotNull NumberBinaryTag tag) { + // != 0 might look weird, but it is what vanilla does + return tag.byteValue() != 0; + } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java index 67c35a7107..fd6d505ab1 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java @@ -38,6 +38,9 @@ import net.kyori.option.OptionState; import org.jetbrains.annotations.NotNull; +import java.util.EnumSet; +import java.util.Set; + import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_CAMEL; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_SNAKE; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.COLOR; @@ -50,11 +53,27 @@ final class StyleSerializer { - private static final String BOLD = "bold"; - private static final String ITALIC = "italic"; - private static final String UNDERLINED = "underlined"; - private static final String STRIKETHROUGH = "strikethrough"; - private static final String OBFUSCATED = "obfuscated"; + @SuppressWarnings("checkstyle:NoWhitespaceAfter") + private static final TextDecoration[] DECORATIONS = { + // The order here is important -- Minecraft does string comparisons of some + // serialized components so we have to make sure our order matches Vanilla + TextDecoration.BOLD, + TextDecoration.ITALIC, + TextDecoration.UNDERLINED, + TextDecoration.STRIKETHROUGH, + TextDecoration.OBFUSCATED + }; + + static { + // Ensure coverage of decorations + final Set knownDecorations = EnumSet.allOf(TextDecoration.class); + for (final TextDecoration decoration : DECORATIONS) { + knownDecorations.remove(decoration); + } + if (!knownDecorations.isEmpty()) { + throw new IllegalStateException("NBT serializer is missing some text decorations: " + knownDecorations); + } + } private StyleSerializer() { } @@ -67,11 +86,12 @@ private StyleSerializer() { styleBuilder.color(TextColorSerializer.deserialize(colorTag)); } - styleBuilder.decoration(TextDecoration.BOLD, readOptionalState(BOLD, compound)) - .decoration(TextDecoration.ITALIC, readOptionalState(ITALIC, compound)) - .decoration(TextDecoration.UNDERLINED, readOptionalState(UNDERLINED, compound)) - .decoration(TextDecoration.STRIKETHROUGH, readOptionalState(STRIKETHROUGH, compound)) - .decoration(TextDecoration.OBFUSCATED, readOptionalState(OBFUSCATED, compound)); + for (TextDecoration decoration : DECORATIONS) { + String name = TextDecoration.NAMES.keyOrThrow(decoration); + ByteBinaryTag decorationTag = NBTSerializerUtils.getOptionalTag(compound, name, BinaryTagTypes.BYTE); + if (decorationTag == null) continue; + styleBuilder.decoration(decoration, NBTSerializerUtils.asBoolean(decorationTag)); + } StringBinaryTag fontTag = getOptionalTag(compound, FONT, BinaryTagTypes.STRING); if (fontTag != null) { @@ -120,34 +140,12 @@ static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder b builder.put(COLOR, TextColorSerializer.serialize(color)); } - style.decorations().forEach((decoration, state) -> { - if (state != TextDecoration.State.NOT_SET) { - String decorationName; - - switch (decoration) { - case OBFUSCATED: - decorationName = OBFUSCATED; - break; - case BOLD: - decorationName = BOLD; - break; - case STRIKETHROUGH: - decorationName = STRIKETHROUGH; - break; - case UNDERLINED: - decorationName = UNDERLINED; - break; - case ITALIC: - decorationName = ITALIC; - break; - default: - // Never called, but needed for proper compilation - throw new IllegalStateException("Unknown text decoration: " + decoration); - } - - builder.putBoolean(decorationName, state == TextDecoration.State.TRUE); - } - }); + for (TextDecoration decoration : DECORATIONS) { + TextDecoration.State state = style.decoration(decoration); + if (state == TextDecoration.State.NOT_SET) continue; + String name = TextDecoration.NAMES.keyOrThrow(decoration); + builder.putBoolean(name, state == TextDecoration.State.TRUE); + } Key font = style.font(); if (font != null) { From bf2092fde62f6e68f7d5e30d79cdae8906e38396 Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 22 Jun 2025 14:35:33 +0200 Subject: [PATCH 36/86] chore: ensure order of serializing and use ComponentTreeConstants in NBTComponentSerializerImpl --- .../nbt/NBTComponentSerializerImpl.java | 201 ++++++++---------- 1 file changed, 90 insertions(+), 111 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index ac30ae1027..07ce7d01d5 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -25,6 +25,8 @@ import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.BinaryTagTypes; +import net.kyori.adventure.nbt.ByteBinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.ListBinaryTag; import net.kyori.adventure.nbt.StringBinaryTag; @@ -50,6 +52,25 @@ import java.util.function.Consumer; import static java.util.Objects.requireNonNull; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.EXTRA; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.KEYBIND; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.NBT; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.NBT_BLOCK; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.NBT_ENTITY; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.NBT_INTERPRET; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.NBT_STORAGE; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SCORE; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SCORE_NAME; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SCORE_OBJECTIVE; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SELECTOR; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SEPARATOR; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.TEXT; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.TRANSLATE; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.TRANSLATE_FALLBACK; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.TRANSLATE_WITH; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.asBoolean; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getOptionalTag; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getRequiredTag; final class NBTComponentSerializerImpl implements NBTComponentSerializer { @@ -79,39 +100,6 @@ static final class Instances { .orElseGet(() -> new NBTComponentSerializerImpl(OptionState.emptyOptionState())); } - private static final String TYPE = "type"; - - private static final String TYPE_TEXT = "text"; - private static final String TYPE_TRANSLATABLE = "translatable"; - private static final String TYPE_KEYBIND = "keybind"; - private static final String TYPE_SCORE = "score"; - private static final String TYPE_SELECTOR = "selector"; - private static final String TYPE_NBT = "nbt"; - - private static final String EXTRA = "extra"; - - private static final String TEXT = "text"; - - private static final String TRANSLATE_KEY = "translate"; - private static final String TRANSLATE_WITH = "with"; - private static final String TRANSLATE_FALLBACK = "fallback"; - - private static final String KEYBIND = "keybind"; - - private static final String SCORE = "score"; - private static final String SCORE_NAME = "name"; - private static final String SCORE_OBJECTIVE = "objective"; - - private static final String SELECTOR = "selector"; - private static final String SELECTOR_SEPARATOR = "separator"; - - private static final String NBT = "nbt"; - private static final String NBT_INTERPRET = "interpret"; - private static final String NBT_SEPARATOR = "separator"; - private static final String NBT_BLOCK = "block"; - private static final String NBT_ENTITY = "entity"; - private static final String NBT_STORAGE = "storage"; - private final OptionState flags; NBTComponentSerializerImpl(@NotNull OptionState flags) { @@ -129,12 +117,14 @@ static final class Instances { } CompoundBinaryTag compound = (CompoundBinaryTag) input; - String type = compound.getString(TYPE); - if (type.isEmpty()) { + StringBinaryTag typeTag = getOptionalTag(compound, TYPE, BinaryTagTypes.STRING); + String type; + + if (typeTag == null) { if (compound.get(TEXT) != null) { type = TYPE_TEXT; - } else if (compound.get(TRANSLATE_KEY) != null) { + } else if (compound.get(TRANSLATE) != null) { type = TYPE_TRANSLATABLE; } else if (compound.get(KEYBIND) != null) { type = TYPE_KEYBIND; @@ -142,125 +132,118 @@ static final class Instances { type = TYPE_SCORE; } else if (compound.get(SELECTOR) != null) { type = TYPE_SELECTOR; - } else if (compound.get(NBT) != null && (compound.get(NBT_BLOCK) != null - || compound.get(NBT_STORAGE) != null || compound.get(NBT_ENTITY) != null)) { + } else if (compound.get(NBT) != null) { type = TYPE_NBT; } else { throw new IllegalArgumentException("Could not guess type of the component"); } + } else { + type = typeTag.value(); } Style style = StyleSerializer.deserialize(compound, this); List children = new ArrayList<>(); - ListBinaryTag binaryChildren = compound.getList(EXTRA); - binaryChildren.forEach(child -> children.add(this.deserialize(child))); + ListBinaryTag extraTag = compound.getList(EXTRA); + // TODO: Deserialize it like vanilla + extraTag.forEach(child -> children.add(this.deserialize(child))); switch (type) { case TYPE_TEXT: return Component.text() - .content(compound.getString(TEXT)) + .content(getRequiredTag(compound, TEXT, BinaryTagTypes.STRING).value()) .style(style) .append(children) .build(); case TYPE_TRANSLATABLE: - ListBinaryTag binaryArguments = compound.getList(TRANSLATE_WITH); - String fallback = compound.getString(TRANSLATE_FALLBACK); - - if (fallback.isEmpty()) { - fallback = null; - } + StringBinaryTag translateTag = getRequiredTag(compound, TRANSLATE, BinaryTagTypes.STRING); + ListBinaryTag translateWithTag = compound.getList(TRANSLATE_WITH); + StringBinaryTag fallbackTag = getOptionalTag(compound, TRANSLATE_FALLBACK, BinaryTagTypes.STRING); + // TODO: Decode it like vanilla List arguments = new ArrayList<>(); - for (BinaryTag argument : binaryArguments) { - arguments.add(this.deserialize(argument)); - } + translateWithTag.forEach(argumentTag -> arguments.add(this.deserialize(argumentTag))); return Component.translatable() - .key(compound.getString(TRANSLATE_KEY)) - .fallback(fallback) + .key(translateTag.value()) + .fallback(fallbackTag == null ? null : fallbackTag.value()) .arguments(arguments) .style(style) .append(children) .build(); case TYPE_KEYBIND: return Component.keybind() - .keybind(compound.getString(KEYBIND)) + .keybind(getRequiredTag(compound, KEYBIND, BinaryTagTypes.STRING).value()) .style(style) .append(children) .build(); case TYPE_SCORE: - CompoundBinaryTag binaryScore = compound.getCompound(SCORE); - - String scoreName = binaryScore.getString(SCORE_NAME); - String scoreObjective = binaryScore.getString(SCORE_OBJECTIVE); - + CompoundBinaryTag scoreTag = getRequiredTag(compound, SCORE, BinaryTagTypes.COMPOUND); return Component.score() - .name(scoreName) - .objective(scoreObjective) + .name(getRequiredTag(scoreTag, SCORE_NAME, BinaryTagTypes.STRING).value()) + .objective(getRequiredTag(scoreTag, SCORE_OBJECTIVE, BinaryTagTypes.STRING).value()) .style(style) .append(children) .build(); case TYPE_SELECTOR: - String selector = compound.getString(SELECTOR); - Component selectorSeparator = null; - - BinaryTag binarySelectorSeparator = compound.get(SELECTOR_SEPARATOR); - if (binarySelectorSeparator != null) { - selectorSeparator = this.deserialize(binarySelectorSeparator); - } - + StringBinaryTag selectorTag = getRequiredTag(compound, SELECTOR, BinaryTagTypes.STRING); + BinaryTag selectorSeparatorTag = compound.get(SEPARATOR); return Component.selector() - .pattern(selector) - .separator(selectorSeparator) + .pattern(selectorTag.value()) + .separator(selectorSeparatorTag == null ? null : this.deserialize(selectorSeparatorTag)) .style(style) .append(children) .build(); case TYPE_NBT: - String nbtPath = compound.getString(NBT); - boolean nbtInterpret = compound.getBoolean(NBT_INTERPRET); + String nbtPath = getRequiredTag(compound, NBT, BinaryTagTypes.STRING).value(); + + ByteBinaryTag nbtInterpretTag = getOptionalTag(compound, NBT_INTERPRET, BinaryTagTypes.BYTE); + boolean nbtInterpret = nbtInterpretTag != null && asBoolean(nbtInterpretTag); + + BinaryTag nbtSeparatorTag = compound.get(SEPARATOR); Component nbtSeparator = null; - BinaryTag binaryNbtSeparator = compound.get(NBT_SEPARATOR); - if (binaryNbtSeparator != null) { - nbtSeparator = this.deserialize(binaryNbtSeparator); + if (nbtSeparatorTag != null) { + nbtSeparator = this.deserialize(nbtSeparatorTag); } - BinaryTag binaryBlock = compound.get(NBT_BLOCK); - BinaryTag binaryEntity = compound.get(NBT_ENTITY); - BinaryTag binaryStorage = compound.get(NBT_STORAGE); + StringBinaryTag nbtBlockTag = getOptionalTag(compound, NBT_BLOCK, BinaryTagTypes.STRING); + StringBinaryTag nbtEntityTag = getOptionalTag(compound, NBT_ENTITY, BinaryTagTypes.STRING); + StringBinaryTag nbtStorageTag = getOptionalTag(compound, NBT_STORAGE, BinaryTagTypes.STRING); - if (binaryBlock != null) { - BlockNBTComponent.Pos pos = BlockNBTComponent.Pos.fromString(((StringBinaryTag) binaryBlock).value()); + // TODO: Deserialize data sources + if (nbtBlockTag != null) { return Component.blockNBT() .nbtPath(nbtPath) .interpret(nbtInterpret) .separator(nbtSeparator) - .pos(pos) + .pos(BlockNBTComponent.Pos.fromString(nbtBlockTag.value())) .style(style) .append(children) .build(); - } else if (binaryEntity != null) { + } else if (nbtEntityTag != null) { return Component.entityNBT() .nbtPath(nbtPath) .interpret(nbtInterpret) .separator(nbtSeparator) - .selector(((StringBinaryTag) binaryEntity).value()) + .selector(nbtEntityTag.value()) .style(style) .append(children) .build(); - } else if (binaryStorage != null) { + } else if (nbtStorageTag != null) { return Component.storageNBT() .nbtPath(nbtPath) .interpret(nbtInterpret) .separator(nbtSeparator) - .storage(Key.key(((StringBinaryTag) binaryStorage).value())) + .storage(Key.key(nbtStorageTag.value())) .style(style) .append(children) .build(); + } else { + throw notSureHowToDeserialize(input); } default: - throw new IllegalArgumentException("Unknown component type " + type); + throw notSureHowToDeserialize(input); } } @@ -275,7 +258,6 @@ static final class Instances { private @NotNull CompoundBinaryTag writeCompoundComponent(@NotNull Component component) { CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder(); - StyleSerializer.serialize(component.style(), builder, this); if (component instanceof TextComponent) { this.writeComponentType(TYPE_TEXT, builder); @@ -284,24 +266,20 @@ static final class Instances { this.writeComponentType(TYPE_TRANSLATABLE, builder); TranslatableComponent translatable = (TranslatableComponent) component; - builder.putString(TRANSLATE_KEY, translatable.key()); + builder.putString(TRANSLATE, translatable.key()); - List arguments = translatable.arguments(); + String fallback = translatable.fallback(); + if (fallback != null) { + builder.putString(TRANSLATE_FALLBACK, fallback); + } + List arguments = translatable.arguments(); if (!arguments.isEmpty()) { List argumentsTags = new ArrayList<>(); - - for (TranslationArgument argument : arguments) { - argumentsTags.add(this.writeCompoundComponent(argument.asComponent())); - } - + // TODO: Encode it like vanilla + arguments.forEach(argument -> argumentsTags.add(this.writeCompoundComponent(argument.asComponent()))); builder.put(TRANSLATE_WITH, ListBinaryTag.from(argumentsTags)); } - - String fallback = translatable.fallback(); - if (fallback != null) { - builder.putString(TRANSLATE_FALLBACK, fallback); - } } else if (component instanceof KeybindComponent) { this.writeComponentType(TYPE_KEYBIND, builder); builder.putString(KEYBIND, ((KeybindComponent) component).keybind()); @@ -322,20 +300,21 @@ static final class Instances { Component separator = selector.separator(); if (separator != null) { - builder.put(SELECTOR_SEPARATOR, this.serialize(separator)); + builder.put(SEPARATOR, this.serialize(separator)); } } else if (component instanceof NBTComponent) { this.writeComponentType(TYPE_NBT, builder); NBTComponent nbt = (NBTComponent) component; builder.putString(NBT, nbt.nbtPath()); - builder.putBoolean(NBT_INTERPRET, nbt.interpret()); + builder.putBoolean(NBT_INTERPRET, nbt.interpret()); // TODO: Make it optional Component separator = nbt.separator(); if (separator != null) { - builder.put(NBT_SEPARATOR, this.serialize(separator)); + builder.put(SEPARATOR, this.serialize(separator)); } + // TODO: Serialize data sources if (nbt instanceof BlockNBTComponent) { builder.putString(NBT_BLOCK, ((BlockNBTComponent) nbt).pos().asString()); } else if (nbt instanceof EntityNBTComponent) { @@ -350,17 +329,14 @@ static final class Instances { } List children = component.children(); - if (!children.isEmpty()) { List serializedChildren = new ArrayList<>(); - - for (Component child : children) { - serializedChildren.add(this.writeCompoundComponent(child)); - } - + // TODO: Encode it like vanilla + children.forEach(child -> serializedChildren.add(this.writeCompoundComponent(child))); builder.put(EXTRA, ListBinaryTag.from(serializedChildren)); } + StyleSerializer.serialize(component.style(), builder, this); return builder.build(); } @@ -374,7 +350,11 @@ private void writeComponentType(final String componentType, final CompoundBinary } } - private static IllegalArgumentException notSureHowToSerialize(final Component component) { + private static @NotNull IllegalArgumentException notSureHowToDeserialize(BinaryTag tag) { + return new IllegalArgumentException("Don't know how to turn " + tag + " into a Component"); + } + + private static @NotNull IllegalArgumentException notSureHowToSerialize(Component component) { return new IllegalArgumentException("Don't know how to serialize " + component + " as a Component"); } @@ -394,8 +374,7 @@ static final class BuilderImpl implements NBTComponentSerializer.Builder { @Override public @NotNull Builder editOptions(@NotNull Consumer optionEditor) { - final OptionState.Builder builder = OptionState.optionState() - .values(this.flags); + final OptionState.Builder builder = OptionState.optionState().values(this.flags); requireNonNull(optionEditor, "optionEditor").accept(builder); this.flags = builder.build(); return this; From b2e6cd15dd2973827885945723263c1094d02d8d Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 22 Jun 2025 15:00:02 +0200 Subject: [PATCH 37/86] chore: do not serialize or deserialize "type" fields of components as it's obsolete --- .../nbt/NBTComponentSerializerImpl.java | 210 +++++++----------- .../serializer/nbt/NBTSerializerOptions.java | 7 - 2 files changed, 85 insertions(+), 132 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 07ce7d01d5..d45f9073a6 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -117,30 +117,6 @@ static final class Instances { } CompoundBinaryTag compound = (CompoundBinaryTag) input; - - StringBinaryTag typeTag = getOptionalTag(compound, TYPE, BinaryTagTypes.STRING); - String type; - - if (typeTag == null) { - if (compound.get(TEXT) != null) { - type = TYPE_TEXT; - } else if (compound.get(TRANSLATE) != null) { - type = TYPE_TRANSLATABLE; - } else if (compound.get(KEYBIND) != null) { - type = TYPE_KEYBIND; - } else if (compound.get(SCORE) != null) { - type = TYPE_SCORE; - } else if (compound.get(SELECTOR) != null) { - type = TYPE_SELECTOR; - } else if (compound.get(NBT) != null) { - type = TYPE_NBT; - } else { - throw new IllegalArgumentException("Could not guess type of the component"); - } - } else { - type = typeTag.value(); - } - Style style = StyleSerializer.deserialize(compound, this); List children = new ArrayList<>(); @@ -148,102 +124,101 @@ static final class Instances { // TODO: Deserialize it like vanilla extraTag.forEach(child -> children.add(this.deserialize(child))); - switch (type) { - case TYPE_TEXT: - return Component.text() - .content(getRequiredTag(compound, TEXT, BinaryTagTypes.STRING).value()) - .style(style) - .append(children) - .build(); - case TYPE_TRANSLATABLE: - StringBinaryTag translateTag = getRequiredTag(compound, TRANSLATE, BinaryTagTypes.STRING); - ListBinaryTag translateWithTag = compound.getList(TRANSLATE_WITH); - StringBinaryTag fallbackTag = getOptionalTag(compound, TRANSLATE_FALLBACK, BinaryTagTypes.STRING); - - // TODO: Decode it like vanilla - List arguments = new ArrayList<>(); - translateWithTag.forEach(argumentTag -> arguments.add(this.deserialize(argumentTag))); - - return Component.translatable() - .key(translateTag.value()) - .fallback(fallbackTag == null ? null : fallbackTag.value()) - .arguments(arguments) - .style(style) - .append(children) - .build(); - case TYPE_KEYBIND: - return Component.keybind() - .keybind(getRequiredTag(compound, KEYBIND, BinaryTagTypes.STRING).value()) + if (compound.get(TEXT) != null) { + return Component.text() + .content(getRequiredTag(compound, TEXT, BinaryTagTypes.STRING).value()) + .style(style) + .append(children) + .build(); + } else if (compound.get(TRANSLATE) != null) { + StringBinaryTag translateTag = getRequiredTag(compound, TRANSLATE, BinaryTagTypes.STRING); + ListBinaryTag translateWithTag = compound.getList(TRANSLATE_WITH); + StringBinaryTag fallbackTag = getOptionalTag(compound, TRANSLATE_FALLBACK, BinaryTagTypes.STRING); + + // TODO: Decode it like vanilla + List arguments = new ArrayList<>(); + translateWithTag.forEach(argumentTag -> arguments.add(this.deserialize(argumentTag))); + + return Component.translatable() + .key(translateTag.value()) + .fallback(fallbackTag == null ? null : fallbackTag.value()) + .arguments(arguments) + .style(style) + .append(children) + .build(); + } else if (compound.get(KEYBIND) != null) { + return Component.keybind() + .keybind(getRequiredTag(compound, KEYBIND, BinaryTagTypes.STRING).value()) + .style(style) + .append(children) + .build(); + } else if (compound.get(SCORE) != null) { + CompoundBinaryTag scoreTag = getRequiredTag(compound, SCORE, BinaryTagTypes.COMPOUND); + return Component.score() + .name(getRequiredTag(scoreTag, SCORE_NAME, BinaryTagTypes.STRING).value()) + .objective(getRequiredTag(scoreTag, SCORE_OBJECTIVE, BinaryTagTypes.STRING).value()) + .style(style) + .append(children) + .build(); + } else if (compound.get(SELECTOR) != null) { + StringBinaryTag selectorTag = getRequiredTag(compound, SELECTOR, BinaryTagTypes.STRING); + BinaryTag selectorSeparatorTag = compound.get(SEPARATOR); + return Component.selector() + .pattern(selectorTag.value()) + .separator(selectorSeparatorTag == null ? null : this.deserialize(selectorSeparatorTag)) + .style(style) + .append(children) + .build(); + } else if (compound.get(NBT) != null) { + String nbtPath = getRequiredTag(compound, NBT, BinaryTagTypes.STRING).value(); + + ByteBinaryTag nbtInterpretTag = getOptionalTag(compound, NBT_INTERPRET, BinaryTagTypes.BYTE); + boolean nbtInterpret = nbtInterpretTag != null && asBoolean(nbtInterpretTag); + + BinaryTag nbtSeparatorTag = compound.get(SEPARATOR); + Component nbtSeparator = null; + + if (nbtSeparatorTag != null) { + nbtSeparator = this.deserialize(nbtSeparatorTag); + } + + StringBinaryTag nbtBlockTag = getOptionalTag(compound, NBT_BLOCK, BinaryTagTypes.STRING); + StringBinaryTag nbtEntityTag = getOptionalTag(compound, NBT_ENTITY, BinaryTagTypes.STRING); + StringBinaryTag nbtStorageTag = getOptionalTag(compound, NBT_STORAGE, BinaryTagTypes.STRING); + + // TODO: Deserialize data sources + if (nbtBlockTag != null) { + return Component.blockNBT() + .nbtPath(nbtPath) + .interpret(nbtInterpret) + .separator(nbtSeparator) + .pos(BlockNBTComponent.Pos.fromString(nbtBlockTag.value())) .style(style) .append(children) .build(); - case TYPE_SCORE: - CompoundBinaryTag scoreTag = getRequiredTag(compound, SCORE, BinaryTagTypes.COMPOUND); - return Component.score() - .name(getRequiredTag(scoreTag, SCORE_NAME, BinaryTagTypes.STRING).value()) - .objective(getRequiredTag(scoreTag, SCORE_OBJECTIVE, BinaryTagTypes.STRING).value()) + } else if (nbtEntityTag != null) { + return Component.entityNBT() + .nbtPath(nbtPath) + .interpret(nbtInterpret) + .separator(nbtSeparator) + .selector(nbtEntityTag.value()) .style(style) .append(children) .build(); - case TYPE_SELECTOR: - StringBinaryTag selectorTag = getRequiredTag(compound, SELECTOR, BinaryTagTypes.STRING); - BinaryTag selectorSeparatorTag = compound.get(SEPARATOR); - return Component.selector() - .pattern(selectorTag.value()) - .separator(selectorSeparatorTag == null ? null : this.deserialize(selectorSeparatorTag)) + } else if (nbtStorageTag != null) { + return Component.storageNBT() + .nbtPath(nbtPath) + .interpret(nbtInterpret) + .separator(nbtSeparator) + .storage(Key.key(nbtStorageTag.value())) .style(style) .append(children) .build(); - case TYPE_NBT: - String nbtPath = getRequiredTag(compound, NBT, BinaryTagTypes.STRING).value(); - - ByteBinaryTag nbtInterpretTag = getOptionalTag(compound, NBT_INTERPRET, BinaryTagTypes.BYTE); - boolean nbtInterpret = nbtInterpretTag != null && asBoolean(nbtInterpretTag); - - BinaryTag nbtSeparatorTag = compound.get(SEPARATOR); - Component nbtSeparator = null; - - if (nbtSeparatorTag != null) { - nbtSeparator = this.deserialize(nbtSeparatorTag); - } - - StringBinaryTag nbtBlockTag = getOptionalTag(compound, NBT_BLOCK, BinaryTagTypes.STRING); - StringBinaryTag nbtEntityTag = getOptionalTag(compound, NBT_ENTITY, BinaryTagTypes.STRING); - StringBinaryTag nbtStorageTag = getOptionalTag(compound, NBT_STORAGE, BinaryTagTypes.STRING); - - // TODO: Deserialize data sources - if (nbtBlockTag != null) { - return Component.blockNBT() - .nbtPath(nbtPath) - .interpret(nbtInterpret) - .separator(nbtSeparator) - .pos(BlockNBTComponent.Pos.fromString(nbtBlockTag.value())) - .style(style) - .append(children) - .build(); - } else if (nbtEntityTag != null) { - return Component.entityNBT() - .nbtPath(nbtPath) - .interpret(nbtInterpret) - .separator(nbtSeparator) - .selector(nbtEntityTag.value()) - .style(style) - .append(children) - .build(); - } else if (nbtStorageTag != null) { - return Component.storageNBT() - .nbtPath(nbtPath) - .interpret(nbtInterpret) - .separator(nbtSeparator) - .storage(Key.key(nbtStorageTag.value())) - .style(style) - .append(children) - .build(); - } else { - throw notSureHowToDeserialize(input); - } - default: + } else { throw notSureHowToDeserialize(input); + } + } else { + throw notSureHowToDeserialize(input); } } @@ -260,11 +235,8 @@ static final class Instances { CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder(); if (component instanceof TextComponent) { - this.writeComponentType(TYPE_TEXT, builder); builder.putString(TEXT, ((TextComponent) component).content()); } else if (component instanceof TranslatableComponent) { - this.writeComponentType(TYPE_TRANSLATABLE, builder); - TranslatableComponent translatable = (TranslatableComponent) component; builder.putString(TRANSLATE, translatable.key()); @@ -281,10 +253,8 @@ static final class Instances { builder.put(TRANSLATE_WITH, ListBinaryTag.from(argumentsTags)); } } else if (component instanceof KeybindComponent) { - this.writeComponentType(TYPE_KEYBIND, builder); builder.putString(KEYBIND, ((KeybindComponent) component).keybind()); } else if (component instanceof ScoreComponent) { - this.writeComponentType(TYPE_SCORE, builder); ScoreComponent score = (ScoreComponent) component; CompoundBinaryTag.Builder scoreBuilder = CompoundBinaryTag.builder() @@ -293,8 +263,6 @@ static final class Instances { builder.put(SCORE, scoreBuilder.build()); } else if (component instanceof SelectorComponent) { - this.writeComponentType(TYPE_SELECTOR, builder); - SelectorComponent selector = (SelectorComponent) component; builder.putString(SELECTOR, selector.pattern()); @@ -303,8 +271,6 @@ static final class Instances { builder.put(SEPARATOR, this.serialize(separator)); } } else if (component instanceof NBTComponent) { - this.writeComponentType(TYPE_NBT, builder); - NBTComponent nbt = (NBTComponent) component; builder.putString(NBT, nbt.nbtPath()); builder.putBoolean(NBT_INTERPRET, nbt.interpret()); // TODO: Make it optional @@ -344,12 +310,6 @@ static final class Instances { return this.flags; } - private void writeComponentType(final String componentType, final CompoundBinaryTag.Builder builder) { - if (this.flags.value(NBTSerializerOptions.SERIALIZE_COMPONENT_TYPES)) { - builder.putString(TYPE, componentType); - } - } - private static @NotNull IllegalArgumentException notSureHowToDeserialize(BinaryTag tag) { return new IllegalArgumentException("Don't know how to turn " + tag + " into a Component"); } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index 0508f8716a..6269115ef7 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -42,13 +42,6 @@ public final class NBTSerializerOptions { */ public static final Option EMIT_COMPACT_TEXT_COMPONENT = Option.booleanOption(key("emit/compact_text_component"), true); - /** - * Whether to serialize the types of {@linkplain net.kyori.adventure.text.Component components}. - * - * @since 4.24.0 - */ - public static final Option SERIALIZE_COMPONENT_TYPES = Option.booleanOption(key("serialize/component-types"), true); - /** * How to emit shadow colour data. * From 2c10acdf39ba5e1230a809f6179e5c5a0e1fd69c Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 22 Jun 2025 15:04:55 +0200 Subject: [PATCH 38/86] chore: remove serialize/deserialize data sources TODO --- .../text/serializer/nbt/NBTComponentSerializerImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index d45f9073a6..98aa786739 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -186,7 +186,6 @@ static final class Instances { StringBinaryTag nbtEntityTag = getOptionalTag(compound, NBT_ENTITY, BinaryTagTypes.STRING); StringBinaryTag nbtStorageTag = getOptionalTag(compound, NBT_STORAGE, BinaryTagTypes.STRING); - // TODO: Deserialize data sources if (nbtBlockTag != null) { return Component.blockNBT() .nbtPath(nbtPath) @@ -280,7 +279,6 @@ static final class Instances { builder.put(SEPARATOR, this.serialize(separator)); } - // TODO: Serialize data sources if (nbt instanceof BlockNBTComponent) { builder.putString(NBT_BLOCK, ((BlockNBTComponent) nbt).pos().asString()); } else if (nbt instanceof EntityNBTComponent) { From 7dc38e1bbadd39ea64d1550cc4492c271b820ec0 Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 22 Jun 2025 16:02:32 +0200 Subject: [PATCH 39/86] feat: add an option for emitting default nbt component interpret value --- .../text/serializer/nbt/NBTComponentSerializerImpl.java | 6 +++++- .../text/serializer/nbt/NBTSerializerOptions.java | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 98aa786739..e139bfd6ca 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -272,7 +272,11 @@ static final class Instances { } else if (component instanceof NBTComponent) { NBTComponent nbt = (NBTComponent) component; builder.putString(NBT, nbt.nbtPath()); - builder.putBoolean(NBT_INTERPRET, nbt.interpret()); // TODO: Make it optional + + boolean interpret = nbt.interpret(); + if (this.flags.value(NBTSerializerOptions.EMIT_DEFAULT_NBT_INTERPRET_VALUE) || interpret) { + builder.putBoolean(NBT_INTERPRET, interpret); + } Component separator = nbt.separator(); if (separator != null) { diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index 6269115ef7..ba2fc6b5a4 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -72,6 +72,13 @@ public final class NBTSerializerOptions { */ public static final Option EMIT_DEFAULT_ITEM_HOVER_QUANTITY = Option.booleanOption(key("emit/default_item_hover_quantity"), true); + /** + * Whether to emit the default interpret value ({@code false}) of NBT components. + * + * @since 4.24.0 + */ + public static final Option EMIT_DEFAULT_NBT_INTERPRET_VALUE = Option.booleanOption(key("emit/default_nbt_interpret_value"), true); + /** * Control how entity ids of show entity hover events should be emitted. * From 69e2a3f8753a93f0f28d0ef802831ff65e21884d Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 22 Jun 2025 16:28:10 +0200 Subject: [PATCH 40/86] chore: remove redundant cast in NBTSerializerUtils#getRequiredTag --- .../kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java index 648336ca6f..0fe1b0de51 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java @@ -18,7 +18,7 @@ private NBTSerializerUtils() { if (tag == null) { throw new IllegalArgumentException("The specified compound tag does not contain a \"" + name + "\" field"); } - return (B) tag; + return tag; } From a45a90cda02e3adc748c80afd99d966f83fb89db Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 22 Jun 2025 16:41:56 +0200 Subject: [PATCH 41/86] chore: fix spacing in NBTSerializerUtils --- .../kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java | 1 - 1 file changed, 1 deletion(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java index 0fe1b0de51..b7f3b7264f 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java @@ -21,7 +21,6 @@ private NBTSerializerUtils() { return tag; } - static @Nullable B getOptionalTag(@NotNull CompoundBinaryTag compoundTag, @NotNull String name, @NotNull BinaryTagType tagType) { BinaryTag tag = compoundTag.get(name); From 7f7ccd53e9d544437f89e84eb6af49b561ac1d99 Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 22 Jun 2025 17:18:00 +0200 Subject: [PATCH 42/86] chore: vanilla-like component children serializing --- .../nbt/NBTComponentSerializerImpl.java | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index e139bfd6ca..8a983b67e7 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -47,6 +47,7 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.function.Consumer; @@ -119,10 +120,15 @@ static final class Instances { CompoundBinaryTag compound = (CompoundBinaryTag) input; Style style = StyleSerializer.deserialize(compound, this); - List children = new ArrayList<>(); - ListBinaryTag extraTag = compound.getList(EXTRA); - // TODO: Deserialize it like vanilla - extraTag.forEach(child -> children.add(this.deserialize(child))); + ListBinaryTag extraTag = getOptionalTag(compound, EXTRA, BinaryTagTypes.LIST); + List children; + + if (extraTag == null) { + children = Collections.emptyList(); + } else { + children = new ArrayList<>(); + extraTag.unwrapHeterogeneity().forEach(child -> children.add(this.deserialize(child))); + } if (compound.get(TEXT) != null) { return Component.text() @@ -298,10 +304,9 @@ static final class Instances { List children = component.children(); if (!children.isEmpty()) { - List serializedChildren = new ArrayList<>(); - // TODO: Encode it like vanilla - children.forEach(child -> serializedChildren.add(this.writeCompoundComponent(child))); - builder.put(EXTRA, ListBinaryTag.from(serializedChildren)); + ListBinaryTag.Builder extraTagBuilder = ListBinaryTag.heterogeneousListBinaryTag(); + children.forEach(child -> extraTagBuilder.add(this.serialize(child))); + builder.put(EXTRA, extraTagBuilder.build().wrapHeterogeneity()); } StyleSerializer.serialize(component.style(), builder, this); From 3cb553e68298cea38e4cce836bcea6c52184a2e8 Mon Sep 17 00:00:00 2001 From: codestech Date: Wed, 25 Jun 2025 11:52:14 +0200 Subject: [PATCH 43/86] chore: vanilla-like translatable component arguments serializing --- .../nbt/NBTComponentSerializerImpl.java | 14 +++-- .../serializer/nbt/NBTSerializerUtils.java | 5 ++ .../nbt/TranslationArgumentSerializer.java | 52 +++++++++++++++++++ 3 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TranslationArgumentSerializer.java diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 8a983b67e7..618cfa6ce5 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -138,12 +138,11 @@ static final class Instances { .build(); } else if (compound.get(TRANSLATE) != null) { StringBinaryTag translateTag = getRequiredTag(compound, TRANSLATE, BinaryTagTypes.STRING); - ListBinaryTag translateWithTag = compound.getList(TRANSLATE_WITH); + ListBinaryTag translateWithTag = compound.getList(TRANSLATE_WITH).unwrapHeterogeneity(); StringBinaryTag fallbackTag = getOptionalTag(compound, TRANSLATE_FALLBACK, BinaryTagTypes.STRING); - // TODO: Decode it like vanilla - List arguments = new ArrayList<>(); - translateWithTag.forEach(argumentTag -> arguments.add(this.deserialize(argumentTag))); + List arguments = new ArrayList<>(); + translateWithTag.forEach(argumentTag -> arguments.add(TranslationArgumentSerializer.deserialize(argumentTag, this))); return Component.translatable() .key(translateTag.value()) @@ -252,10 +251,9 @@ static final class Instances { List arguments = translatable.arguments(); if (!arguments.isEmpty()) { - List argumentsTags = new ArrayList<>(); - // TODO: Encode it like vanilla - arguments.forEach(argument -> argumentsTags.add(this.writeCompoundComponent(argument.asComponent()))); - builder.put(TRANSLATE_WITH, ListBinaryTag.from(argumentsTags)); + ListBinaryTag.Builder translateWithTagBuilder = ListBinaryTag.heterogeneousListBinaryTag(); + arguments.forEach(argument -> translateWithTagBuilder.add(TranslationArgumentSerializer.serialize(argument, this))); + builder.put(TRANSLATE_WITH, translateWithTagBuilder.build().wrapHeterogeneity()); } } else if (component instanceof KeybindComponent) { builder.putString(KEYBIND, ((KeybindComponent) component).keybind()); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java index b7f3b7264f..91732b37ec 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java @@ -2,6 +2,7 @@ import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.BinaryTagType; +import net.kyori.adventure.nbt.ByteBinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.NumberBinaryTag; import org.jetbrains.annotations.NotNull; @@ -44,4 +45,8 @@ static boolean asBoolean(@NotNull NumberBinaryTag tag) { // != 0 might look weird, but it is what vanilla does return tag.byteValue() != 0; } + + static @NotNull ByteBinaryTag asTag(boolean value) { + return value ? ByteBinaryTag.ONE : ByteBinaryTag.ZERO; + } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TranslationArgumentSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TranslationArgumentSerializer.java new file mode 100644 index 0000000000..1d9e0fa0d8 --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TranslationArgumentSerializer.java @@ -0,0 +1,52 @@ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.ByteBinaryTag; +import net.kyori.adventure.nbt.DoubleBinaryTag; +import net.kyori.adventure.nbt.FloatBinaryTag; +import net.kyori.adventure.nbt.IntBinaryTag; +import net.kyori.adventure.nbt.LongBinaryTag; +import net.kyori.adventure.nbt.NumberBinaryTag; +import net.kyori.adventure.nbt.ShortBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TranslationArgument; +import org.jetbrains.annotations.NotNull; + +final class TranslationArgumentSerializer { + + private TranslationArgumentSerializer() { + } + + static @NotNull TranslationArgument deserialize(@NotNull BinaryTag tag, @NotNull NBTComponentSerializerImpl serializer) { + /* Serialized booleans are not deserialized as booleans because Minecraft also does that - NbtOps serializes + booleans as byte tags and there is no way to distinguish the original type during deserialization.*/ + if (tag instanceof NumberBinaryTag) { + return TranslationArgument.numeric(((NumberBinaryTag) tag).numberValue()); + } else { + return TranslationArgument.component(serializer.deserialize(tag)); + } + } + + static @NotNull BinaryTag serialize(@NotNull TranslationArgument argument, @NotNull NBTComponentSerializerImpl serializer) { + Object value = argument.value(); + if (value instanceof Boolean) { + return NBTSerializerUtils.asTag((boolean) value); + } else if (value instanceof Byte) { + return ByteBinaryTag.byteBinaryTag((byte) value); + } else if (value instanceof Short) { + return ShortBinaryTag.shortBinaryTag((short) value); + } else if (value instanceof Integer) { + return IntBinaryTag.intBinaryTag((int) value); + } else if (value instanceof Long) { + return LongBinaryTag.longBinaryTag((long) value); + } else if (value instanceof Float) { + return FloatBinaryTag.floatBinaryTag((float) value); + } else if (value instanceof Number) { + return DoubleBinaryTag.doubleBinaryTag(((Number) value).doubleValue()); + } else if (value instanceof Component) { + return serializer.serialize((Component) value); + } else { + throw new IllegalArgumentException("Don't know how to serialize the specified translation argument value: " + value); + } + } +} From a85d088d07b7507a3d5006dbd804652b323b3e6a Mon Sep 17 00:00:00 2001 From: codestech Date: Wed, 25 Jun 2025 12:55:05 +0200 Subject: [PATCH 44/86] chore: add missing license headers and update to 2025 --- .../serializer/nbt/ClickEventSerializer.java | 2 +- .../serializer/nbt/HoverEventSerializer.java | 2 +- .../nbt/NBTComponentSerializer.java | 2 +- .../nbt/NBTComponentSerializerImpl.java | 2 +- .../serializer/nbt/NBTDataComponentValue.java | 2 +- .../nbt/NBTDataComponentValueImpl.java | 2 +- .../serializer/nbt/NBTSerializerOptions.java | 2 +- .../serializer/nbt/NBTSerializerUtils.java | 23 +++++++++++++++++++ .../serializer/nbt/ShadowColorSerializer.java | 23 +++++++++++++++++++ .../serializer/nbt/ShowEntitySerializer.java | 23 +++++++++++++++++++ .../serializer/nbt/ShowItemSerializer.java | 23 +++++++++++++++++++ .../text/serializer/nbt/StyleSerializer.java | 2 +- .../serializer/nbt/TextColorSerializer.java | 23 +++++++++++++++++++ .../nbt/TranslationArgumentSerializer.java | 23 +++++++++++++++++++ .../text/serializer/nbt/UUIDSerializer.java | 23 +++++++++++++++++++ .../serializer/nbt/BlockNBTComponentTest.java | 2 +- .../text/serializer/nbt/ClickEventTest.java | 2 +- .../nbt/EntityNBTComponentTest.java | 2 +- .../text/serializer/nbt/HoverEventTest.java | 2 +- .../serializer/nbt/KeybindComponentTest.java | 2 +- .../text/serializer/nbt/NBTComponentTest.java | 2 +- .../serializer/nbt/ScoreComponentTest.java | 2 +- .../serializer/nbt/SelectorComponentTest.java | 2 +- .../nbt/StorageNBTComponentTest.java | 2 +- .../serializer/nbt/TextComponentTest.java | 2 +- .../nbt/TranslatableComponentTest.java | 2 +- 26 files changed, 180 insertions(+), 19 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java index 2f70b3cb39..ff45e6636a 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java index 843bf0b0ed..c4b4f82c4c 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java index 28435bdec8..c8a5a0f4b3 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 618cfa6ce5..44da453ade 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java index 67da72a64d..f56167712c 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java index 01bb00f1bd..b2c163d94a 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index ba2fc6b5a4..03e4c80d10 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java index 91732b37ec..aaee5f4676 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java @@ -1,3 +1,26 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.nbt.BinaryTag; diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java index dcb2da2ed1..72c26f358c 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java @@ -1,3 +1,26 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.nbt.BinaryTag; diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java index bf12a1d5a5..9516031433 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java @@ -1,3 +1,26 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.key.Key; diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java index 79067afc5e..0abf39b336 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java @@ -1,3 +1,26 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.key.Key; diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java index fd6d505ab1..c9a23f21ec 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TextColorSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TextColorSerializer.java index 0dfbb5ac33..1d1cbb1c7b 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TextColorSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TextColorSerializer.java @@ -1,3 +1,26 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.nbt.StringBinaryTag; diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TranslationArgumentSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TranslationArgumentSerializer.java index 1d9e0fa0d8..87443fed85 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TranslationArgumentSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TranslationArgumentSerializer.java @@ -1,3 +1,26 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.nbt.BinaryTag; diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java index a159a5ecd9..fa9e2e010a 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java @@ -1,3 +1,26 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.nbt.BinaryTag; diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java index ee66aeed49..2ef197afff 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ClickEventTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ClickEventTest.java index 926e481ba4..ec68a266fe 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ClickEventTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ClickEventTest.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java index d42756db14..fe2876d474 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/HoverEventTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/HoverEventTest.java index 1f44bbca5f..c84a5ef2b1 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/HoverEventTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/HoverEventTest.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java index 22e26b2a7e..ca2666862b 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/NBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/NBTComponentTest.java index 226e657f7a..83ac0fdd6b 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/NBTComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/NBTComponentTest.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java index 1277fe63d0..3e507e96c3 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java index 505abc8b06..9cf56b3065 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java index ef386d8b8b..6530a9981b 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java index f30b47dbea..a9fc257f6a 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java index acb291996c..c18dc96670 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java @@ -1,7 +1,7 @@ /* * This file is part of adventure, licensed under the MIT License. * - * Copyright (c) 2017-2024 KyoriPowered + * Copyright (c) 2017-2025 KyoriPowered * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal From 1a948f22e5715f1c24108bd8a6db1ed89234f0af Mon Sep 17 00:00:00 2001 From: codestech Date: Wed, 25 Jun 2025 13:25:13 +0200 Subject: [PATCH 45/86] chore: use TextDecoration#values for style decoration serialization (order does not matter in NBT since compound tags use maps) --- .../text/serializer/nbt/StyleSerializer.java | 37 +------------------ 1 file changed, 2 insertions(+), 35 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java index c9a23f21ec..5bd0f95242 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java @@ -38,9 +38,6 @@ import net.kyori.option.OptionState; import org.jetbrains.annotations.NotNull; -import java.util.EnumSet; -import java.util.Set; - import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_CAMEL; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_SNAKE; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.COLOR; @@ -53,28 +50,6 @@ final class StyleSerializer { - @SuppressWarnings("checkstyle:NoWhitespaceAfter") - private static final TextDecoration[] DECORATIONS = { - // The order here is important -- Minecraft does string comparisons of some - // serialized components so we have to make sure our order matches Vanilla - TextDecoration.BOLD, - TextDecoration.ITALIC, - TextDecoration.UNDERLINED, - TextDecoration.STRIKETHROUGH, - TextDecoration.OBFUSCATED - }; - - static { - // Ensure coverage of decorations - final Set knownDecorations = EnumSet.allOf(TextDecoration.class); - for (final TextDecoration decoration : DECORATIONS) { - knownDecorations.remove(decoration); - } - if (!knownDecorations.isEmpty()) { - throw new IllegalStateException("NBT serializer is missing some text decorations: " + knownDecorations); - } - } - private StyleSerializer() { } @@ -86,7 +61,7 @@ private StyleSerializer() { styleBuilder.color(TextColorSerializer.deserialize(colorTag)); } - for (TextDecoration decoration : DECORATIONS) { + for (TextDecoration decoration : TextDecoration.values()) { String name = TextDecoration.NAMES.keyOrThrow(decoration); ByteBinaryTag decorationTag = NBTSerializerUtils.getOptionalTag(compound, name, BinaryTagTypes.BYTE); if (decorationTag == null) continue; @@ -140,7 +115,7 @@ static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder b builder.put(COLOR, TextColorSerializer.serialize(color)); } - for (TextDecoration decoration : DECORATIONS) { + for (TextDecoration decoration : TextDecoration.values()) { TextDecoration.State state = style.decoration(decoration); if (state == TextDecoration.State.NOT_SET) continue; String name = TextDecoration.NAMES.keyOrThrow(decoration); @@ -211,12 +186,4 @@ static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder b } } } - - private static TextDecoration.@NotNull State readOptionalState(@NotNull String key, @NotNull CompoundBinaryTag compound) { - BinaryTag tag = compound.get(key); - if (tag == null) { - return TextDecoration.State.NOT_SET; - } - return TextDecoration.State.byBoolean(((ByteBinaryTag) tag).value() != 0); - } } From ad8d730c5576be70ca0e54a433aee487c51187c4 Mon Sep 17 00:00:00 2001 From: codestech Date: Thu, 26 Jun 2025 11:35:19 +0200 Subject: [PATCH 46/86] chore: use option schema for NBT serializer options instead --- .../nbt/NBTComponentSerializerImpl.java | 11 +++-- .../serializer/nbt/NBTSerializerOptions.java | 46 ++++++++++++++++--- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 44da453ade..712b05dbeb 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -98,13 +98,16 @@ final class NBTComponentSerializerImpl implements NBTComponentSerializer { static final class Instances { static final NBTComponentSerializer INSTANCE = SERVICE .map(Provider::nbt) - .orElseGet(() -> new NBTComponentSerializerImpl(OptionState.emptyOptionState())); + .orElseGet(() -> new NBTComponentSerializerImpl(NBTSerializerOptions.schema().emptyState())); } private final OptionState flags; NBTComponentSerializerImpl(@NotNull OptionState flags) { - this.flags = flags; + this.flags = requireNonNull(flags, "flags"); + if (flags.schema() != NBTSerializerOptions.schema()) { + throw new IllegalArgumentException("The specified option state does not use the NBT serializer option schema"); + } } @Override @@ -325,7 +328,7 @@ static final class Instances { static final class BuilderImpl implements NBTComponentSerializer.Builder { - private OptionState flags = OptionState.emptyOptionState(); + private OptionState flags = NBTSerializerOptions.schema().emptyState(); BuilderImpl() { BUILDER.accept(this); // let service provider touch the builder before anybody else touches it @@ -339,7 +342,7 @@ static final class BuilderImpl implements NBTComponentSerializer.Builder { @Override public @NotNull Builder editOptions(@NotNull Consumer optionEditor) { - final OptionState.Builder builder = OptionState.optionState().values(this.flags); + final OptionState.Builder builder = NBTSerializerOptions.schema().stateBuilder().values(this.flags); requireNonNull(optionEditor, "optionEditor").accept(builder); this.flags = builder.build(); return this; diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index 03e4c80d10..0409eead5a 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -24,6 +24,8 @@ package net.kyori.adventure.text.serializer.nbt; import net.kyori.option.Option; +import net.kyori.option.OptionSchema; +import org.jetbrains.annotations.NotNull; /** * Options that can apply to {@linkplain NBTComponentSerializer NBT serializers}. @@ -40,28 +42,28 @@ public final class NBTSerializerOptions { * @since 4.24.0 * @sinceMinecraft 1.20.3 */ - public static final Option EMIT_COMPACT_TEXT_COMPONENT = Option.booleanOption(key("emit/compact_text_component"), true); + public static final Option EMIT_COMPACT_TEXT_COMPONENT; /** * How to emit shadow colour data. * * @since 4.24.0 */ - public static final Option SHADOW_COLOR_MODE = Option.enumOption(key("emit/shadow_color"), ShadowColorEmitMode.class, ShadowColorEmitMode.EMIT_INTEGER); + public static final Option SHADOW_COLOR_MODE; /** * Control how hover event values should be emitted. * * @since 4.24.0 */ - public static final Option EMIT_HOVER_EVENT_TYPE = Option.enumOption(key("emit/hover_value_mode"), HoverEventValueMode.class, HoverEventValueMode.SNAKE_CASE); + public static final Option EMIT_HOVER_EVENT_TYPE; /** * Control how click event values should be emitted. * * @since 4.24.0 */ - public static final Option EMIT_CLICK_EVENT_TYPE = Option.enumOption(key("emit/click_value_mode"), ClickEventValueMode.class, ClickEventValueMode.SNAKE_CASE); + public static final Option EMIT_CLICK_EVENT_TYPE; /** * Whether to emit the default hover event item stack quantity of {@code 1}. @@ -70,21 +72,41 @@ public final class NBTSerializerOptions { * * @since 4.24.0 */ - public static final Option EMIT_DEFAULT_ITEM_HOVER_QUANTITY = Option.booleanOption(key("emit/default_item_hover_quantity"), true); + public static final Option EMIT_DEFAULT_ITEM_HOVER_QUANTITY; /** * Whether to emit the default interpret value ({@code false}) of NBT components. * * @since 4.24.0 */ - public static final Option EMIT_DEFAULT_NBT_INTERPRET_VALUE = Option.booleanOption(key("emit/default_nbt_interpret_value"), true); + public static final Option EMIT_DEFAULT_NBT_INTERPRET_VALUE; /** * Control how entity ids of show entity hover events should be emitted. * * @since 4.24.0 */ - public static final Option EMIT_SHOW_ENTITY_UUID_TYPE = Option.enumOption(key("emit/show_entity_uuid"), ShowEntityUUIDEmitMode.class, ShowEntityUUIDEmitMode.EMIT_INT_ARRAY); + public static final Option EMIT_SHOW_ENTITY_UUID_TYPE; + + private static final OptionSchema SCHEMA; + + // TODO: Add show item hover data mode + // TODO: Add component type field emitting mode + // TODO: Add a way to serialize components as lists + // TODO: Add source field emitting mode + // TODO: Add show item hover data mode + + static { + OptionSchema.Mutable schema = OptionSchema.emptySchema(); + EMIT_COMPACT_TEXT_COMPONENT = schema.booleanOption(key("emit/compact_text_component"), true); + SHADOW_COLOR_MODE = schema.enumOption(key("emit/shadow_color"), ShadowColorEmitMode.class, ShadowColorEmitMode.EMIT_INTEGER); + EMIT_HOVER_EVENT_TYPE = schema.enumOption(key("emit/hover_value_mode"), HoverEventValueMode.class, HoverEventValueMode.SNAKE_CASE); + EMIT_CLICK_EVENT_TYPE = schema.enumOption(key("emit/click_value_mode"), ClickEventValueMode.class, ClickEventValueMode.SNAKE_CASE); + EMIT_DEFAULT_ITEM_HOVER_QUANTITY = schema.booleanOption(key("emit/default_item_hover_quantity"), true); + EMIT_DEFAULT_NBT_INTERPRET_VALUE = schema.booleanOption(key("emit/default_nbt_interpret_value"), true); + EMIT_SHOW_ENTITY_UUID_TYPE = schema.enumOption(key("emit/show_entity_uuid"), ShowEntityUUIDEmitMode.class, ShowEntityUUIDEmitMode.EMIT_INT_ARRAY); + SCHEMA = schema.frozenView(); + } private NBTSerializerOptions() { } @@ -93,6 +115,16 @@ private static String key(final String value) { return "adventure:nbt/" + value; } + /** + * A schema of available options. + * + * @return the schema of known NBT serializer options + * @since 4.20.0 + */ + public static @NotNull OptionSchema schema() { + return SCHEMA; + } + /** * Configure how to emit hover event values. * From 619a62ac6c136e6926b001198524f8c01f5bb59b Mon Sep 17 00:00:00 2001 From: codestech Date: Thu, 26 Jun 2025 12:45:04 +0200 Subject: [PATCH 47/86] feat: deserializing components from list binary tags --- .../serializer/nbt/NBTComponentSerializerImpl.java | 14 ++++++++++++-- .../text/serializer/nbt/NBTSerializerOptions.java | 3 +-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 712b05dbeb..877173cc9c 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -114,9 +114,19 @@ static final class Instances { public @NotNull Component deserialize(@NotNull BinaryTag input) { if (input instanceof StringBinaryTag) { return Component.text(((StringBinaryTag) input).value()); - } + } else if (input instanceof ListBinaryTag) { + ListBinaryTag castTag = (ListBinaryTag) input; + if (castTag.isEmpty()) { + throw new IllegalArgumentException("The list binary tag must not be empty"); + } + + Component rootTag = this.deserialize(castTag.get(0)); + for (int index = 1; index < castTag.size(); index++) { + rootTag = rootTag.append(this.deserialize(castTag.get(index))); + } - if (!(input instanceof CompoundBinaryTag)) { + return rootTag; + } else if (!(input instanceof CompoundBinaryTag)) { throw new IllegalArgumentException("The input isn't a compound or string binary tag"); } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index 0409eead5a..56e7dea772 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -37,7 +37,7 @@ public final class NBTSerializerOptions { /** - * Whether to emit text components with no style and no children as plain text. + * Whether to emit text components with no style and no children as a plain text. * * @since 4.24.0 * @sinceMinecraft 1.20.3 @@ -92,7 +92,6 @@ public final class NBTSerializerOptions { // TODO: Add show item hover data mode // TODO: Add component type field emitting mode - // TODO: Add a way to serialize components as lists // TODO: Add source field emitting mode // TODO: Add show item hover data mode From 923905ca107c69dcb071267332c5e80406861700 Mon Sep 17 00:00:00 2001 From: codestech Date: Thu, 26 Jun 2025 14:11:35 +0200 Subject: [PATCH 48/86] feat: deserialize and serialize legacy additional data of show item hover events --- .../serializer/nbt/HoverEventSerializer.java | 4 +- .../serializer/nbt/NBTSerializerOptions.java | 39 ++++++++++++++-- .../serializer/nbt/ShowItemSerializer.java | 46 +++++++++++++------ 3 files changed, 67 insertions(+), 22 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java index c4b4f82c4c..96aaaf8baf 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -62,7 +62,7 @@ private HoverEventSerializer() { } return HoverEvent.showText(serializer.deserialize(textTag)); } else if (action == HoverEvent.Action.SHOW_ITEM) { - return HoverEvent.showItem(ShowItemSerializer.deserialize(contentsTag)); + return HoverEvent.showItem(ShowItemSerializer.deserialize(contentsTag, snakeCase)); } else if (action == HoverEvent.Action.SHOW_ENTITY) { return HoverEvent.showEntity(ShowEntitySerializer.deserialize(contentsTag, snakeCase, serializer)); } else { @@ -88,7 +88,7 @@ private HoverEventSerializer() { contentsTag = serializedComponent; } } else if (action == HoverEvent.Action.SHOW_ITEM) { - contentsTag = ShowItemSerializer.serialize((HoverEvent.ShowItem) event.value(), serializer); + contentsTag = ShowItemSerializer.serialize((HoverEvent.ShowItem) event.value(), snakeCase, serializer); } else if (action == HoverEvent.Action.SHOW_ENTITY) { contentsTag = ShowEntitySerializer.serialize((HoverEvent.ShowEntity) event.value(), snakeCase, serializer); } else { diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index 56e7dea772..a8f6ccffa9 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -88,12 +88,14 @@ public final class NBTSerializerOptions { */ public static final Option EMIT_SHOW_ENTITY_UUID_TYPE; - private static final OptionSchema SCHEMA; + /** + * How to emit show item hovers in {@code hoverEvent} (camelCase) fields. + * + * @since 4.24.0 + */ + public static final Option SHOW_ITEM_HOVER_DATA_MODE; - // TODO: Add show item hover data mode - // TODO: Add component type field emitting mode - // TODO: Add source field emitting mode - // TODO: Add show item hover data mode + private static final OptionSchema SCHEMA; static { OptionSchema.Mutable schema = OptionSchema.emptySchema(); @@ -104,6 +106,7 @@ public final class NBTSerializerOptions { EMIT_DEFAULT_ITEM_HOVER_QUANTITY = schema.booleanOption(key("emit/default_item_hover_quantity"), true); EMIT_DEFAULT_NBT_INTERPRET_VALUE = schema.booleanOption(key("emit/default_nbt_interpret_value"), true); EMIT_SHOW_ENTITY_UUID_TYPE = schema.enumOption(key("emit/show_entity_uuid"), ShowEntityUUIDEmitMode.class, ShowEntityUUIDEmitMode.EMIT_INT_ARRAY); + SHOW_ITEM_HOVER_DATA_MODE = schema.enumOption(key("emit/show_item_hover_data"), ShowItemHoverDataMode.class, ShowItemHoverDataMode.EMIT_EITHER); SCHEMA = schema.frozenView(); } @@ -226,4 +229,30 @@ public enum ShowEntityUUIDEmitMode { */ EMIT_LIST } + + /** + * Configure how to emit show item hovers in {@code hoverEvent} (camelCase) fields. + * + * @since 4.24.0 + */ + public enum ShowItemHoverDataMode { + /** + * Only emit the pre-1.20.5 item NBT. + * + * @since 4.24.0 + */ + EMIT_LEGACY_NBT, + /** + * Only emit modern data components. + * + * @since 4.24.0 + */ + EMIT_DATA_COMPONENTS, + /** + * Emit whichever of legacy or modern data the item has. + * + * @since 4.24.0 + */ + EMIT_EITHER, + } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java index 0abf39b336..caa28a74ed 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java @@ -29,6 +29,8 @@ import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.EndBinaryTag; import net.kyori.adventure.nbt.IntBinaryTag; +import net.kyori.adventure.nbt.StringBinaryTag; +import net.kyori.adventure.nbt.api.BinaryTagHolder; import net.kyori.adventure.text.event.DataComponentValue; import net.kyori.adventure.text.event.HoverEvent; import org.jetbrains.annotations.NotNull; @@ -39,56 +41,65 @@ import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ITEM_COMPONENTS; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ITEM_COUNT; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ITEM_ID; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ITEM_TAG; import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getOptionalTag; import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getRequiredTag; final class ShowItemSerializer { private static final String DATA_COMPONENT_REMOVAL_PREFIX = "!"; + private static final int DEFAULT_ITEM_QUANTITY = 1; private ShowItemSerializer() { } - static HoverEvent.@NotNull ShowItem deserialize(@NotNull CompoundBinaryTag compound) { + static HoverEvent.@NotNull ShowItem deserialize(@NotNull CompoundBinaryTag compound, boolean snakeCase) { Key itemId = Key.key(getRequiredTag(compound, SHOW_ITEM_ID, BinaryTagTypes.STRING).value()); IntBinaryTag countTag = getOptionalTag(compound, SHOW_ITEM_COUNT, BinaryTagTypes.INT); - int itemCount = countTag == null ? 1 : countTag.value(); + int itemCount = countTag == null ? DEFAULT_ITEM_QUANTITY : countTag.value(); - CompoundBinaryTag components = getOptionalTag(compound, SHOW_ITEM_COMPONENTS, BinaryTagTypes.COMPOUND); - if (components == null) { - return HoverEvent.ShowItem.showItem(itemId, itemCount); + CompoundBinaryTag componentsTag = getOptionalTag(compound, SHOW_ITEM_COMPONENTS, BinaryTagTypes.COMPOUND); + StringBinaryTag nbtTag = getOptionalTag(compound, SHOW_ITEM_TAG, BinaryTagTypes.STRING); + + if (componentsTag == null) { + if (snakeCase || nbtTag == null) { + return HoverEvent.ShowItem.showItem(itemId, itemCount); + } + return HoverEvent.ShowItem.showItem(itemId, itemCount, BinaryTagHolder.binaryTagHolder(nbtTag.value())); } else { Map componentValues = new HashMap<>(); - for (String string : components.keySet()) { + for (String string : componentsTag.keySet()) { boolean removed = string.startsWith(DATA_COMPONENT_REMOVAL_PREFIX); - BinaryTag value = components.get(string); - if (value == null) continue; + BinaryTag valueTag = componentsTag.get(string); + if (valueTag == null) continue; if (removed) { string = string.substring(1); } - componentValues.put(Key.key(string), removed ? DataComponentValue.removed() : NBTDataComponentValue.nbtDataComponentValue(value)); + componentValues.put(Key.key(string), removed ? DataComponentValue.removed() : NBTDataComponentValue.nbtDataComponentValue(valueTag)); } return HoverEvent.ShowItem.showItem(itemId, itemCount, componentValues); } } - static @NotNull CompoundBinaryTag serialize(HoverEvent.@NotNull ShowItem showItem, @NotNull NBTComponentSerializerImpl serializer) { + static @NotNull CompoundBinaryTag serialize(HoverEvent.@NotNull ShowItem showItem, boolean snakeCase, + @NotNull NBTComponentSerializerImpl serializer) { CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() .putString(SHOW_ITEM_ID, showItem.item().asString()); int count = showItem.count(); - if (count != 1 || serializer.flags().value(NBTSerializerOptions.EMIT_DEFAULT_ITEM_HOVER_QUANTITY)) { + if (count != DEFAULT_ITEM_QUANTITY || serializer.flags().value(NBTSerializerOptions.EMIT_DEFAULT_ITEM_HOVER_QUANTITY)) { builder.putInt(SHOW_ITEM_COUNT, count); } - if (!showItem.dataComponents().isEmpty()) { - CompoundBinaryTag.Builder dataComponentsBuilder = CompoundBinaryTag.builder(); + NBTSerializerOptions.ShowItemHoverDataMode dataMode = serializer.flags().value(NBTSerializerOptions.SHOW_ITEM_HOVER_DATA_MODE); + if ((snakeCase || dataMode != NBTSerializerOptions.ShowItemHoverDataMode.EMIT_LEGACY_NBT) && !showItem.dataComponents().isEmpty()) { + CompoundBinaryTag.Builder componentsTagBuilder = CompoundBinaryTag.builder(); Map components = showItem.dataComponentsAs(NBTDataComponentValue.class); for (Map.Entry entry : components.entrySet()) { @@ -99,10 +110,15 @@ private ShowItemSerializer() { key = DATA_COMPONENT_REMOVAL_PREFIX + key; } - dataComponentsBuilder.put(key, value); + componentsTagBuilder.put(key, value); } - builder.put(SHOW_ITEM_COMPONENTS, dataComponentsBuilder.build()); + builder.put(SHOW_ITEM_COMPONENTS, componentsTagBuilder.build()); + } else if (!snakeCase && dataMode != NBTSerializerOptions.ShowItemHoverDataMode.EMIT_DATA_COMPONENTS) { + BinaryTagHolder nbt = showItem.nbt(); + if (nbt != null) { + builder.putString(SHOW_ITEM_TAG, nbt.string()); + } } return builder.build(); From 0a354ce1375519728c0bd2a552eec5520554de27 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 08:27:24 +0200 Subject: [PATCH 49/86] chore: make the code consistent --- .../serializer/nbt/ClickEventSerializer.java | 22 ++++---- .../nbt/NBTComponentSerializerImpl.java | 39 ++++++------- .../serializer/nbt/NBTSerializerUtils.java | 8 +-- .../serializer/nbt/ShadowColorSerializer.java | 48 ++++++++-------- .../serializer/nbt/ShowEntitySerializer.java | 8 +-- .../serializer/nbt/ShowItemSerializer.java | 4 +- .../text/serializer/nbt/StyleSerializer.java | 56 +++++++++---------- .../text/serializer/nbt/UUIDSerializer.java | 8 +-- 8 files changed, 94 insertions(+), 99 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java index ff45e6636a..89ede19b5f 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java @@ -47,9 +47,9 @@ final class ClickEventSerializer { private ClickEventSerializer() { } - static @Nullable ClickEvent deserializeCamel(@NotNull CompoundBinaryTag tag) { - StringBinaryTag actionTag = getRequiredTag(tag, CLICK_EVENT_ACTION, BinaryTagTypes.STRING); - StringBinaryTag valueTag = getRequiredTag(tag, CLICK_EVENT_VALUE, BinaryTagTypes.STRING); + static @Nullable ClickEvent deserializeCamel(@NotNull CompoundBinaryTag compound) { + StringBinaryTag actionTag = getRequiredTag(compound, CLICK_EVENT_ACTION, BinaryTagTypes.STRING); + StringBinaryTag valueTag = getRequiredTag(compound, CLICK_EVENT_VALUE, BinaryTagTypes.STRING); ClickEvent.Action action = ClickEvent.Action.NAMES.valueOrThrow(actionTag.value()); if (!action.readable()) { @@ -59,8 +59,8 @@ private ClickEventSerializer() { return ClickEvent.clickEvent(action, valueTag.value()); } - static @Nullable ClickEvent deserializeSnake(@NotNull CompoundBinaryTag tag) { - StringBinaryTag actionTag = getRequiredTag(tag, CLICK_EVENT_ACTION, BinaryTagTypes.STRING); + static @Nullable ClickEvent deserializeSnake(@NotNull CompoundBinaryTag compound) { + StringBinaryTag actionTag = getRequiredTag(compound, CLICK_EVENT_ACTION, BinaryTagTypes.STRING); ClickEvent.Action action = ClickEvent.Action.NAMES.valueOrThrow(actionTag.value()); if (!action.readable()) { @@ -69,22 +69,22 @@ private ClickEventSerializer() { switch (action) { case OPEN_URL: - StringBinaryTag urlTag = getRequiredTag(tag, CLICK_EVENT_URL, BinaryTagTypes.STRING); + StringBinaryTag urlTag = getRequiredTag(compound, CLICK_EVENT_URL, BinaryTagTypes.STRING); return ClickEvent.openUrl(urlTag.value()); case RUN_COMMAND: case SUGGEST_COMMAND: - StringBinaryTag commandTag = getRequiredTag(tag, CLICK_EVENT_COMMAND, BinaryTagTypes.STRING); + StringBinaryTag commandTag = getRequiredTag(compound, CLICK_EVENT_COMMAND, BinaryTagTypes.STRING); String command = commandTag.value(); return action == ClickEvent.Action.RUN_COMMAND ? ClickEvent.runCommand(command) : ClickEvent.suggestCommand(command); case CHANGE_PAGE: - IntBinaryTag pageTag = getRequiredTag(tag, CLICK_EVENT_PAGE, BinaryTagTypes.INT); + IntBinaryTag pageTag = getRequiredTag(compound, CLICK_EVENT_PAGE, BinaryTagTypes.INT); return ClickEvent.changePage(pageTag.value()); case COPY_TO_CLIPBOARD: - StringBinaryTag valueTag = getRequiredTag(tag, CLICK_EVENT_VALUE, BinaryTagTypes.STRING); + StringBinaryTag valueTag = getRequiredTag(compound, CLICK_EVENT_VALUE, BinaryTagTypes.STRING); return ClickEvent.copyToClipboard(valueTag.value()); case CUSTOM: - StringBinaryTag clickEventIdTag = getRequiredTag(tag, CLICK_EVENT_ID, BinaryTagTypes.STRING); - StringBinaryTag payloadTag = getRequiredTag(tag, CLICK_EVENT_PAYLOAD, BinaryTagTypes.STRING); + StringBinaryTag clickEventIdTag = getRequiredTag(compound, CLICK_EVENT_ID, BinaryTagTypes.STRING); + StringBinaryTag payloadTag = getRequiredTag(compound, CLICK_EVENT_PAYLOAD, BinaryTagTypes.STRING); return ClickEvent.custom(Key.key(clickEventIdTag.value()), BinaryTagHolder.binaryTagHolder(payloadTag.value())); default: // Never called, but needed for proper compilation diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 877173cc9c..390ce889b1 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -101,11 +101,11 @@ static final class Instances { .orElseGet(() -> new NBTComponentSerializerImpl(NBTSerializerOptions.schema().emptyState())); } - private final OptionState flags; + private final OptionState options; - NBTComponentSerializerImpl(@NotNull OptionState flags) { - this.flags = requireNonNull(flags, "flags"); - if (flags.schema() != NBTSerializerOptions.schema()) { + NBTComponentSerializerImpl(@NotNull OptionState options) { + this.options = requireNonNull(options, "options"); + if (options.schema() != NBTSerializerOptions.schema()) { throw new IllegalArgumentException("The specified option state does not use the NBT serializer option schema"); } } @@ -115,19 +115,19 @@ static final class Instances { if (input instanceof StringBinaryTag) { return Component.text(((StringBinaryTag) input).value()); } else if (input instanceof ListBinaryTag) { - ListBinaryTag castTag = (ListBinaryTag) input; - if (castTag.isEmpty()) { + ListBinaryTag castInput = (ListBinaryTag) input; + if (castInput.isEmpty()) { throw new IllegalArgumentException("The list binary tag must not be empty"); } - Component rootTag = this.deserialize(castTag.get(0)); - for (int index = 1; index < castTag.size(); index++) { - rootTag = rootTag.append(this.deserialize(castTag.get(index))); + Component rootTag = this.deserialize(castInput.get(0)); + for (int index = 1; index < castInput.size(); index++) { + rootTag = rootTag.append(this.deserialize(castInput.get(index))); } return rootTag; } else if (!(input instanceof CompoundBinaryTag)) { - throw new IllegalArgumentException("The input isn't a compound or string binary tag"); + throw new IllegalArgumentException("The input isn't a compound, string or list binary tag"); } CompoundBinaryTag compound = (CompoundBinaryTag) input; @@ -241,14 +241,11 @@ static final class Instances { @Override public @NotNull BinaryTag serialize(@NotNull Component component) { - if (this.flags.value(NBTSerializerOptions.EMIT_COMPACT_TEXT_COMPONENT) && component instanceof TextComponent + if (this.options.value(NBTSerializerOptions.EMIT_COMPACT_TEXT_COMPONENT) && component instanceof TextComponent && !component.hasStyling() && component.children().isEmpty()) { return StringBinaryTag.stringBinaryTag(((TextComponent) component).content()); } - return writeCompoundComponent(component); - } - private @NotNull CompoundBinaryTag writeCompoundComponent(@NotNull Component component) { CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder(); if (component instanceof TextComponent) { @@ -273,11 +270,11 @@ static final class Instances { } else if (component instanceof ScoreComponent) { ScoreComponent score = (ScoreComponent) component; - CompoundBinaryTag.Builder scoreBuilder = CompoundBinaryTag.builder() + CompoundBinaryTag.Builder scoreTagBuilder = CompoundBinaryTag.builder() .putString(SCORE_NAME, score.name()) .putString(SCORE_OBJECTIVE, score.objective()); - builder.put(SCORE, scoreBuilder.build()); + builder.put(SCORE, scoreTagBuilder.build()); } else if (component instanceof SelectorComponent) { SelectorComponent selector = (SelectorComponent) component; builder.putString(SELECTOR, selector.pattern()); @@ -291,7 +288,7 @@ static final class Instances { builder.putString(NBT, nbt.nbtPath()); boolean interpret = nbt.interpret(); - if (this.flags.value(NBTSerializerOptions.EMIT_DEFAULT_NBT_INTERPRET_VALUE) || interpret) { + if (this.options.value(NBTSerializerOptions.EMIT_DEFAULT_NBT_INTERPRET_VALUE) || interpret) { builder.putBoolean(NBT_INTERPRET, interpret); } @@ -324,15 +321,15 @@ static final class Instances { return builder.build(); } - @NotNull OptionState flags() { - return this.flags; + @NotNull OptionState options() { + return this.options; } - private static @NotNull IllegalArgumentException notSureHowToDeserialize(BinaryTag tag) { + private static @NotNull IllegalArgumentException notSureHowToDeserialize(@NotNull BinaryTag tag) { return new IllegalArgumentException("Don't know how to turn " + tag + " into a Component"); } - private static @NotNull IllegalArgumentException notSureHowToSerialize(Component component) { + private static @NotNull IllegalArgumentException notSureHowToSerialize(@NotNull Component component) { return new IllegalArgumentException("Don't know how to serialize " + component + " as a Component"); } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java index aaee5f4676..544fa51137 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java @@ -36,18 +36,18 @@ final class NBTSerializerUtils { private NBTSerializerUtils() { } - static @NotNull B getRequiredTag(@NotNull CompoundBinaryTag compoundTag, + static @NotNull B getRequiredTag(@NotNull CompoundBinaryTag compound, @NotNull String name, @NotNull BinaryTagType tagType) { - B tag = getOptionalTag(compoundTag, name, tagType); + B tag = getOptionalTag(compound, name, tagType); if (tag == null) { throw new IllegalArgumentException("The specified compound tag does not contain a \"" + name + "\" field"); } return tag; } - static @Nullable B getOptionalTag(@NotNull CompoundBinaryTag compoundTag, + static @Nullable B getOptionalTag(@NotNull CompoundBinaryTag compound, @NotNull String name, @NotNull BinaryTagType tagType) { - BinaryTag tag = compoundTag.get(name); + BinaryTag tag = compound.get(name); if (tag == null) { return null; } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java index 72c26f358c..8de3b940c1 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java @@ -37,43 +37,43 @@ final class ShadowColorSerializer { private ShadowColorSerializer() { } + static @NotNull ShadowColor deserialize(@NotNull BinaryTag tag) { + if (tag instanceof IntBinaryTag) { + IntBinaryTag castTag = (IntBinaryTag) tag; + return ShadowColor.shadowColor(castTag.value()); + } else if (tag instanceof ListBinaryTag) { + ListBinaryTag castTag = (ListBinaryTag) tag; + return ShadowColor.shadowColor( + getShadowColorComponent(castTag, 0), + getShadowColorComponent(castTag, 1), + getShadowColorComponent(castTag, 2), + getShadowColorComponent(castTag, 3) + ); + } else { + throw new IllegalArgumentException("The binary tag representing the shadow color is of an invalid type"); + } + } + static @Nullable BinaryTag serialize(@NotNull ShadowColor color, @NotNull NBTComponentSerializerImpl serializer) { - NBTSerializerOptions.ShadowColorEmitMode emitMode = serializer.flags().value(NBTSerializerOptions.SHADOW_COLOR_MODE); + NBTSerializerOptions.ShadowColorEmitMode emitMode = serializer.options().value(NBTSerializerOptions.SHADOW_COLOR_MODE); switch (emitMode) { case NONE: return null; case EMIT_INTEGER: return IntBinaryTag.intBinaryTag(color.value()); case EMIT_ARRAY: - ListBinaryTag.Builder shadowColorTagBuilder = ListBinaryTag.builder(BinaryTagTypes.FLOAT); - addShadowColorComponent(shadowColorTagBuilder, color.red()); - addShadowColorComponent(shadowColorTagBuilder, color.green()); - addShadowColorComponent(shadowColorTagBuilder, color.blue()); - addShadowColorComponent(shadowColorTagBuilder, color.alpha()); - return shadowColorTagBuilder.build(); + ListBinaryTag.Builder builder = ListBinaryTag.builder(BinaryTagTypes.FLOAT); + addShadowColorComponent(builder, color.red()); + addShadowColorComponent(builder, color.green()); + addShadowColorComponent(builder, color.blue()); + addShadowColorComponent(builder, color.alpha()); + return builder.build(); default: // Never called, but needed for proper compilation throw new IllegalArgumentException("Unknown shadow color emit mode: " + emitMode); } } - static @NotNull ShadowColor deserialize(@NotNull BinaryTag tag) { - if (tag instanceof IntBinaryTag) { - IntBinaryTag castShadowColorTag = (IntBinaryTag) tag; - return ShadowColor.shadowColor(castShadowColorTag.value()); - } else if (tag instanceof ListBinaryTag) { - ListBinaryTag castShadowColorTag = (ListBinaryTag) tag; - return ShadowColor.shadowColor( - getShadowColorComponent(castShadowColorTag, 0), - getShadowColorComponent(castShadowColorTag, 1), - getShadowColorComponent(castShadowColorTag, 2), - getShadowColorComponent(castShadowColorTag, 3) - ); - } else { - throw new IllegalArgumentException("The binary tag representing the shadow color is of an invalid type"); - } - } - private static int getShadowColorComponent(@NotNull ListBinaryTag tag, int index) { return (int) (tag.getFloat(index) * 0xff); } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java index 9516031433..eed9314d00 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java @@ -54,12 +54,12 @@ private ShowEntitySerializer() { } UUID entityId = UUIDSerializer.deserialize(entityIdTag); - BinaryTag entityName = compound.get(SHOW_ENTITY_NAME); + BinaryTag entityNameTag = compound.get(SHOW_ENTITY_NAME); - if (entityName == null) { + if (entityNameTag == null) { return HoverEvent.ShowEntity.showEntity(entityType, entityId); } else { - return HoverEvent.ShowEntity.showEntity(entityType, entityId, serializer.deserialize(entityName)); + return HoverEvent.ShowEntity.showEntity(entityType, entityId, serializer.deserialize(entityNameTag)); } } @@ -70,7 +70,7 @@ private ShowEntitySerializer() { UUID entityId = showEntity.id(); if (snakeCase) { - NBTSerializerOptions.ShowEntityUUIDEmitMode uuidEmitMode = serializer.flags().value(NBTSerializerOptions.EMIT_SHOW_ENTITY_UUID_TYPE); + NBTSerializerOptions.ShowEntityUUIDEmitMode uuidEmitMode = serializer.options().value(NBTSerializerOptions.EMIT_SHOW_ENTITY_UUID_TYPE); builder.put(SHOW_ENTITY_UUID, UUIDSerializer.serialize(entityId, uuidEmitMode)); } else { builder.put(SHOW_ENTITY_ID, UUIDSerializer.serialize(entityId, NBTSerializerOptions.ShowEntityUUIDEmitMode.EMIT_STRING)); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java index caa28a74ed..1192a732e0 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java @@ -93,11 +93,11 @@ private ShowItemSerializer() { .putString(SHOW_ITEM_ID, showItem.item().asString()); int count = showItem.count(); - if (count != DEFAULT_ITEM_QUANTITY || serializer.flags().value(NBTSerializerOptions.EMIT_DEFAULT_ITEM_HOVER_QUANTITY)) { + if (count != DEFAULT_ITEM_QUANTITY || serializer.options().value(NBTSerializerOptions.EMIT_DEFAULT_ITEM_HOVER_QUANTITY)) { builder.putInt(SHOW_ITEM_COUNT, count); } - NBTSerializerOptions.ShowItemHoverDataMode dataMode = serializer.flags().value(NBTSerializerOptions.SHOW_ITEM_HOVER_DATA_MODE); + NBTSerializerOptions.ShowItemHoverDataMode dataMode = serializer.options().value(NBTSerializerOptions.SHOW_ITEM_HOVER_DATA_MODE); if ((snakeCase || dataMode != NBTSerializerOptions.ShowItemHoverDataMode.EMIT_LEGACY_NBT) && !showItem.dataComponents().isEmpty()) { CompoundBinaryTag.Builder componentsTagBuilder = CompoundBinaryTag.builder(); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java index 5bd0f95242..9cad3ced67 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java @@ -78,24 +78,24 @@ private StyleSerializer() { styleBuilder.insertion(insertionTag.value()); } - CompoundBinaryTag binaryClickEvent = getOptionalTag(compound, CLICK_EVENT_SNAKE, BinaryTagTypes.COMPOUND); - if (binaryClickEvent == null) { - binaryClickEvent = getOptionalTag(compound, CLICK_EVENT_CAMEL, BinaryTagTypes.COMPOUND); - if (binaryClickEvent != null) { - styleBuilder.clickEvent(ClickEventSerializer.deserializeCamel(binaryClickEvent)); + CompoundBinaryTag clickEventTag = getOptionalTag(compound, CLICK_EVENT_SNAKE, BinaryTagTypes.COMPOUND); + if (clickEventTag == null) { + clickEventTag = getOptionalTag(compound, CLICK_EVENT_CAMEL, BinaryTagTypes.COMPOUND); + if (clickEventTag != null) { + styleBuilder.clickEvent(ClickEventSerializer.deserializeCamel(clickEventTag)); } } else { - styleBuilder.clickEvent(ClickEventSerializer.deserializeSnake(binaryClickEvent)); + styleBuilder.clickEvent(ClickEventSerializer.deserializeSnake(clickEventTag)); } - CompoundBinaryTag binaryHoverEvent = getOptionalTag(compound, HOVER_EVENT_SNAKE, BinaryTagTypes.COMPOUND); - if (binaryHoverEvent == null) { - binaryHoverEvent = getOptionalTag(compound, HOVER_EVENT_CAMEL, BinaryTagTypes.COMPOUND); - if (binaryHoverEvent != null) { - styleBuilder.hoverEvent(HoverEventSerializer.deserialize(binaryHoverEvent, false, serializer)); + CompoundBinaryTag hoverEventTag = getOptionalTag(compound, HOVER_EVENT_SNAKE, BinaryTagTypes.COMPOUND); + if (hoverEventTag == null) { + hoverEventTag = getOptionalTag(compound, HOVER_EVENT_CAMEL, BinaryTagTypes.COMPOUND); + if (hoverEventTag != null) { + styleBuilder.hoverEvent(HoverEventSerializer.deserialize(hoverEventTag, false, serializer)); } } else { - styleBuilder.hoverEvent(HoverEventSerializer.deserialize(binaryHoverEvent, true, serializer)); + styleBuilder.hoverEvent(HoverEventSerializer.deserialize(hoverEventTag, true, serializer)); } BinaryTag shadowColorTag = compound.get(SHADOW_COLOR); @@ -108,7 +108,7 @@ private StyleSerializer() { static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder builder, @NotNull NBTComponentSerializerImpl serializer) { - OptionState flags = serializer.flags(); + OptionState flags = serializer.options(); TextColor color = style.color(); if (color != null) { @@ -141,16 +141,16 @@ static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder b boolean emitCamelCaseClickEvent = clickEventValueMode == NBTSerializerOptions.ClickEventValueMode.CAMEL_CASE; if (emitBothClickEvents || emitSnakeCaseClickEvent) { - BinaryTag serializedClickEvent = ClickEventSerializer.serialize(clickEvent, true); - if (serializedClickEvent != null) { - builder.put(CLICK_EVENT_SNAKE, serializedClickEvent); + BinaryTag clickEventTag = ClickEventSerializer.serialize(clickEvent, true); + if (clickEventTag != null) { + builder.put(CLICK_EVENT_SNAKE, clickEventTag); } } if (emitBothClickEvents || emitCamelCaseClickEvent) { - BinaryTag serializedClickEvent = ClickEventSerializer.serialize(clickEvent, false); - if (serializedClickEvent != null) { - builder.put(CLICK_EVENT_CAMEL, serializedClickEvent); + BinaryTag clickEventTag = ClickEventSerializer.serialize(clickEvent, false); + if (clickEventTag != null) { + builder.put(CLICK_EVENT_CAMEL, clickEventTag); } } } @@ -164,25 +164,25 @@ static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder b boolean emitCamelCaseHoverEvent = hoverEventValueMode == NBTSerializerOptions.HoverEventValueMode.CAMEL_CASE; if (emitBothHoverEvents || emitSnakeCaseHoverEvent) { - BinaryTag serializedHoverEvent = HoverEventSerializer.serialize(hoverEvent, true, serializer); - if (serializedHoverEvent != null) { - builder.put(HOVER_EVENT_SNAKE, serializedHoverEvent); + BinaryTag hoverEventTag = HoverEventSerializer.serialize(hoverEvent, true, serializer); + if (hoverEventTag != null) { + builder.put(HOVER_EVENT_SNAKE, hoverEventTag); } } if (emitBothHoverEvents || emitCamelCaseHoverEvent) { - BinaryTag serializedHoverEvent = HoverEventSerializer.serialize(hoverEvent, false, serializer); - if (serializedHoverEvent != null) { - builder.put(HOVER_EVENT_CAMEL, serializedHoverEvent); + BinaryTag hoverEventTag = HoverEventSerializer.serialize(hoverEvent, false, serializer); + if (hoverEventTag != null) { + builder.put(HOVER_EVENT_CAMEL, hoverEventTag); } } } ShadowColor shadowColor = style.shadowColor(); if (shadowColor != null) { - BinaryTag serializedShadowColor = ShadowColorSerializer.serialize(shadowColor, serializer); - if (serializedShadowColor != null) { - builder.put(SHADOW_COLOR, serializedShadowColor); + BinaryTag shadowColorTag = ShadowColorSerializer.serialize(shadowColor, serializer); + if (shadowColorTag != null) { + builder.put(SHADOW_COLOR, shadowColorTag); } } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java index fa9e2e010a..f8a578ced4 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java @@ -31,8 +31,6 @@ import net.kyori.adventure.nbt.StringBinaryTag; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.List; import java.util.UUID; final class UUIDSerializer { @@ -68,11 +66,11 @@ private UUIDSerializer() { case EMIT_INT_ARRAY: return IntArrayBinaryTag.intArrayBinaryTag(createArrayFromUUID(uuid)); case EMIT_LIST: - List tags = new ArrayList<>(); + ListBinaryTag.Builder builder = ListBinaryTag.builder(BinaryTagTypes.INT); for (int value : createArrayFromUUID(uuid)) { - tags.add(IntBinaryTag.intBinaryTag(value)); + builder.add(IntBinaryTag.intBinaryTag(value)); } - return ListBinaryTag.listBinaryTag(BinaryTagTypes.INT, tags); + return builder.build(); default: // Never called, but needed for proper compilation throw new IllegalStateException("Unknown emit mode: " + emitMode); From 15c63b6984c0798ac460c59a46e9e51023018693 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 08:58:58 +0200 Subject: [PATCH 50/86] feat: initial versioned option state with options for 23w40a --- .../serializer/nbt/NBTSerializerOptions.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index a8f6ccffa9..370e23261b 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -25,6 +25,7 @@ import net.kyori.option.Option; import net.kyori.option.OptionSchema; +import net.kyori.option.OptionState; import org.jetbrains.annotations.NotNull; /** @@ -96,6 +97,9 @@ public final class NBTSerializerOptions { public static final Option SHOW_ITEM_HOVER_DATA_MODE; private static final OptionSchema SCHEMA; + private static final OptionState.Versioned BY_DATA_VERSION; + + private static final int VERSION_23W40A = 3679; static { OptionSchema.Mutable schema = OptionSchema.emptySchema(); @@ -108,6 +112,20 @@ public final class NBTSerializerOptions { EMIT_SHOW_ENTITY_UUID_TYPE = schema.enumOption(key("emit/show_entity_uuid"), ShowEntityUUIDEmitMode.class, ShowEntityUUIDEmitMode.EMIT_INT_ARRAY); SHOW_ITEM_HOVER_DATA_MODE = schema.enumOption(key("emit/show_item_hover_data"), ShowItemHoverDataMode.class, ShowItemHoverDataMode.EMIT_EITHER); SCHEMA = schema.frozenView(); + + BY_DATA_VERSION = SCHEMA.versionedStateBuilder() + .version( + VERSION_23W40A, + builder -> builder.value(EMIT_COMPACT_TEXT_COMPONENT, true) + .value(SHADOW_COLOR_MODE, ShadowColorEmitMode.NONE) + .value(EMIT_HOVER_EVENT_TYPE, HoverEventValueMode.CAMEL_CASE) + .value(EMIT_CLICK_EVENT_TYPE, ClickEventValueMode.CAMEL_CASE) + .value(EMIT_DEFAULT_ITEM_HOVER_QUANTITY, false) + .value(EMIT_DEFAULT_NBT_INTERPRET_VALUE, false) + .value(EMIT_SHOW_ENTITY_UUID_TYPE, ShowEntityUUIDEmitMode.EMIT_INT_ARRAY) + .value(SHOW_ITEM_HOVER_DATA_MODE, ShowItemHoverDataMode.EMIT_LEGACY_NBT) + ) + .build(); } private NBTSerializerOptions() { @@ -121,12 +139,22 @@ private static String key(final String value) { * A schema of available options. * * @return the schema of known NBT serializer options - * @since 4.20.0 + * @since 4.24.0 */ public static @NotNull OptionSchema schema() { return SCHEMA; } + /** + * NBT serializer options delineated by world data version. + * + * @return the versioned option state + * @since 4.24.0 + */ + public static OptionState.@NotNull Versioned byDataVersion() { + return BY_DATA_VERSION; + } + /** * Configure how to emit hover event values. * From cd4a440302ed064d08000096b4db2e6eba021961 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 09:42:13 +0200 Subject: [PATCH 51/86] feat: support plain string show-item hover events in deserialization --- .../serializer/nbt/HoverEventSerializer.java | 12 +++--------- .../text/serializer/nbt/NBTSerializerUtils.java | 14 +++++++++++++- .../text/serializer/nbt/ShowItemSerializer.java | 16 ++++++++++++++-- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java index 96aaaf8baf..c9f04bca71 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -50,20 +50,14 @@ private HoverEventSerializer() { return null; } - CompoundBinaryTag contentsTag = snakeCase ? compound : getRequiredTag(compound, HOVER_EVENT_CONTENTS, BinaryTagTypes.COMPOUND); if (action == HoverEvent.Action.SHOW_TEXT) { - BinaryTag textTag; - if (snakeCase) { - textTag = compound.get(HOVER_EVENT_VALUE); - if (textTag == null) - throw new IllegalArgumentException("The show text hover event action tag does not contain a text field"); - } else { - textTag = contentsTag; - } + BinaryTag textTag = getRequiredTag(compound, snakeCase ? HOVER_EVENT_VALUE : HOVER_EVENT_CONTENTS); return HoverEvent.showText(serializer.deserialize(textTag)); } else if (action == HoverEvent.Action.SHOW_ITEM) { + BinaryTag contentsTag = getRequiredTag(compound, HOVER_EVENT_CONTENTS); return HoverEvent.showItem(ShowItemSerializer.deserialize(contentsTag, snakeCase)); } else if (action == HoverEvent.Action.SHOW_ENTITY) { + CompoundBinaryTag contentsTag = getRequiredTag(compound, HOVER_EVENT_CONTENTS, BinaryTagTypes.COMPOUND); return HoverEvent.showEntity(ShowEntitySerializer.deserialize(contentsTag, snakeCase, serializer)); } else { throw new IllegalArgumentException("Don't know how to deserialize a hoverEvent with action of " + actionString + " from a binary tag"); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java index 544fa51137..1a9c47e733 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java @@ -36,11 +36,19 @@ final class NBTSerializerUtils { private NBTSerializerUtils() { } + static @NotNull BinaryTag getRequiredTag(@NotNull CompoundBinaryTag compound, @NotNull String name) { + BinaryTag tag = compound.get(name); + if (tag == null) { + throw noSuchField(name); + } + return tag; + } + static @NotNull B getRequiredTag(@NotNull CompoundBinaryTag compound, @NotNull String name, @NotNull BinaryTagType tagType) { B tag = getOptionalTag(compound, name, tagType); if (tag == null) { - throw new IllegalArgumentException("The specified compound tag does not contain a \"" + name + "\" field"); + throw noSuchField(name); } return tag; } @@ -72,4 +80,8 @@ static boolean asBoolean(@NotNull NumberBinaryTag tag) { static @NotNull ByteBinaryTag asTag(boolean value) { return value ? ByteBinaryTag.ONE : ByteBinaryTag.ZERO; } + + private static @NotNull IllegalArgumentException noSuchField(@NotNull String name) { + return new IllegalArgumentException("The specified compound tag does not contain a \"" + name + "\" field"); + } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java index 1192a732e0..bf5334d649 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java @@ -53,9 +53,21 @@ final class ShowItemSerializer { private ShowItemSerializer() { } - static HoverEvent.@NotNull ShowItem deserialize(@NotNull CompoundBinaryTag compound, boolean snakeCase) { - Key itemId = Key.key(getRequiredTag(compound, SHOW_ITEM_ID, BinaryTagTypes.STRING).value()); + static HoverEvent.@NotNull ShowItem deserialize(@NotNull BinaryTag tag, boolean snakeCase) { + if (tag instanceof StringBinaryTag && !snakeCase) { + StringBinaryTag castTag = (StringBinaryTag) tag; + return HoverEvent.ShowItem.showItem(Key.key(castTag.value()), DEFAULT_ITEM_QUANTITY); + } else if (!(tag instanceof CompoundBinaryTag)) { + if (snakeCase) { + throw new IllegalArgumentException("The specified binary tag isn't a compound tag"); + } else { + throw new IllegalArgumentException("The specified binary tag isn't either a string tag or compound tag"); + } + } + CompoundBinaryTag compound = (CompoundBinaryTag) tag; + + Key itemId = Key.key(getRequiredTag(compound, SHOW_ITEM_ID, BinaryTagTypes.STRING).value()); IntBinaryTag countTag = getOptionalTag(compound, SHOW_ITEM_COUNT, BinaryTagTypes.INT); int itemCount = countTag == null ? DEFAULT_ITEM_QUANTITY : countTag.value(); From 6674ca9cd15d940f6eb1be32d3f0071f78693296 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 10:15:06 +0200 Subject: [PATCH 52/86] feat: add 24w09a version to the versioned option state --- .../text/serializer/nbt/NBTSerializerOptions.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index 370e23261b..24c566cb71 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -100,6 +100,7 @@ public final class NBTSerializerOptions { private static final OptionState.Versioned BY_DATA_VERSION; private static final int VERSION_23W40A = 3679; + private static final int VERSION_24W09A = 3819; static { OptionSchema.Mutable schema = OptionSchema.emptySchema(); @@ -124,7 +125,11 @@ public final class NBTSerializerOptions { .value(EMIT_DEFAULT_NBT_INTERPRET_VALUE, false) .value(EMIT_SHOW_ENTITY_UUID_TYPE, ShowEntityUUIDEmitMode.EMIT_INT_ARRAY) .value(SHOW_ITEM_HOVER_DATA_MODE, ShowItemHoverDataMode.EMIT_LEGACY_NBT) - ) + ) + .version( + VERSION_24W09A, + builder -> builder.value(SHOW_ITEM_HOVER_DATA_MODE, ShowItemHoverDataMode.EMIT_DATA_COMPONENTS) + ) .build(); } From 3eb33f2eb296c5080d875cb3b47b0849977ecd77 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 10:16:57 +0200 Subject: [PATCH 53/86] feat: add 24w44a version to the versioned option state --- .../adventure/text/serializer/nbt/NBTSerializerOptions.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index 24c566cb71..f949a35ff9 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -101,6 +101,7 @@ public final class NBTSerializerOptions { private static final int VERSION_23W40A = 3679; private static final int VERSION_24W09A = 3819; + private static final int VERSION_24W44A = 4174; static { OptionSchema.Mutable schema = OptionSchema.emptySchema(); @@ -130,6 +131,10 @@ public final class NBTSerializerOptions { VERSION_24W09A, builder -> builder.value(SHOW_ITEM_HOVER_DATA_MODE, ShowItemHoverDataMode.EMIT_DATA_COMPONENTS) ) + .version( + VERSION_24W44A, + builder -> builder.value(SHADOW_COLOR_MODE, ShadowColorEmitMode.EMIT_ARRAY) + ) .build(); } From 7d7b6b47fb7a6dd62727c364c5573b694ff58b7d Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 10:20:48 +0200 Subject: [PATCH 54/86] feat: add 25w02a version to the versioned option state --- .../adventure/text/serializer/nbt/NBTSerializerOptions.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index f949a35ff9..66f0c7e658 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -102,6 +102,7 @@ public final class NBTSerializerOptions { private static final int VERSION_23W40A = 3679; private static final int VERSION_24W09A = 3819; private static final int VERSION_24W44A = 4174; + private static final int VERSION_25W02A = 4298; static { OptionSchema.Mutable schema = OptionSchema.emptySchema(); @@ -135,6 +136,11 @@ public final class NBTSerializerOptions { VERSION_24W44A, builder -> builder.value(SHADOW_COLOR_MODE, ShadowColorEmitMode.EMIT_ARRAY) ) + .version( + VERSION_25W02A, + builder -> builder.value(EMIT_HOVER_EVENT_TYPE, HoverEventValueMode.SNAKE_CASE) + .value(EMIT_CLICK_EVENT_TYPE, ClickEventValueMode.SNAKE_CASE) + ) .build(); } From 4a36ed39eabcefaf77b3e996dd03e4e92fa1515b Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 11:17:37 +0200 Subject: [PATCH 55/86] chore: remove unneeded options --- .../nbt/NBTComponentSerializerImpl.java | 8 +-- .../serializer/nbt/NBTSerializerOptions.java | 60 +------------------ .../serializer/nbt/ShowEntitySerializer.java | 11 +--- .../text/serializer/nbt/UUIDSerializer.java | 34 +++-------- 4 files changed, 15 insertions(+), 98 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 390ce889b1..bafdd80688 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -241,8 +241,7 @@ static final class Instances { @Override public @NotNull BinaryTag serialize(@NotNull Component component) { - if (this.options.value(NBTSerializerOptions.EMIT_COMPACT_TEXT_COMPONENT) && component instanceof TextComponent - && !component.hasStyling() && component.children().isEmpty()) { + if (component instanceof TextComponent && !component.hasStyling() && component.children().isEmpty()) { return StringBinaryTag.stringBinaryTag(((TextComponent) component).content()); } @@ -287,9 +286,8 @@ static final class Instances { NBTComponent nbt = (NBTComponent) component; builder.putString(NBT, nbt.nbtPath()); - boolean interpret = nbt.interpret(); - if (this.options.value(NBTSerializerOptions.EMIT_DEFAULT_NBT_INTERPRET_VALUE) || interpret) { - builder.putBoolean(NBT_INTERPRET, interpret); + if (nbt.interpret()) { + builder.putBoolean(NBT_INTERPRET, true); } Component separator = nbt.separator(); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index 66f0c7e658..c2ec2ab3b9 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -37,14 +37,6 @@ */ public final class NBTSerializerOptions { - /** - * Whether to emit text components with no style and no children as a plain text. - * - * @since 4.24.0 - * @sinceMinecraft 1.20.3 - */ - public static final Option EMIT_COMPACT_TEXT_COMPONENT; - /** * How to emit shadow colour data. * @@ -69,25 +61,11 @@ public final class NBTSerializerOptions { /** * Whether to emit the default hover event item stack quantity of {@code 1}. * - *

When enabled, this matches Vanilla as of 1.20.5.

+ *

When enabled, this matches Vanilla as of 1.21.6.

* * @since 4.24.0 */ - public static final Option EMIT_DEFAULT_ITEM_HOVER_QUANTITY; - - /** - * Whether to emit the default interpret value ({@code false}) of NBT components. - * - * @since 4.24.0 - */ - public static final Option EMIT_DEFAULT_NBT_INTERPRET_VALUE; - - /** - * Control how entity ids of show entity hover events should be emitted. - * - * @since 4.24.0 - */ - public static final Option EMIT_SHOW_ENTITY_UUID_TYPE; + public static final Option EMIT_DEFAULT_ITEM_HOVER_QUANTITY; // TODO: Find out in which version it was added and add it to the option state /** * How to emit show item hovers in {@code hoverEvent} (camelCase) fields. @@ -106,26 +84,20 @@ public final class NBTSerializerOptions { static { OptionSchema.Mutable schema = OptionSchema.emptySchema(); - EMIT_COMPACT_TEXT_COMPONENT = schema.booleanOption(key("emit/compact_text_component"), true); SHADOW_COLOR_MODE = schema.enumOption(key("emit/shadow_color"), ShadowColorEmitMode.class, ShadowColorEmitMode.EMIT_INTEGER); EMIT_HOVER_EVENT_TYPE = schema.enumOption(key("emit/hover_value_mode"), HoverEventValueMode.class, HoverEventValueMode.SNAKE_CASE); EMIT_CLICK_EVENT_TYPE = schema.enumOption(key("emit/click_value_mode"), ClickEventValueMode.class, ClickEventValueMode.SNAKE_CASE); EMIT_DEFAULT_ITEM_HOVER_QUANTITY = schema.booleanOption(key("emit/default_item_hover_quantity"), true); - EMIT_DEFAULT_NBT_INTERPRET_VALUE = schema.booleanOption(key("emit/default_nbt_interpret_value"), true); - EMIT_SHOW_ENTITY_UUID_TYPE = schema.enumOption(key("emit/show_entity_uuid"), ShowEntityUUIDEmitMode.class, ShowEntityUUIDEmitMode.EMIT_INT_ARRAY); SHOW_ITEM_HOVER_DATA_MODE = schema.enumOption(key("emit/show_item_hover_data"), ShowItemHoverDataMode.class, ShowItemHoverDataMode.EMIT_EITHER); SCHEMA = schema.frozenView(); BY_DATA_VERSION = SCHEMA.versionedStateBuilder() .version( VERSION_23W40A, - builder -> builder.value(EMIT_COMPACT_TEXT_COMPONENT, true) - .value(SHADOW_COLOR_MODE, ShadowColorEmitMode.NONE) + builder -> builder.value(SHADOW_COLOR_MODE, ShadowColorEmitMode.NONE) .value(EMIT_HOVER_EVENT_TYPE, HoverEventValueMode.CAMEL_CASE) .value(EMIT_CLICK_EVENT_TYPE, ClickEventValueMode.CAMEL_CASE) .value(EMIT_DEFAULT_ITEM_HOVER_QUANTITY, false) - .value(EMIT_DEFAULT_NBT_INTERPRET_VALUE, false) - .value(EMIT_SHOW_ENTITY_UUID_TYPE, ShowEntityUUIDEmitMode.EMIT_INT_ARRAY) .value(SHOW_ITEM_HOVER_DATA_MODE, ShowItemHoverDataMode.EMIT_LEGACY_NBT) ) .version( @@ -248,32 +220,6 @@ public enum ShadowColorEmitMode { EMIT_ARRAY } - /** - * Configure how to emit entity ids of show entity hover events. - * - * @since 4.24.0 - */ - public enum ShowEntityUUIDEmitMode { - /** - * Emit as a string. - * - * @since 4.24.0 - */ - EMIT_STRING, - /** - * Emit as an int array. - * - * @since 4.24.0 - */ - EMIT_INT_ARRAY, - /** - * Emit as an int list. - * - * @since 4.24.0 - */ - EMIT_LIST - } - /** * Configure how to emit show item hovers in {@code hoverEvent} (camelCase) fields. * diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java index eed9314d00..4d851a472f 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java @@ -66,15 +66,8 @@ private ShowEntitySerializer() { static @NotNull CompoundBinaryTag serialize(HoverEvent.@NotNull ShowEntity showEntity, boolean snakeCase, @NotNull NBTComponentSerializerImpl serializer) { CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() - .putString(snakeCase ? SHOW_ENTITY_ID : SHOW_ENTITY_TYPE, showEntity.type().asString()); - - UUID entityId = showEntity.id(); - if (snakeCase) { - NBTSerializerOptions.ShowEntityUUIDEmitMode uuidEmitMode = serializer.options().value(NBTSerializerOptions.EMIT_SHOW_ENTITY_UUID_TYPE); - builder.put(SHOW_ENTITY_UUID, UUIDSerializer.serialize(entityId, uuidEmitMode)); - } else { - builder.put(SHOW_ENTITY_ID, UUIDSerializer.serialize(entityId, NBTSerializerOptions.ShowEntityUUIDEmitMode.EMIT_STRING)); - } + .putString(snakeCase ? SHOW_ENTITY_ID : SHOW_ENTITY_TYPE, showEntity.type().asString()) + .put(snakeCase ? SHOW_ENTITY_UUID : SHOW_ENTITY_ID, UUIDSerializer.serialize(showEntity.id())); Component customName = showEntity.name(); if (customName != null) { diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java index f8a578ced4..e6909cc4d8 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java @@ -24,9 +24,7 @@ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.nbt.BinaryTag; -import net.kyori.adventure.nbt.BinaryTagTypes; import net.kyori.adventure.nbt.IntArrayBinaryTag; -import net.kyori.adventure.nbt.IntBinaryTag; import net.kyori.adventure.nbt.ListBinaryTag; import net.kyori.adventure.nbt.StringBinaryTag; import org.jetbrains.annotations.NotNull; @@ -59,22 +57,13 @@ private UUIDSerializer() { } } - static @NotNull BinaryTag serialize(@NotNull UUID uuid, NBTSerializerOptions.@NotNull ShowEntityUUIDEmitMode emitMode) { - switch (emitMode) { - case EMIT_STRING: - return StringBinaryTag.stringBinaryTag(uuid.toString()); - case EMIT_INT_ARRAY: - return IntArrayBinaryTag.intArrayBinaryTag(createArrayFromUUID(uuid)); - case EMIT_LIST: - ListBinaryTag.Builder builder = ListBinaryTag.builder(BinaryTagTypes.INT); - for (int value : createArrayFromUUID(uuid)) { - builder.add(IntBinaryTag.intBinaryTag(value)); - } - return builder.build(); - default: - // Never called, but needed for proper compilation - throw new IllegalStateException("Unknown emit mode: " + emitMode); - } + static @NotNull BinaryTag serialize(@NotNull UUID uuid) { + long mostSignificantBits = uuid.getMostSignificantBits(); + long leastSignificantBits = uuid.getLeastSignificantBits(); + return IntArrayBinaryTag.intArrayBinaryTag( + mostSignificantBits(mostSignificantBits), leastSignificantBits(mostSignificantBits), + mostSignificantBits(leastSignificantBits), leastSignificantBits(leastSignificantBits) + ); } private static @NotNull UUID createUUIDFromArray(int @NotNull [] array) { @@ -83,15 +72,6 @@ private UUIDSerializer() { return new UUID(mostSignificantBits, leastSignificantBits); } - private static int @NotNull [] createArrayFromUUID(@NotNull UUID uuid) { - long mostSignificantBits = uuid.getMostSignificantBits(); - long leastSignificantBits = uuid.getLeastSignificantBits(); - return new int[] { - mostSignificantBits(mostSignificantBits), leastSignificantBits(mostSignificantBits), - mostSignificantBits(leastSignificantBits), leastSignificantBits(leastSignificantBits) - }; - } - private static long binaryConcat(int mostSignificantBits, int leastSignificantBits) { return ((long) mostSignificantBits << Integer.SIZE) | ((long) leastSignificantBits & LONG_HALF); } From f6b30be4b1255f4428fa1d5559637835877d43bd Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 11:27:50 +0200 Subject: [PATCH 56/86] chore: replace ClickEventSerializer#deserializeCamel and ClickEventSerializer#deserializeSnake methods with ClickEventSerializer#deserialize to be more consistent with StyleSerializer --- .../serializer/nbt/ClickEventSerializer.java | 63 +++++++++---------- .../text/serializer/nbt/StyleSerializer.java | 4 +- 2 files changed, 30 insertions(+), 37 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java index 89ede19b5f..78b91e706c 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java @@ -47,19 +47,7 @@ final class ClickEventSerializer { private ClickEventSerializer() { } - static @Nullable ClickEvent deserializeCamel(@NotNull CompoundBinaryTag compound) { - StringBinaryTag actionTag = getRequiredTag(compound, CLICK_EVENT_ACTION, BinaryTagTypes.STRING); - StringBinaryTag valueTag = getRequiredTag(compound, CLICK_EVENT_VALUE, BinaryTagTypes.STRING); - - ClickEvent.Action action = ClickEvent.Action.NAMES.valueOrThrow(actionTag.value()); - if (!action.readable()) { - return null; - } - - return ClickEvent.clickEvent(action, valueTag.value()); - } - - static @Nullable ClickEvent deserializeSnake(@NotNull CompoundBinaryTag compound) { + static @Nullable ClickEvent deserialize(@NotNull CompoundBinaryTag compound, boolean snakeCase) { StringBinaryTag actionTag = getRequiredTag(compound, CLICK_EVENT_ACTION, BinaryTagTypes.STRING); ClickEvent.Action action = ClickEvent.Action.NAMES.valueOrThrow(actionTag.value()); @@ -67,28 +55,33 @@ private ClickEventSerializer() { return null; } - switch (action) { - case OPEN_URL: - StringBinaryTag urlTag = getRequiredTag(compound, CLICK_EVENT_URL, BinaryTagTypes.STRING); - return ClickEvent.openUrl(urlTag.value()); - case RUN_COMMAND: - case SUGGEST_COMMAND: - StringBinaryTag commandTag = getRequiredTag(compound, CLICK_EVENT_COMMAND, BinaryTagTypes.STRING); - String command = commandTag.value(); - return action == ClickEvent.Action.RUN_COMMAND ? ClickEvent.runCommand(command) : ClickEvent.suggestCommand(command); - case CHANGE_PAGE: - IntBinaryTag pageTag = getRequiredTag(compound, CLICK_EVENT_PAGE, BinaryTagTypes.INT); - return ClickEvent.changePage(pageTag.value()); - case COPY_TO_CLIPBOARD: - StringBinaryTag valueTag = getRequiredTag(compound, CLICK_EVENT_VALUE, BinaryTagTypes.STRING); - return ClickEvent.copyToClipboard(valueTag.value()); - case CUSTOM: - StringBinaryTag clickEventIdTag = getRequiredTag(compound, CLICK_EVENT_ID, BinaryTagTypes.STRING); - StringBinaryTag payloadTag = getRequiredTag(compound, CLICK_EVENT_PAYLOAD, BinaryTagTypes.STRING); - return ClickEvent.custom(Key.key(clickEventIdTag.value()), BinaryTagHolder.binaryTagHolder(payloadTag.value())); - default: - // Never called, but needed for proper compilation - throw new IllegalArgumentException("Unknown click event action: " + action); + if (snakeCase) { + switch (action) { + case OPEN_URL: + StringBinaryTag urlTag = getRequiredTag(compound, CLICK_EVENT_URL, BinaryTagTypes.STRING); + return ClickEvent.openUrl(urlTag.value()); + case RUN_COMMAND: + case SUGGEST_COMMAND: + StringBinaryTag commandTag = getRequiredTag(compound, CLICK_EVENT_COMMAND, BinaryTagTypes.STRING); + String command = commandTag.value(); + return action == ClickEvent.Action.RUN_COMMAND ? ClickEvent.runCommand(command) : ClickEvent.suggestCommand(command); + case CHANGE_PAGE: + IntBinaryTag pageTag = getRequiredTag(compound, CLICK_EVENT_PAGE, BinaryTagTypes.INT); + return ClickEvent.changePage(pageTag.value()); + case COPY_TO_CLIPBOARD: + StringBinaryTag valueTag = getRequiredTag(compound, CLICK_EVENT_VALUE, BinaryTagTypes.STRING); + return ClickEvent.copyToClipboard(valueTag.value()); + case CUSTOM: + StringBinaryTag clickEventIdTag = getRequiredTag(compound, CLICK_EVENT_ID, BinaryTagTypes.STRING); + StringBinaryTag payloadTag = getRequiredTag(compound, CLICK_EVENT_PAYLOAD, BinaryTagTypes.STRING); + return ClickEvent.custom(Key.key(clickEventIdTag.value()), BinaryTagHolder.binaryTagHolder(payloadTag.value())); + default: + // Never called, but needed for proper compilation + throw new IllegalArgumentException("Unknown click event action: " + action); + } + } else { + StringBinaryTag valueTag = getRequiredTag(compound, CLICK_EVENT_VALUE, BinaryTagTypes.STRING); + return ClickEvent.clickEvent(action, valueTag.value()); } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java index 9cad3ced67..f464451ff3 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java @@ -82,10 +82,10 @@ private StyleSerializer() { if (clickEventTag == null) { clickEventTag = getOptionalTag(compound, CLICK_EVENT_CAMEL, BinaryTagTypes.COMPOUND); if (clickEventTag != null) { - styleBuilder.clickEvent(ClickEventSerializer.deserializeCamel(clickEventTag)); + styleBuilder.clickEvent(ClickEventSerializer.deserialize(clickEventTag, false)); } } else { - styleBuilder.clickEvent(ClickEventSerializer.deserializeSnake(clickEventTag)); + styleBuilder.clickEvent(ClickEventSerializer.deserialize(clickEventTag, true)); } CompoundBinaryTag hoverEventTag = getOptionalTag(compound, HOVER_EVENT_SNAKE, BinaryTagTypes.COMPOUND); From 67e5711bde648576761938caf70fb1c9a2ed755f Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 11:29:58 +0200 Subject: [PATCH 57/86] chore: add TODO messages about show_text field names in HoverEventSerializer --- .../adventure/text/serializer/nbt/HoverEventSerializer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java index c9f04bca71..694d2187c1 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -51,6 +51,7 @@ private HoverEventSerializer() { } if (action == HoverEvent.Action.SHOW_TEXT) { + // TODO: According to the MCW, pre-25w03a and post-25w03a use different fields for this, we need to take a look into that BinaryTag textTag = getRequiredTag(compound, snakeCase ? HOVER_EVENT_VALUE : HOVER_EVENT_CONTENTS); return HoverEvent.showText(serializer.deserialize(textTag)); } else if (action == HoverEvent.Action.SHOW_ITEM) { @@ -75,6 +76,7 @@ private HoverEventSerializer() { if (action == HoverEvent.Action.SHOW_TEXT) { BinaryTag serializedComponent = serializer.serialize((Component) event.value()); if (snakeCase) { + // TODO: According to the MCW, pre-25w03a and post-25w03a use different fields for this, we need to take a look into that contentsTag = CompoundBinaryTag.builder() .put(HOVER_EVENT_VALUE, serializedComponent) .build(); From 310d841ccf957e2e22699284c8cd08044b195e9a Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 15:46:49 +0200 Subject: [PATCH 58/86] chore: review whether the serialization matches Minecraft 23w40a and 1.21.6 serialization --- .../serializer/nbt/ClickEventSerializer.java | 28 ++++++++--- .../serializer/nbt/HoverEventSerializer.java | 4 +- .../nbt/NBTComponentSerializerImpl.java | 48 +++++++++---------- .../serializer/nbt/ShowEntitySerializer.java | 15 ++---- .../text/serializer/nbt/StyleSerializer.java | 16 +++---- .../serializer/nbt/TextColorSerializer.java | 8 +++- .../text/serializer/nbt/UUIDSerializer.java | 2 +- 7 files changed, 68 insertions(+), 53 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java index 78b91e706c..d4deddc060 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java @@ -24,15 +24,20 @@ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.BinaryTagTypes; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.IntBinaryTag; import net.kyori.adventure.nbt.StringBinaryTag; +import net.kyori.adventure.nbt.TagStringIO; import net.kyori.adventure.nbt.api.BinaryTagHolder; import net.kyori.adventure.text.event.ClickEvent; +import net.kyori.adventure.util.Codec; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.IOException; + import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_ACTION; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_COMMAND; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_ID; @@ -44,6 +49,9 @@ final class ClickEventSerializer { + private static final TagStringIO SNBT_IO = TagStringIO.tagStringIO(); + private static final Codec SNBT_CODEC = Codec.codec(SNBT_IO::asTag, SNBT_IO::asString); + private ClickEventSerializer() { } @@ -72,9 +80,13 @@ private ClickEventSerializer() { StringBinaryTag valueTag = getRequiredTag(compound, CLICK_EVENT_VALUE, BinaryTagTypes.STRING); return ClickEvent.copyToClipboard(valueTag.value()); case CUSTOM: - StringBinaryTag clickEventIdTag = getRequiredTag(compound, CLICK_EVENT_ID, BinaryTagTypes.STRING); - StringBinaryTag payloadTag = getRequiredTag(compound, CLICK_EVENT_PAYLOAD, BinaryTagTypes.STRING); - return ClickEvent.custom(Key.key(clickEventIdTag.value()), BinaryTagHolder.binaryTagHolder(payloadTag.value())); + try { + StringBinaryTag clickEventIdTag = getRequiredTag(compound, CLICK_EVENT_ID, BinaryTagTypes.STRING); + BinaryTag payloadTag = getRequiredTag(compound, CLICK_EVENT_PAYLOAD); + return ClickEvent.custom(Key.key(clickEventIdTag.value()), BinaryTagHolder.encode(payloadTag, SNBT_CODEC)); + } catch (IOException exception) { + throw new RuntimeException("An error occurred while encoding payload tag", exception); + } default: // Never called, but needed for proper compilation throw new IllegalArgumentException("Unknown click event action: " + action); @@ -115,9 +127,13 @@ private ClickEventSerializer() { } builder.putString(payloadFieldName, ((ClickEvent.Payload.Text) payload).value()); } else if (payload instanceof ClickEvent.Payload.Custom) { - ClickEvent.Payload.Custom castPayload = (ClickEvent.Payload.Custom) payload; - builder.putString(CLICK_EVENT_ID, castPayload.key().asString()); - builder.putString(CLICK_EVENT_PAYLOAD, castPayload.nbt().string()); + try { + ClickEvent.Payload.Custom castPayload = (ClickEvent.Payload.Custom) payload; + builder.putString(CLICK_EVENT_ID, castPayload.key().asString()); + builder.put(CLICK_EVENT_PAYLOAD, castPayload.nbt().get(SNBT_CODEC)); + } catch (IOException exception) { + throw new RuntimeException("An error occurred while decoding a payload tag", exception); + } } else if (payload instanceof ClickEvent.Payload.Int) { builder.putInt(CLICK_EVENT_PAGE, ((ClickEvent.Payload.Int) payload).integer()); } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java index 694d2187c1..4d7be805cc 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -55,10 +55,10 @@ private HoverEventSerializer() { BinaryTag textTag = getRequiredTag(compound, snakeCase ? HOVER_EVENT_VALUE : HOVER_EVENT_CONTENTS); return HoverEvent.showText(serializer.deserialize(textTag)); } else if (action == HoverEvent.Action.SHOW_ITEM) { - BinaryTag contentsTag = getRequiredTag(compound, HOVER_EVENT_CONTENTS); + BinaryTag contentsTag = snakeCase ? compound : getRequiredTag(compound, HOVER_EVENT_CONTENTS); return HoverEvent.showItem(ShowItemSerializer.deserialize(contentsTag, snakeCase)); } else if (action == HoverEvent.Action.SHOW_ENTITY) { - CompoundBinaryTag contentsTag = getRequiredTag(compound, HOVER_EVENT_CONTENTS, BinaryTagTypes.COMPOUND); + CompoundBinaryTag contentsTag = snakeCase ? compound : getRequiredTag(compound, HOVER_EVENT_CONTENTS, BinaryTagTypes.COMPOUND); return HoverEvent.showEntity(ShowEntitySerializer.deserialize(contentsTag, snakeCase, serializer)); } else { throw new IllegalArgumentException("Don't know how to deserialize a hoverEvent with action of " + actionString + " from a binary tag"); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index bafdd80688..a920b1919e 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -117,7 +117,7 @@ static final class Instances { } else if (input instanceof ListBinaryTag) { ListBinaryTag castInput = (ListBinaryTag) input; if (castInput.isEmpty()) { - throw new IllegalArgumentException("The list binary tag must not be empty"); + throw new IllegalArgumentException("The list binary tag representing a component must not be empty"); } Component rootTag = this.deserialize(castInput.get(0)); @@ -180,54 +180,54 @@ static final class Instances { .build(); } else if (compound.get(SELECTOR) != null) { StringBinaryTag selectorTag = getRequiredTag(compound, SELECTOR, BinaryTagTypes.STRING); - BinaryTag selectorSeparatorTag = compound.get(SEPARATOR); + BinaryTag separatorTag = compound.get(SEPARATOR); return Component.selector() .pattern(selectorTag.value()) - .separator(selectorSeparatorTag == null ? null : this.deserialize(selectorSeparatorTag)) + .separator(separatorTag == null ? null : this.deserialize(separatorTag)) .style(style) .append(children) .build(); } else if (compound.get(NBT) != null) { String nbtPath = getRequiredTag(compound, NBT, BinaryTagTypes.STRING).value(); - ByteBinaryTag nbtInterpretTag = getOptionalTag(compound, NBT_INTERPRET, BinaryTagTypes.BYTE); - boolean nbtInterpret = nbtInterpretTag != null && asBoolean(nbtInterpretTag); + ByteBinaryTag interpretTag = getOptionalTag(compound, NBT_INTERPRET, BinaryTagTypes.BYTE); + boolean interpret = interpretTag != null && asBoolean(interpretTag); - BinaryTag nbtSeparatorTag = compound.get(SEPARATOR); - Component nbtSeparator = null; + BinaryTag separatorTag = compound.get(SEPARATOR); + Component separator = null; - if (nbtSeparatorTag != null) { - nbtSeparator = this.deserialize(nbtSeparatorTag); + if (separatorTag != null) { + separator = this.deserialize(separatorTag); } - StringBinaryTag nbtBlockTag = getOptionalTag(compound, NBT_BLOCK, BinaryTagTypes.STRING); - StringBinaryTag nbtEntityTag = getOptionalTag(compound, NBT_ENTITY, BinaryTagTypes.STRING); - StringBinaryTag nbtStorageTag = getOptionalTag(compound, NBT_STORAGE, BinaryTagTypes.STRING); + StringBinaryTag blockTag = getOptionalTag(compound, NBT_BLOCK, BinaryTagTypes.STRING); + StringBinaryTag entityTag = getOptionalTag(compound, NBT_ENTITY, BinaryTagTypes.STRING); + StringBinaryTag storageTag = getOptionalTag(compound, NBT_STORAGE, BinaryTagTypes.STRING); - if (nbtBlockTag != null) { + if (blockTag != null) { return Component.blockNBT() .nbtPath(nbtPath) - .interpret(nbtInterpret) - .separator(nbtSeparator) - .pos(BlockNBTComponent.Pos.fromString(nbtBlockTag.value())) + .interpret(interpret) + .separator(separator) + .pos(BlockNBTComponent.Pos.fromString(blockTag.value())) .style(style) .append(children) .build(); - } else if (nbtEntityTag != null) { + } else if (entityTag != null) { return Component.entityNBT() .nbtPath(nbtPath) - .interpret(nbtInterpret) - .separator(nbtSeparator) - .selector(nbtEntityTag.value()) + .interpret(interpret) + .separator(separator) + .selector(entityTag.value()) .style(style) .append(children) .build(); - } else if (nbtStorageTag != null) { + } else if (storageTag != null) { return Component.storageNBT() .nbtPath(nbtPath) - .interpret(nbtInterpret) - .separator(nbtSeparator) - .storage(Key.key(nbtStorageTag.value())) + .interpret(interpret) + .separator(separator) + .storage(Key.key(storageTag.value())) .style(style) .append(children) .build(); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java index 4d851a472f..8737588ff1 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java @@ -47,15 +47,10 @@ private ShowEntitySerializer() { static HoverEvent.@NotNull ShowEntity deserialize(@NotNull CompoundBinaryTag compound, boolean snakeCase, @NotNull NBTComponentSerializerImpl serializer) { Key entityType = Key.key(getRequiredTag(compound, snakeCase ? SHOW_ENTITY_ID : SHOW_ENTITY_TYPE, BinaryTagTypes.STRING).value()); - - BinaryTag entityIdTag = compound.get(snakeCase ? SHOW_ENTITY_UUID : SHOW_ENTITY_ID); - if (entityIdTag == null) { - throw new IllegalArgumentException("The show entity compound tag does not contain an entity id field"); - } - - UUID entityId = UUIDSerializer.deserialize(entityIdTag); + BinaryTag entityIdTag = getRequiredTag(compound, snakeCase ? SHOW_ENTITY_UUID : SHOW_ENTITY_ID); BinaryTag entityNameTag = compound.get(SHOW_ENTITY_NAME); + UUID entityId = UUIDSerializer.deserialize(entityIdTag); if (entityNameTag == null) { return HoverEvent.ShowEntity.showEntity(entityType, entityId); } else { @@ -69,9 +64,9 @@ private ShowEntitySerializer() { .putString(snakeCase ? SHOW_ENTITY_ID : SHOW_ENTITY_TYPE, showEntity.type().asString()) .put(snakeCase ? SHOW_ENTITY_UUID : SHOW_ENTITY_ID, UUIDSerializer.serialize(showEntity.id())); - Component customName = showEntity.name(); - if (customName != null) { - builder.put(SHOW_ENTITY_NAME, serializer.serialize(customName)); + Component entityName = showEntity.name(); + if (entityName != null) { + builder.put(SHOW_ENTITY_NAME, serializer.serialize(entityName)); } return builder.build(); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java index f464451ff3..b1c9b623cb 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java @@ -115,6 +115,14 @@ static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder b builder.put(COLOR, TextColorSerializer.serialize(color)); } + ShadowColor shadowColor = style.shadowColor(); + if (shadowColor != null) { + BinaryTag shadowColorTag = ShadowColorSerializer.serialize(shadowColor, serializer); + if (shadowColorTag != null) { + builder.put(SHADOW_COLOR, shadowColorTag); + } + } + for (TextDecoration decoration : TextDecoration.values()) { TextDecoration.State state = style.decoration(decoration); if (state == TextDecoration.State.NOT_SET) continue; @@ -177,13 +185,5 @@ static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder b } } } - - ShadowColor shadowColor = style.shadowColor(); - if (shadowColor != null) { - BinaryTag shadowColorTag = ShadowColorSerializer.serialize(shadowColor, serializer); - if (shadowColorTag != null) { - builder.put(SHADOW_COLOR, shadowColorTag); - } - } } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TextColorSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TextColorSerializer.java index 1d1cbb1c7b..82ec7110b7 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TextColorSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TextColorSerializer.java @@ -38,9 +38,13 @@ private TextColorSerializer() { static @NotNull TextColor deserialize(@NotNull StringBinaryTag tag) { String value = tag.value(); if (value.startsWith(TextColor.HEX_PREFIX)) { - return TextColor.fromHexString(value); + TextColor color = TextColor.fromHexString(value); + if (color == null) { + throw new IllegalArgumentException("Invalid hex text color: " + value); + } + return color; } else { - return NamedTextColor.NAMES.value(value); + return NamedTextColor.NAMES.valueOrThrow(value); } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java index e6909cc4d8..497d13a0b0 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java @@ -77,7 +77,7 @@ private static long binaryConcat(int mostSignificantBits, int leastSignificantBi } private static int mostSignificantBits(long value) { - return (int) ((value >> Integer.SIZE) & LONG_HALF); + return (int) (value >> Integer.SIZE); } private static int leastSignificantBits(long value) { From 8b0c247fb095906bfd08197af5c27df64a630d66 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 17:39:56 +0200 Subject: [PATCH 59/86] chore: remove all previous tests --- .../serializer/nbt/BlockNBTComponentTest.java | 54 ---------------- .../text/serializer/nbt/ClickEventTest.java | 60 ------------------ .../nbt/EntityNBTComponentTest.java | 46 -------------- .../text/serializer/nbt/HoverEventTest.java | 63 ------------------- .../serializer/nbt/KeybindComponentTest.java | 42 ------------- .../text/serializer/nbt/NBTComponentTest.java | 46 -------------- .../serializer/nbt/ScoreComponentTest.java | 43 ------------- .../serializer/nbt/SelectorComponentTest.java | 43 ------------- .../nbt/StorageNBTComponentTest.java | 49 --------------- .../serializer/nbt/TextComponentTest.java | 42 ------------- .../nbt/TranslatableComponentTest.java | 42 ------------- 11 files changed, 530 deletions(-) delete mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java delete mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ClickEventTest.java delete mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java delete mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/HoverEventTest.java delete mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java delete mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/NBTComponentTest.java delete mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java delete mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java delete mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java delete mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java delete mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java deleted file mode 100644 index 2ef197afff..0000000000 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of adventure, licensed under the MIT License. - * - * Copyright (c) 2017-2025 KyoriPowered - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package net.kyori.adventure.text.serializer.nbt; - -import net.kyori.adventure.text.BlockNBTComponent; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.junit.jupiter.api.Test; - -import static net.kyori.adventure.text.BlockNBTComponent.WorldPos.Coordinate.absolute; - -final class BlockNBTComponentTest implements NBTComponentTest { - @Test - public void testNoStyling() { - this.test(Component.blockNBT( - "abc", - true, - Component.text("separator?"), - BlockNBTComponent.WorldPos.worldPos(absolute(435), absolute(512), absolute(4243))) - ); - } - - @Test - public void testWithStyling() { - this.test(Component.blockNBT() - .nbtPath("cab") - .interpret(false) - .separator(Component.text("another-separator", NamedTextColor.RED, TextDecoration.OBFUSCATED)) - .worldPos(absolute(44), absolute(51), absolute(42)) - .build()); - } -} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ClickEventTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ClickEventTest.java deleted file mode 100644 index ec68a266fe..0000000000 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ClickEventTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of adventure, licensed under the MIT License. - * - * Copyright (c) 2017-2025 KyoriPowered - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package net.kyori.adventure.text.serializer.nbt; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.event.ClickEvent; -import org.junit.jupiter.api.Test; - -final class ClickEventTest implements NBTComponentTest { - @Test - public void testUrl() { - this.test(Component.empty().clickEvent(ClickEvent.openUrl("https://docs.advntr.dev/"))); - } - - @Test - public void testFile() { - this.test(Component.empty().clickEvent(ClickEvent.openFile("/root/some-file.extension"))); - } - - @Test - public void testRunCommand() { - this.test(Component.empty().clickEvent(ClickEvent.runCommand("/help"))); - } - - @Test - public void testSuggestCommand() { - this.test(Component.empty().clickEvent(ClickEvent.suggestCommand("/?"))); - } - - @Test - public void testChangePage() { - this.test(Component.empty().clickEvent(ClickEvent.changePage(6))); - } - - @Test - public void testCopyToClipboard() { - this.test(Component.empty().clickEvent(ClickEvent.copyToClipboard("abcdxyz"))); - } -} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java deleted file mode 100644 index fe2876d474..0000000000 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of adventure, licensed under the MIT License. - * - * Copyright (c) 2017-2025 KyoriPowered - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package net.kyori.adventure.text.serializer.nbt; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.junit.jupiter.api.Test; - -final class EntityNBTComponentTest implements NBTComponentTest { - @Test - public void testNoStyling() { - this.test(Component.entityNBT("abc", "@a")); - } - - @Test - public void testWithStyling() { - this.test(Component.entityNBT() - .nbtPath("cab") - .interpret(true) - .separator(Component.text("another-separator", NamedTextColor.RED, TextDecoration.OBFUSCATED)) - .selector("@p") - .build()); - } -} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/HoverEventTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/HoverEventTest.java deleted file mode 100644 index c84a5ef2b1..0000000000 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/HoverEventTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of adventure, licensed under the MIT License. - * - * Copyright (c) 2017-2025 KyoriPowered - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package net.kyori.adventure.text.serializer.nbt; - -import com.google.common.collect.ImmutableMap; -import net.kyori.adventure.key.Key; -import net.kyori.adventure.nbt.IntBinaryTag; -import net.kyori.adventure.nbt.StringBinaryTag; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.event.HoverEvent; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.junit.jupiter.api.Test; - -import java.util.UUID; - -final class HoverEventTest implements NBTComponentTest { - @Test - public void testShowText() { - this.test(Component.empty().hoverEvent( - HoverEvent.showText(Component.text("Hi!", NamedTextColor.RED, TextDecoration.STRIKETHROUGH)) - )); - } - - @Test - public void testShowItem() { - this.test(Component.empty().hoverEvent(HoverEvent.showItem(Key.key("netherite_chestplate"), 2, ImmutableMap.of( - Key.key("count"), NBTDataComponentValue.nbtDataComponentValue(IntBinaryTag.intBinaryTag(2)), - Key.key("display_name"), NBTDataComponentValue.nbtDataComponentValue(StringBinaryTag.stringBinaryTag("test")) - )))); - } - - @Test - public void testShowEntity() { - this.test(Component.empty().hoverEvent( - HoverEvent.showEntity( - Key.key("enderman"), - UUID.randomUUID(), - Component.text("An entity name", NamedTextColor.RED, TextDecoration.STRIKETHROUGH)) - )); - } -} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java deleted file mode 100644 index ca2666862b..0000000000 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of adventure, licensed under the MIT License. - * - * Copyright (c) 2017-2025 KyoriPowered - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package net.kyori.adventure.text.serializer.nbt; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.junit.jupiter.api.Test; - -final class KeybindComponentTest implements NBTComponentTest { - @Test - public void testNoStyling() { - this.test(Component.translatable("some.translation")); - } - - @Test - public void testWithStyling() { - this.test(Component.translatable("another-translation", NamedTextColor.GOLD, TextDecoration.STRIKETHROUGH) - .decoration(TextDecoration.ITALIC, false)); - } -} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/NBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/NBTComponentTest.java deleted file mode 100644 index 83ac0fdd6b..0000000000 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/NBTComponentTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of adventure, licensed under the MIT License. - * - * Copyright (c) 2017-2025 KyoriPowered - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package net.kyori.adventure.text.serializer.nbt; - -import net.kyori.adventure.nbt.BinaryTag; -import net.kyori.adventure.nbt.CompoundBinaryTag; -import net.kyori.adventure.text.Component; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.Assertions; - -interface NBTComponentTest { - default void test(@NotNull Component component) { - this.test(component, CompoundBinaryTag.class); - } - - default void test(@NotNull Component component, @NotNull Class expectedTag) { - NBTComponentSerializer serializer = NBTComponentSerializer.nbt(); - - BinaryTag serialized = serializer.serialize(component); - Assertions.assertInstanceOf(expectedTag, serialized); - - Component deserialized = serializer.deserialize(serialized); - Assertions.assertEquals(component, deserialized); - } -} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java deleted file mode 100644 index 3e507e96c3..0000000000 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of adventure, licensed under the MIT License. - * - * Copyright (c) 2017-2025 KyoriPowered - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package net.kyori.adventure.text.serializer.nbt; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.junit.jupiter.api.Test; - -final class ScoreComponentTest implements NBTComponentTest { - @Test - public void testNoStyling() { - this.test(Component.score("a-score", "dummy")); - } - - @Test - public void testWithStyling() { - this.test(Component.score("some-score", "another-dummy-objective") - .decorate(TextDecoration.BOLD) - .color(NamedTextColor.RED)); - } -} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java deleted file mode 100644 index 9cf56b3065..0000000000 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of adventure, licensed under the MIT License. - * - * Copyright (c) 2017-2025 KyoriPowered - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package net.kyori.adventure.text.serializer.nbt; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.junit.jupiter.api.Test; - -final class SelectorComponentTest implements NBTComponentTest { - @Test - public void testNoStyling() { - this.test(Component.selector("@p", Component.text("a-separator"))); - } - - @Test - public void testWithStyling() { - this.test(Component.selector("@e", Component.text("some-separator", NamedTextColor.RED, TextDecoration.STRIKETHROUGH)) - .color(NamedTextColor.GOLD) - .decorate(TextDecoration.BOLD)); - } -} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java deleted file mode 100644 index 6530a9981b..0000000000 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of adventure, licensed under the MIT License. - * - * Copyright (c) 2017-2025 KyoriPowered - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package net.kyori.adventure.text.serializer.nbt; - -import net.kyori.adventure.key.Key; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.junit.jupiter.api.Test; - -final class StorageNBTComponentTest implements NBTComponentTest { - @Test - public void testNoStyling() { - this.test(Component.storageNBT("dsa", true, Component.text("separator?"), Key.key("minecraft", "chest"))); - } - - @Test - public void testWithStyling() { - this.test(Component.storageNBT() - .nbtPath("rsaby") - .interpret(false) - .separator(Component.text("another-separator", NamedTextColor.RED, TextDecoration.OBFUSCATED)) - .storage(Key.key("dummy", "storage")) - .color(NamedTextColor.YELLOW) - .decorate(TextDecoration.BOLD) - .build()); - } -} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java deleted file mode 100644 index a9fc257f6a..0000000000 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of adventure, licensed under the MIT License. - * - * Copyright (c) 2017-2025 KyoriPowered - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package net.kyori.adventure.text.serializer.nbt; - -import net.kyori.adventure.nbt.StringBinaryTag; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.junit.jupiter.api.Test; - -final class TextComponentTest implements NBTComponentTest { - @Test - public void testNoStyling() { - this.test(Component.text("Codestech was here!"), StringBinaryTag.class); - } - - @Test - public void testWithStyling() { - this.test(Component.text("A component with style!", NamedTextColor.RED, TextDecoration.BOLD)); - } -} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java deleted file mode 100644 index c18dc96670..0000000000 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of adventure, licensed under the MIT License. - * - * Copyright (c) 2017-2025 KyoriPowered - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package net.kyori.adventure.text.serializer.nbt; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.junit.jupiter.api.Test; - -final class TranslatableComponentTest implements NBTComponentTest { - @Test - public void testNoStyling() { - this.test(Component.translatable("some.translation")); - } - - @Test - public void testWithStyling() { - this.test(Component.translatable("another-translation", NamedTextColor.GOLD, TextDecoration.STRIKETHROUGH) - .decoration(TextDecoration.ITALIC, false)); - } -} From fee8bd0c6d4044b563f4e448d58b1f36b4e18e1e Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 17:42:21 +0200 Subject: [PATCH 60/86] feat: text component serialization test --- .../text/serializer/nbt/SerializerTest.java | 50 +++++++ .../serializer/nbt/TextComponentTest.java | 124 ++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTest.java create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTest.java new file mode 100644 index 0000000000..7d385e1c14 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTest.java @@ -0,0 +1,50 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.text.Component; +import org.jspecify.annotations.NonNull; +import org.junit.jupiter.api.BeforeEach; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public abstract class SerializerTest { + + private NBTComponentSerializer serializer; + + public void test(@NonNull Component component, @NonNull BinaryTag tag) { + assertEquals(tag, this.serializer.serialize(component)); + assertEquals(component, this.serializer.deserialize(tag)); + } + + @BeforeEach + public void setUpSerializer() { + this.serializer = this.createSerializer(); + } + + protected @NonNull NBTComponentSerializer createSerializer() { + return NBTComponentSerializer.nbt(); + } +} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java new file mode 100644 index 0000000000..3fc2a2dfd9 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java @@ -0,0 +1,124 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; +import net.kyori.adventure.nbt.StringBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.HoverEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import org.junit.jupiter.api.Test; + +public final class TextComponentTest extends SerializerTest { + @Test + public void testSimple() { + this.test( + Component.text("Hello, world."), + StringBinaryTag.stringBinaryTag("Hello, world.") + ); + } + + @Test + public void testComplex1() { + this.test( + Component.text().content("c") + .color(NamedTextColor.GOLD) + .append(Component.text("o", NamedTextColor.DARK_AQUA)) + .append(Component.text("l", NamedTextColor.LIGHT_PURPLE)) + .append(Component.text("o", NamedTextColor.DARK_PURPLE)) + .append(Component.text("u", NamedTextColor.BLUE)) + .append(Component.text("r", NamedTextColor.DARK_GREEN)) + .append(Component.text("s", NamedTextColor.RED)) + .build(), + CompoundBinaryTag.builder() + .putString("text", "c") + .putString("color", "gold") + .put( + "extra", + ListBinaryTag.builder() + .add(CompoundBinaryTag.builder() + .putString("text", "o") + .putString("color", "dark_aqua") + .build()) + .add(CompoundBinaryTag.builder() + .putString("text", "l") + .putString("color", "light_purple") + .build()) + .add(CompoundBinaryTag.builder() + .putString("text", "o") + .putString("color", "dark_purple") + .build()) + .add(CompoundBinaryTag.builder() + .putString("text", "u") + .putString("color", "blue") + .build()) + .add(CompoundBinaryTag.builder() + .putString("text", "r") + .putString("color", "dark_green") + .build()) + .add(CompoundBinaryTag.builder() + .putString("text", "s") + .putString("color", "red") + .build()) + .build() + ) + .build() + ); + } + + @Test + public void testComplex2() { + this.test( + Component.text().content("This is a test.") + .color(NamedTextColor.DARK_PURPLE) + .hoverEvent(HoverEvent.showText(Component.text("A test."))) + .append(Component.text(" ")) + .append(Component.text("A what?", NamedTextColor.DARK_AQUA)) + .build(), + CompoundBinaryTag.builder() + .putString("text", "This is a test.") + .putString("color", "dark_purple") + .put( + "hover_event", + CompoundBinaryTag.builder() + .putString("action", "show_text") + .putString("value", "A test.") + .build() + ) + .put( + "extra", + ListBinaryTag.heterogeneousListBinaryTag() + .add(StringBinaryTag.stringBinaryTag(" ")) + .add(CompoundBinaryTag.builder() + .putString("text", "A what?") + .putString("color", "dark_aqua") + .build()) + .build() + .wrapHeterogeneity() + ) + .build() + ); + } +} From bac65e1db441ca6da262eea78a7111431c5b8e76 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 18:11:22 +0200 Subject: [PATCH 61/86] chore: use ComponentTreeConstants instead for field names in TextComponentTest --- .../serializer/nbt/TextComponentTest.java | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java index 3fc2a2dfd9..169b402e50 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java @@ -29,6 +29,7 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; import org.junit.jupiter.api.Test; public final class TextComponentTest extends SerializerTest { @@ -53,34 +54,34 @@ public void testComplex1() { .append(Component.text("s", NamedTextColor.RED)) .build(), CompoundBinaryTag.builder() - .putString("text", "c") - .putString("color", "gold") + .putString(ComponentTreeConstants.TEXT, "c") + .putString(ComponentTreeConstants.COLOR, "gold") .put( - "extra", + ComponentTreeConstants.EXTRA, ListBinaryTag.builder() .add(CompoundBinaryTag.builder() - .putString("text", "o") - .putString("color", "dark_aqua") + .putString(ComponentTreeConstants.TEXT, "o") + .putString(ComponentTreeConstants.COLOR, "dark_aqua") .build()) .add(CompoundBinaryTag.builder() - .putString("text", "l") - .putString("color", "light_purple") + .putString(ComponentTreeConstants.TEXT, "l") + .putString(ComponentTreeConstants.COLOR, "light_purple") .build()) .add(CompoundBinaryTag.builder() - .putString("text", "o") - .putString("color", "dark_purple") + .putString(ComponentTreeConstants.TEXT, "o") + .putString(ComponentTreeConstants.COLOR, "dark_purple") .build()) .add(CompoundBinaryTag.builder() - .putString("text", "u") - .putString("color", "blue") + .putString(ComponentTreeConstants.TEXT, "u") + .putString(ComponentTreeConstants.COLOR, "blue") .build()) .add(CompoundBinaryTag.builder() - .putString("text", "r") - .putString("color", "dark_green") + .putString(ComponentTreeConstants.TEXT, "r") + .putString(ComponentTreeConstants.COLOR, "dark_green") .build()) .add(CompoundBinaryTag.builder() - .putString("text", "s") - .putString("color", "red") + .putString(ComponentTreeConstants.TEXT, "s") + .putString(ComponentTreeConstants.COLOR, "red") .build()) .build() ) @@ -98,22 +99,22 @@ public void testComplex2() { .append(Component.text("A what?", NamedTextColor.DARK_AQUA)) .build(), CompoundBinaryTag.builder() - .putString("text", "This is a test.") - .putString("color", "dark_purple") + .putString(ComponentTreeConstants.TEXT, "This is a test.") + .putString(ComponentTreeConstants.COLOR, "dark_purple") .put( - "hover_event", + ComponentTreeConstants.HOVER_EVENT_SNAKE, CompoundBinaryTag.builder() - .putString("action", "show_text") - .putString("value", "A test.") + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_text") + .putString(ComponentTreeConstants.HOVER_EVENT_VALUE, "A test.") .build() ) .put( - "extra", + ComponentTreeConstants.EXTRA, ListBinaryTag.heterogeneousListBinaryTag() .add(StringBinaryTag.stringBinaryTag(" ")) .add(CompoundBinaryTag.builder() - .putString("text", "A what?") - .putString("color", "dark_aqua") + .putString(ComponentTreeConstants.TEXT, "A what?") + .putString(ComponentTreeConstants.COLOR, "dark_aqua") .build()) .build() .wrapHeterogeneity() From 0ab8662ca3f71c166f8e83a0390fb2555452359c Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 18:12:10 +0200 Subject: [PATCH 62/86] feat: translatable component serialization test --- .../nbt/TranslatableComponentTest.java | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java new file mode 100644 index 0000000000..a052a4b080 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java @@ -0,0 +1,120 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.IntArrayBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.ClickEvent; +import net.kyori.adventure.text.event.HoverEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; +import org.junit.jupiter.api.Test; + +import java.util.UUID; + +final class TranslatableComponentTest extends SerializerTest { + @Test + public void testNoArgs() { + String translationKey = "multiplayer.player.left"; + this.test( + Component.translatable(translationKey), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.TRANSLATE, translationKey) + .build() + ); + } + + @Test + public void testFallback() { + String translationKey = "thisIsA"; + String fallback = "This is a test."; + this.test( + Component.translatable() + .key(translationKey) + .fallback(fallback) + .build(), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.TRANSLATE, translationKey) + .putString(ComponentTreeConstants.TRANSLATE_FALLBACK, fallback) + .build() + ); + } + + @Test + public void testSingleArgWithEvents() { + String translationKey = "translatable.message"; + + UUID id = UUID.fromString("86365c36-e272-4d32-8ab8-d4fee19f6231"); + String name = "Codestech"; + String command = String.format("/msg %s ", name); + + this.test( + Component.translatable() + .key(translationKey) + .color(NamedTextColor.YELLOW) + .arguments(Component.text() + .content(name) + .clickEvent(ClickEvent.suggestCommand(command)) + .hoverEvent(HoverEvent.showEntity(Key.key("minecraft", "player"), id, Component.text(name))) + .build()) + .build(), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.TRANSLATE, translationKey) + .putString(ComponentTreeConstants.COLOR, "yellow") + .put( + ComponentTreeConstants.TRANSLATE_WITH, + ListBinaryTag.builder() + .add( + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.TEXT, name) + .put( + ComponentTreeConstants.CLICK_EVENT_SNAKE, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.CLICK_EVENT_ACTION, "suggest_command") + .putString(ComponentTreeConstants.CLICK_EVENT_COMMAND, command) + .build() + ) + .put( + ComponentTreeConstants.HOVER_EVENT_SNAKE, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_entity") + .putString(ComponentTreeConstants.SHOW_ENTITY_ID, "minecraft:player") + .put( + ComponentTreeConstants.SHOW_ENTITY_UUID, + IntArrayBinaryTag.intArrayBinaryTag(-2043257802, -495825614, -1967598338, -509648335) + ) + .putString(ComponentTreeConstants.SHOW_ENTITY_NAME, name) + .build() + ) + .build() + ) + .build() + ) + .build() + ); + } +} From 514f23fdbb3953126c2f42047960489af82e3345 Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 18:13:04 +0200 Subject: [PATCH 63/86] chore: make TextComponentTest package-private --- .../kyori/adventure/text/serializer/nbt/TextComponentTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java index 169b402e50..1c85efde01 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java @@ -32,7 +32,7 @@ import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; import org.junit.jupiter.api.Test; -public final class TextComponentTest extends SerializerTest { +final class TextComponentTest extends SerializerTest { @Test public void testSimple() { this.test( From bf1d2abb1063821d1c9f9614aa266fecad867f6a Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 18:16:14 +0200 Subject: [PATCH 64/86] feat: keybind component serialization test --- .../serializer/nbt/KeybindComponentTest.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java new file mode 100644 index 0000000000..7f44dbe0a0 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java @@ -0,0 +1,42 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; +import org.junit.jupiter.api.Test; + +final class KeybindComponentTest extends SerializerTest { + @Test + public void test() { + String keybind = "key.jump"; + this.test( + Component.keybind(keybind), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.KEYBIND, keybind) + .build() + ); + } +} From ab6ae46df3cf11796c8a8826092b184c9192983c Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 18:32:13 +0200 Subject: [PATCH 65/86] feat: score component serialization test --- .../serializer/nbt/NBTSerializerUtils.java | 2 +- .../serializer/nbt/ScoreComponentTest.java | 68 +++++++++++++++++++ .../text/serializer/nbt/SerializerTest.java | 12 +++- 3 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java index 1a9c47e733..d45ad1a5f2 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java @@ -82,6 +82,6 @@ static boolean asBoolean(@NotNull NumberBinaryTag tag) { } private static @NotNull IllegalArgumentException noSuchField(@NotNull String name) { - return new IllegalArgumentException("The specified compound tag does not contain a \"" + name + "\" field"); + return new IllegalArgumentException("The specified compound tag does not contain a field with name of \"" + name + "\""); } } diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java new file mode 100644 index 0000000000..b2d8061dc9 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java @@ -0,0 +1,68 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +final class ScoreComponentTest extends SerializerTest { + @Test + public void test() { + String name = "abc"; + String objective = "def"; + this.test( + Component.score(name, objective), + CompoundBinaryTag.builder() + .put( + ComponentTreeConstants.SCORE, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.SCORE_NAME, name) + .putString(ComponentTreeConstants.SCORE_OBJECTIVE, objective) + .build() + ) + .build() + ); + } + + @Test + public void testWithoutObjective() { + assertThrows( + IllegalArgumentException.class, + () -> this.deserialize( + CompoundBinaryTag.builder() + .put( + ComponentTreeConstants.SCORE, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.SCORE_NAME, "qwerty") + .build() + ) + .build() + ) + ); + } +} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTest.java index 7d385e1c14..14a231b0f0 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTest.java @@ -35,8 +35,8 @@ public abstract class SerializerTest { private NBTComponentSerializer serializer; public void test(@NonNull Component component, @NonNull BinaryTag tag) { - assertEquals(tag, this.serializer.serialize(component)); - assertEquals(component, this.serializer.deserialize(tag)); + assertEquals(tag, this.serialize(component)); + assertEquals(component, this.deserialize(tag)); } @BeforeEach @@ -44,6 +44,14 @@ public void setUpSerializer() { this.serializer = this.createSerializer(); } + protected @NonNull Component deserialize(@NonNull BinaryTag tag) { + return this.serializer.deserialize(tag); + } + + protected @NonNull BinaryTag serialize(@NonNull Component component) { + return this.serializer.serialize(component); + } + protected @NonNull NBTComponentSerializer createSerializer() { return NBTComponentSerializer.nbt(); } From 0b1d3ad0b846759f83514c296f7b83b2391f7d4b Mon Sep 17 00:00:00 2001 From: codestech Date: Sat, 28 Jun 2025 18:45:55 +0200 Subject: [PATCH 66/86] feat: selector component serialization test --- .../serializer/nbt/SelectorComponentTest.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java new file mode 100644 index 0000000000..c76fed3147 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java @@ -0,0 +1,55 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; +import org.junit.jupiter.api.Test; + +final class SelectorComponentTest extends SerializerTest { + @Test + public void test() { + String pattern = "@p"; + this.test( + Component.selector(pattern), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.SELECTOR, pattern) + .build() + ); + } + + @Test + public void testSeparator() { + String pattern = "@r"; + Component separator = Component.text(","); + this.test( + Component.selector(pattern, separator), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.SELECTOR, pattern) + .put(ComponentTreeConstants.SEPARATOR, this.serialize(separator)) + .build() + ); + } +} From dd6fcd11db0213045fb660c000e773919897e64f Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 29 Jun 2025 13:06:40 +0200 Subject: [PATCH 67/86] feat: block NBT component serialization test --- .../serializer/nbt/BlockNBTComponentTest.java | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java new file mode 100644 index 0000000000..502e1b32c1 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java @@ -0,0 +1,118 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.text.BlockNBTComponent; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; +import org.junit.jupiter.api.Test; + +final class BlockNBTComponentTest extends SerializerTest { + @Test + public void testLocal() { + String nbtPath = "abc"; + + double left = 1.23D; + double up = 2.0D; + double forwards = 3.89D; + + this.test( + Component.blockNBT() + .nbtPath(nbtPath) + .localPos(left, up, forwards) + .build(), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.NBT, nbtPath) + .putString(ComponentTreeConstants.NBT_BLOCK, "^" + left + " ^" + up + " ^" + forwards) + .build() + ); + } + + @Test + public void testAbsoluteWorld() { + String nbtPath = "xyz"; + + int x = 4; + int y = 5; + int z = 6; + + this.test( + Component.blockNBT() + .nbtPath(nbtPath) + .absoluteWorldPos(x, y, z) + .interpret(true) + .build(), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.NBT, nbtPath) + .putBoolean(ComponentTreeConstants.NBT_INTERPRET, true) + .putString(ComponentTreeConstants.NBT_BLOCK, x + " " + y + " " + z) + .build() + ); + } + + @Test + public void testRelativeWorld() { + String nbtPath = "eeee"; + + int x = 7; + int y = 83; + int z = 900; + + this.test( + Component.blockNBT() + .nbtPath(nbtPath) + .relativeWorldPos(x, y, z) + .build(), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.NBT, nbtPath) + .putString(ComponentTreeConstants.NBT_BLOCK, "~" + x + " ~" + y + " ~" + z) + .build() + ); + } + + @Test + public void testMixedAbsoluteAndRelative() { + String nbtPath = "qwert"; + + int x = 12; + int y = 3; + int z = 1200; + + this.test( + Component.blockNBT() + .nbtPath(nbtPath) + .worldPos( + BlockNBTComponent.WorldPos.Coordinate.absolute(12), + BlockNBTComponent.WorldPos.Coordinate.relative(3), + BlockNBTComponent.WorldPos.Coordinate.absolute(1200) + ) + .build(), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.NBT, nbtPath) + .putString(ComponentTreeConstants.NBT_BLOCK, x + " ~" + y + " " + z) + .build() + ); + } +} From 44c79539b57ac1966cbd35028ed497cec2acd36b Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 29 Jun 2025 13:10:58 +0200 Subject: [PATCH 68/86] feat: entity NBT component serialization test --- .../nbt/EntityNBTComponentTest.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java new file mode 100644 index 0000000000..0e41695d65 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java @@ -0,0 +1,67 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; +import org.junit.jupiter.api.Test; + +final class EntityNBTComponentTest extends SerializerTest { + @Test + public void testWithoutInterpret() { + String nbtPath = "abc"; + String selector = "test"; + + this.test( + Component.entityNBT() + .nbtPath(nbtPath) + .selector(selector) + .build(), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.NBT, nbtPath) + .putString(ComponentTreeConstants.NBT_ENTITY, selector) + .build() + ); + } + + @Test + public void testWithInterpret() { + String nbtPath = "abc"; + String selector = "test"; + + this.test( + Component.entityNBT() + .nbtPath(nbtPath) + .selector(selector) + .interpret(true) + .build(), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.NBT, nbtPath) + .putBoolean(ComponentTreeConstants.NBT_INTERPRET, true) + .putString(ComponentTreeConstants.NBT_ENTITY, selector) + .build() + ); + } +} From 904748a714a41d6daa837a178a6f41a55e293fb5 Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 29 Jun 2025 13:15:16 +0200 Subject: [PATCH 69/86] feat: storage NBT component serialization test --- .../nbt/StorageNBTComponentTest.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java new file mode 100644 index 0000000000..42ad757542 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java @@ -0,0 +1,68 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; +import org.junit.jupiter.api.Test; + +final class StorageNBTComponentTest extends SerializerTest { + @Test + public void testWithoutInterpret() { + String nbtPath = "abc"; + String storage = "doom:apple"; + + this.test( + Component.storageNBT() + .nbtPath(nbtPath) + .storage(Key.key(storage)) + .build(), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.NBT, nbtPath) + .putString(ComponentTreeConstants.NBT_STORAGE, storage) + .build() + ); + } + + @Test + public void testWithInterpret() { + String nbtPath = "abc"; + String storage = "doom:apple"; + + this.test( + Component.storageNBT() + .nbtPath(nbtPath) + .storage(Key.key(storage)) + .interpret(true) + .build(), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.NBT, nbtPath) + .putBoolean(ComponentTreeConstants.NBT_INTERPRET, true) + .putString(ComponentTreeConstants.NBT_STORAGE, storage) + .build() + ); + } +} From 0d2d83c6ded71c86928fedba0f4dea331cae4c82 Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 29 Jun 2025 14:15:02 +0200 Subject: [PATCH 70/86] feat: component style serialization test, chore: use jetbrains not-null annotations instead --- .../text/serializer/nbt/SerializerTest.java | 28 ++- .../text/serializer/nbt/StyleTest.java | 217 ++++++++++++++++++ 2 files changed, 237 insertions(+), 8 deletions(-) create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StyleTest.java diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTest.java index 14a231b0f0..39c486ffd0 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTest.java @@ -24,8 +24,10 @@ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.text.Component; -import org.jspecify.annotations.NonNull; +import net.kyori.adventure.text.format.Style; +import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeEach; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -34,25 +36,35 @@ public abstract class SerializerTest { private NBTComponentSerializer serializer; - public void test(@NonNull Component component, @NonNull BinaryTag tag) { + @BeforeEach + public void setUpSerializer() { + this.serializer = this.createSerializer(); + } + + protected void test(@NotNull Component component, @NotNull BinaryTag tag) { assertEquals(tag, this.serialize(component)); assertEquals(component, this.deserialize(tag)); } - @BeforeEach - public void setUpSerializer() { - this.serializer = this.createSerializer(); + protected void test(@NotNull Style style, @NotNull CompoundBinaryTag tag) { + this.test(this.serializer, style, tag); + } + + protected void test(@NotNull NBTComponentSerializer serializer, + @NotNull Style style, @NotNull CompoundBinaryTag tag) { + assertEquals(tag, serializer.serializeStyle(style)); + assertEquals(style, serializer.deserializeStyle(tag)); } - protected @NonNull Component deserialize(@NonNull BinaryTag tag) { + protected @NotNull Component deserialize(@NotNull BinaryTag tag) { return this.serializer.deserialize(tag); } - protected @NonNull BinaryTag serialize(@NonNull Component component) { + protected @NotNull BinaryTag serialize(@NotNull Component component) { return this.serializer.serialize(component); } - protected @NonNull NBTComponentSerializer createSerializer() { + protected @NotNull NBTComponentSerializer createSerializer() { return NBTComponentSerializer.nbt(); } } diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StyleTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StyleTest.java new file mode 100644 index 0000000000..66976ee43b --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StyleTest.java @@ -0,0 +1,217 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.BinaryTagTypes; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.EndBinaryTag; +import net.kyori.adventure.nbt.FloatBinaryTag; +import net.kyori.adventure.nbt.IntArrayBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.ClickEvent; +import net.kyori.adventure.text.event.HoverEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.ShadowColor; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; +import net.kyori.adventure.util.TriState; +import org.junit.jupiter.api.Test; + +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +final class StyleTest extends SerializerTest { + @Test + public void testEmpty() { + this.test(Style.empty(), CompoundBinaryTag.empty()); + } + + @Test + public void testHexColor() { + this.test( + Style.style(TextColor.color(0x0a1ab9)), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.COLOR, "#0A1AB9") + .build() + ); + } + + @Test + public void testNamedColor() { + this.test( + Style.style(NamedTextColor.LIGHT_PURPLE), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.COLOR, "light_purple") + .build() + ); + } + + @Test + public void testDecoration() { + this.test( + Style.style(TextDecoration.BOLD), + CompoundBinaryTag.builder() + .putBoolean("bold", true) + .build() + ); + + this.test( + Style.style(TextDecoration.BOLD.withState(false)), + CompoundBinaryTag.builder() + .putBoolean("bold", false) + .build() + ); + + this.test( + Style.style(TextDecoration.BOLD.withState(TriState.NOT_SET)), + CompoundBinaryTag.empty() + ); + + assertThrows( + IllegalArgumentException.class, + () -> this.deserialize( + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.TEXT, "") + .put("bold", EndBinaryTag.endBinaryTag()) + .build() + ) + ); + } + + @Test + public void testShadowColorInt() { + int shadowColorValue = 0xCCFF0022; + this.test( + Style.style(ShadowColor.shadowColor(shadowColorValue)), + CompoundBinaryTag.builder() + .putInt(ComponentTreeConstants.SHADOW_COLOR, shadowColorValue) + .build() + ); + } + + @Test + public void testShadowColorFloats() { + this.test( + NBTComponentSerializer.builder() + .editOptions(builder -> builder.value(NBTSerializerOptions.SHADOW_COLOR_MODE, NBTSerializerOptions.ShadowColorEmitMode.EMIT_ARRAY)) + .build(), + Style.style(ShadowColor.shadowColor(0x80, 0x40, 0xcc, 0xff)), + CompoundBinaryTag.builder() + .put( + ComponentTreeConstants.SHADOW_COLOR, + ListBinaryTag.builder(BinaryTagTypes.FLOAT) + .add(FloatBinaryTag.floatBinaryTag(0.501960813999176f)) + .add(FloatBinaryTag.floatBinaryTag(0.250980406999588f)) + .add(FloatBinaryTag.floatBinaryTag(0.800000011920929f)) + .add(FloatBinaryTag.floatBinaryTag(1f)) + .build() + ) + .build() + ); + } + + @Test + public void testInsertion() { + String insertion = "honk"; + this.test( + Style.style() + .insertion(insertion) + .build(), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.INSERTION, insertion) + .build() + ); + } + + @Test + public void testMixedFontColorDecorationClickEvent() { + String clickEventUrl = "https://github.com"; + this.test( + Style.style() + .font(Key.key("kyori", "kittens")) + .color(NamedTextColor.RED) + .decoration(TextDecoration.BOLD, true) + .clickEvent(ClickEvent.openUrl(clickEventUrl)) + .build(), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.FONT, "kyori:kittens") + .putString(ComponentTreeConstants.COLOR, "red") + .putBoolean("bold", true) + .put( + ComponentTreeConstants.CLICK_EVENT_SNAKE, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.CLICK_EVENT_ACTION, "open_url") + .putString(ComponentTreeConstants.CLICK_EVENT_URL, clickEventUrl) + .build() + ) + .build() + ); + } + + @Test + public void testShowEntityHoverEvent() { + UUID showEntityUUID = UUID.randomUUID(); + String showEntityName = "Dolores"; + + this.test( + Style.style() + .hoverEvent(HoverEvent.showEntity( + Key.key(Key.MINECRAFT_NAMESPACE, "pig"), + showEntityUUID, + Component.text(showEntityName, TextColor.color(0x0a1ab9)) + )) + .build(), + CompoundBinaryTag.builder() + .put( + ComponentTreeConstants.HOVER_EVENT_SNAKE, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_entity") + .putString(ComponentTreeConstants.SHOW_ENTITY_ID, "minecraft:pig") + .put( + ComponentTreeConstants.SHOW_ENTITY_UUID, + IntArrayBinaryTag.intArrayBinaryTag( + (int) (showEntityUUID.getMostSignificantBits() >> 32), + (int) (showEntityUUID.getMostSignificantBits() & 0xffffffffL), + (int) (showEntityUUID.getLeastSignificantBits() >> 32), + (int) (showEntityUUID.getLeastSignificantBits() & 0xffffffffL) + ) + ) + .put( + ComponentTreeConstants.SHOW_ENTITY_NAME, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.TEXT, showEntityName) + .putString(ComponentTreeConstants.COLOR, "#0A1AB9") + .build() + ) + .build() + ) + .build() + ); + } +} From bcafca44bc3a7f00cd625846951907877abcadd8 Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 29 Jun 2025 18:04:44 +0200 Subject: [PATCH 71/86] feat: add a test for deserializing component from lists, fix: deserializing from lists does not support heterogeneous lists --- .../nbt/NBTComponentSerializerImpl.java | 2 +- .../nbt/ListComponentDeserializationTest.java | 148 ++++++++++++++++++ 2 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ListComponentDeserializationTest.java diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index a920b1919e..0a607a07a5 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -115,7 +115,7 @@ static final class Instances { if (input instanceof StringBinaryTag) { return Component.text(((StringBinaryTag) input).value()); } else if (input instanceof ListBinaryTag) { - ListBinaryTag castInput = (ListBinaryTag) input; + ListBinaryTag castInput = ((ListBinaryTag) input).unwrapHeterogeneity(); if (castInput.isEmpty()) { throw new IllegalArgumentException("The list binary tag representing a component must not be empty"); } diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ListComponentDeserializationTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ListComponentDeserializationTest.java new file mode 100644 index 0000000000..285d58d57f --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ListComponentDeserializationTest.java @@ -0,0 +1,148 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.BinaryTagTypes; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; +import net.kyori.adventure.nbt.StringBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +final class ListComponentDeserializationTest extends SerializerTest { + @Test + public void testStringListDeserialization() { + assertEquals( + Component.text() + .content("a") + .append(Component.text("b")) + .append(Component.text("c")) + .build(), + this.deserialize( + ListBinaryTag.builder(BinaryTagTypes.STRING) + .add(StringBinaryTag.stringBinaryTag("a")) + .add(StringBinaryTag.stringBinaryTag("b")) + .add(StringBinaryTag.stringBinaryTag("c")) + .build() + ) + ); + } + + @Test + public void testCompoundListDeserialization() { + assertEquals( + Component.text() + .content("x") + .color(NamedTextColor.RED) + .append(Component.translatable("message.disconnection", Style.style(TextDecoration.BOLD))) + .append(Component.text("z", Style.style(TextDecoration.ITALIC.withState(false), NamedTextColor.DARK_AQUA))) + .append( + Component.text() + .content("qwerty") + .color(NamedTextColor.BLACK) + .append(Component.text("abc")) + .build() + ) + .build(), + this.deserialize( + ListBinaryTag.builder(BinaryTagTypes.COMPOUND) + .add( + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.TEXT, "x") + .putString(ComponentTreeConstants.COLOR, "red") + .put( + ComponentTreeConstants.EXTRA, + ListBinaryTag.builder(BinaryTagTypes.COMPOUND) + .add( + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.TRANSLATE, "message.disconnection") + .putBoolean("bold", true) + .build() + ) + .build() + ) + .build() + ) + .add( + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.TEXT, "z") + .putString(ComponentTreeConstants.COLOR, "dark_aqua") + .putBoolean("italic", false) + .build() + ) + .add( + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.TEXT, "qwerty") + .putString(ComponentTreeConstants.COLOR, "black") + .put( + ComponentTreeConstants.EXTRA, + ListBinaryTag.builder(BinaryTagTypes.STRING) + .add(StringBinaryTag.stringBinaryTag("abc")) + .build() + ) + .build() + ) + .build() + ) + ); + } + + @Test + public void testHeterogeneousListDeserialization() { + assertEquals( + Component.text() + .content("a") + .color(NamedTextColor.RED) + .append(Component.empty()) + .append(Component.text("b", NamedTextColor.YELLOW)) + .append(Component.text("qwerty")) + .build(), + this.deserialize( + ListBinaryTag.heterogeneousListBinaryTag() + .add( + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.TEXT, "a") + .putString(ComponentTreeConstants.COLOR, "red") + .build() + ) + .add(StringBinaryTag.stringBinaryTag("")) + .add( + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.TEXT, "b") + .putString(ComponentTreeConstants.COLOR, "yellow") + .build() + ) + .add(StringBinaryTag.stringBinaryTag("qwerty")) + .build() + .wrapHeterogeneity() + ) + ); + } +} From 7a6d5ceb4c804acb9e1e948e5210223be944b57a Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 29 Jun 2025 18:29:45 +0200 Subject: [PATCH 72/86] feat: show entity serialization test --- .../text/serializer/nbt/ShowEntityTest.java | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowEntityTest.java diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowEntityTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowEntityTest.java new file mode 100644 index 0000000000..3a051817f2 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowEntityTest.java @@ -0,0 +1,99 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.IntArrayBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.HoverEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; +import org.junit.jupiter.api.Test; + +import java.util.UUID; + +final class ShowEntityTest extends SerializerTest { + @Test + public void testWithoutName() { + UUID uuid = UUID.fromString("c04d19f7-9854-4122-93ab-ad7d4e1af8bc"); + this.test( + Style.style() + .hoverEvent(HoverEvent.showEntity(Key.key("zombie"), uuid)) + .build(), + CompoundBinaryTag.builder() + .put( + ComponentTreeConstants.HOVER_EVENT_SNAKE, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_entity") + .putString(ComponentTreeConstants.SHOW_ENTITY_ID, "minecraft:zombie") + .put( + ComponentTreeConstants.SHOW_ENTITY_UUID, + IntArrayBinaryTag.intArrayBinaryTag(-1068688905, -1739308766, -1817465475, 1310390460) + ) + .build() + ) + .build() + ); + } + + @Test + public void testWithName() { + String entityId = "minecraft:spider"; + UUID uuid = UUID.randomUUID(); + String entityName = "Adventure spider"; + + this.test( + Style.style() + .hoverEvent(HoverEvent.showEntity(Key.key(entityId), uuid, Component.text(entityName, NamedTextColor.RED))) + .build(), + CompoundBinaryTag.builder() + .put( + ComponentTreeConstants.HOVER_EVENT_SNAKE, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_entity") + .putString(ComponentTreeConstants.SHOW_ENTITY_ID, entityId) + .put( + ComponentTreeConstants.SHOW_ENTITY_UUID, + IntArrayBinaryTag.intArrayBinaryTag( + (int) (uuid.getMostSignificantBits() >> Integer.SIZE), + (int) uuid.getMostSignificantBits(), + (int) (uuid.getLeastSignificantBits() >> Integer.SIZE), + (int) uuid.getLeastSignificantBits() + ) + ) + .put( + ComponentTreeConstants.SHOW_ENTITY_NAME, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.TEXT, entityName) + .putString(ComponentTreeConstants.COLOR, "red") + .build() + ) + .build() + ) + .build() + ); + } +} From 5e22119d0b5660ceae848ca4cc7b8ba713142a88 Mon Sep 17 00:00:00 2001 From: codestech Date: Mon, 30 Jun 2025 10:26:36 +0200 Subject: [PATCH 73/86] feat: show item serialization test --- text-serializer-nbt/build.gradle.kts | 2 + ...BTDataComponentValueConverterProvider.java | 66 +++++++ .../serializer/nbt/impl/package-info.java | 7 + .../text/serializer/nbt/ShowItemTest.java | 168 ++++++++++++++++++ 4 files changed, 243 insertions(+) create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/NBTDataComponentValueConverterProvider.java create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/package-info.java create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowItemTest.java diff --git a/text-serializer-nbt/build.gradle.kts b/text-serializer-nbt/build.gradle.kts index 88320bdde3..b82e13ce5b 100644 --- a/text-serializer-nbt/build.gradle.kts +++ b/text-serializer-nbt/build.gradle.kts @@ -6,7 +6,9 @@ dependencies { api(libs.option) api(projects.adventureApi) api(projects.adventureNbt) + compileOnlyApi(libs.autoService.annotations) implementation(projects.adventureTextSerializerCommons) + annotationProcessor(libs.autoService) } applyJarMetadata("net.kyori.adventure.text.serializer.nbt") diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/NBTDataComponentValueConverterProvider.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/NBTDataComponentValueConverterProvider.java new file mode 100644 index 0000000000..44d48b0731 --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/NBTDataComponentValueConverterProvider.java @@ -0,0 +1,66 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt.impl; + +import com.google.auto.service.AutoService; +import net.kyori.adventure.Adventure; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.EndBinaryTag; +import net.kyori.adventure.text.event.DataComponentValue; +import net.kyori.adventure.text.event.DataComponentValueConverterRegistry; +import net.kyori.adventure.text.serializer.nbt.NBTDataComponentValue; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; + +/** + * A provider for NBT component serializer's implementations of data component value converters. + * + *

This is public SPI, not API.

+ * + * @since 4.24.0 + */ +@AutoService(DataComponentValueConverterRegistry.Provider.class) +@ApiStatus.Internal +public final class NBTDataComponentValueConverterProvider implements DataComponentValueConverterRegistry.Provider { + + private static final Key ID = Key.key(Adventure.NAMESPACE, "serializer/nbt"); + + @Override + public @NotNull Key id() { + return ID; + } + + @Override + public @NotNull Iterable> conversions() { + return Collections.singletonList( + DataComponentValueConverterRegistry.Conversion.convert( + DataComponentValue.Removed.class, + NBTDataComponentValue.class, + (key, removed) -> NBTDataComponentValue.nbtDataComponentValue(EndBinaryTag.endBinaryTag()) + ) + ); + } +} diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/package-info.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/package-info.java new file mode 100644 index 0000000000..66e56bba3b --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/package-info.java @@ -0,0 +1,7 @@ +/** + * Internal classes for the NBT component serializer. + */ +@ApiStatus.Internal +package net.kyori.adventure.text.serializer.nbt.impl; + +import org.jetbrains.annotations.ApiStatus; diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowItemTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowItemTest.java new file mode 100644 index 0000000000..f77af1fed9 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowItemTest.java @@ -0,0 +1,168 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.EndBinaryTag; +import net.kyori.adventure.nbt.StringBinaryTag; +import net.kyori.adventure.nbt.TagStringIO; +import net.kyori.adventure.nbt.api.BinaryTagHolder; +import net.kyori.adventure.text.event.DataComponentValue; +import net.kyori.adventure.text.event.HoverEvent; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.Collections; + +final class ShowItemTest extends SerializerTest { + @Test + public void testWithPopulatedTag() throws IOException { + String item = "minecraft:diamond"; + int count = 2; + + this.test( + NBTComponentSerializer.builder() + .editOptions(builder -> { + builder.value( + NBTSerializerOptions.SHOW_ITEM_HOVER_DATA_MODE, + NBTSerializerOptions.ShowItemHoverDataMode.EMIT_EITHER + ); + builder.value( + NBTSerializerOptions.EMIT_HOVER_EVENT_TYPE, + NBTSerializerOptions.HoverEventValueMode.CAMEL_CASE + ); + }) + .build(), + Style.style() + .hoverEvent(HoverEvent.showItem( + Key.key(item), count, + BinaryTagHolder.binaryTagHolder(TagStringIO.tagStringIO().asString( + CompoundBinaryTag.builder() + .put("display", CompoundBinaryTag.builder() + .put("Name", StringBinaryTag.stringBinaryTag("A test!")) + .build()) + .build() + )) + )) + .build(), + CompoundBinaryTag.builder() + .put( + ComponentTreeConstants.HOVER_EVENT_CAMEL, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_item") + .put( + ComponentTreeConstants.HOVER_EVENT_CONTENTS, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.SHOW_ITEM_ID, item) + .putInt(ComponentTreeConstants.SHOW_ITEM_COUNT, count) + .putString(ComponentTreeConstants.SHOW_ITEM_TAG, "{display:{Name:\"A test!\"}}") + .build() + ) + .build() + ) + .build() + ); + } + + @Test + public void testWithoutAdditionalData() { + String item = "minecraft:diamond"; + int count = 2; + + this.test( + Style.style() + .hoverEvent(HoverEvent.showItem(Key.key(item), count, Collections.emptyMap())) + .build(), + CompoundBinaryTag.builder() + .put( + ComponentTreeConstants.HOVER_EVENT_SNAKE, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_item") + .putString(ComponentTreeConstants.SHOW_ITEM_ID, item) + .putInt(ComponentTreeConstants.SHOW_ITEM_COUNT, count) + .build() + ) + .build() + ); + } + + @Test + public void testWithCountOfOne() { + String item = "minecraft:diamond"; + int count = 1; + + this.test( + Style.style() + .hoverEvent(HoverEvent.showItem(Key.key(item), count)) + .build(), + CompoundBinaryTag.builder() + .put( + ComponentTreeConstants.HOVER_EVENT_SNAKE, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_item") + .putString(ComponentTreeConstants.SHOW_ITEM_ID, item) + .putInt(ComponentTreeConstants.SHOW_ITEM_COUNT, count) + .build() + ) + .build() + ); + } + + @Test + public void testWithRemovedComponent() { + String item = "minecraft:diamond"; + int count = 2; + String component = "minecraft:damage"; + + this.test( + Style.style() + .hoverEvent( + HoverEvent.showItem( + Key.key(item), count, + Collections.singletonMap(Key.key(component), DataComponentValue.removed()) + ) + ) + .build(), + CompoundBinaryTag.builder() + .put( + ComponentTreeConstants.HOVER_EVENT_SNAKE, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_item") + .putString(ComponentTreeConstants.SHOW_ITEM_ID, item) + .putInt(ComponentTreeConstants.SHOW_ITEM_COUNT, count) + .put( + ComponentTreeConstants.SHOW_ITEM_COMPONENTS, + CompoundBinaryTag.builder() + .put("!" + component, EndBinaryTag.endBinaryTag()) + .build() + ) + .build() + ) + .build() + ); + } +} From fac131fc31c5026ad6828a2eaec5d00a4fec4132 Mon Sep 17 00:00:00 2001 From: codestech Date: Mon, 30 Jun 2025 13:08:21 +0200 Subject: [PATCH 74/86] chore: cleanup tests --- .../serializer/nbt/BlockNBTComponentTest.java | 20 ++-- .../nbt/EntityNBTComponentTest.java | 12 ++- .../serializer/nbt/KeybindComponentTest.java | 8 +- .../nbt/ListComponentDeserializationTest.java | 30 +++--- .../serializer/nbt/ScoreComponentTest.java | 13 ++- .../serializer/nbt/SelectorComponentTest.java | 16 ++-- .../text/serializer/nbt/SerializerTest.java | 70 -------------- .../text/serializer/nbt/SerializerTests.java | 91 +++++++++++++++++++ .../text/serializer/nbt/ShowEntityTest.java | 19 ++-- .../text/serializer/nbt/ShowItemTest.java | 29 +++--- .../nbt/StorageNBTComponentTest.java | 12 ++- .../text/serializer/nbt/StyleTest.java | 70 +++++++------- .../serializer/nbt/TextComponentTest.java | 35 +++---- .../nbt/TranslatableComponentTest.java | 29 +++--- 14 files changed, 254 insertions(+), 200 deletions(-) delete mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTest.java create mode 100644 text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTests.java diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java index 502e1b32c1..3e21a83cfb 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java @@ -29,16 +29,18 @@ import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; import org.junit.jupiter.api.Test; -final class BlockNBTComponentTest extends SerializerTest { +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.testComponent; + +final class BlockNBTComponentTest { @Test - public void testLocal() { + void testLocal() { String nbtPath = "abc"; double left = 1.23D; double up = 2.0D; double forwards = 3.89D; - this.test( + testComponent( Component.blockNBT() .nbtPath(nbtPath) .localPos(left, up, forwards) @@ -51,14 +53,14 @@ public void testLocal() { } @Test - public void testAbsoluteWorld() { + void testAbsoluteWorld() { String nbtPath = "xyz"; int x = 4; int y = 5; int z = 6; - this.test( + testComponent( Component.blockNBT() .nbtPath(nbtPath) .absoluteWorldPos(x, y, z) @@ -73,14 +75,14 @@ public void testAbsoluteWorld() { } @Test - public void testRelativeWorld() { + void testRelativeWorld() { String nbtPath = "eeee"; int x = 7; int y = 83; int z = 900; - this.test( + testComponent( Component.blockNBT() .nbtPath(nbtPath) .relativeWorldPos(x, y, z) @@ -93,14 +95,14 @@ public void testRelativeWorld() { } @Test - public void testMixedAbsoluteAndRelative() { + void testMixedAbsoluteAndRelative() { String nbtPath = "qwert"; int x = 12; int y = 3; int z = 1200; - this.test( + testComponent( Component.blockNBT() .nbtPath(nbtPath) .worldPos( diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java index 0e41695d65..6c8a304ee4 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java @@ -28,13 +28,15 @@ import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; import org.junit.jupiter.api.Test; -final class EntityNBTComponentTest extends SerializerTest { +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.testComponent; + +final class EntityNBTComponentTest { @Test - public void testWithoutInterpret() { + void testWithoutInterpret() { String nbtPath = "abc"; String selector = "test"; - this.test( + testComponent( Component.entityNBT() .nbtPath(nbtPath) .selector(selector) @@ -47,11 +49,11 @@ public void testWithoutInterpret() { } @Test - public void testWithInterpret() { + void testWithInterpret() { String nbtPath = "abc"; String selector = "test"; - this.test( + testComponent( Component.entityNBT() .nbtPath(nbtPath) .selector(selector) diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java index 7f44dbe0a0..a8f491c28c 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java @@ -28,11 +28,13 @@ import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; import org.junit.jupiter.api.Test; -final class KeybindComponentTest extends SerializerTest { +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.testComponent; + +final class KeybindComponentTest { @Test - public void test() { + void test() { String keybind = "key.jump"; - this.test( + testComponent( Component.keybind(keybind), CompoundBinaryTag.builder() .putString(ComponentTreeConstants.KEYBIND, keybind) diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ListComponentDeserializationTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ListComponentDeserializationTest.java index 285d58d57f..e179d2e45a 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ListComponentDeserializationTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ListComponentDeserializationTest.java @@ -34,18 +34,20 @@ import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; import org.junit.jupiter.api.Test; +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.deserializeComponent; +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.name; import static org.junit.jupiter.api.Assertions.assertEquals; -final class ListComponentDeserializationTest extends SerializerTest { +final class ListComponentDeserializationTest { @Test - public void testStringListDeserialization() { + void testStringListDeserialization() { assertEquals( Component.text() .content("a") .append(Component.text("b")) .append(Component.text("c")) .build(), - this.deserialize( + deserializeComponent( ListBinaryTag.builder(BinaryTagTypes.STRING) .add(StringBinaryTag.stringBinaryTag("a")) .add(StringBinaryTag.stringBinaryTag("b")) @@ -56,7 +58,7 @@ public void testStringListDeserialization() { } @Test - public void testCompoundListDeserialization() { + void testCompoundListDeserialization() { assertEquals( Component.text() .content("x") @@ -71,19 +73,19 @@ public void testCompoundListDeserialization() { .build() ) .build(), - this.deserialize( + deserializeComponent( ListBinaryTag.builder(BinaryTagTypes.COMPOUND) .add( CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TEXT, "x") - .putString(ComponentTreeConstants.COLOR, "red") + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.RED)) .put( ComponentTreeConstants.EXTRA, ListBinaryTag.builder(BinaryTagTypes.COMPOUND) .add( CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TRANSLATE, "message.disconnection") - .putBoolean("bold", true) + .putBoolean(name(TextDecoration.BOLD), true) .build() ) .build() @@ -93,14 +95,14 @@ public void testCompoundListDeserialization() { .add( CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TEXT, "z") - .putString(ComponentTreeConstants.COLOR, "dark_aqua") - .putBoolean("italic", false) + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.DARK_AQUA)) + .putBoolean(name(TextDecoration.ITALIC), false) .build() ) .add( CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TEXT, "qwerty") - .putString(ComponentTreeConstants.COLOR, "black") + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.BLACK)) .put( ComponentTreeConstants.EXTRA, ListBinaryTag.builder(BinaryTagTypes.STRING) @@ -115,7 +117,7 @@ public void testCompoundListDeserialization() { } @Test - public void testHeterogeneousListDeserialization() { + void testHeterogeneousListDeserialization() { assertEquals( Component.text() .content("a") @@ -124,19 +126,19 @@ public void testHeterogeneousListDeserialization() { .append(Component.text("b", NamedTextColor.YELLOW)) .append(Component.text("qwerty")) .build(), - this.deserialize( + deserializeComponent( ListBinaryTag.heterogeneousListBinaryTag() .add( CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TEXT, "a") - .putString(ComponentTreeConstants.COLOR, "red") + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.RED)) .build() ) .add(StringBinaryTag.stringBinaryTag("")) .add( CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TEXT, "b") - .putString(ComponentTreeConstants.COLOR, "yellow") + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.YELLOW)) .build() ) .add(StringBinaryTag.stringBinaryTag("qwerty")) diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java index b2d8061dc9..d418f553d5 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java @@ -28,14 +28,17 @@ import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; import org.junit.jupiter.api.Test; +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.deserializeComponent; +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.testComponent; import static org.junit.jupiter.api.Assertions.assertThrows; -final class ScoreComponentTest extends SerializerTest { +final class ScoreComponentTest { @Test - public void test() { + void test() { String name = "abc"; String objective = "def"; - this.test( + + testComponent( Component.score(name, objective), CompoundBinaryTag.builder() .put( @@ -50,10 +53,10 @@ public void test() { } @Test - public void testWithoutObjective() { + void testWithoutObjective() { assertThrows( IllegalArgumentException.class, - () -> this.deserialize( + () -> deserializeComponent( CompoundBinaryTag.builder() .put( ComponentTreeConstants.SCORE, diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java index c76fed3147..c659a0857a 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java @@ -28,11 +28,14 @@ import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; import org.junit.jupiter.api.Test; -final class SelectorComponentTest extends SerializerTest { +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.serializeComponent; +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.testComponent; + +final class SelectorComponentTest { @Test - public void test() { + void test() { String pattern = "@p"; - this.test( + testComponent( Component.selector(pattern), CompoundBinaryTag.builder() .putString(ComponentTreeConstants.SELECTOR, pattern) @@ -41,14 +44,15 @@ public void test() { } @Test - public void testSeparator() { + void testSeparator() { String pattern = "@r"; Component separator = Component.text(","); - this.test( + + testComponent( Component.selector(pattern, separator), CompoundBinaryTag.builder() .putString(ComponentTreeConstants.SELECTOR, pattern) - .put(ComponentTreeConstants.SEPARATOR, this.serialize(separator)) + .put(ComponentTreeConstants.SEPARATOR, serializeComponent(separator)) .build() ); } diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTest.java deleted file mode 100644 index 39c486ffd0..0000000000 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of adventure, licensed under the MIT License. - * - * Copyright (c) 2017-2025 KyoriPowered - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package net.kyori.adventure.text.serializer.nbt; - -import net.kyori.adventure.nbt.BinaryTag; -import net.kyori.adventure.nbt.CompoundBinaryTag; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.Style; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.BeforeEach; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public abstract class SerializerTest { - - private NBTComponentSerializer serializer; - - @BeforeEach - public void setUpSerializer() { - this.serializer = this.createSerializer(); - } - - protected void test(@NotNull Component component, @NotNull BinaryTag tag) { - assertEquals(tag, this.serialize(component)); - assertEquals(component, this.deserialize(tag)); - } - - protected void test(@NotNull Style style, @NotNull CompoundBinaryTag tag) { - this.test(this.serializer, style, tag); - } - - protected void test(@NotNull NBTComponentSerializer serializer, - @NotNull Style style, @NotNull CompoundBinaryTag tag) { - assertEquals(tag, serializer.serializeStyle(style)); - assertEquals(style, serializer.deserializeStyle(tag)); - } - - protected @NotNull Component deserialize(@NotNull BinaryTag tag) { - return this.serializer.deserialize(tag); - } - - protected @NotNull BinaryTag serialize(@NotNull Component component) { - return this.serializer.serialize(component); - } - - protected @NotNull NBTComponentSerializer createSerializer() { - return NBTComponentSerializer.nbt(); - } -} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTests.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTests.java new file mode 100644 index 0000000000..cf04b13989 --- /dev/null +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTests.java @@ -0,0 +1,91 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.ClickEvent; +import net.kyori.adventure.text.event.HoverEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextDecoration; +import org.jetbrains.annotations.NotNull; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +final class SerializerTests { + + private static final NBTComponentSerializer DEFAULT_SERIALIZER = NBTComponentSerializer.nbt(); + + private SerializerTests() {} + + static void testComponent(@NotNull Component component, @NotNull BinaryTag tag) { + testComponent(DEFAULT_SERIALIZER, component, tag); + } + + static void testComponent(@NotNull NBTComponentSerializer serializer, + @NotNull Component component, @NotNull BinaryTag tag) { + assertEquals(tag, serializer.serialize(component)); + assertEquals(component, serializer.deserialize(tag)); + } + + static void testStyle(@NotNull Style style, @NotNull CompoundBinaryTag tag) { + testStyle(DEFAULT_SERIALIZER, style, tag); + } + + static void testStyle(@NotNull NBTComponentSerializer serializer, + @NotNull Style style, @NotNull CompoundBinaryTag tag) { + assertEquals(tag, serializer.serializeStyle(style)); + assertEquals(style, serializer.deserializeStyle(tag)); + } + + static @NotNull Component deserializeComponent(@NotNull BinaryTag tag) { + return DEFAULT_SERIALIZER.deserialize(tag); + } + + static @NotNull BinaryTag serializeComponent(@NotNull Component component) { + return DEFAULT_SERIALIZER.serialize(component); + } + + static @NotNull Style deserializeStyle(@NotNull CompoundBinaryTag tag) { + return DEFAULT_SERIALIZER.deserializeStyle(tag); + } + + static @NotNull String name(@NotNull TextDecoration decoration) { + return TextDecoration.NAMES.keyOrThrow(decoration); + } + + static @NotNull String name(@NotNull NamedTextColor decoration) { + return NamedTextColor.NAMES.keyOrThrow(decoration); + } + + static @NotNull String name(ClickEvent.@NotNull Action action) { + return ClickEvent.Action.NAMES.keyOrThrow(action); + } + + static @NotNull String name(HoverEvent.@NotNull Action action) { + return HoverEvent.Action.NAMES.keyOrThrow(action); + } +} diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowEntityTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowEntityTest.java index 3a051817f2..fd169a5634 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowEntityTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowEntityTest.java @@ -35,11 +35,14 @@ import java.util.UUID; -final class ShowEntityTest extends SerializerTest { +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.name; +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.testStyle; + +final class ShowEntityTest { @Test - public void testWithoutName() { + void testWithoutName() { UUID uuid = UUID.fromString("c04d19f7-9854-4122-93ab-ad7d4e1af8bc"); - this.test( + testStyle( Style.style() .hoverEvent(HoverEvent.showEntity(Key.key("zombie"), uuid)) .build(), @@ -47,7 +50,7 @@ public void testWithoutName() { .put( ComponentTreeConstants.HOVER_EVENT_SNAKE, CompoundBinaryTag.builder() - .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_entity") + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, name(HoverEvent.Action.SHOW_ENTITY)) .putString(ComponentTreeConstants.SHOW_ENTITY_ID, "minecraft:zombie") .put( ComponentTreeConstants.SHOW_ENTITY_UUID, @@ -60,12 +63,12 @@ public void testWithoutName() { } @Test - public void testWithName() { + void testWithName() { String entityId = "minecraft:spider"; UUID uuid = UUID.randomUUID(); String entityName = "Adventure spider"; - this.test( + testStyle( Style.style() .hoverEvent(HoverEvent.showEntity(Key.key(entityId), uuid, Component.text(entityName, NamedTextColor.RED))) .build(), @@ -73,7 +76,7 @@ public void testWithName() { .put( ComponentTreeConstants.HOVER_EVENT_SNAKE, CompoundBinaryTag.builder() - .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_entity") + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, name(HoverEvent.Action.SHOW_ENTITY)) .putString(ComponentTreeConstants.SHOW_ENTITY_ID, entityId) .put( ComponentTreeConstants.SHOW_ENTITY_UUID, @@ -88,7 +91,7 @@ public void testWithName() { ComponentTreeConstants.SHOW_ENTITY_NAME, CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TEXT, entityName) - .putString(ComponentTreeConstants.COLOR, "red") + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.RED)) .build() ) .build() diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowItemTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowItemTest.java index f77af1fed9..49da81f5d1 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowItemTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowItemTest.java @@ -38,13 +38,16 @@ import java.io.IOException; import java.util.Collections; -final class ShowItemTest extends SerializerTest { +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.name; +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.testStyle; + +final class ShowItemTest { @Test - public void testWithPopulatedTag() throws IOException { + void testWithPopulatedTag() throws IOException { String item = "minecraft:diamond"; int count = 2; - this.test( + testStyle( NBTComponentSerializer.builder() .editOptions(builder -> { builder.value( @@ -73,7 +76,7 @@ public void testWithPopulatedTag() throws IOException { .put( ComponentTreeConstants.HOVER_EVENT_CAMEL, CompoundBinaryTag.builder() - .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_item") + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, name(HoverEvent.Action.SHOW_ITEM)) .put( ComponentTreeConstants.HOVER_EVENT_CONTENTS, CompoundBinaryTag.builder() @@ -89,11 +92,11 @@ public void testWithPopulatedTag() throws IOException { } @Test - public void testWithoutAdditionalData() { + void testWithoutAdditionalData() { String item = "minecraft:diamond"; int count = 2; - this.test( + testStyle( Style.style() .hoverEvent(HoverEvent.showItem(Key.key(item), count, Collections.emptyMap())) .build(), @@ -101,7 +104,7 @@ public void testWithoutAdditionalData() { .put( ComponentTreeConstants.HOVER_EVENT_SNAKE, CompoundBinaryTag.builder() - .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_item") + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, name(HoverEvent.Action.SHOW_ITEM)) .putString(ComponentTreeConstants.SHOW_ITEM_ID, item) .putInt(ComponentTreeConstants.SHOW_ITEM_COUNT, count) .build() @@ -111,11 +114,11 @@ public void testWithoutAdditionalData() { } @Test - public void testWithCountOfOne() { + void testWithCountOfOne() { String item = "minecraft:diamond"; int count = 1; - this.test( + testStyle( Style.style() .hoverEvent(HoverEvent.showItem(Key.key(item), count)) .build(), @@ -123,7 +126,7 @@ public void testWithCountOfOne() { .put( ComponentTreeConstants.HOVER_EVENT_SNAKE, CompoundBinaryTag.builder() - .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_item") + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, name(HoverEvent.Action.SHOW_ITEM)) .putString(ComponentTreeConstants.SHOW_ITEM_ID, item) .putInt(ComponentTreeConstants.SHOW_ITEM_COUNT, count) .build() @@ -133,12 +136,12 @@ public void testWithCountOfOne() { } @Test - public void testWithRemovedComponent() { + void testWithRemovedComponent() { String item = "minecraft:diamond"; int count = 2; String component = "minecraft:damage"; - this.test( + testStyle( Style.style() .hoverEvent( HoverEvent.showItem( @@ -151,7 +154,7 @@ public void testWithRemovedComponent() { .put( ComponentTreeConstants.HOVER_EVENT_SNAKE, CompoundBinaryTag.builder() - .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_item") + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, name(HoverEvent.Action.SHOW_ITEM)) .putString(ComponentTreeConstants.SHOW_ITEM_ID, item) .putInt(ComponentTreeConstants.SHOW_ITEM_COUNT, count) .put( diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java index 42ad757542..e6ce59db02 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java @@ -29,13 +29,15 @@ import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; import org.junit.jupiter.api.Test; -final class StorageNBTComponentTest extends SerializerTest { +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.testComponent; + +final class StorageNBTComponentTest { @Test - public void testWithoutInterpret() { + void testWithoutInterpret() { String nbtPath = "abc"; String storage = "doom:apple"; - this.test( + testComponent( Component.storageNBT() .nbtPath(nbtPath) .storage(Key.key(storage)) @@ -48,11 +50,11 @@ public void testWithoutInterpret() { } @Test - public void testWithInterpret() { + void testWithInterpret() { String nbtPath = "abc"; String storage = "doom:apple"; - this.test( + testComponent( Component.storageNBT() .nbtPath(nbtPath) .storage(Key.key(storage)) diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StyleTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StyleTest.java index 66976ee43b..c2ee98cd43 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StyleTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StyleTest.java @@ -44,17 +44,20 @@ import java.util.UUID; +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.deserializeStyle; +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.name; +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.testStyle; import static org.junit.jupiter.api.Assertions.assertThrows; -final class StyleTest extends SerializerTest { +final class StyleTest { @Test - public void testEmpty() { - this.test(Style.empty(), CompoundBinaryTag.empty()); + void testEmpty() { + testStyle(Style.empty(), CompoundBinaryTag.empty()); } @Test - public void testHexColor() { - this.test( + void testHexColor() { + testStyle( Style.style(TextColor.color(0x0a1ab9)), CompoundBinaryTag.builder() .putString(ComponentTreeConstants.COLOR, "#0A1AB9") @@ -63,51 +66,50 @@ public void testHexColor() { } @Test - public void testNamedColor() { - this.test( + void testNamedColor() { + testStyle( Style.style(NamedTextColor.LIGHT_PURPLE), CompoundBinaryTag.builder() - .putString(ComponentTreeConstants.COLOR, "light_purple") + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.LIGHT_PURPLE)) .build() ); } @Test - public void testDecoration() { - this.test( + void testDecoration() { + testStyle( Style.style(TextDecoration.BOLD), CompoundBinaryTag.builder() - .putBoolean("bold", true) + .putBoolean(name(TextDecoration.BOLD), true) .build() ); - this.test( + testStyle( Style.style(TextDecoration.BOLD.withState(false)), CompoundBinaryTag.builder() - .putBoolean("bold", false) + .putBoolean(name(TextDecoration.BOLD), false) .build() ); - this.test( + testStyle( Style.style(TextDecoration.BOLD.withState(TriState.NOT_SET)), CompoundBinaryTag.empty() ); assertThrows( IllegalArgumentException.class, - () -> this.deserialize( + () -> deserializeStyle( CompoundBinaryTag.builder() - .putString(ComponentTreeConstants.TEXT, "") - .put("bold", EndBinaryTag.endBinaryTag()) + .put(name(TextDecoration.BOLD), EndBinaryTag.endBinaryTag()) .build() ) ); } @Test - public void testShadowColorInt() { + void testShadowColorInt() { int shadowColorValue = 0xCCFF0022; - this.test( + testStyle( Style.style(ShadowColor.shadowColor(shadowColorValue)), CompoundBinaryTag.builder() .putInt(ComponentTreeConstants.SHADOW_COLOR, shadowColorValue) @@ -116,8 +118,8 @@ public void testShadowColorInt() { } @Test - public void testShadowColorFloats() { - this.test( + void testShadowColorFloats() { + testStyle( NBTComponentSerializer.builder() .editOptions(builder -> builder.value(NBTSerializerOptions.SHADOW_COLOR_MODE, NBTSerializerOptions.ShadowColorEmitMode.EMIT_ARRAY)) .build(), @@ -126,9 +128,9 @@ public void testShadowColorFloats() { .put( ComponentTreeConstants.SHADOW_COLOR, ListBinaryTag.builder(BinaryTagTypes.FLOAT) - .add(FloatBinaryTag.floatBinaryTag(0.501960813999176f)) - .add(FloatBinaryTag.floatBinaryTag(0.250980406999588f)) - .add(FloatBinaryTag.floatBinaryTag(0.800000011920929f)) + .add(FloatBinaryTag.floatBinaryTag(0.5019608f)) + .add(FloatBinaryTag.floatBinaryTag(0.2509804f)) + .add(FloatBinaryTag.floatBinaryTag(0.8f)) .add(FloatBinaryTag.floatBinaryTag(1f)) .build() ) @@ -137,9 +139,9 @@ public void testShadowColorFloats() { } @Test - public void testInsertion() { + void testInsertion() { String insertion = "honk"; - this.test( + testStyle( Style.style() .insertion(insertion) .build(), @@ -150,9 +152,9 @@ public void testInsertion() { } @Test - public void testMixedFontColorDecorationClickEvent() { + void testMixedFontColorDecorationClickEvent() { String clickEventUrl = "https://github.com"; - this.test( + testStyle( Style.style() .font(Key.key("kyori", "kittens")) .color(NamedTextColor.RED) @@ -161,12 +163,12 @@ public void testMixedFontColorDecorationClickEvent() { .build(), CompoundBinaryTag.builder() .putString(ComponentTreeConstants.FONT, "kyori:kittens") - .putString(ComponentTreeConstants.COLOR, "red") - .putBoolean("bold", true) + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.RED)) + .putBoolean(name(TextDecoration.BOLD), true) .put( ComponentTreeConstants.CLICK_EVENT_SNAKE, CompoundBinaryTag.builder() - .putString(ComponentTreeConstants.CLICK_EVENT_ACTION, "open_url") + .putString(ComponentTreeConstants.CLICK_EVENT_ACTION, name(ClickEvent.Action.OPEN_URL)) .putString(ComponentTreeConstants.CLICK_EVENT_URL, clickEventUrl) .build() ) @@ -175,11 +177,11 @@ public void testMixedFontColorDecorationClickEvent() { } @Test - public void testShowEntityHoverEvent() { + void testShowEntityHoverEvent() { UUID showEntityUUID = UUID.randomUUID(); String showEntityName = "Dolores"; - this.test( + testStyle( Style.style() .hoverEvent(HoverEvent.showEntity( Key.key(Key.MINECRAFT_NAMESPACE, "pig"), @@ -191,7 +193,7 @@ public void testShowEntityHoverEvent() { .put( ComponentTreeConstants.HOVER_EVENT_SNAKE, CompoundBinaryTag.builder() - .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_entity") + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, name(HoverEvent.Action.SHOW_ENTITY)) .putString(ComponentTreeConstants.SHOW_ENTITY_ID, "minecraft:pig") .put( ComponentTreeConstants.SHOW_ENTITY_UUID, diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java index 1c85efde01..68598a86e1 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TextComponentTest.java @@ -32,18 +32,21 @@ import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; import org.junit.jupiter.api.Test; -final class TextComponentTest extends SerializerTest { +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.name; +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.testComponent; + +final class TextComponentTest { @Test - public void testSimple() { - this.test( + void testSimple() { + testComponent( Component.text("Hello, world."), StringBinaryTag.stringBinaryTag("Hello, world.") ); } @Test - public void testComplex1() { - this.test( + void testComplex1() { + testComponent( Component.text().content("c") .color(NamedTextColor.GOLD) .append(Component.text("o", NamedTextColor.DARK_AQUA)) @@ -55,33 +58,33 @@ public void testComplex1() { .build(), CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TEXT, "c") - .putString(ComponentTreeConstants.COLOR, "gold") + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.GOLD)) .put( ComponentTreeConstants.EXTRA, ListBinaryTag.builder() .add(CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TEXT, "o") - .putString(ComponentTreeConstants.COLOR, "dark_aqua") + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.DARK_AQUA)) .build()) .add(CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TEXT, "l") - .putString(ComponentTreeConstants.COLOR, "light_purple") + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.LIGHT_PURPLE)) .build()) .add(CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TEXT, "o") - .putString(ComponentTreeConstants.COLOR, "dark_purple") + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.DARK_PURPLE)) .build()) .add(CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TEXT, "u") - .putString(ComponentTreeConstants.COLOR, "blue") + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.BLUE)) .build()) .add(CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TEXT, "r") - .putString(ComponentTreeConstants.COLOR, "dark_green") + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.DARK_GREEN)) .build()) .add(CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TEXT, "s") - .putString(ComponentTreeConstants.COLOR, "red") + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.RED)) .build()) .build() ) @@ -90,8 +93,8 @@ public void testComplex1() { } @Test - public void testComplex2() { - this.test( + void testComplex2() { + testComponent( Component.text().content("This is a test.") .color(NamedTextColor.DARK_PURPLE) .hoverEvent(HoverEvent.showText(Component.text("A test."))) @@ -100,7 +103,7 @@ public void testComplex2() { .build(), CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TEXT, "This is a test.") - .putString(ComponentTreeConstants.COLOR, "dark_purple") + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.DARK_PURPLE)) .put( ComponentTreeConstants.HOVER_EVENT_SNAKE, CompoundBinaryTag.builder() @@ -114,7 +117,7 @@ public void testComplex2() { .add(StringBinaryTag.stringBinaryTag(" ")) .add(CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TEXT, "A what?") - .putString(ComponentTreeConstants.COLOR, "dark_aqua") + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.DARK_AQUA)) .build()) .build() .wrapHeterogeneity() diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java index a052a4b080..c72c24c305 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java @@ -36,11 +36,14 @@ import java.util.UUID; -final class TranslatableComponentTest extends SerializerTest { +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.name; +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.testComponent; + +final class TranslatableComponentTest { @Test - public void testNoArgs() { + void testNoArgs() { String translationKey = "multiplayer.player.left"; - this.test( + testComponent( Component.translatable(translationKey), CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TRANSLATE, translationKey) @@ -49,10 +52,11 @@ public void testNoArgs() { } @Test - public void testFallback() { + void testFallback() { String translationKey = "thisIsA"; String fallback = "This is a test."; - this.test( + + testComponent( Component.translatable() .key(translationKey) .fallback(fallback) @@ -65,26 +69,27 @@ public void testFallback() { } @Test - public void testSingleArgWithEvents() { + void testSingleArgWithEvents() { String translationKey = "translatable.message"; UUID id = UUID.fromString("86365c36-e272-4d32-8ab8-d4fee19f6231"); String name = "Codestech"; String command = String.format("/msg %s ", name); + String showEntityId = "minecraft:player"; - this.test( + testComponent( Component.translatable() .key(translationKey) .color(NamedTextColor.YELLOW) .arguments(Component.text() .content(name) .clickEvent(ClickEvent.suggestCommand(command)) - .hoverEvent(HoverEvent.showEntity(Key.key("minecraft", "player"), id, Component.text(name))) + .hoverEvent(HoverEvent.showEntity(Key.key(showEntityId), id, Component.text(name))) .build()) .build(), CompoundBinaryTag.builder() .putString(ComponentTreeConstants.TRANSLATE, translationKey) - .putString(ComponentTreeConstants.COLOR, "yellow") + .putString(ComponentTreeConstants.COLOR, name(NamedTextColor.YELLOW)) .put( ComponentTreeConstants.TRANSLATE_WITH, ListBinaryTag.builder() @@ -94,15 +99,15 @@ public void testSingleArgWithEvents() { .put( ComponentTreeConstants.CLICK_EVENT_SNAKE, CompoundBinaryTag.builder() - .putString(ComponentTreeConstants.CLICK_EVENT_ACTION, "suggest_command") + .putString(ComponentTreeConstants.CLICK_EVENT_ACTION, name(ClickEvent.Action.SUGGEST_COMMAND)) .putString(ComponentTreeConstants.CLICK_EVENT_COMMAND, command) .build() ) .put( ComponentTreeConstants.HOVER_EVENT_SNAKE, CompoundBinaryTag.builder() - .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, "show_entity") - .putString(ComponentTreeConstants.SHOW_ENTITY_ID, "minecraft:player") + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, name(HoverEvent.Action.SHOW_ENTITY)) + .putString(ComponentTreeConstants.SHOW_ENTITY_ID, showEntityId) .put( ComponentTreeConstants.SHOW_ENTITY_UUID, IntArrayBinaryTag.intArrayBinaryTag(-2043257802, -495825614, -1967598338, -509648335) From f61a594b2d92308e35bf996e922a34de74ac9bad Mon Sep 17 00:00:00 2001 From: codestech Date: Mon, 30 Jun 2025 15:40:57 +0200 Subject: [PATCH 75/86] feat: legacy hover event deserializing --- .../serializer/nbt/ClickEventSerializer.java | 6 +- .../serializer/nbt/HoverEventSerializer.java | 5 +- .../serializer/nbt/NBTSerializerUtils.java | 7 ++ .../serializer/nbt/ShowEntitySerializer.java | 57 +++++++-- .../serializer/nbt/ShowItemSerializer.java | 108 +++++++++++++----- .../text/serializer/nbt/ShowEntityTest.java | 68 +++++++++++ .../text/serializer/nbt/ShowItemTest.java | 81 ++++++++++++- 7 files changed, 281 insertions(+), 51 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java index d4deddc060..11b37d36d3 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java @@ -29,10 +29,8 @@ import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.IntBinaryTag; import net.kyori.adventure.nbt.StringBinaryTag; -import net.kyori.adventure.nbt.TagStringIO; import net.kyori.adventure.nbt.api.BinaryTagHolder; import net.kyori.adventure.text.event.ClickEvent; -import net.kyori.adventure.util.Codec; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -45,13 +43,11 @@ import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_PAYLOAD; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_URL; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_VALUE; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.SNBT_CODEC; import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getRequiredTag; final class ClickEventSerializer { - private static final TagStringIO SNBT_IO = TagStringIO.tagStringIO(); - private static final Codec SNBT_CODEC = Codec.codec(SNBT_IO::asTag, SNBT_IO::asString); - private ClickEventSerializer() { } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java index 4d7be805cc..f97dfd7f45 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -24,7 +24,6 @@ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.nbt.BinaryTag; -import net.kyori.adventure.nbt.BinaryTagTypes; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.HoverEvent; @@ -56,9 +55,9 @@ private HoverEventSerializer() { return HoverEvent.showText(serializer.deserialize(textTag)); } else if (action == HoverEvent.Action.SHOW_ITEM) { BinaryTag contentsTag = snakeCase ? compound : getRequiredTag(compound, HOVER_EVENT_CONTENTS); - return HoverEvent.showItem(ShowItemSerializer.deserialize(contentsTag, snakeCase)); + return HoverEvent.showItem(ShowItemSerializer.deserialize(contentsTag, snakeCase, serializer)); } else if (action == HoverEvent.Action.SHOW_ENTITY) { - CompoundBinaryTag contentsTag = snakeCase ? compound : getRequiredTag(compound, HOVER_EVENT_CONTENTS, BinaryTagTypes.COMPOUND); + BinaryTag contentsTag = snakeCase ? compound : getRequiredTag(compound, HOVER_EVENT_CONTENTS); return HoverEvent.showEntity(ShowEntitySerializer.deserialize(contentsTag, snakeCase, serializer)); } else { throw new IllegalArgumentException("Don't know how to deserialize a hoverEvent with action of " + actionString + " from a binary tag"); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java index d45ad1a5f2..bfc4fca50d 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java @@ -28,11 +28,18 @@ import net.kyori.adventure.nbt.ByteBinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.NumberBinaryTag; +import net.kyori.adventure.nbt.TagStringIO; +import net.kyori.adventure.util.Codec; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.IOException; + final class NBTSerializerUtils { + static final TagStringIO SNBT_IO = TagStringIO.tagStringIO(); + static final Codec SNBT_CODEC = Codec.codec(SNBT_IO::asTag, SNBT_IO::asString); + private NBTSerializerUtils() { } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java index 8737588ff1..97c04c7cff 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java @@ -28,33 +28,35 @@ import net.kyori.adventure.nbt.BinaryTagTypes; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.event.HoverEvent; import org.jetbrains.annotations.NotNull; +import java.io.IOException; import java.util.UUID; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ENTITY_ID; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ENTITY_NAME; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ENTITY_TYPE; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ENTITY_UUID; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.SNBT_IO; import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getRequiredTag; final class ShowEntitySerializer { private ShowEntitySerializer() { } - - static HoverEvent.@NotNull ShowEntity deserialize(@NotNull CompoundBinaryTag compound, boolean snakeCase, - @NotNull NBTComponentSerializerImpl serializer) { - Key entityType = Key.key(getRequiredTag(compound, snakeCase ? SHOW_ENTITY_ID : SHOW_ENTITY_TYPE, BinaryTagTypes.STRING).value()); - BinaryTag entityIdTag = getRequiredTag(compound, snakeCase ? SHOW_ENTITY_UUID : SHOW_ENTITY_ID); - BinaryTag entityNameTag = compound.get(SHOW_ENTITY_NAME); - UUID entityId = UUIDSerializer.deserialize(entityIdTag); - if (entityNameTag == null) { - return HoverEvent.ShowEntity.showEntity(entityType, entityId); - } else { - return HoverEvent.ShowEntity.showEntity(entityType, entityId, serializer.deserialize(entityNameTag)); + static HoverEvent.@NotNull ShowEntity deserialize(@NotNull BinaryTag tag, boolean snakeCase, + @NotNull NBTComponentSerializerImpl serializer) { + try { + return deserializeModern((CompoundBinaryTag) tag, snakeCase, serializer); + } catch (Exception exception) { + if (snakeCase) { + throw notSureHowToDeserialize(tag); + } else { + return deserializeLegacy(tag, serializer); + } } } @@ -71,4 +73,37 @@ private ShowEntitySerializer() { return builder.build(); } + + private static HoverEvent.@NotNull ShowEntity deserializeModern(@NotNull CompoundBinaryTag compound, boolean snakeCase, + @NotNull NBTComponentSerializerImpl serializer) { + Key entityType = Key.key(getRequiredTag(compound, snakeCase ? SHOW_ENTITY_ID : SHOW_ENTITY_TYPE, BinaryTagTypes.STRING).value()); + BinaryTag entityIdTag = getRequiredTag(compound, snakeCase ? SHOW_ENTITY_UUID : SHOW_ENTITY_ID); + BinaryTag entityNameTag = compound.get(SHOW_ENTITY_NAME); + + UUID entityId = UUIDSerializer.deserialize(entityIdTag); + if (entityNameTag == null) { + return HoverEvent.ShowEntity.showEntity(entityType, entityId); + } else { + return HoverEvent.ShowEntity.showEntity(entityType, entityId, serializer.deserialize(entityNameTag)); + } + } + + private static HoverEvent.@NotNull ShowEntity deserializeLegacy(@NotNull BinaryTag tag, @NotNull NBTComponentSerializerImpl serializer) { + try { + Component component = serializer.deserialize(tag); + if (!(component instanceof TextComponent)) { + throw notSureHowToDeserialize(tag); + } + + String content = ((TextComponent) component).content(); + CompoundBinaryTag compound = SNBT_IO.asCompound(content); + return deserializeModern(compound, false, serializer); + } catch (IOException exception) { + throw notSureHowToDeserialize(tag); + } + } + + private static @NotNull IllegalArgumentException notSureHowToDeserialize(@NotNull BinaryTag tag) { + return new IllegalArgumentException("Don't know how to turn " + tag + " into a show entity hover event data"); + } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java index bf5334d649..99bca7a637 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java @@ -31,10 +31,13 @@ import net.kyori.adventure.nbt.IntBinaryTag; import net.kyori.adventure.nbt.StringBinaryTag; import net.kyori.adventure.nbt.api.BinaryTagHolder; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.event.DataComponentValue; import net.kyori.adventure.text.event.HoverEvent; import org.jetbrains.annotations.NotNull; +import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -42,18 +45,72 @@ import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ITEM_COUNT; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ITEM_ID; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ITEM_TAG; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.SNBT_CODEC; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.SNBT_IO; import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getOptionalTag; import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getRequiredTag; final class ShowItemSerializer { private static final String DATA_COMPONENT_REMOVAL_PREFIX = "!"; + private static final String LEGACY_ITEM_COUNT = "Count"; + private static final int DEFAULT_ITEM_QUANTITY = 1; private ShowItemSerializer() { } - static HoverEvent.@NotNull ShowItem deserialize(@NotNull BinaryTag tag, boolean snakeCase) { + static HoverEvent.@NotNull ShowItem deserialize(@NotNull BinaryTag tag, boolean snakeCase, + @NotNull NBTComponentSerializerImpl serializer) { + try { + return deserializeModern(tag, snakeCase); + } catch (Exception exception) { + if (snakeCase) { + throw notSureHowToDeserialize(tag); + } else { + return deserializeLegacy(tag, serializer); + } + } + } + + static @NotNull CompoundBinaryTag serialize(HoverEvent.@NotNull ShowItem showItem, boolean snakeCase, + @NotNull NBTComponentSerializerImpl serializer) { + CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() + .putString(SHOW_ITEM_ID, showItem.item().asString()); + + int count = showItem.count(); + if (count != DEFAULT_ITEM_QUANTITY || serializer.options().value(NBTSerializerOptions.EMIT_DEFAULT_ITEM_HOVER_QUANTITY)) { + builder.putInt(SHOW_ITEM_COUNT, count); + } + + NBTSerializerOptions.ShowItemHoverDataMode dataMode = serializer.options().value(NBTSerializerOptions.SHOW_ITEM_HOVER_DATA_MODE); + if ((snakeCase || dataMode != NBTSerializerOptions.ShowItemHoverDataMode.EMIT_LEGACY_NBT) && !showItem.dataComponents().isEmpty()) { + CompoundBinaryTag.Builder componentsTagBuilder = CompoundBinaryTag.builder(); + + Map components = showItem.dataComponentsAs(NBTDataComponentValue.class); + for (Map.Entry entry : components.entrySet()) { + String key = entry.getKey().asString(); + BinaryTag value = entry.getValue().binaryTag(); + + if (value instanceof EndBinaryTag) { // removed + key = DATA_COMPONENT_REMOVAL_PREFIX + key; + } + + componentsTagBuilder.put(key, value); + } + + builder.put(SHOW_ITEM_COMPONENTS, componentsTagBuilder.build()); + } else if (!snakeCase && dataMode != NBTSerializerOptions.ShowItemHoverDataMode.EMIT_DATA_COMPONENTS) { + BinaryTagHolder nbt = showItem.nbt(); + if (nbt != null) { + builder.putString(SHOW_ITEM_TAG, nbt.string()); + } + } + + return builder.build(); + } + + private static HoverEvent.@NotNull ShowItem deserializeModern(@NotNull BinaryTag tag, boolean snakeCase) { if (tag instanceof StringBinaryTag && !snakeCase) { StringBinaryTag castTag = (StringBinaryTag) tag; return HoverEvent.ShowItem.showItem(Key.key(castTag.value()), DEFAULT_ITEM_QUANTITY); @@ -99,40 +156,31 @@ private ShowItemSerializer() { } } - static @NotNull CompoundBinaryTag serialize(HoverEvent.@NotNull ShowItem showItem, boolean snakeCase, - @NotNull NBTComponentSerializerImpl serializer) { - CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() - .putString(SHOW_ITEM_ID, showItem.item().asString()); - - int count = showItem.count(); - if (count != DEFAULT_ITEM_QUANTITY || serializer.options().value(NBTSerializerOptions.EMIT_DEFAULT_ITEM_HOVER_QUANTITY)) { - builder.putInt(SHOW_ITEM_COUNT, count); - } - - NBTSerializerOptions.ShowItemHoverDataMode dataMode = serializer.options().value(NBTSerializerOptions.SHOW_ITEM_HOVER_DATA_MODE); - if ((snakeCase || dataMode != NBTSerializerOptions.ShowItemHoverDataMode.EMIT_LEGACY_NBT) && !showItem.dataComponents().isEmpty()) { - CompoundBinaryTag.Builder componentsTagBuilder = CompoundBinaryTag.builder(); - - Map components = showItem.dataComponentsAs(NBTDataComponentValue.class); - for (Map.Entry entry : components.entrySet()) { - String key = entry.getKey().asString(); - BinaryTag value = entry.getValue().binaryTag(); + private static HoverEvent.@NotNull ShowItem deserializeLegacy(@NotNull BinaryTag tag, @NotNull NBTComponentSerializerImpl serializer) { + try { + Component component = serializer.deserialize(tag); + if (!(component instanceof TextComponent)) { + throw notSureHowToDeserialize(tag); + } - if (value instanceof EndBinaryTag) { // removed - key = DATA_COMPONENT_REMOVAL_PREFIX + key; - } + String content = ((TextComponent) component).content(); + CompoundBinaryTag compound = SNBT_IO.asCompound(content); - componentsTagBuilder.put(key, value); - } + Key key = Key.key(getRequiredTag(compound, SHOW_ITEM_ID, BinaryTagTypes.STRING).value()); + byte count = getRequiredTag(compound, LEGACY_ITEM_COUNT, BinaryTagTypes.BYTE).value(); - builder.put(SHOW_ITEM_COMPONENTS, componentsTagBuilder.build()); - } else if (!snakeCase && dataMode != NBTSerializerOptions.ShowItemHoverDataMode.EMIT_DATA_COMPONENTS) { - BinaryTagHolder nbt = showItem.nbt(); - if (nbt != null) { - builder.putString(SHOW_ITEM_TAG, nbt.string()); + CompoundBinaryTag nbtTag = getOptionalTag(compound, SHOW_ITEM_TAG, BinaryTagTypes.COMPOUND); + if (nbtTag == null) { + return HoverEvent.ShowItem.showItem(key, count); + } else { + return HoverEvent.ShowItem.showItem(key, count, BinaryTagHolder.encode(nbtTag, SNBT_CODEC)); } + } catch (IOException exception) { + throw notSureHowToDeserialize(tag); } + } - return builder.build(); + private static @NotNull IllegalArgumentException notSureHowToDeserialize(@NotNull BinaryTag tag) { + return new IllegalArgumentException("Don't know how to turn " + tag + " into a show item hover event data"); } } diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowEntityTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowEntityTest.java index fd169a5634..c951fc411b 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowEntityTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowEntityTest.java @@ -33,10 +33,15 @@ import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; import org.junit.jupiter.api.Test; +import java.io.IOException; import java.util.UUID; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.SNBT_IO; +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.deserializeStyle; import static net.kyori.adventure.text.serializer.nbt.SerializerTests.name; +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.serializeComponent; import static net.kyori.adventure.text.serializer.nbt.SerializerTests.testStyle; +import static org.junit.jupiter.api.Assertions.assertEquals; final class ShowEntityTest { @Test @@ -99,4 +104,67 @@ void testWithName() { .build() ); } + + @Test + void testLegacyWithoutName() throws IOException { + String entityType = "minecraft:blaze"; + UUID uuid = UUID.randomUUID(); + + CompoundBinaryTag contentsTag = CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.SHOW_ENTITY_TYPE, entityType) + .putString(ComponentTreeConstants.SHOW_ENTITY_ID, uuid.toString()) + .build(); + + assertEquals( + Style.style() + .hoverEvent(HoverEvent.showEntity(Key.key(entityType), uuid)) + .build(), + deserializeStyle( + CompoundBinaryTag.builder() + .put( + ComponentTreeConstants.HOVER_EVENT_CAMEL, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, name(HoverEvent.Action.SHOW_ENTITY)) + .put( + ComponentTreeConstants.HOVER_EVENT_CONTENTS, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.TEXT, SNBT_IO.asString(contentsTag)) + .build() + ) + .build() + ) + .build() + ) + ); + } + + @Test + void testLegacyWithName() throws IOException { + String entityType = "minecraft:chicken"; + UUID uuid = UUID.fromString("a8aa3054-ca11-41bd-ac7e-95967816a135"); + Component entityName = Component.text("Lava chicken", NamedTextColor.DARK_RED); + + CompoundBinaryTag contentsTag = CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.SHOW_ENTITY_TYPE, entityType) + .putString(ComponentTreeConstants.SHOW_ENTITY_ID, uuid.toString()) + .put(ComponentTreeConstants.SHOW_ENTITY_NAME, serializeComponent(entityName)) + .build(); + + assertEquals( + Style.style() + .hoverEvent(HoverEvent.showEntity(Key.key(entityType), uuid, entityName)) + .build(), + deserializeStyle( + CompoundBinaryTag.builder() + .put( + ComponentTreeConstants.HOVER_EVENT_CAMEL, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, name(HoverEvent.Action.SHOW_ENTITY)) + .putString(ComponentTreeConstants.HOVER_EVENT_CONTENTS, SNBT_IO.asString(contentsTag)) + .build() + ) + .build() + ) + ); + } } diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowItemTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowItemTest.java index 49da81f5d1..3a932e9bea 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowItemTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowItemTest.java @@ -26,7 +26,6 @@ import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.EndBinaryTag; -import net.kyori.adventure.nbt.StringBinaryTag; import net.kyori.adventure.nbt.TagStringIO; import net.kyori.adventure.nbt.api.BinaryTagHolder; import net.kyori.adventure.text.event.DataComponentValue; @@ -38,10 +37,17 @@ import java.io.IOException; import java.util.Collections; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.SNBT_CODEC; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.SNBT_IO; +import static net.kyori.adventure.text.serializer.nbt.SerializerTests.deserializeStyle; import static net.kyori.adventure.text.serializer.nbt.SerializerTests.name; import static net.kyori.adventure.text.serializer.nbt.SerializerTests.testStyle; +import static org.junit.jupiter.api.Assertions.assertEquals; final class ShowItemTest { + + private static final String LEGACY_COUNT = "Count"; + @Test void testWithPopulatedTag() throws IOException { String item = "minecraft:diamond"; @@ -66,7 +72,7 @@ void testWithPopulatedTag() throws IOException { BinaryTagHolder.binaryTagHolder(TagStringIO.tagStringIO().asString( CompoundBinaryTag.builder() .put("display", CompoundBinaryTag.builder() - .put("Name", StringBinaryTag.stringBinaryTag("A test!")) + .putString("Name", "A test!") .build()) .build() )) @@ -168,4 +174,75 @@ void testWithRemovedComponent() { .build() ); } + + @Test + void testLegacyWithoutTag() throws IOException { + String item = "minecraft:diamond"; + byte count = 3; + + CompoundBinaryTag itemData = CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.SHOW_ITEM_ID, item) + .putByte(LEGACY_COUNT, count) + .build(); + + assertEquals( + Style.style() + .hoverEvent(HoverEvent.showItem(Key.key(item), count)) + .build(), + deserializeStyle( + CompoundBinaryTag.builder() + .put( + ComponentTreeConstants.HOVER_EVENT_CAMEL, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, name(HoverEvent.Action.SHOW_ITEM)) + .putString(ComponentTreeConstants.HOVER_EVENT_CONTENTS, SNBT_IO.asString(itemData)) + .build() + ) + .build() + ) + ); + } + + @Test + void testLegacyWithTag() throws IOException { + String item = "minecraft:diamond"; + byte count = 1; + + CompoundBinaryTag itemTag = CompoundBinaryTag.builder() + .put( + "display", + CompoundBinaryTag.builder() + .putString("Name", "Legacy test!") + .build() + ) + .build(); + + CompoundBinaryTag itemData = CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.SHOW_ITEM_ID, item) + .putByte(LEGACY_COUNT, count) + .put(ComponentTreeConstants.SHOW_ITEM_TAG, itemTag) + .build(); + + assertEquals( + Style.style() + .hoverEvent(HoverEvent.showItem(Key.key(item), count, BinaryTagHolder.encode(itemTag, SNBT_CODEC))) + .build(), + deserializeStyle( + CompoundBinaryTag.builder() + .put( + ComponentTreeConstants.HOVER_EVENT_CAMEL, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.HOVER_EVENT_ACTION, name(HoverEvent.Action.SHOW_ITEM)) + .put( + ComponentTreeConstants.HOVER_EVENT_CONTENTS, + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.TEXT, SNBT_IO.asString(itemData)) + .build() + ) + .build() + ) + .build() + ) + ); + } } From 736b5d0c7fe8b2e875d7551d152754b0f92d3184 Mon Sep 17 00:00:00 2001 From: codestech Date: Mon, 30 Jun 2025 16:11:11 +0200 Subject: [PATCH 76/86] chore: replace Key serialization with KeySerializer --- .../serializer/nbt/ClickEventSerializer.java | 5 +-- .../text/serializer/nbt/KeySerializer.java | 41 +++++++++++++++++++ .../nbt/NBTComponentSerializerImpl.java | 5 +-- .../serializer/nbt/ShowEntitySerializer.java | 4 +- .../serializer/nbt/ShowItemSerializer.java | 8 ++-- .../text/serializer/nbt/StyleSerializer.java | 4 +- 6 files changed, 53 insertions(+), 14 deletions(-) create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/KeySerializer.java diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java index 11b37d36d3..bf41f043e4 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java @@ -23,7 +23,6 @@ */ package net.kyori.adventure.text.serializer.nbt; -import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.BinaryTagTypes; import net.kyori.adventure.nbt.CompoundBinaryTag; @@ -79,7 +78,7 @@ private ClickEventSerializer() { try { StringBinaryTag clickEventIdTag = getRequiredTag(compound, CLICK_EVENT_ID, BinaryTagTypes.STRING); BinaryTag payloadTag = getRequiredTag(compound, CLICK_EVENT_PAYLOAD); - return ClickEvent.custom(Key.key(clickEventIdTag.value()), BinaryTagHolder.encode(payloadTag, SNBT_CODEC)); + return ClickEvent.custom(KeySerializer.deserialize(clickEventIdTag), BinaryTagHolder.encode(payloadTag, SNBT_CODEC)); } catch (IOException exception) { throw new RuntimeException("An error occurred while encoding payload tag", exception); } @@ -125,7 +124,7 @@ private ClickEventSerializer() { } else if (payload instanceof ClickEvent.Payload.Custom) { try { ClickEvent.Payload.Custom castPayload = (ClickEvent.Payload.Custom) payload; - builder.putString(CLICK_EVENT_ID, castPayload.key().asString()); + builder.put(CLICK_EVENT_ID, KeySerializer.serialize(castPayload.key())); builder.put(CLICK_EVENT_PAYLOAD, castPayload.nbt().get(SNBT_CODEC)); } catch (IOException exception) { throw new RuntimeException("An error occurred while decoding a payload tag", exception); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/KeySerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/KeySerializer.java new file mode 100644 index 0000000000..ed9b7588c8 --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/KeySerializer.java @@ -0,0 +1,41 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.StringBinaryTag; +import org.jetbrains.annotations.NotNull; + +final class KeySerializer { + + private KeySerializer() {} + + static @NotNull Key deserialize(@NotNull StringBinaryTag tag) { + return Key.key(tag.value()); + } + + static @NotNull StringBinaryTag serialize(@NotNull Key key) { + return StringBinaryTag.stringBinaryTag(key.asString()); + } +} diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 0a607a07a5..64ac1a2b7b 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -23,7 +23,6 @@ */ package net.kyori.adventure.text.serializer.nbt; -import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.BinaryTagTypes; import net.kyori.adventure.nbt.ByteBinaryTag; @@ -227,7 +226,7 @@ static final class Instances { .nbtPath(nbtPath) .interpret(interpret) .separator(separator) - .storage(Key.key(storageTag.value())) + .storage(KeySerializer.deserialize(storageTag)) .style(style) .append(children) .build(); @@ -300,7 +299,7 @@ static final class Instances { } else if (nbt instanceof EntityNBTComponent) { builder.putString(NBT_ENTITY, ((EntityNBTComponent) nbt).selector()); } else if (nbt instanceof StorageNBTComponent) { - builder.putString(NBT_STORAGE, ((StorageNBTComponent) nbt).storage().asString()); + builder.put(NBT_STORAGE, KeySerializer.serialize(((StorageNBTComponent) nbt).storage())); } else { throw notSureHowToSerialize(component); } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java index 97c04c7cff..c55dcb62c2 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java @@ -63,7 +63,7 @@ private ShowEntitySerializer() { static @NotNull CompoundBinaryTag serialize(HoverEvent.@NotNull ShowEntity showEntity, boolean snakeCase, @NotNull NBTComponentSerializerImpl serializer) { CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() - .putString(snakeCase ? SHOW_ENTITY_ID : SHOW_ENTITY_TYPE, showEntity.type().asString()) + .put(snakeCase ? SHOW_ENTITY_ID : SHOW_ENTITY_TYPE, KeySerializer.serialize(showEntity.type())) .put(snakeCase ? SHOW_ENTITY_UUID : SHOW_ENTITY_ID, UUIDSerializer.serialize(showEntity.id())); Component entityName = showEntity.name(); @@ -76,7 +76,7 @@ private ShowEntitySerializer() { private static HoverEvent.@NotNull ShowEntity deserializeModern(@NotNull CompoundBinaryTag compound, boolean snakeCase, @NotNull NBTComponentSerializerImpl serializer) { - Key entityType = Key.key(getRequiredTag(compound, snakeCase ? SHOW_ENTITY_ID : SHOW_ENTITY_TYPE, BinaryTagTypes.STRING).value()); + Key entityType = KeySerializer.deserialize(getRequiredTag(compound, snakeCase ? SHOW_ENTITY_ID : SHOW_ENTITY_TYPE, BinaryTagTypes.STRING)); BinaryTag entityIdTag = getRequiredTag(compound, snakeCase ? SHOW_ENTITY_UUID : SHOW_ENTITY_ID); BinaryTag entityNameTag = compound.get(SHOW_ENTITY_NAME); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java index 99bca7a637..d9fa4d31ac 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java @@ -76,7 +76,7 @@ private ShowItemSerializer() { static @NotNull CompoundBinaryTag serialize(HoverEvent.@NotNull ShowItem showItem, boolean snakeCase, @NotNull NBTComponentSerializerImpl serializer) { CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() - .putString(SHOW_ITEM_ID, showItem.item().asString()); + .put(SHOW_ITEM_ID, KeySerializer.serialize(showItem.item())); int count = showItem.count(); if (count != DEFAULT_ITEM_QUANTITY || serializer.options().value(NBTSerializerOptions.EMIT_DEFAULT_ITEM_HOVER_QUANTITY)) { @@ -113,7 +113,7 @@ private ShowItemSerializer() { private static HoverEvent.@NotNull ShowItem deserializeModern(@NotNull BinaryTag tag, boolean snakeCase) { if (tag instanceof StringBinaryTag && !snakeCase) { StringBinaryTag castTag = (StringBinaryTag) tag; - return HoverEvent.ShowItem.showItem(Key.key(castTag.value()), DEFAULT_ITEM_QUANTITY); + return HoverEvent.ShowItem.showItem(KeySerializer.deserialize(castTag), DEFAULT_ITEM_QUANTITY); } else if (!(tag instanceof CompoundBinaryTag)) { if (snakeCase) { throw new IllegalArgumentException("The specified binary tag isn't a compound tag"); @@ -124,7 +124,7 @@ private ShowItemSerializer() { CompoundBinaryTag compound = (CompoundBinaryTag) tag; - Key itemId = Key.key(getRequiredTag(compound, SHOW_ITEM_ID, BinaryTagTypes.STRING).value()); + Key itemId = KeySerializer.deserialize(getRequiredTag(compound, SHOW_ITEM_ID, BinaryTagTypes.STRING)); IntBinaryTag countTag = getOptionalTag(compound, SHOW_ITEM_COUNT, BinaryTagTypes.INT); int itemCount = countTag == null ? DEFAULT_ITEM_QUANTITY : countTag.value(); @@ -166,7 +166,7 @@ private ShowItemSerializer() { String content = ((TextComponent) component).content(); CompoundBinaryTag compound = SNBT_IO.asCompound(content); - Key key = Key.key(getRequiredTag(compound, SHOW_ITEM_ID, BinaryTagTypes.STRING).value()); + Key key = KeySerializer.deserialize(getRequiredTag(compound, SHOW_ITEM_ID, BinaryTagTypes.STRING)); byte count = getRequiredTag(compound, LEGACY_ITEM_COUNT, BinaryTagTypes.BYTE).value(); CompoundBinaryTag nbtTag = getOptionalTag(compound, SHOW_ITEM_TAG, BinaryTagTypes.COMPOUND); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java index b1c9b623cb..6808bcbe24 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java @@ -70,7 +70,7 @@ private StyleSerializer() { StringBinaryTag fontTag = getOptionalTag(compound, FONT, BinaryTagTypes.STRING); if (fontTag != null) { - styleBuilder.font(Key.key(fontTag.value())); + styleBuilder.font(KeySerializer.deserialize(fontTag)); } StringBinaryTag insertionTag = getOptionalTag(compound, INSERTION, BinaryTagTypes.STRING); @@ -132,7 +132,7 @@ static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder b Key font = style.font(); if (font != null) { - builder.putString(FONT, font.asString()); + builder.put(FONT, KeySerializer.serialize(font)); } String insertion = style.insertion(); From 1b335f209c330b318f76c567a85fbd8ae8bfffc9 Mon Sep 17 00:00:00 2001 From: codestech Date: Tue, 1 Jul 2025 03:43:13 +0200 Subject: [PATCH 77/86] chore: resolve TODOs --- .../commons/ComponentTreeConstants.java | 2 ++ .../serializer/nbt/HoverEventSerializer.java | 22 +++++++++++++--- .../serializer/nbt/NBTSerializerOptions.java | 25 +++++++++++++++++-- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/text-serializer-commons/src/main/java/net/kyori/adventure/text/serializer/commons/ComponentTreeConstants.java b/text-serializer-commons/src/main/java/net/kyori/adventure/text/serializer/commons/ComponentTreeConstants.java index fb1fb9fc54..b880568bee 100644 --- a/text-serializer-commons/src/main/java/net/kyori/adventure/text/serializer/commons/ComponentTreeConstants.java +++ b/text-serializer-commons/src/main/java/net/kyori/adventure/text/serializer/commons/ComponentTreeConstants.java @@ -71,6 +71,8 @@ public final class ComponentTreeConstants { @Deprecated public static final String HOVER_EVENT_VALUE = "value"; @Deprecated + public static final String SHOW_TEXT_TEXT = "text"; + @Deprecated public static final String SHOW_ENTITY_TYPE = "type"; public static final String SHOW_ENTITY_ID = "id"; public static final String SHOW_ENTITY_UUID = "uuid"; diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java index f97dfd7f45..8211f1b2d0 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -33,6 +33,7 @@ import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.HOVER_EVENT_ACTION; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.HOVER_EVENT_CONTENTS; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.HOVER_EVENT_VALUE; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_TEXT_TEXT; import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getRequiredTag; final class HoverEventSerializer { @@ -50,8 +51,21 @@ private HoverEventSerializer() { } if (action == HoverEvent.Action.SHOW_TEXT) { - // TODO: According to the MCW, pre-25w03a and post-25w03a use different fields for this, we need to take a look into that - BinaryTag textTag = getRequiredTag(compound, snakeCase ? HOVER_EVENT_VALUE : HOVER_EVENT_CONTENTS); + BinaryTag textTag; + + if (snakeCase) { + textTag = compound.get(HOVER_EVENT_VALUE); + if (textTag == null) { + textTag = compound.get(SHOW_TEXT_TEXT); + } + + if (textTag == null) { + throw new IllegalStateException("Could not find a field containing text of the show_text hover event"); + } + } else { + textTag = getRequiredTag(compound, HOVER_EVENT_CONTENTS); + } + return HoverEvent.showText(serializer.deserialize(textTag)); } else if (action == HoverEvent.Action.SHOW_ITEM) { BinaryTag contentsTag = snakeCase ? compound : getRequiredTag(compound, HOVER_EVENT_CONTENTS); @@ -75,9 +89,9 @@ private HoverEventSerializer() { if (action == HoverEvent.Action.SHOW_TEXT) { BinaryTag serializedComponent = serializer.serialize((Component) event.value()); if (snakeCase) { - // TODO: According to the MCW, pre-25w03a and post-25w03a use different fields for this, we need to take a look into that + String textFieldName = serializer.options().value(NBTSerializerOptions.EMIT_SHOW_TEXT_HOVER_TEXT_FIELD) ? SHOW_TEXT_TEXT : HOVER_EVENT_VALUE; contentsTag = CompoundBinaryTag.builder() - .put(HOVER_EVENT_VALUE, serializedComponent) + .put(textFieldName, serializedComponent) .build(); } else { contentsTag = serializedComponent; diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index c2ec2ab3b9..4cd75b527a 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -61,11 +61,11 @@ public final class NBTSerializerOptions { /** * Whether to emit the default hover event item stack quantity of {@code 1}. * - *

When enabled, this matches Vanilla as of 1.21.6.

+ *

When enabled, this matches Vanilla as of 1.20.5.

* * @since 4.24.0 */ - public static final Option EMIT_DEFAULT_ITEM_HOVER_QUANTITY; // TODO: Find out in which version it was added and add it to the option state + public static final Option EMIT_DEFAULT_ITEM_HOVER_QUANTITY; /** * How to emit show item hovers in {@code hoverEvent} (camelCase) fields. @@ -74,13 +74,23 @@ public final class NBTSerializerOptions { */ public static final Option SHOW_ITEM_HOVER_DATA_MODE; + /** + * Whether to emit {@code text} field instead of {@code value} field in {@code show_item} + * hover events specified in {@code hover_event} (snake_case) fields. + * + * @since 4.24.0 + */ + public static final Option EMIT_SHOW_TEXT_HOVER_TEXT_FIELD; + private static final OptionSchema SCHEMA; private static final OptionState.Versioned BY_DATA_VERSION; private static final int VERSION_23W40A = 3679; private static final int VERSION_24W09A = 3819; + private static final int VERSION_24W10A = 3821; private static final int VERSION_24W44A = 4174; private static final int VERSION_25W02A = 4298; + private static final int VERSION_25W03A = 4304; static { OptionSchema.Mutable schema = OptionSchema.emptySchema(); @@ -89,6 +99,7 @@ public final class NBTSerializerOptions { EMIT_CLICK_EVENT_TYPE = schema.enumOption(key("emit/click_value_mode"), ClickEventValueMode.class, ClickEventValueMode.SNAKE_CASE); EMIT_DEFAULT_ITEM_HOVER_QUANTITY = schema.booleanOption(key("emit/default_item_hover_quantity"), true); SHOW_ITEM_HOVER_DATA_MODE = schema.enumOption(key("emit/show_item_hover_data"), ShowItemHoverDataMode.class, ShowItemHoverDataMode.EMIT_EITHER); + EMIT_SHOW_TEXT_HOVER_TEXT_FIELD = schema.booleanOption(key("emit/show_text_hover_text_field"), false); SCHEMA = schema.frozenView(); BY_DATA_VERSION = SCHEMA.versionedStateBuilder() @@ -99,11 +110,16 @@ public final class NBTSerializerOptions { .value(EMIT_CLICK_EVENT_TYPE, ClickEventValueMode.CAMEL_CASE) .value(EMIT_DEFAULT_ITEM_HOVER_QUANTITY, false) .value(SHOW_ITEM_HOVER_DATA_MODE, ShowItemHoverDataMode.EMIT_LEGACY_NBT) + .value(EMIT_SHOW_TEXT_HOVER_TEXT_FIELD, false) ) .version( VERSION_24W09A, builder -> builder.value(SHOW_ITEM_HOVER_DATA_MODE, ShowItemHoverDataMode.EMIT_DATA_COMPONENTS) ) + .version( + VERSION_24W10A, + builder -> builder.value(EMIT_DEFAULT_ITEM_HOVER_QUANTITY, true) + ) .version( VERSION_24W44A, builder -> builder.value(SHADOW_COLOR_MODE, ShadowColorEmitMode.EMIT_ARRAY) @@ -112,6 +128,11 @@ public final class NBTSerializerOptions { VERSION_25W02A, builder -> builder.value(EMIT_HOVER_EVENT_TYPE, HoverEventValueMode.SNAKE_CASE) .value(EMIT_CLICK_EVENT_TYPE, ClickEventValueMode.SNAKE_CASE) + .value(EMIT_SHOW_TEXT_HOVER_TEXT_FIELD, true) + ) + .version( + VERSION_25W03A, + builder -> builder.value(EMIT_SHOW_TEXT_HOVER_TEXT_FIELD, false) ) .build(); } From e4cee93d63cabad1aba82b3e9132a9cef95c5686 Mon Sep 17 00:00:00 2001 From: codestech Date: Tue, 1 Jul 2025 04:02:59 +0200 Subject: [PATCH 78/86] chore: cleanup --- .../nbt/NBTComponentSerializer.java | 1 + .../serializer/nbt/NBTDataComponentValue.java | 1 + .../serializer/nbt/NBTSerializerOptions.java | 15 +++++----- .../serializer/nbt/impl/package-info.java | 26 ++++++++++++++++ .../text/serializer/nbt/package-info.java | 30 +++++++++++++++++++ 5 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/package-info.java diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java index c8a5a0f4b3..b7c1f7159b 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java @@ -40,6 +40,7 @@ * A NBT component serializer. * * @since 4.24.0 + * @sinceMinecraft 1.20.3 */ public interface NBTComponentSerializer extends ComponentSerializer { /** diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java index f56167712c..2b9398cf1d 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java @@ -37,6 +37,7 @@ *

This holder is exposed to allow conversions to/from NBT data holders.

* * @since 4.24.0 + * @sinceMinecraft 1.20.3 */ @ApiStatus.NonExtendable public interface NBTDataComponentValue extends DataComponentValue { diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index 4cd75b527a..3ce12dfc36 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -29,11 +29,12 @@ import org.jetbrains.annotations.NotNull; /** - * Options that can apply to {@linkplain NBTComponentSerializer NBT serializers}. + * Options that can apply to {@linkplain NBTComponentSerializer NBT component serializers}. * *

See serializer documentation for specific details on which flags are supported.

* * @since 4.24.0 + * @sinceMinecraft 1.20.3 */ public final class NBTSerializerOptions { @@ -85,12 +86,12 @@ public final class NBTSerializerOptions { private static final OptionSchema SCHEMA; private static final OptionState.Versioned BY_DATA_VERSION; - private static final int VERSION_23W40A = 3679; - private static final int VERSION_24W09A = 3819; - private static final int VERSION_24W10A = 3821; - private static final int VERSION_24W44A = 4174; - private static final int VERSION_25W02A = 4298; - private static final int VERSION_25W03A = 4304; + private static final int VERSION_23W40A = 3679; // 1.20.3 snapshot, initial version with NBT component serialization + private static final int VERSION_24W09A = 3819; // 1.20.5 snapshot + private static final int VERSION_24W10A = 3821; // 1.20.5 snapshot + private static final int VERSION_24W44A = 4174; // 1.21.4 snapshot + private static final int VERSION_25W02A = 4298; // 1.21.5 snapshot + private static final int VERSION_25W03A = 4304; // 1.21.5 snapshot static { OptionSchema.Mutable schema = OptionSchema.emptySchema(); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/package-info.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/package-info.java index 66e56bba3b..d29533dafb 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/package-info.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/package-info.java @@ -1,5 +1,31 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ /** * Internal classes for the NBT component serializer. + * + * @since 4.24.0 + * @sinceMinecraft 1.20.3 */ @ApiStatus.Internal package net.kyori.adventure.text.serializer.nbt.impl; diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/package-info.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/package-info.java new file mode 100644 index 0000000000..75a191b4e0 --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/package-info.java @@ -0,0 +1,30 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +/** + * NBT-based component serialization and deserialization. + * + * @since 4.24.0 + * @sinceMinecraft 1.20.3 + */ +package net.kyori.adventure.text.serializer.nbt; From 1ef87f0dd7229bd192a7c30491b77afd5e72c701 Mon Sep 17 00:00:00 2001 From: codestech Date: Tue, 1 Jul 2025 10:12:25 +0200 Subject: [PATCH 79/86] chore: fix style of the main module --- .../serializer/nbt/ClickEventSerializer.java | 43 ++++--- .../serializer/nbt/HoverEventSerializer.java | 32 +++--- .../text/serializer/nbt/KeySerializer.java | 7 +- .../nbt/NBTComponentSerializer.java | 7 +- .../nbt/NBTComponentSerializerImpl.java | 107 +++++++++--------- .../nbt/NBTDataComponentValueImpl.java | 9 +- .../serializer/nbt/NBTSerializerOptions.java | 2 +- .../serializer/nbt/NBTSerializerUtils.java | 27 +++-- .../serializer/nbt/ShadowColorSerializer.java | 24 ++-- .../serializer/nbt/ShowEntitySerializer.java | 45 ++++---- .../serializer/nbt/ShowItemSerializer.java | 88 +++++++------- .../text/serializer/nbt/StyleSerializer.java | 78 ++++++------- .../serializer/nbt/TextColorSerializer.java | 13 +-- .../nbt/TranslationArgumentSerializer.java | 6 +- .../text/serializer/nbt/UUIDSerializer.java | 27 +++-- ...BTDataComponentValueConverterProvider.java | 3 +- 16 files changed, 253 insertions(+), 265 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java index bf41f043e4..36f05b6d0c 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ClickEventSerializer.java @@ -23,6 +23,7 @@ */ package net.kyori.adventure.text.serializer.nbt; +import java.io.IOException; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.BinaryTagTypes; import net.kyori.adventure.nbt.CompoundBinaryTag; @@ -33,8 +34,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.IOException; - import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_ACTION; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_COMMAND; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_ID; @@ -43,16 +42,16 @@ import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_URL; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.CLICK_EVENT_VALUE; import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.SNBT_CODEC; -import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getRequiredTag; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.requiredTag; final class ClickEventSerializer { private ClickEventSerializer() { } - static @Nullable ClickEvent deserialize(@NotNull CompoundBinaryTag compound, boolean snakeCase) { - StringBinaryTag actionTag = getRequiredTag(compound, CLICK_EVENT_ACTION, BinaryTagTypes.STRING); - ClickEvent.Action action = ClickEvent.Action.NAMES.valueOrThrow(actionTag.value()); + static @Nullable ClickEvent deserialize(final @NotNull CompoundBinaryTag compound, final boolean snakeCase) { + final StringBinaryTag actionTag = requiredTag(compound, CLICK_EVENT_ACTION, BinaryTagTypes.STRING); + final ClickEvent.Action action = ClickEvent.Action.NAMES.valueOrThrow(actionTag.value()); if (!action.readable()) { return null; @@ -61,25 +60,25 @@ private ClickEventSerializer() { if (snakeCase) { switch (action) { case OPEN_URL: - StringBinaryTag urlTag = getRequiredTag(compound, CLICK_EVENT_URL, BinaryTagTypes.STRING); + final StringBinaryTag urlTag = requiredTag(compound, CLICK_EVENT_URL, BinaryTagTypes.STRING); return ClickEvent.openUrl(urlTag.value()); case RUN_COMMAND: case SUGGEST_COMMAND: - StringBinaryTag commandTag = getRequiredTag(compound, CLICK_EVENT_COMMAND, BinaryTagTypes.STRING); - String command = commandTag.value(); + final StringBinaryTag commandTag = requiredTag(compound, CLICK_EVENT_COMMAND, BinaryTagTypes.STRING); + final String command = commandTag.value(); return action == ClickEvent.Action.RUN_COMMAND ? ClickEvent.runCommand(command) : ClickEvent.suggestCommand(command); case CHANGE_PAGE: - IntBinaryTag pageTag = getRequiredTag(compound, CLICK_EVENT_PAGE, BinaryTagTypes.INT); + final IntBinaryTag pageTag = requiredTag(compound, CLICK_EVENT_PAGE, BinaryTagTypes.INT); return ClickEvent.changePage(pageTag.value()); case COPY_TO_CLIPBOARD: - StringBinaryTag valueTag = getRequiredTag(compound, CLICK_EVENT_VALUE, BinaryTagTypes.STRING); + final StringBinaryTag valueTag = requiredTag(compound, CLICK_EVENT_VALUE, BinaryTagTypes.STRING); return ClickEvent.copyToClipboard(valueTag.value()); case CUSTOM: try { - StringBinaryTag clickEventIdTag = getRequiredTag(compound, CLICK_EVENT_ID, BinaryTagTypes.STRING); - BinaryTag payloadTag = getRequiredTag(compound, CLICK_EVENT_PAYLOAD); + final StringBinaryTag clickEventIdTag = requiredTag(compound, CLICK_EVENT_ID, BinaryTagTypes.STRING); + final BinaryTag payloadTag = requiredTag(compound, CLICK_EVENT_PAYLOAD); return ClickEvent.custom(KeySerializer.deserialize(clickEventIdTag), BinaryTagHolder.encode(payloadTag, SNBT_CODEC)); - } catch (IOException exception) { + } catch (final IOException exception) { throw new RuntimeException("An error occurred while encoding payload tag", exception); } default: @@ -87,24 +86,24 @@ private ClickEventSerializer() { throw new IllegalArgumentException("Unknown click event action: " + action); } } else { - StringBinaryTag valueTag = getRequiredTag(compound, CLICK_EVENT_VALUE, BinaryTagTypes.STRING); + final StringBinaryTag valueTag = requiredTag(compound, CLICK_EVENT_VALUE, BinaryTagTypes.STRING); return ClickEvent.clickEvent(action, valueTag.value()); } } - static @Nullable CompoundBinaryTag serialize(@NotNull ClickEvent event, boolean snakeCase) { - CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() + static @Nullable CompoundBinaryTag serialize(final @NotNull ClickEvent event, final boolean snakeCase) { + final CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() .putString(CLICK_EVENT_ACTION, ClickEvent.Action.NAMES.keyOrThrow(event.action())); if (snakeCase) { - ClickEvent.Action action = event.action(); + final ClickEvent.Action action = event.action(); if (!action.readable()) { return null; } - ClickEvent.Payload payload = event.payload(); + final ClickEvent.Payload payload = event.payload(); if (payload instanceof ClickEvent.Payload.Text) { - String payloadFieldName; + final String payloadFieldName; switch (action) { case OPEN_URL: payloadFieldName = CLICK_EVENT_URL; @@ -123,10 +122,10 @@ private ClickEventSerializer() { builder.putString(payloadFieldName, ((ClickEvent.Payload.Text) payload).value()); } else if (payload instanceof ClickEvent.Payload.Custom) { try { - ClickEvent.Payload.Custom castPayload = (ClickEvent.Payload.Custom) payload; + final ClickEvent.Payload.Custom castPayload = (ClickEvent.Payload.Custom) payload; builder.put(CLICK_EVENT_ID, KeySerializer.serialize(castPayload.key())); builder.put(CLICK_EVENT_PAYLOAD, castPayload.nbt().get(SNBT_CODEC)); - } catch (IOException exception) { + } catch (final IOException exception) { throw new RuntimeException("An error occurred while decoding a payload tag", exception); } } else if (payload instanceof ClickEvent.Payload.Int) { diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java index 8211f1b2d0..59f23b0fff 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/HoverEventSerializer.java @@ -34,17 +34,17 @@ import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.HOVER_EVENT_CONTENTS; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.HOVER_EVENT_VALUE; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_TEXT_TEXT; -import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getRequiredTag; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.requiredTag; final class HoverEventSerializer { private HoverEventSerializer() { } - static @Nullable HoverEvent deserialize(@NotNull CompoundBinaryTag compound, boolean snakeCase, - @NotNull NBTComponentSerializerImpl serializer) { - String actionString = compound.getString(HOVER_EVENT_ACTION); - HoverEvent.Action action = HoverEvent.Action.NAMES.valueOrThrow(actionString); + static @Nullable HoverEvent deserialize(final @NotNull CompoundBinaryTag compound, final boolean snakeCase, + final @NotNull NBTComponentSerializerImpl serializer) { + final String actionString = compound.getString(HOVER_EVENT_ACTION); + final HoverEvent.Action action = HoverEvent.Action.NAMES.valueOrThrow(actionString); if (!action.readable()) { return null; @@ -63,33 +63,33 @@ private HoverEventSerializer() { throw new IllegalStateException("Could not find a field containing text of the show_text hover event"); } } else { - textTag = getRequiredTag(compound, HOVER_EVENT_CONTENTS); + textTag = requiredTag(compound, HOVER_EVENT_CONTENTS); } return HoverEvent.showText(serializer.deserialize(textTag)); } else if (action == HoverEvent.Action.SHOW_ITEM) { - BinaryTag contentsTag = snakeCase ? compound : getRequiredTag(compound, HOVER_EVENT_CONTENTS); + final BinaryTag contentsTag = snakeCase ? compound : requiredTag(compound, HOVER_EVENT_CONTENTS); return HoverEvent.showItem(ShowItemSerializer.deserialize(contentsTag, snakeCase, serializer)); } else if (action == HoverEvent.Action.SHOW_ENTITY) { - BinaryTag contentsTag = snakeCase ? compound : getRequiredTag(compound, HOVER_EVENT_CONTENTS); + final BinaryTag contentsTag = snakeCase ? compound : requiredTag(compound, HOVER_EVENT_CONTENTS); return HoverEvent.showEntity(ShowEntitySerializer.deserialize(contentsTag, snakeCase, serializer)); } else { throw new IllegalArgumentException("Don't know how to deserialize a hoverEvent with action of " + actionString + " from a binary tag"); } } - static @Nullable CompoundBinaryTag serialize(@NotNull HoverEvent event, boolean snakeCase, - @NotNull NBTComponentSerializerImpl serializer) { - HoverEvent.Action action = event.action(); + static @Nullable CompoundBinaryTag serialize(final @NotNull HoverEvent event, final boolean snakeCase, + final @NotNull NBTComponentSerializerImpl serializer) { + final HoverEvent.Action action = event.action(); if (!action.readable()) { return null; } - BinaryTag contentsTag; + final BinaryTag contentsTag; if (action == HoverEvent.Action.SHOW_TEXT) { - BinaryTag serializedComponent = serializer.serialize((Component) event.value()); + final BinaryTag serializedComponent = serializer.serialize((Component) event.value()); if (snakeCase) { - String textFieldName = serializer.options().value(NBTSerializerOptions.EMIT_SHOW_TEXT_HOVER_TEXT_FIELD) ? SHOW_TEXT_TEXT : HOVER_EVENT_VALUE; + final String textFieldName = serializer.options().value(NBTSerializerOptions.EMIT_SHOW_TEXT_HOVER_TEXT_FIELD) ? SHOW_TEXT_TEXT : HOVER_EVENT_VALUE; contentsTag = CompoundBinaryTag.builder() .put(textFieldName, serializedComponent) .build(); @@ -104,11 +104,11 @@ private HoverEventSerializer() { throw new IllegalArgumentException("Don't know how to serialize " + event + " as a binary tag"); } - CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() + final CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() .putString(HOVER_EVENT_ACTION, HoverEvent.Action.NAMES.keyOrThrow(action)); if (snakeCase) { - CompoundBinaryTag castContentsTag = (CompoundBinaryTag) contentsTag; + final CompoundBinaryTag castContentsTag = (CompoundBinaryTag) contentsTag; castContentsTag.forEach(entry -> builder.put(entry.getKey(), entry.getValue())); } else { builder.put(HOVER_EVENT_CONTENTS, contentsTag); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/KeySerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/KeySerializer.java index ed9b7588c8..064d52cc5d 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/KeySerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/KeySerializer.java @@ -29,13 +29,14 @@ final class KeySerializer { - private KeySerializer() {} + private KeySerializer() { + } - static @NotNull Key deserialize(@NotNull StringBinaryTag tag) { + static @NotNull Key deserialize(final @NotNull StringBinaryTag tag) { return Key.key(tag.value()); } - static @NotNull StringBinaryTag serialize(@NotNull Key key) { + static @NotNull StringBinaryTag serialize(final @NotNull Key key) { return StringBinaryTag.stringBinaryTag(key.asString()); } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java index b7c1f7159b..4ce379d2df 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java @@ -23,6 +23,7 @@ */ package net.kyori.adventure.text.serializer.nbt; +import java.util.function.Consumer; import net.kyori.adventure.builder.AbstractBuilder; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; @@ -34,8 +35,6 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; -import java.util.function.Consumer; - /** * A NBT component serializer. * @@ -50,7 +49,7 @@ public interface NBTComponentSerializer extends ComponentSerializer children; + final ListBinaryTag extraTag = optionalTag(compound, EXTRA, BinaryTagTypes.LIST); + final List children; if (extraTag == null) { children = Collections.emptyList(); @@ -144,16 +143,16 @@ static final class Instances { if (compound.get(TEXT) != null) { return Component.text() - .content(getRequiredTag(compound, TEXT, BinaryTagTypes.STRING).value()) + .content(requiredTag(compound, TEXT, BinaryTagTypes.STRING).value()) .style(style) .append(children) .build(); } else if (compound.get(TRANSLATE) != null) { - StringBinaryTag translateTag = getRequiredTag(compound, TRANSLATE, BinaryTagTypes.STRING); - ListBinaryTag translateWithTag = compound.getList(TRANSLATE_WITH).unwrapHeterogeneity(); - StringBinaryTag fallbackTag = getOptionalTag(compound, TRANSLATE_FALLBACK, BinaryTagTypes.STRING); + final StringBinaryTag translateTag = requiredTag(compound, TRANSLATE, BinaryTagTypes.STRING); + final ListBinaryTag translateWithTag = compound.getList(TRANSLATE_WITH).unwrapHeterogeneity(); + final StringBinaryTag fallbackTag = optionalTag(compound, TRANSLATE_FALLBACK, BinaryTagTypes.STRING); - List arguments = new ArrayList<>(); + final List arguments = new ArrayList<>(); translateWithTag.forEach(argumentTag -> arguments.add(TranslationArgumentSerializer.deserialize(argumentTag, this))); return Component.translatable() @@ -165,21 +164,21 @@ static final class Instances { .build(); } else if (compound.get(KEYBIND) != null) { return Component.keybind() - .keybind(getRequiredTag(compound, KEYBIND, BinaryTagTypes.STRING).value()) + .keybind(requiredTag(compound, KEYBIND, BinaryTagTypes.STRING).value()) .style(style) .append(children) .build(); } else if (compound.get(SCORE) != null) { - CompoundBinaryTag scoreTag = getRequiredTag(compound, SCORE, BinaryTagTypes.COMPOUND); + final CompoundBinaryTag scoreTag = requiredTag(compound, SCORE, BinaryTagTypes.COMPOUND); return Component.score() - .name(getRequiredTag(scoreTag, SCORE_NAME, BinaryTagTypes.STRING).value()) - .objective(getRequiredTag(scoreTag, SCORE_OBJECTIVE, BinaryTagTypes.STRING).value()) + .name(requiredTag(scoreTag, SCORE_NAME, BinaryTagTypes.STRING).value()) + .objective(requiredTag(scoreTag, SCORE_OBJECTIVE, BinaryTagTypes.STRING).value()) .style(style) .append(children) .build(); } else if (compound.get(SELECTOR) != null) { - StringBinaryTag selectorTag = getRequiredTag(compound, SELECTOR, BinaryTagTypes.STRING); - BinaryTag separatorTag = compound.get(SEPARATOR); + final StringBinaryTag selectorTag = requiredTag(compound, SELECTOR, BinaryTagTypes.STRING); + final BinaryTag separatorTag = compound.get(SEPARATOR); return Component.selector() .pattern(selectorTag.value()) .separator(separatorTag == null ? null : this.deserialize(separatorTag)) @@ -187,21 +186,21 @@ static final class Instances { .append(children) .build(); } else if (compound.get(NBT) != null) { - String nbtPath = getRequiredTag(compound, NBT, BinaryTagTypes.STRING).value(); + final String nbtPath = requiredTag(compound, NBT, BinaryTagTypes.STRING).value(); - ByteBinaryTag interpretTag = getOptionalTag(compound, NBT_INTERPRET, BinaryTagTypes.BYTE); - boolean interpret = interpretTag != null && asBoolean(interpretTag); + final ByteBinaryTag interpretTag = optionalTag(compound, NBT_INTERPRET, BinaryTagTypes.BYTE); + final boolean interpret = interpretTag != null && asBoolean(interpretTag); - BinaryTag separatorTag = compound.get(SEPARATOR); + final BinaryTag separatorTag = compound.get(SEPARATOR); Component separator = null; if (separatorTag != null) { separator = this.deserialize(separatorTag); } - StringBinaryTag blockTag = getOptionalTag(compound, NBT_BLOCK, BinaryTagTypes.STRING); - StringBinaryTag entityTag = getOptionalTag(compound, NBT_ENTITY, BinaryTagTypes.STRING); - StringBinaryTag storageTag = getOptionalTag(compound, NBT_STORAGE, BinaryTagTypes.STRING); + final StringBinaryTag blockTag = optionalTag(compound, NBT_BLOCK, BinaryTagTypes.STRING); + final StringBinaryTag entityTag = optionalTag(compound, NBT_ENTITY, BinaryTagTypes.STRING); + final StringBinaryTag storageTag = optionalTag(compound, NBT_STORAGE, BinaryTagTypes.STRING); if (blockTag != null) { return Component.blockNBT() @@ -239,57 +238,57 @@ static final class Instances { } @Override - public @NotNull BinaryTag serialize(@NotNull Component component) { + public @NotNull BinaryTag serialize(final @NotNull Component component) { if (component instanceof TextComponent && !component.hasStyling() && component.children().isEmpty()) { return StringBinaryTag.stringBinaryTag(((TextComponent) component).content()); } - CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder(); + final CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder(); if (component instanceof TextComponent) { builder.putString(TEXT, ((TextComponent) component).content()); } else if (component instanceof TranslatableComponent) { - TranslatableComponent translatable = (TranslatableComponent) component; + final TranslatableComponent translatable = (TranslatableComponent) component; builder.putString(TRANSLATE, translatable.key()); - String fallback = translatable.fallback(); + final String fallback = translatable.fallback(); if (fallback != null) { builder.putString(TRANSLATE_FALLBACK, fallback); } - List arguments = translatable.arguments(); + final List arguments = translatable.arguments(); if (!arguments.isEmpty()) { - ListBinaryTag.Builder translateWithTagBuilder = ListBinaryTag.heterogeneousListBinaryTag(); + final ListBinaryTag.Builder translateWithTagBuilder = ListBinaryTag.heterogeneousListBinaryTag(); arguments.forEach(argument -> translateWithTagBuilder.add(TranslationArgumentSerializer.serialize(argument, this))); builder.put(TRANSLATE_WITH, translateWithTagBuilder.build().wrapHeterogeneity()); } } else if (component instanceof KeybindComponent) { builder.putString(KEYBIND, ((KeybindComponent) component).keybind()); } else if (component instanceof ScoreComponent) { - ScoreComponent score = (ScoreComponent) component; + final ScoreComponent score = (ScoreComponent) component; - CompoundBinaryTag.Builder scoreTagBuilder = CompoundBinaryTag.builder() + final CompoundBinaryTag.Builder scoreTagBuilder = CompoundBinaryTag.builder() .putString(SCORE_NAME, score.name()) .putString(SCORE_OBJECTIVE, score.objective()); builder.put(SCORE, scoreTagBuilder.build()); } else if (component instanceof SelectorComponent) { - SelectorComponent selector = (SelectorComponent) component; + final SelectorComponent selector = (SelectorComponent) component; builder.putString(SELECTOR, selector.pattern()); - Component separator = selector.separator(); + final Component separator = selector.separator(); if (separator != null) { builder.put(SEPARATOR, this.serialize(separator)); } } else if (component instanceof NBTComponent) { - NBTComponent nbt = (NBTComponent) component; + final NBTComponent nbt = (NBTComponent) component; builder.putString(NBT, nbt.nbtPath()); if (nbt.interpret()) { builder.putBoolean(NBT_INTERPRET, true); } - Component separator = nbt.separator(); + final Component separator = nbt.separator(); if (separator != null) { builder.put(SEPARATOR, this.serialize(separator)); } @@ -307,9 +306,9 @@ static final class Instances { throw notSureHowToSerialize(component); } - List children = component.children(); + final List children = component.children(); if (!children.isEmpty()) { - ListBinaryTag.Builder extraTagBuilder = ListBinaryTag.heterogeneousListBinaryTag(); + final ListBinaryTag.Builder extraTagBuilder = ListBinaryTag.heterogeneousListBinaryTag(); children.forEach(child -> extraTagBuilder.add(this.serialize(child))); builder.put(EXTRA, extraTagBuilder.build().wrapHeterogeneity()); } @@ -322,11 +321,11 @@ static final class Instances { return this.options; } - private static @NotNull IllegalArgumentException notSureHowToDeserialize(@NotNull BinaryTag tag) { + private static @NotNull IllegalArgumentException notSureHowToDeserialize(final @NotNull BinaryTag tag) { return new IllegalArgumentException("Don't know how to turn " + tag + " into a Component"); } - private static @NotNull IllegalArgumentException notSureHowToSerialize(@NotNull Component component) { + private static @NotNull IllegalArgumentException notSureHowToSerialize(final @NotNull Component component) { return new IllegalArgumentException("Don't know how to serialize " + component + " as a Component"); } @@ -339,13 +338,13 @@ static final class BuilderImpl implements NBTComponentSerializer.Builder { } @Override - public @NotNull Builder options(@NotNull OptionState flags) { + public @NotNull Builder options(final @NotNull OptionState flags) { this.flags = requireNonNull(flags, "flags"); return this; } @Override - public @NotNull Builder editOptions(@NotNull Consumer optionEditor) { + public @NotNull Builder editOptions(final @NotNull Consumer optionEditor) { final OptionState.Builder builder = NBTSerializerOptions.schema().stateBuilder().values(this.flags); requireNonNull(optionEditor, "optionEditor").accept(builder); this.flags = builder.build(); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java index b2c163d94a..b842b1587f 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValueImpl.java @@ -23,18 +23,17 @@ */ package net.kyori.adventure.text.serializer.nbt; +import java.util.Objects; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.EndBinaryTag; import net.kyori.adventure.text.event.DataComponentValue; import org.jetbrains.annotations.NotNull; -import java.util.Objects; - class NBTDataComponentValueImpl implements NBTDataComponentValue { private final BinaryTag binaryTag; - NBTDataComponentValueImpl(@NotNull BinaryTag binaryTag) { + NBTDataComponentValueImpl(final @NotNull BinaryTag binaryTag) { this.binaryTag = binaryTag; } @@ -44,10 +43,10 @@ class NBTDataComponentValueImpl implements NBTDataComponentValue { } @Override - public boolean equals(Object o) { + public boolean equals(final Object o) { if (this == o) return true; if (!(o instanceof NBTDataComponentValueImpl)) return false; - NBTDataComponentValueImpl that = (NBTDataComponentValueImpl) o; + final NBTDataComponentValueImpl that = (NBTDataComponentValueImpl) o; return Objects.equals(this.binaryTag, that.binaryTag); } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index 3ce12dfc36..e6457edbf8 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -94,7 +94,7 @@ public final class NBTSerializerOptions { private static final int VERSION_25W03A = 4304; // 1.21.5 snapshot static { - OptionSchema.Mutable schema = OptionSchema.emptySchema(); + final OptionSchema.Mutable schema = OptionSchema.emptySchema(); SHADOW_COLOR_MODE = schema.enumOption(key("emit/shadow_color"), ShadowColorEmitMode.class, ShadowColorEmitMode.EMIT_INTEGER); EMIT_HOVER_EVENT_TYPE = schema.enumOption(key("emit/hover_value_mode"), HoverEventValueMode.class, HoverEventValueMode.SNAKE_CASE); EMIT_CLICK_EVENT_TYPE = schema.enumOption(key("emit/click_value_mode"), ClickEventValueMode.class, ClickEventValueMode.SNAKE_CASE); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java index bfc4fca50d..68fb6cb0a6 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java @@ -23,6 +23,7 @@ */ package net.kyori.adventure.text.serializer.nbt; +import java.io.IOException; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.BinaryTagType; import net.kyori.adventure.nbt.ByteBinaryTag; @@ -33,8 +34,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.IOException; - final class NBTSerializerUtils { static final TagStringIO SNBT_IO = TagStringIO.tagStringIO(); @@ -43,31 +42,31 @@ final class NBTSerializerUtils { private NBTSerializerUtils() { } - static @NotNull BinaryTag getRequiredTag(@NotNull CompoundBinaryTag compound, @NotNull String name) { - BinaryTag tag = compound.get(name); + static @NotNull BinaryTag requiredTag(final @NotNull CompoundBinaryTag compound, final @NotNull String name) { + final BinaryTag tag = compound.get(name); if (tag == null) { throw noSuchField(name); } return tag; } - static @NotNull B getRequiredTag(@NotNull CompoundBinaryTag compound, - @NotNull String name, @NotNull BinaryTagType tagType) { - B tag = getOptionalTag(compound, name, tagType); + static @NotNull B requiredTag(final @NotNull CompoundBinaryTag compound, + final @NotNull String name, final @NotNull BinaryTagType tagType) { + final B tag = optionalTag(compound, name, tagType); if (tag == null) { throw noSuchField(name); } return tag; } - static @Nullable B getOptionalTag(@NotNull CompoundBinaryTag compound, - @NotNull String name, @NotNull BinaryTagType tagType) { - BinaryTag tag = compound.get(name); + static @Nullable B optionalTag(final @NotNull CompoundBinaryTag compound, + final @NotNull String name, final @NotNull BinaryTagType tagType) { + final BinaryTag tag = compound.get(name); if (tag == null) { return null; } - BinaryTagType actualTagType = tag.type(); + final BinaryTagType actualTagType = tag.type(); if (actualTagType != tagType) { throw new IllegalArgumentException( "A type of the tag is different than expected." + @@ -79,16 +78,16 @@ private NBTSerializerUtils() { return (B) tag; } - static boolean asBoolean(@NotNull NumberBinaryTag tag) { + static boolean asBoolean(final @NotNull NumberBinaryTag tag) { // != 0 might look weird, but it is what vanilla does return tag.byteValue() != 0; } - static @NotNull ByteBinaryTag asTag(boolean value) { + static @NotNull ByteBinaryTag asTag(final boolean value) { return value ? ByteBinaryTag.ONE : ByteBinaryTag.ZERO; } - private static @NotNull IllegalArgumentException noSuchField(@NotNull String name) { + private static @NotNull IllegalArgumentException noSuchField(final @NotNull String name) { return new IllegalArgumentException("The specified compound tag does not contain a field with name of \"" + name + "\""); } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java index 8de3b940c1..1049ac0bb8 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java @@ -37,32 +37,32 @@ final class ShadowColorSerializer { private ShadowColorSerializer() { } - static @NotNull ShadowColor deserialize(@NotNull BinaryTag tag) { + static @NotNull ShadowColor deserialize(final @NotNull BinaryTag tag) { if (tag instanceof IntBinaryTag) { - IntBinaryTag castTag = (IntBinaryTag) tag; + final IntBinaryTag castTag = (IntBinaryTag) tag; return ShadowColor.shadowColor(castTag.value()); } else if (tag instanceof ListBinaryTag) { - ListBinaryTag castTag = (ListBinaryTag) tag; + final ListBinaryTag castTag = (ListBinaryTag) tag; return ShadowColor.shadowColor( - getShadowColorComponent(castTag, 0), - getShadowColorComponent(castTag, 1), - getShadowColorComponent(castTag, 2), - getShadowColorComponent(castTag, 3) + shadowColorComponent(castTag, 0), + shadowColorComponent(castTag, 1), + shadowColorComponent(castTag, 2), + shadowColorComponent(castTag, 3) ); } else { throw new IllegalArgumentException("The binary tag representing the shadow color is of an invalid type"); } } - static @Nullable BinaryTag serialize(@NotNull ShadowColor color, @NotNull NBTComponentSerializerImpl serializer) { - NBTSerializerOptions.ShadowColorEmitMode emitMode = serializer.options().value(NBTSerializerOptions.SHADOW_COLOR_MODE); + static @Nullable BinaryTag serialize(final @NotNull ShadowColor color, final @NotNull NBTComponentSerializerImpl serializer) { + final NBTSerializerOptions.ShadowColorEmitMode emitMode = serializer.options().value(NBTSerializerOptions.SHADOW_COLOR_MODE); switch (emitMode) { case NONE: return null; case EMIT_INTEGER: return IntBinaryTag.intBinaryTag(color.value()); case EMIT_ARRAY: - ListBinaryTag.Builder builder = ListBinaryTag.builder(BinaryTagTypes.FLOAT); + final ListBinaryTag.Builder builder = ListBinaryTag.builder(BinaryTagTypes.FLOAT); addShadowColorComponent(builder, color.red()); addShadowColorComponent(builder, color.green()); addShadowColorComponent(builder, color.blue()); @@ -74,11 +74,11 @@ private ShadowColorSerializer() { } } - private static int getShadowColorComponent(@NotNull ListBinaryTag tag, int index) { + private static int shadowColorComponent(final @NotNull ListBinaryTag tag, final int index) { return (int) (tag.getFloat(index) * 0xff); } - private static void addShadowColorComponent(@NotNull ListBinaryTag.Builder builder, int element) { + private static void addShadowColorComponent(final ListBinaryTag.@NotNull Builder builder, final int element) { builder.add(FloatBinaryTag.floatBinaryTag((float) element / 0xff)); } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java index c55dcb62c2..8e759099d6 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java @@ -23,6 +23,8 @@ */ package net.kyori.adventure.text.serializer.nbt; +import java.io.IOException; +import java.util.UUID; import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.BinaryTagTypes; @@ -32,26 +34,23 @@ import net.kyori.adventure.text.event.HoverEvent; import org.jetbrains.annotations.NotNull; -import java.io.IOException; -import java.util.UUID; - import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ENTITY_ID; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ENTITY_NAME; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ENTITY_TYPE; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ENTITY_UUID; import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.SNBT_IO; -import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getRequiredTag; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.requiredTag; final class ShowEntitySerializer { private ShowEntitySerializer() { } - static HoverEvent.@NotNull ShowEntity deserialize(@NotNull BinaryTag tag, boolean snakeCase, - @NotNull NBTComponentSerializerImpl serializer) { + static HoverEvent.@NotNull ShowEntity deserialize(final @NotNull BinaryTag tag, final boolean snakeCase, + final @NotNull NBTComponentSerializerImpl serializer) { try { return deserializeModern((CompoundBinaryTag) tag, snakeCase, serializer); - } catch (Exception exception) { + } catch (final Exception exception) { if (snakeCase) { throw notSureHowToDeserialize(tag); } else { @@ -60,13 +59,13 @@ private ShowEntitySerializer() { } } - static @NotNull CompoundBinaryTag serialize(HoverEvent.@NotNull ShowEntity showEntity, boolean snakeCase, - @NotNull NBTComponentSerializerImpl serializer) { - CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() + static @NotNull CompoundBinaryTag serialize(final HoverEvent.@NotNull ShowEntity showEntity, final boolean snakeCase, + final @NotNull NBTComponentSerializerImpl serializer) { + final CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() .put(snakeCase ? SHOW_ENTITY_ID : SHOW_ENTITY_TYPE, KeySerializer.serialize(showEntity.type())) .put(snakeCase ? SHOW_ENTITY_UUID : SHOW_ENTITY_ID, UUIDSerializer.serialize(showEntity.id())); - Component entityName = showEntity.name(); + final Component entityName = showEntity.name(); if (entityName != null) { builder.put(SHOW_ENTITY_NAME, serializer.serialize(entityName)); } @@ -74,13 +73,13 @@ private ShowEntitySerializer() { return builder.build(); } - private static HoverEvent.@NotNull ShowEntity deserializeModern(@NotNull CompoundBinaryTag compound, boolean snakeCase, - @NotNull NBTComponentSerializerImpl serializer) { - Key entityType = KeySerializer.deserialize(getRequiredTag(compound, snakeCase ? SHOW_ENTITY_ID : SHOW_ENTITY_TYPE, BinaryTagTypes.STRING)); - BinaryTag entityIdTag = getRequiredTag(compound, snakeCase ? SHOW_ENTITY_UUID : SHOW_ENTITY_ID); - BinaryTag entityNameTag = compound.get(SHOW_ENTITY_NAME); + private static HoverEvent.@NotNull ShowEntity deserializeModern(final @NotNull CompoundBinaryTag compound, final boolean snakeCase, + final @NotNull NBTComponentSerializerImpl serializer) { + final Key entityType = KeySerializer.deserialize(requiredTag(compound, snakeCase ? SHOW_ENTITY_ID : SHOW_ENTITY_TYPE, BinaryTagTypes.STRING)); + final BinaryTag entityIdTag = requiredTag(compound, snakeCase ? SHOW_ENTITY_UUID : SHOW_ENTITY_ID); + final BinaryTag entityNameTag = compound.get(SHOW_ENTITY_NAME); - UUID entityId = UUIDSerializer.deserialize(entityIdTag); + final UUID entityId = UUIDSerializer.deserialize(entityIdTag); if (entityNameTag == null) { return HoverEvent.ShowEntity.showEntity(entityType, entityId); } else { @@ -88,22 +87,22 @@ private ShowEntitySerializer() { } } - private static HoverEvent.@NotNull ShowEntity deserializeLegacy(@NotNull BinaryTag tag, @NotNull NBTComponentSerializerImpl serializer) { + private static HoverEvent.@NotNull ShowEntity deserializeLegacy(final @NotNull BinaryTag tag, final @NotNull NBTComponentSerializerImpl serializer) { try { - Component component = serializer.deserialize(tag); + final Component component = serializer.deserialize(tag); if (!(component instanceof TextComponent)) { throw notSureHowToDeserialize(tag); } - String content = ((TextComponent) component).content(); - CompoundBinaryTag compound = SNBT_IO.asCompound(content); + final String content = ((TextComponent) component).content(); + final CompoundBinaryTag compound = SNBT_IO.asCompound(content); return deserializeModern(compound, false, serializer); - } catch (IOException exception) { + } catch (final IOException exception) { throw notSureHowToDeserialize(tag); } } - private static @NotNull IllegalArgumentException notSureHowToDeserialize(@NotNull BinaryTag tag) { + private static @NotNull IllegalArgumentException notSureHowToDeserialize(final @NotNull BinaryTag tag) { return new IllegalArgumentException("Don't know how to turn " + tag + " into a show entity hover event data"); } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java index d9fa4d31ac..ba61a24bc4 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowItemSerializer.java @@ -23,6 +23,9 @@ */ package net.kyori.adventure.text.serializer.nbt; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.BinaryTagTypes; @@ -37,18 +40,14 @@ import net.kyori.adventure.text.event.HoverEvent; import org.jetbrains.annotations.NotNull; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ITEM_COMPONENTS; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ITEM_COUNT; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ITEM_ID; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHOW_ITEM_TAG; import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.SNBT_CODEC; import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.SNBT_IO; -import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getOptionalTag; -import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getRequiredTag; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.optionalTag; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.requiredTag; final class ShowItemSerializer { @@ -60,11 +59,11 @@ final class ShowItemSerializer { private ShowItemSerializer() { } - static HoverEvent.@NotNull ShowItem deserialize(@NotNull BinaryTag tag, boolean snakeCase, - @NotNull NBTComponentSerializerImpl serializer) { + static HoverEvent.@NotNull ShowItem deserialize(final @NotNull BinaryTag tag, final boolean snakeCase, + final @NotNull NBTComponentSerializerImpl serializer) { try { return deserializeModern(tag, snakeCase); - } catch (Exception exception) { + } catch (final Exception exception) { if (snakeCase) { throw notSureHowToDeserialize(tag); } else { @@ -73,25 +72,25 @@ private ShowItemSerializer() { } } - static @NotNull CompoundBinaryTag serialize(HoverEvent.@NotNull ShowItem showItem, boolean snakeCase, - @NotNull NBTComponentSerializerImpl serializer) { - CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() + static @NotNull CompoundBinaryTag serialize(final HoverEvent.@NotNull ShowItem showItem, final boolean snakeCase, + final @NotNull NBTComponentSerializerImpl serializer) { + final CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() .put(SHOW_ITEM_ID, KeySerializer.serialize(showItem.item())); - int count = showItem.count(); + final int count = showItem.count(); if (count != DEFAULT_ITEM_QUANTITY || serializer.options().value(NBTSerializerOptions.EMIT_DEFAULT_ITEM_HOVER_QUANTITY)) { builder.putInt(SHOW_ITEM_COUNT, count); } - NBTSerializerOptions.ShowItemHoverDataMode dataMode = serializer.options().value(NBTSerializerOptions.SHOW_ITEM_HOVER_DATA_MODE); + final NBTSerializerOptions.ShowItemHoverDataMode dataMode = serializer.options().value(NBTSerializerOptions.SHOW_ITEM_HOVER_DATA_MODE); if ((snakeCase || dataMode != NBTSerializerOptions.ShowItemHoverDataMode.EMIT_LEGACY_NBT) && !showItem.dataComponents().isEmpty()) { - CompoundBinaryTag.Builder componentsTagBuilder = CompoundBinaryTag.builder(); + final CompoundBinaryTag.Builder componentsTagBuilder = CompoundBinaryTag.builder(); + final Map components = showItem.dataComponentsAs(NBTDataComponentValue.class); - Map components = showItem.dataComponentsAs(NBTDataComponentValue.class); - for (Map.Entry entry : components.entrySet()) { - String key = entry.getKey().asString(); - BinaryTag value = entry.getValue().binaryTag(); + for (final Map.Entry entry : components.entrySet()) { + final BinaryTag value = entry.getValue().binaryTag(); + String key = entry.getKey().asString(); if (value instanceof EndBinaryTag) { // removed key = DATA_COMPONENT_REMOVAL_PREFIX + key; } @@ -101,7 +100,7 @@ private ShowItemSerializer() { builder.put(SHOW_ITEM_COMPONENTS, componentsTagBuilder.build()); } else if (!snakeCase && dataMode != NBTSerializerOptions.ShowItemHoverDataMode.EMIT_DATA_COMPONENTS) { - BinaryTagHolder nbt = showItem.nbt(); + final BinaryTagHolder nbt = showItem.nbt(); if (nbt != null) { builder.putString(SHOW_ITEM_TAG, nbt.string()); } @@ -110,9 +109,9 @@ private ShowItemSerializer() { return builder.build(); } - private static HoverEvent.@NotNull ShowItem deserializeModern(@NotNull BinaryTag tag, boolean snakeCase) { + private static HoverEvent.@NotNull ShowItem deserializeModern(final @NotNull BinaryTag tag, final boolean snakeCase) { if (tag instanceof StringBinaryTag && !snakeCase) { - StringBinaryTag castTag = (StringBinaryTag) tag; + final StringBinaryTag castTag = (StringBinaryTag) tag; return HoverEvent.ShowItem.showItem(KeySerializer.deserialize(castTag), DEFAULT_ITEM_QUANTITY); } else if (!(tag instanceof CompoundBinaryTag)) { if (snakeCase) { @@ -122,14 +121,14 @@ private ShowItemSerializer() { } } - CompoundBinaryTag compound = (CompoundBinaryTag) tag; + final CompoundBinaryTag compound = (CompoundBinaryTag) tag; - Key itemId = KeySerializer.deserialize(getRequiredTag(compound, SHOW_ITEM_ID, BinaryTagTypes.STRING)); - IntBinaryTag countTag = getOptionalTag(compound, SHOW_ITEM_COUNT, BinaryTagTypes.INT); - int itemCount = countTag == null ? DEFAULT_ITEM_QUANTITY : countTag.value(); + final Key itemId = KeySerializer.deserialize(requiredTag(compound, SHOW_ITEM_ID, BinaryTagTypes.STRING)); + final IntBinaryTag countTag = optionalTag(compound, SHOW_ITEM_COUNT, BinaryTagTypes.INT); + final int itemCount = countTag == null ? DEFAULT_ITEM_QUANTITY : countTag.value(); - CompoundBinaryTag componentsTag = getOptionalTag(compound, SHOW_ITEM_COMPONENTS, BinaryTagTypes.COMPOUND); - StringBinaryTag nbtTag = getOptionalTag(compound, SHOW_ITEM_TAG, BinaryTagTypes.STRING); + final CompoundBinaryTag componentsTag = optionalTag(compound, SHOW_ITEM_COMPONENTS, BinaryTagTypes.COMPOUND); + final StringBinaryTag nbtTag = optionalTag(compound, SHOW_ITEM_TAG, BinaryTagTypes.STRING); if (componentsTag == null) { if (snakeCase || nbtTag == null) { @@ -137,50 +136,47 @@ private ShowItemSerializer() { } return HoverEvent.ShowItem.showItem(itemId, itemCount, BinaryTagHolder.binaryTagHolder(nbtTag.value())); } else { - Map componentValues = new HashMap<>(); + final Map componentValues = new HashMap<>(); - for (String string : componentsTag.keySet()) { - boolean removed = string.startsWith(DATA_COMPONENT_REMOVAL_PREFIX); + for (final String string : componentsTag.keySet()) { + final boolean removed = string.startsWith(DATA_COMPONENT_REMOVAL_PREFIX); - BinaryTag valueTag = componentsTag.get(string); + final BinaryTag valueTag = componentsTag.get(string); if (valueTag == null) continue; - if (removed) { - string = string.substring(1); - } - - componentValues.put(Key.key(string), removed ? DataComponentValue.removed() : NBTDataComponentValue.nbtDataComponentValue(valueTag)); + final String key = removed ? string.substring(1) : string; + componentValues.put(Key.key(key), removed ? DataComponentValue.removed() : NBTDataComponentValue.nbtDataComponentValue(valueTag)); } return HoverEvent.ShowItem.showItem(itemId, itemCount, componentValues); } } - private static HoverEvent.@NotNull ShowItem deserializeLegacy(@NotNull BinaryTag tag, @NotNull NBTComponentSerializerImpl serializer) { + private static HoverEvent.@NotNull ShowItem deserializeLegacy(final @NotNull BinaryTag tag, final @NotNull NBTComponentSerializerImpl serializer) { try { - Component component = serializer.deserialize(tag); + final Component component = serializer.deserialize(tag); if (!(component instanceof TextComponent)) { throw notSureHowToDeserialize(tag); } - String content = ((TextComponent) component).content(); - CompoundBinaryTag compound = SNBT_IO.asCompound(content); + final String content = ((TextComponent) component).content(); + final CompoundBinaryTag compound = SNBT_IO.asCompound(content); - Key key = KeySerializer.deserialize(getRequiredTag(compound, SHOW_ITEM_ID, BinaryTagTypes.STRING)); - byte count = getRequiredTag(compound, LEGACY_ITEM_COUNT, BinaryTagTypes.BYTE).value(); + final Key key = KeySerializer.deserialize(requiredTag(compound, SHOW_ITEM_ID, BinaryTagTypes.STRING)); + final byte count = requiredTag(compound, LEGACY_ITEM_COUNT, BinaryTagTypes.BYTE).value(); - CompoundBinaryTag nbtTag = getOptionalTag(compound, SHOW_ITEM_TAG, BinaryTagTypes.COMPOUND); + final CompoundBinaryTag nbtTag = optionalTag(compound, SHOW_ITEM_TAG, BinaryTagTypes.COMPOUND); if (nbtTag == null) { return HoverEvent.ShowItem.showItem(key, count); } else { return HoverEvent.ShowItem.showItem(key, count, BinaryTagHolder.encode(nbtTag, SNBT_CODEC)); } - } catch (IOException exception) { + } catch (final IOException exception) { throw notSureHowToDeserialize(tag); } } - private static @NotNull IllegalArgumentException notSureHowToDeserialize(@NotNull BinaryTag tag) { + private static @NotNull IllegalArgumentException notSureHowToDeserialize(final @NotNull BinaryTag tag) { return new IllegalArgumentException("Don't know how to turn " + tag + " into a show item hover event data"); } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java index 6808bcbe24..e495476b37 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/StyleSerializer.java @@ -46,41 +46,41 @@ import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.HOVER_EVENT_SNAKE; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.INSERTION; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.SHADOW_COLOR; -import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.getOptionalTag; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.optionalTag; final class StyleSerializer { private StyleSerializer() { } - static @NotNull Style deserialize(@NotNull CompoundBinaryTag compound, @NotNull NBTComponentSerializerImpl serializer) { - Style.Builder styleBuilder = Style.style(); + static @NotNull Style deserialize(final @NotNull CompoundBinaryTag compound, final @NotNull NBTComponentSerializerImpl serializer) { + final Style.Builder styleBuilder = Style.style(); - StringBinaryTag colorTag = NBTSerializerUtils.getOptionalTag(compound, COLOR, BinaryTagTypes.STRING); + final StringBinaryTag colorTag = optionalTag(compound, COLOR, BinaryTagTypes.STRING); if (colorTag != null) { styleBuilder.color(TextColorSerializer.deserialize(colorTag)); } - for (TextDecoration decoration : TextDecoration.values()) { - String name = TextDecoration.NAMES.keyOrThrow(decoration); - ByteBinaryTag decorationTag = NBTSerializerUtils.getOptionalTag(compound, name, BinaryTagTypes.BYTE); + for (final TextDecoration decoration : TextDecoration.values()) { + final String name = TextDecoration.NAMES.keyOrThrow(decoration); + final ByteBinaryTag decorationTag = optionalTag(compound, name, BinaryTagTypes.BYTE); if (decorationTag == null) continue; styleBuilder.decoration(decoration, NBTSerializerUtils.asBoolean(decorationTag)); } - StringBinaryTag fontTag = getOptionalTag(compound, FONT, BinaryTagTypes.STRING); + final StringBinaryTag fontTag = optionalTag(compound, FONT, BinaryTagTypes.STRING); if (fontTag != null) { styleBuilder.font(KeySerializer.deserialize(fontTag)); } - StringBinaryTag insertionTag = getOptionalTag(compound, INSERTION, BinaryTagTypes.STRING); + final StringBinaryTag insertionTag = optionalTag(compound, INSERTION, BinaryTagTypes.STRING); if (insertionTag != null) { styleBuilder.insertion(insertionTag.value()); } - CompoundBinaryTag clickEventTag = getOptionalTag(compound, CLICK_EVENT_SNAKE, BinaryTagTypes.COMPOUND); + CompoundBinaryTag clickEventTag = optionalTag(compound, CLICK_EVENT_SNAKE, BinaryTagTypes.COMPOUND); if (clickEventTag == null) { - clickEventTag = getOptionalTag(compound, CLICK_EVENT_CAMEL, BinaryTagTypes.COMPOUND); + clickEventTag = optionalTag(compound, CLICK_EVENT_CAMEL, BinaryTagTypes.COMPOUND); if (clickEventTag != null) { styleBuilder.clickEvent(ClickEventSerializer.deserialize(clickEventTag, false)); } @@ -88,9 +88,9 @@ private StyleSerializer() { styleBuilder.clickEvent(ClickEventSerializer.deserialize(clickEventTag, true)); } - CompoundBinaryTag hoverEventTag = getOptionalTag(compound, HOVER_EVENT_SNAKE, BinaryTagTypes.COMPOUND); + CompoundBinaryTag hoverEventTag = optionalTag(compound, HOVER_EVENT_SNAKE, BinaryTagTypes.COMPOUND); if (hoverEventTag == null) { - hoverEventTag = getOptionalTag(compound, HOVER_EVENT_CAMEL, BinaryTagTypes.COMPOUND); + hoverEventTag = optionalTag(compound, HOVER_EVENT_CAMEL, BinaryTagTypes.COMPOUND); if (hoverEventTag != null) { styleBuilder.hoverEvent(HoverEventSerializer.deserialize(hoverEventTag, false, serializer)); } @@ -98,7 +98,7 @@ private StyleSerializer() { styleBuilder.hoverEvent(HoverEventSerializer.deserialize(hoverEventTag, true, serializer)); } - BinaryTag shadowColorTag = compound.get(SHADOW_COLOR); + final BinaryTag shadowColorTag = compound.get(SHADOW_COLOR); if (shadowColorTag != null) { styleBuilder.shadowColor(ShadowColorSerializer.deserialize(shadowColorTag)); } @@ -106,80 +106,80 @@ private StyleSerializer() { return styleBuilder.build(); } - static void serialize(@NotNull Style style, CompoundBinaryTag.@NotNull Builder builder, - @NotNull NBTComponentSerializerImpl serializer) { - OptionState flags = serializer.options(); + static void serialize(final @NotNull Style style, final CompoundBinaryTag.@NotNull Builder builder, + final @NotNull NBTComponentSerializerImpl serializer) { + final OptionState flags = serializer.options(); - TextColor color = style.color(); + final TextColor color = style.color(); if (color != null) { builder.put(COLOR, TextColorSerializer.serialize(color)); } - ShadowColor shadowColor = style.shadowColor(); + final ShadowColor shadowColor = style.shadowColor(); if (shadowColor != null) { - BinaryTag shadowColorTag = ShadowColorSerializer.serialize(shadowColor, serializer); + final BinaryTag shadowColorTag = ShadowColorSerializer.serialize(shadowColor, serializer); if (shadowColorTag != null) { builder.put(SHADOW_COLOR, shadowColorTag); } } - for (TextDecoration decoration : TextDecoration.values()) { - TextDecoration.State state = style.decoration(decoration); + for (final TextDecoration decoration : TextDecoration.values()) { + final TextDecoration.State state = style.decoration(decoration); if (state == TextDecoration.State.NOT_SET) continue; - String name = TextDecoration.NAMES.keyOrThrow(decoration); + final String name = TextDecoration.NAMES.keyOrThrow(decoration); builder.putBoolean(name, state == TextDecoration.State.TRUE); } - Key font = style.font(); + final Key font = style.font(); if (font != null) { builder.put(FONT, KeySerializer.serialize(font)); } - String insertion = style.insertion(); + final String insertion = style.insertion(); if (insertion != null) { builder.putString(INSERTION, insertion); } - ClickEvent clickEvent = style.clickEvent(); + final ClickEvent clickEvent = style.clickEvent(); if (clickEvent != null) { - NBTSerializerOptions.ClickEventValueMode clickEventValueMode = flags.value(NBTSerializerOptions.EMIT_CLICK_EVENT_TYPE); + final NBTSerializerOptions.ClickEventValueMode clickEventValueMode = flags.value(NBTSerializerOptions.EMIT_CLICK_EVENT_TYPE); - boolean emitBothClickEvents = clickEventValueMode == NBTSerializerOptions.ClickEventValueMode.BOTH; - boolean emitSnakeCaseClickEvent = clickEventValueMode == NBTSerializerOptions.ClickEventValueMode.SNAKE_CASE; - boolean emitCamelCaseClickEvent = clickEventValueMode == NBTSerializerOptions.ClickEventValueMode.CAMEL_CASE; + final boolean emitBothClickEvents = clickEventValueMode == NBTSerializerOptions.ClickEventValueMode.BOTH; + final boolean emitSnakeCaseClickEvent = clickEventValueMode == NBTSerializerOptions.ClickEventValueMode.SNAKE_CASE; + final boolean emitCamelCaseClickEvent = clickEventValueMode == NBTSerializerOptions.ClickEventValueMode.CAMEL_CASE; if (emitBothClickEvents || emitSnakeCaseClickEvent) { - BinaryTag clickEventTag = ClickEventSerializer.serialize(clickEvent, true); + final BinaryTag clickEventTag = ClickEventSerializer.serialize(clickEvent, true); if (clickEventTag != null) { builder.put(CLICK_EVENT_SNAKE, clickEventTag); } } if (emitBothClickEvents || emitCamelCaseClickEvent) { - BinaryTag clickEventTag = ClickEventSerializer.serialize(clickEvent, false); + final BinaryTag clickEventTag = ClickEventSerializer.serialize(clickEvent, false); if (clickEventTag != null) { builder.put(CLICK_EVENT_CAMEL, clickEventTag); } } } - HoverEvent hoverEvent = style.hoverEvent(); + final HoverEvent hoverEvent = style.hoverEvent(); if (hoverEvent != null) { - NBTSerializerOptions.HoverEventValueMode hoverEventValueMode = flags.value(NBTSerializerOptions.EMIT_HOVER_EVENT_TYPE); + final NBTSerializerOptions.HoverEventValueMode hoverEventValueMode = flags.value(NBTSerializerOptions.EMIT_HOVER_EVENT_TYPE); - boolean emitBothHoverEvents = hoverEventValueMode == NBTSerializerOptions.HoverEventValueMode.BOTH; - boolean emitSnakeCaseHoverEvent = hoverEventValueMode == NBTSerializerOptions.HoverEventValueMode.SNAKE_CASE; - boolean emitCamelCaseHoverEvent = hoverEventValueMode == NBTSerializerOptions.HoverEventValueMode.CAMEL_CASE; + final boolean emitBothHoverEvents = hoverEventValueMode == NBTSerializerOptions.HoverEventValueMode.BOTH; + final boolean emitSnakeCaseHoverEvent = hoverEventValueMode == NBTSerializerOptions.HoverEventValueMode.SNAKE_CASE; + final boolean emitCamelCaseHoverEvent = hoverEventValueMode == NBTSerializerOptions.HoverEventValueMode.CAMEL_CASE; if (emitBothHoverEvents || emitSnakeCaseHoverEvent) { - BinaryTag hoverEventTag = HoverEventSerializer.serialize(hoverEvent, true, serializer); + final BinaryTag hoverEventTag = HoverEventSerializer.serialize(hoverEvent, true, serializer); if (hoverEventTag != null) { builder.put(HOVER_EVENT_SNAKE, hoverEventTag); } } if (emitBothHoverEvents || emitCamelCaseHoverEvent) { - BinaryTag hoverEventTag = HoverEventSerializer.serialize(hoverEvent, false, serializer); + final BinaryTag hoverEventTag = HoverEventSerializer.serialize(hoverEvent, false, serializer); if (hoverEventTag != null) { builder.put(HOVER_EVENT_CAMEL, hoverEventTag); } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TextColorSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TextColorSerializer.java index 82ec7110b7..8921cbd4bb 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TextColorSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TextColorSerializer.java @@ -23,22 +23,21 @@ */ package net.kyori.adventure.text.serializer.nbt; +import java.util.Locale; import net.kyori.adventure.nbt.StringBinaryTag; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; import org.jetbrains.annotations.NotNull; -import java.util.Locale; - final class TextColorSerializer { private TextColorSerializer() { } - static @NotNull TextColor deserialize(@NotNull StringBinaryTag tag) { - String value = tag.value(); + static @NotNull TextColor deserialize(final @NotNull StringBinaryTag tag) { + final String value = tag.value(); if (value.startsWith(TextColor.HEX_PREFIX)) { - TextColor color = TextColor.fromHexString(value); + final TextColor color = TextColor.fromHexString(value); if (color == null) { throw new IllegalArgumentException("Invalid hex text color: " + value); } @@ -48,8 +47,8 @@ private TextColorSerializer() { } } - static @NotNull StringBinaryTag serialize(@NotNull TextColor color) { - String value = color instanceof NamedTextColor + static @NotNull StringBinaryTag serialize(final @NotNull TextColor color) { + final String value = color instanceof NamedTextColor ? NamedTextColor.NAMES.keyOrThrow((NamedTextColor) color) : asUpperCaseHexString(color); return StringBinaryTag.stringBinaryTag(value); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TranslationArgumentSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TranslationArgumentSerializer.java index 87443fed85..124ab41910 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TranslationArgumentSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/TranslationArgumentSerializer.java @@ -40,7 +40,7 @@ final class TranslationArgumentSerializer { private TranslationArgumentSerializer() { } - static @NotNull TranslationArgument deserialize(@NotNull BinaryTag tag, @NotNull NBTComponentSerializerImpl serializer) { + static @NotNull TranslationArgument deserialize(final @NotNull BinaryTag tag, final @NotNull NBTComponentSerializerImpl serializer) { /* Serialized booleans are not deserialized as booleans because Minecraft also does that - NbtOps serializes booleans as byte tags and there is no way to distinguish the original type during deserialization.*/ if (tag instanceof NumberBinaryTag) { @@ -50,8 +50,8 @@ private TranslationArgumentSerializer() { } } - static @NotNull BinaryTag serialize(@NotNull TranslationArgument argument, @NotNull NBTComponentSerializerImpl serializer) { - Object value = argument.value(); + static @NotNull BinaryTag serialize(final @NotNull TranslationArgument argument, final @NotNull NBTComponentSerializerImpl serializer) { + final Object value = argument.value(); if (value instanceof Boolean) { return NBTSerializerUtils.asTag((boolean) value); } else if (value instanceof Byte) { diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java index 497d13a0b0..974cc4f3b5 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/UUIDSerializer.java @@ -23,14 +23,13 @@ */ package net.kyori.adventure.text.serializer.nbt; +import java.util.UUID; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.IntArrayBinaryTag; import net.kyori.adventure.nbt.ListBinaryTag; import net.kyori.adventure.nbt.StringBinaryTag; import org.jetbrains.annotations.NotNull; -import java.util.UUID; - final class UUIDSerializer { private static final long LONG_HALF = 0xffffffffL; @@ -38,14 +37,14 @@ final class UUIDSerializer { private UUIDSerializer() { } - static @NotNull UUID deserialize(@NotNull BinaryTag tag) { + static @NotNull UUID deserialize(final @NotNull BinaryTag tag) { if (tag instanceof StringBinaryTag) { return UUID.fromString(((StringBinaryTag) tag).value()); } else if (tag instanceof IntArrayBinaryTag) { return createUUIDFromArray(((IntArrayBinaryTag) tag).value()); } else if (tag instanceof ListBinaryTag) { - ListBinaryTag castTag = (ListBinaryTag) tag; - int[] array = new int[castTag.size()]; + final ListBinaryTag castTag = (ListBinaryTag) tag; + final int[] array = new int[castTag.size()]; for (int index = 0; index < array.length; index++) { array[index] = castTag.getInt(index); @@ -57,30 +56,30 @@ private UUIDSerializer() { } } - static @NotNull BinaryTag serialize(@NotNull UUID uuid) { - long mostSignificantBits = uuid.getMostSignificantBits(); - long leastSignificantBits = uuid.getLeastSignificantBits(); + static @NotNull BinaryTag serialize(final @NotNull UUID uuid) { + final long mostSignificantBits = uuid.getMostSignificantBits(); + final long leastSignificantBits = uuid.getLeastSignificantBits(); return IntArrayBinaryTag.intArrayBinaryTag( mostSignificantBits(mostSignificantBits), leastSignificantBits(mostSignificantBits), mostSignificantBits(leastSignificantBits), leastSignificantBits(leastSignificantBits) ); } - private static @NotNull UUID createUUIDFromArray(int @NotNull [] array) { - long mostSignificantBits = binaryConcat(array[0], array[1]); - long leastSignificantBits = binaryConcat(array[2], array[3]); + private static @NotNull UUID createUUIDFromArray(final int @NotNull [] array) { + final long mostSignificantBits = binaryConcat(array[0], array[1]); + final long leastSignificantBits = binaryConcat(array[2], array[3]); return new UUID(mostSignificantBits, leastSignificantBits); } - private static long binaryConcat(int mostSignificantBits, int leastSignificantBits) { + private static long binaryConcat(final int mostSignificantBits, final int leastSignificantBits) { return ((long) mostSignificantBits << Integer.SIZE) | ((long) leastSignificantBits & LONG_HALF); } - private static int mostSignificantBits(long value) { + private static int mostSignificantBits(final long value) { return (int) (value >> Integer.SIZE); } - private static int leastSignificantBits(long value) { + private static int leastSignificantBits(final long value) { return (int) (value & LONG_HALF); } } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/NBTDataComponentValueConverterProvider.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/NBTDataComponentValueConverterProvider.java index 44d48b0731..00f24c94be 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/NBTDataComponentValueConverterProvider.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/NBTDataComponentValueConverterProvider.java @@ -24,6 +24,7 @@ package net.kyori.adventure.text.serializer.nbt.impl; import com.google.auto.service.AutoService; +import java.util.Collections; import net.kyori.adventure.Adventure; import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.EndBinaryTag; @@ -33,8 +34,6 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; -import java.util.Collections; - /** * A provider for NBT component serializer's implementations of data component value converters. * From f64f2f50114783a5bf0488d19a63c1e5435be312 Mon Sep 17 00:00:00 2001 From: codestech Date: Tue, 1 Jul 2025 10:28:24 +0200 Subject: [PATCH 80/86] chore: fix style of the test module --- .../serializer/nbt/BlockNBTComponentTest.java | 62 +++++++++---------- .../nbt/EntityNBTComponentTest.java | 8 +-- .../serializer/nbt/KeybindComponentTest.java | 2 +- .../serializer/nbt/ScoreComponentTest.java | 4 +- .../serializer/nbt/SelectorComponentTest.java | 6 +- .../text/serializer/nbt/SerializerTests.java | 29 ++++----- .../text/serializer/nbt/ShowEntityTest.java | 27 ++++---- .../text/serializer/nbt/ShowItemTest.java | 37 ++++++----- .../nbt/StorageNBTComponentTest.java | 8 +-- .../text/serializer/nbt/StyleTest.java | 13 ++-- .../nbt/TranslatableComponentTest.java | 19 +++--- 11 files changed, 106 insertions(+), 109 deletions(-) diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java index 3e21a83cfb..17fa37256d 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/BlockNBTComponentTest.java @@ -34,11 +34,11 @@ final class BlockNBTComponentTest { @Test void testLocal() { - String nbtPath = "abc"; + final String nbtPath = "abc"; - double left = 1.23D; - double up = 2.0D; - double forwards = 3.89D; + final double left = 1.23D; + final double up = 2.0D; + final double forwards = 3.89D; testComponent( Component.blockNBT() @@ -52,35 +52,35 @@ void testLocal() { ); } - @Test - void testAbsoluteWorld() { - String nbtPath = "xyz"; + @Test + void testAbsoluteWorld() { + final String nbtPath = "xyz"; - int x = 4; - int y = 5; - int z = 6; + final int x = 4; + final int y = 5; + final int z = 6; - testComponent( - Component.blockNBT() - .nbtPath(nbtPath) - .absoluteWorldPos(x, y, z) - .interpret(true) - .build(), - CompoundBinaryTag.builder() - .putString(ComponentTreeConstants.NBT, nbtPath) - .putBoolean(ComponentTreeConstants.NBT_INTERPRET, true) - .putString(ComponentTreeConstants.NBT_BLOCK, x + " " + y + " " + z) - .build() - ); - } + testComponent( + Component.blockNBT() + .nbtPath(nbtPath) + .absoluteWorldPos(x, y, z) + .interpret(true) + .build(), + CompoundBinaryTag.builder() + .putString(ComponentTreeConstants.NBT, nbtPath) + .putBoolean(ComponentTreeConstants.NBT_INTERPRET, true) + .putString(ComponentTreeConstants.NBT_BLOCK, x + " " + y + " " + z) + .build() + ); + } @Test void testRelativeWorld() { - String nbtPath = "eeee"; + final String nbtPath = "eeee"; - int x = 7; - int y = 83; - int z = 900; + final int x = 7; + final int y = 83; + final int z = 900; testComponent( Component.blockNBT() @@ -96,11 +96,11 @@ void testRelativeWorld() { @Test void testMixedAbsoluteAndRelative() { - String nbtPath = "qwert"; + final String nbtPath = "qwert"; - int x = 12; - int y = 3; - int z = 1200; + final int x = 12; + final int y = 3; + final int z = 1200; testComponent( Component.blockNBT() diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java index 6c8a304ee4..0af07bc878 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/EntityNBTComponentTest.java @@ -33,8 +33,8 @@ final class EntityNBTComponentTest { @Test void testWithoutInterpret() { - String nbtPath = "abc"; - String selector = "test"; + final String nbtPath = "abc"; + final String selector = "test"; testComponent( Component.entityNBT() @@ -50,8 +50,8 @@ void testWithoutInterpret() { @Test void testWithInterpret() { - String nbtPath = "abc"; - String selector = "test"; + final String nbtPath = "abc"; + final String selector = "test"; testComponent( Component.entityNBT() diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java index a8f491c28c..8f37179e82 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/KeybindComponentTest.java @@ -33,7 +33,7 @@ final class KeybindComponentTest { @Test void test() { - String keybind = "key.jump"; + final String keybind = "key.jump"; testComponent( Component.keybind(keybind), CompoundBinaryTag.builder() diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java index d418f553d5..e77c4940a0 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ScoreComponentTest.java @@ -35,8 +35,8 @@ final class ScoreComponentTest { @Test void test() { - String name = "abc"; - String objective = "def"; + final String name = "abc"; + final String objective = "def"; testComponent( Component.score(name, objective), diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java index c659a0857a..8e23e5282b 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SelectorComponentTest.java @@ -34,7 +34,7 @@ final class SelectorComponentTest { @Test void test() { - String pattern = "@p"; + final String pattern = "@p"; testComponent( Component.selector(pattern), CompoundBinaryTag.builder() @@ -45,8 +45,8 @@ void test() { @Test void testSeparator() { - String pattern = "@r"; - Component separator = Component.text(","); + final String pattern = "@r"; + final Component separator = Component.text(","); testComponent( Component.selector(pattern, separator), diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTests.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTests.java index cf04b13989..c7a10f369d 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTests.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/SerializerTests.java @@ -39,53 +39,54 @@ final class SerializerTests { private static final NBTComponentSerializer DEFAULT_SERIALIZER = NBTComponentSerializer.nbt(); - private SerializerTests() {} + private SerializerTests() { + } - static void testComponent(@NotNull Component component, @NotNull BinaryTag tag) { + static void testComponent(final @NotNull Component component, final @NotNull BinaryTag tag) { testComponent(DEFAULT_SERIALIZER, component, tag); } - static void testComponent(@NotNull NBTComponentSerializer serializer, - @NotNull Component component, @NotNull BinaryTag tag) { + static void testComponent(final @NotNull NBTComponentSerializer serializer, + final @NotNull Component component, final @NotNull BinaryTag tag) { assertEquals(tag, serializer.serialize(component)); assertEquals(component, serializer.deserialize(tag)); } - static void testStyle(@NotNull Style style, @NotNull CompoundBinaryTag tag) { + static void testStyle(final @NotNull Style style, final @NotNull CompoundBinaryTag tag) { testStyle(DEFAULT_SERIALIZER, style, tag); } - static void testStyle(@NotNull NBTComponentSerializer serializer, - @NotNull Style style, @NotNull CompoundBinaryTag tag) { + static void testStyle(final @NotNull NBTComponentSerializer serializer, + final @NotNull Style style, final @NotNull CompoundBinaryTag tag) { assertEquals(tag, serializer.serializeStyle(style)); assertEquals(style, serializer.deserializeStyle(tag)); } - static @NotNull Component deserializeComponent(@NotNull BinaryTag tag) { + static @NotNull Component deserializeComponent(final @NotNull BinaryTag tag) { return DEFAULT_SERIALIZER.deserialize(tag); } - static @NotNull BinaryTag serializeComponent(@NotNull Component component) { + static @NotNull BinaryTag serializeComponent(final @NotNull Component component) { return DEFAULT_SERIALIZER.serialize(component); } - static @NotNull Style deserializeStyle(@NotNull CompoundBinaryTag tag) { + static @NotNull Style deserializeStyle(final @NotNull CompoundBinaryTag tag) { return DEFAULT_SERIALIZER.deserializeStyle(tag); } - static @NotNull String name(@NotNull TextDecoration decoration) { + static @NotNull String name(final @NotNull TextDecoration decoration) { return TextDecoration.NAMES.keyOrThrow(decoration); } - static @NotNull String name(@NotNull NamedTextColor decoration) { + static @NotNull String name(final @NotNull NamedTextColor decoration) { return NamedTextColor.NAMES.keyOrThrow(decoration); } - static @NotNull String name(ClickEvent.@NotNull Action action) { + static @NotNull String name(final ClickEvent.@NotNull Action action) { return ClickEvent.Action.NAMES.keyOrThrow(action); } - static @NotNull String name(HoverEvent.@NotNull Action action) { + static @NotNull String name(final HoverEvent.@NotNull Action action) { return HoverEvent.Action.NAMES.keyOrThrow(action); } } diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowEntityTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowEntityTest.java index c951fc411b..60ec6bc283 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowEntityTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowEntityTest.java @@ -23,6 +23,8 @@ */ package net.kyori.adventure.text.serializer.nbt; +import java.io.IOException; +import java.util.UUID; import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.IntArrayBinaryTag; @@ -33,9 +35,6 @@ import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; import org.junit.jupiter.api.Test; -import java.io.IOException; -import java.util.UUID; - import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.SNBT_IO; import static net.kyori.adventure.text.serializer.nbt.SerializerTests.deserializeStyle; import static net.kyori.adventure.text.serializer.nbt.SerializerTests.name; @@ -46,7 +45,7 @@ final class ShowEntityTest { @Test void testWithoutName() { - UUID uuid = UUID.fromString("c04d19f7-9854-4122-93ab-ad7d4e1af8bc"); + final UUID uuid = UUID.fromString("c04d19f7-9854-4122-93ab-ad7d4e1af8bc"); testStyle( Style.style() .hoverEvent(HoverEvent.showEntity(Key.key("zombie"), uuid)) @@ -69,9 +68,9 @@ void testWithoutName() { @Test void testWithName() { - String entityId = "minecraft:spider"; - UUID uuid = UUID.randomUUID(); - String entityName = "Adventure spider"; + final String entityId = "minecraft:spider"; + final UUID uuid = UUID.randomUUID(); + final String entityName = "Adventure spider"; testStyle( Style.style() @@ -107,10 +106,10 @@ void testWithName() { @Test void testLegacyWithoutName() throws IOException { - String entityType = "minecraft:blaze"; - UUID uuid = UUID.randomUUID(); + final String entityType = "minecraft:blaze"; + final UUID uuid = UUID.randomUUID(); - CompoundBinaryTag contentsTag = CompoundBinaryTag.builder() + final CompoundBinaryTag contentsTag = CompoundBinaryTag.builder() .putString(ComponentTreeConstants.SHOW_ENTITY_TYPE, entityType) .putString(ComponentTreeConstants.SHOW_ENTITY_ID, uuid.toString()) .build(); @@ -140,11 +139,11 @@ void testLegacyWithoutName() throws IOException { @Test void testLegacyWithName() throws IOException { - String entityType = "minecraft:chicken"; - UUID uuid = UUID.fromString("a8aa3054-ca11-41bd-ac7e-95967816a135"); - Component entityName = Component.text("Lava chicken", NamedTextColor.DARK_RED); + final String entityType = "minecraft:chicken"; + final UUID uuid = UUID.fromString("a8aa3054-ca11-41bd-ac7e-95967816a135"); + final Component entityName = Component.text("Lava chicken", NamedTextColor.DARK_RED); - CompoundBinaryTag contentsTag = CompoundBinaryTag.builder() + final CompoundBinaryTag contentsTag = CompoundBinaryTag.builder() .putString(ComponentTreeConstants.SHOW_ENTITY_TYPE, entityType) .putString(ComponentTreeConstants.SHOW_ENTITY_ID, uuid.toString()) .put(ComponentTreeConstants.SHOW_ENTITY_NAME, serializeComponent(entityName)) diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowItemTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowItemTest.java index 3a932e9bea..feb9f59460 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowItemTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/ShowItemTest.java @@ -23,6 +23,8 @@ */ package net.kyori.adventure.text.serializer.nbt; +import java.io.IOException; +import java.util.Collections; import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.EndBinaryTag; @@ -34,9 +36,6 @@ import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; import org.junit.jupiter.api.Test; -import java.io.IOException; -import java.util.Collections; - import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.SNBT_CODEC; import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.SNBT_IO; import static net.kyori.adventure.text.serializer.nbt.SerializerTests.deserializeStyle; @@ -50,8 +49,8 @@ final class ShowItemTest { @Test void testWithPopulatedTag() throws IOException { - String item = "minecraft:diamond"; - int count = 2; + final String item = "minecraft:diamond"; + final int count = 2; testStyle( NBTComponentSerializer.builder() @@ -99,8 +98,8 @@ void testWithPopulatedTag() throws IOException { @Test void testWithoutAdditionalData() { - String item = "minecraft:diamond"; - int count = 2; + final String item = "minecraft:diamond"; + final int count = 2; testStyle( Style.style() @@ -121,8 +120,8 @@ void testWithoutAdditionalData() { @Test void testWithCountOfOne() { - String item = "minecraft:diamond"; - int count = 1; + final String item = "minecraft:diamond"; + final int count = 1; testStyle( Style.style() @@ -143,9 +142,9 @@ void testWithCountOfOne() { @Test void testWithRemovedComponent() { - String item = "minecraft:diamond"; - int count = 2; - String component = "minecraft:damage"; + final String item = "minecraft:diamond"; + final int count = 2; + final String component = "minecraft:damage"; testStyle( Style.style() @@ -177,10 +176,10 @@ void testWithRemovedComponent() { @Test void testLegacyWithoutTag() throws IOException { - String item = "minecraft:diamond"; - byte count = 3; + final String item = "minecraft:diamond"; + final byte count = 3; - CompoundBinaryTag itemData = CompoundBinaryTag.builder() + final CompoundBinaryTag itemData = CompoundBinaryTag.builder() .putString(ComponentTreeConstants.SHOW_ITEM_ID, item) .putByte(LEGACY_COUNT, count) .build(); @@ -205,10 +204,10 @@ void testLegacyWithoutTag() throws IOException { @Test void testLegacyWithTag() throws IOException { - String item = "minecraft:diamond"; - byte count = 1; + final String item = "minecraft:diamond"; + final byte count = 1; - CompoundBinaryTag itemTag = CompoundBinaryTag.builder() + final CompoundBinaryTag itemTag = CompoundBinaryTag.builder() .put( "display", CompoundBinaryTag.builder() @@ -217,7 +216,7 @@ void testLegacyWithTag() throws IOException { ) .build(); - CompoundBinaryTag itemData = CompoundBinaryTag.builder() + final CompoundBinaryTag itemData = CompoundBinaryTag.builder() .putString(ComponentTreeConstants.SHOW_ITEM_ID, item) .putByte(LEGACY_COUNT, count) .put(ComponentTreeConstants.SHOW_ITEM_TAG, itemTag) diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java index e6ce59db02..7b91908bed 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StorageNBTComponentTest.java @@ -34,8 +34,8 @@ final class StorageNBTComponentTest { @Test void testWithoutInterpret() { - String nbtPath = "abc"; - String storage = "doom:apple"; + final String nbtPath = "abc"; + final String storage = "doom:apple"; testComponent( Component.storageNBT() @@ -51,8 +51,8 @@ void testWithoutInterpret() { @Test void testWithInterpret() { - String nbtPath = "abc"; - String storage = "doom:apple"; + final String nbtPath = "abc"; + final String storage = "doom:apple"; testComponent( Component.storageNBT() diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StyleTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StyleTest.java index c2ee98cd43..9a6fd817a7 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StyleTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StyleTest.java @@ -23,6 +23,7 @@ */ package net.kyori.adventure.text.serializer.nbt; +import java.util.UUID; import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.BinaryTagTypes; import net.kyori.adventure.nbt.CompoundBinaryTag; @@ -42,8 +43,6 @@ import net.kyori.adventure.util.TriState; import org.junit.jupiter.api.Test; -import java.util.UUID; - import static net.kyori.adventure.text.serializer.nbt.SerializerTests.deserializeStyle; import static net.kyori.adventure.text.serializer.nbt.SerializerTests.name; import static net.kyori.adventure.text.serializer.nbt.SerializerTests.testStyle; @@ -108,7 +107,7 @@ void testDecoration() { @Test void testShadowColorInt() { - int shadowColorValue = 0xCCFF0022; + final int shadowColorValue = 0xCCFF0022; testStyle( Style.style(ShadowColor.shadowColor(shadowColorValue)), CompoundBinaryTag.builder() @@ -140,7 +139,7 @@ void testShadowColorFloats() { @Test void testInsertion() { - String insertion = "honk"; + final String insertion = "honk"; testStyle( Style.style() .insertion(insertion) @@ -153,7 +152,7 @@ void testInsertion() { @Test void testMixedFontColorDecorationClickEvent() { - String clickEventUrl = "https://github.com"; + final String clickEventUrl = "https://github.com"; testStyle( Style.style() .font(Key.key("kyori", "kittens")) @@ -178,8 +177,8 @@ void testMixedFontColorDecorationClickEvent() { @Test void testShowEntityHoverEvent() { - UUID showEntityUUID = UUID.randomUUID(); - String showEntityName = "Dolores"; + final UUID showEntityUUID = UUID.randomUUID(); + final String showEntityName = "Dolores"; testStyle( Style.style() diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java index c72c24c305..d94e640046 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/TranslatableComponentTest.java @@ -23,6 +23,7 @@ */ package net.kyori.adventure.text.serializer.nbt; +import java.util.UUID; import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.IntArrayBinaryTag; @@ -34,15 +35,13 @@ import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; import org.junit.jupiter.api.Test; -import java.util.UUID; - import static net.kyori.adventure.text.serializer.nbt.SerializerTests.name; import static net.kyori.adventure.text.serializer.nbt.SerializerTests.testComponent; final class TranslatableComponentTest { @Test void testNoArgs() { - String translationKey = "multiplayer.player.left"; + final String translationKey = "multiplayer.player.left"; testComponent( Component.translatable(translationKey), CompoundBinaryTag.builder() @@ -53,8 +52,8 @@ void testNoArgs() { @Test void testFallback() { - String translationKey = "thisIsA"; - String fallback = "This is a test."; + final String translationKey = "thisIsA"; + final String fallback = "This is a test."; testComponent( Component.translatable() @@ -70,12 +69,12 @@ void testFallback() { @Test void testSingleArgWithEvents() { - String translationKey = "translatable.message"; + final String translationKey = "translatable.message"; - UUID id = UUID.fromString("86365c36-e272-4d32-8ab8-d4fee19f6231"); - String name = "Codestech"; - String command = String.format("/msg %s ", name); - String showEntityId = "minecraft:player"; + final UUID id = UUID.fromString("86365c36-e272-4d32-8ab8-d4fee19f6231"); + final String name = "Codestech"; + final String command = String.format("/msg %s ", name); + final String showEntityId = "minecraft:player"; testComponent( Component.translatable() From d82991a97260e605b013009894c96db56820ed02 Mon Sep 17 00:00:00 2001 From: codestech Date: Tue, 1 Jul 2025 10:33:38 +0200 Subject: [PATCH 81/86] fix: spotless task is failing --- .../adventure/text/serializer/nbt/ShowEntitySerializer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java index 8e759099d6..dbbcacad31 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShowEntitySerializer.java @@ -42,7 +42,7 @@ import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.requiredTag; final class ShowEntitySerializer { - + private ShowEntitySerializer() { } @@ -58,7 +58,7 @@ private ShowEntitySerializer() { } } } - + static @NotNull CompoundBinaryTag serialize(final HoverEvent.@NotNull ShowEntity showEntity, final boolean snakeCase, final @NotNull NBTComponentSerializerImpl serializer) { final CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() From b6e307c87d3d4259ce0288900149382c235cb40c Mon Sep 17 00:00:00 2001 From: codestech Date: Wed, 2 Jul 2025 16:20:20 +0200 Subject: [PATCH 82/86] fix: lists are not serialized as arrays when it is possible (vanilla does that) --- .../serializer/nbt/NBTAggregateCollector.java | 193 ++++++++++++++++++ .../nbt/NBTComponentSerializerImpl.java | 27 ++- .../serializer/nbt/NBTSerializerUtils.java | 27 +++ 3 files changed, 233 insertions(+), 14 deletions(-) create mode 100644 text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTAggregateCollector.java diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTAggregateCollector.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTAggregateCollector.java new file mode 100644 index 0000000000..88208b2cbb --- /dev/null +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTAggregateCollector.java @@ -0,0 +1,193 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2025 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.serializer.nbt; + +import java.util.Arrays; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.ByteArrayBinaryTag; +import net.kyori.adventure.nbt.ByteBinaryTag; +import net.kyori.adventure.nbt.IntArrayBinaryTag; +import net.kyori.adventure.nbt.IntBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; +import net.kyori.adventure.nbt.LongArrayBinaryTag; +import net.kyori.adventure.nbt.LongBinaryTag; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/*sealed*/ interface NBTAggregateCollector { + + void add(final @NotNull BinaryTag tag); + + @NotNull BinaryTag collect(); + + static @NotNull NBTAggregateCollector create() { + return new Initial(); + } + + final class Initial implements NBTAggregateCollector { + + private @Nullable NBTAggregateCollector delegate = null; + + private Initial() { + } + + @Override + public void add(final @NotNull BinaryTag tag) { + if (this.delegate != null) { + this.delegate.add(tag); + } else if (tag instanceof ByteBinaryTag) { + this.delegate = new ByteArrayCollector(((ByteBinaryTag) tag).value()); + } else if (tag instanceof IntBinaryTag) { + this.delegate = new IntArrayCollector(((IntBinaryTag) tag).value()); + } else if (tag instanceof LongBinaryTag) { + this.delegate = new LongArrayCollector(((LongBinaryTag) tag).value()); + } else { + this.delegate = new ListCollector(tag); + } + } + + @Override + public @NotNull BinaryTag collect() { + return this.delegate == null ? ListBinaryTag.empty() : this.delegate.collect(); + } + } + + final class ListCollector implements NBTAggregateCollector { + + private final ListBinaryTag.Builder builder = ListBinaryTag.heterogeneousListBinaryTag(); + + private ListCollector() { + } + + private ListCollector(final @NotNull BinaryTag firstElement) { + this.add(firstElement); + } + + @Override + public void add(final @NotNull BinaryTag tag) { + this.builder.add(tag); + } + + @Override + public @NotNull BinaryTag collect() { + return this.builder.build().wrapHeterogeneity(); + } + } + + final class ByteArrayCollector implements NBTAggregateCollector { + + private byte @NotNull [] array; + private @Nullable NBTAggregateCollector delegate = null; + + private ByteArrayCollector(final byte firstElement) { + this.array = new byte[]{firstElement}; + } + + @Override + public void add(final @NotNull BinaryTag tag) { + if (this.delegate != null) { + this.delegate.add(tag); + } else if (tag instanceof ByteBinaryTag) { + final int index = this.array.length; + this.array = Arrays.copyOf(this.array, index + 1); + this.array[index] = ((ByteBinaryTag) tag).value(); + } else { + this.delegate = new ListCollector(); + for (final byte element : this.array) { + this.delegate.add(ByteBinaryTag.byteBinaryTag(element)); + } + this.delegate.add(tag); + } + } + + @Override + public @NotNull BinaryTag collect() { + return this.delegate == null ? ByteArrayBinaryTag.byteArrayBinaryTag(this.array) : this.delegate.collect(); + } + } + + final class IntArrayCollector implements NBTAggregateCollector { + + private int @NotNull [] array; + private @Nullable NBTAggregateCollector delegate = null; + + private IntArrayCollector(final int firstElement) { + this.array = new int[]{firstElement}; + } + + @Override + public void add(final @NotNull BinaryTag tag) { + if (this.delegate != null) { + this.delegate.add(tag); + } else if (tag instanceof IntBinaryTag) { + final int index = this.array.length; + this.array = Arrays.copyOf(this.array, index + 1); + this.array[index] = ((IntBinaryTag) tag).value(); + } else { + this.delegate = new ListCollector(); + for (final int element : this.array) { + this.delegate.add(IntBinaryTag.intBinaryTag(element)); + } + this.delegate.add(tag); + } + } + + @Override + public @NotNull BinaryTag collect() { + return this.delegate == null ? IntArrayBinaryTag.intArrayBinaryTag(this.array) : this.delegate.collect(); + } + } + + final class LongArrayCollector implements NBTAggregateCollector { + + private long @NotNull [] array; + private @Nullable NBTAggregateCollector delegate = null; + + private LongArrayCollector(final long firstElement) { + this.array = new long[]{firstElement}; + } + + @Override + public void add(final @NotNull BinaryTag tag) { + if (this.delegate != null) { + this.delegate.add(tag); + } else if (tag instanceof LongBinaryTag) { + final int index = this.array.length; + this.array = Arrays.copyOf(this.array, index + 1); + this.array[index] = ((LongBinaryTag) tag).value(); + } else { + this.delegate = new ListCollector(); + for (final long element : this.array) { + this.delegate.add(LongBinaryTag.longBinaryTag(element)); + } + this.delegate.add(tag); + } + } + + @Override + public @NotNull BinaryTag collect() { + return this.delegate == null ? LongArrayBinaryTag.longArrayBinaryTag(this.array) : this.delegate.collect(); + } + } +} diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index 0b72f51931..acea384265 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -24,7 +24,6 @@ package net.kyori.adventure.text.serializer.nbt; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.function.Consumer; @@ -68,6 +67,7 @@ import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.TRANSLATE_FALLBACK; import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.TRANSLATE_WITH; import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.asBoolean; +import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.forEach; import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.optionalTag; import static net.kyori.adventure.text.serializer.nbt.NBTSerializerUtils.requiredTag; @@ -131,14 +131,11 @@ static final class Instances { final CompoundBinaryTag compound = (CompoundBinaryTag) input; final Style style = StyleSerializer.deserialize(compound, this); - final ListBinaryTag extraTag = optionalTag(compound, EXTRA, BinaryTagTypes.LIST); - final List children; + final BinaryTag extraTag = compound.get(EXTRA); + final List children = new ArrayList<>(); - if (extraTag == null) { - children = Collections.emptyList(); - } else { - children = new ArrayList<>(); - extraTag.unwrapHeterogeneity().forEach(child -> children.add(this.deserialize(child))); + if (extraTag != null) { + forEach(extraTag, child -> children.add(this.deserialize(child))); } if (compound.get(TEXT) != null) { @@ -149,11 +146,13 @@ static final class Instances { .build(); } else if (compound.get(TRANSLATE) != null) { final StringBinaryTag translateTag = requiredTag(compound, TRANSLATE, BinaryTagTypes.STRING); - final ListBinaryTag translateWithTag = compound.getList(TRANSLATE_WITH).unwrapHeterogeneity(); + final BinaryTag translateWithTag = compound.get(TRANSLATE_WITH); final StringBinaryTag fallbackTag = optionalTag(compound, TRANSLATE_FALLBACK, BinaryTagTypes.STRING); final List arguments = new ArrayList<>(); - translateWithTag.forEach(argumentTag -> arguments.add(TranslationArgumentSerializer.deserialize(argumentTag, this))); + if (translateWithTag != null) { + forEach(translateWithTag, argumentTag -> arguments.add(TranslationArgumentSerializer.deserialize(argumentTag, this))); + } return Component.translatable() .key(translateTag.value()) @@ -258,9 +257,9 @@ static final class Instances { final List arguments = translatable.arguments(); if (!arguments.isEmpty()) { - final ListBinaryTag.Builder translateWithTagBuilder = ListBinaryTag.heterogeneousListBinaryTag(); + final NBTAggregateCollector translateWithTagBuilder = NBTAggregateCollector.create(); arguments.forEach(argument -> translateWithTagBuilder.add(TranslationArgumentSerializer.serialize(argument, this))); - builder.put(TRANSLATE_WITH, translateWithTagBuilder.build().wrapHeterogeneity()); + builder.put(TRANSLATE_WITH, translateWithTagBuilder.collect()); } } else if (component instanceof KeybindComponent) { builder.putString(KEYBIND, ((KeybindComponent) component).keybind()); @@ -308,9 +307,9 @@ static final class Instances { final List children = component.children(); if (!children.isEmpty()) { - final ListBinaryTag.Builder extraTagBuilder = ListBinaryTag.heterogeneousListBinaryTag(); + final NBTAggregateCollector extraTagBuilder = NBTAggregateCollector.create(); children.forEach(child -> extraTagBuilder.add(this.serialize(child))); - builder.put(EXTRA, extraTagBuilder.build().wrapHeterogeneity()); + builder.put(EXTRA, extraTagBuilder.collect()); } StyleSerializer.serialize(component.style(), builder, this); diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java index 68fb6cb0a6..e22368be30 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerUtils.java @@ -24,10 +24,17 @@ package net.kyori.adventure.text.serializer.nbt; import java.io.IOException; +import java.util.function.Consumer; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.BinaryTagType; +import net.kyori.adventure.nbt.ByteArrayBinaryTag; import net.kyori.adventure.nbt.ByteBinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.IntArrayBinaryTag; +import net.kyori.adventure.nbt.IntBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; +import net.kyori.adventure.nbt.LongArrayBinaryTag; +import net.kyori.adventure.nbt.LongBinaryTag; import net.kyori.adventure.nbt.NumberBinaryTag; import net.kyori.adventure.nbt.TagStringIO; import net.kyori.adventure.util.Codec; @@ -87,6 +94,26 @@ static boolean asBoolean(final @NotNull NumberBinaryTag tag) { return value ? ByteBinaryTag.ONE : ByteBinaryTag.ZERO; } + static void forEach(final @NotNull BinaryTag tag, final @NotNull Consumer action) { + if (tag instanceof ListBinaryTag) { + ((ListBinaryTag) tag).unwrapHeterogeneity().forEach(action); + } else if (tag instanceof ByteArrayBinaryTag) { + for (final byte value : ((ByteArrayBinaryTag) tag).value()) { + action.accept(ByteBinaryTag.byteBinaryTag(value)); + } + } else if (tag instanceof IntArrayBinaryTag) { + for (final int value : ((IntArrayBinaryTag) tag).value()) { + action.accept(IntBinaryTag.intBinaryTag(value)); + } + } else if (tag instanceof LongArrayBinaryTag) { + for (final long value : ((LongArrayBinaryTag) tag).value()) { + action.accept(LongBinaryTag.longBinaryTag(value)); + } + } else { + throw new IllegalArgumentException("The specified tag (" + tag + ") does not represent an aggregate"); + } + } + private static @NotNull IllegalArgumentException noSuchField(final @NotNull String name) { return new IllegalArgumentException("The specified compound tag does not contain a field with name of \"" + name + "\""); } From 7a6f3b9cc8b38ba975e3f5a6fe68eed65675adb6 Mon Sep 17 00:00:00 2001 From: codestech Date: Thu, 3 Jul 2025 12:34:48 +0200 Subject: [PATCH 83/86] fix(nbt): TagStringWriter does not write compound entries in vanilla order --- .../kyori/adventure/nbt/TagStringWriter.java | 17 +++++++++++++---- nbt/src/test/resources/bigtest.snbt | 10 +++++----- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/nbt/src/main/java/net/kyori/adventure/nbt/TagStringWriter.java b/nbt/src/main/java/net/kyori/adventure/nbt/TagStringWriter.java index c3e7934bb8..f90b4ea2fe 100644 --- a/nbt/src/main/java/net/kyori/adventure/nbt/TagStringWriter.java +++ b/nbt/src/main/java/net/kyori/adventure/nbt/TagStringWriter.java @@ -25,7 +25,9 @@ import java.io.IOException; import java.io.Writer; -import java.util.Map; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; /** * An emitter for the SNBT format. @@ -94,10 +96,17 @@ public TagStringWriter writeTag(final BinaryTag tag) throws IOException { private TagStringWriter writeCompound(final CompoundBinaryTag tag) throws IOException { this.beginCompound(); - for (final Map.Entry entry : tag) { - this.key(entry.getKey()); - this.writeTag(entry.getValue()); + + final List keys = new ArrayList<>(tag.keySet()); + Collections.sort(keys); + + for (final String key : keys) { + final BinaryTag value = tag.get(key); + if (value == null) continue; + this.key(key); + this.writeTag(value); } + this.endCompound(); return this; } diff --git a/nbt/src/test/resources/bigtest.snbt b/nbt/src/test/resources/bigtest.snbt index ec5e3b4a2d..ce40e15049 100644 --- a/nbt/src/test/resources/bigtest.snbt +++ b/nbt/src/test/resources/bigtest.snbt @@ -1,11 +1,8 @@ { - shortTest: 32767s, - longTest: 9223372036854775807L, - byteTest: 127b, "byteArrayTest (the first 1000 values of (n*n*255+n*7)%100, starting with n=0 (0, 62, 34, 16, 8, ...))": [B; 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B, 0B, 62B, 34B, 16B, 8B, 10B, 22B, 44B, 76B, 18B, 70B, 32B, 4B, 86B, 78B, 80B, 92B, 14B, 46B, 88B, 40B, 2B, 74B, 56B, 48B, 50B, 62B, 84B, 16B, 58B, 10B, 72B, 44B, 26B, 18B, 20B, 32B, 54B, 86B, 28B, 80B, 42B, 14B, 96B, 88B, 90B, 2B, 24B, 56B, 98B, 50B, 12B, 84B, 66B, 58B, 60B, 72B, 94B, 26B, 68B, 20B, 82B, 54B, 36B, 28B, 30B, 42B, 64B, 96B, 38B, 90B, 52B, 24B, 6B, 98B, 0B, 12B, 34B, 66B, 8B, 60B, 22B, 94B, 76B, 68B, 70B, 82B, 4B, 36B, 78B, 30B, 92B, 64B, 46B, 38B, 40B, 52B, 74B, 6B, 48B], - "listTest (long)": [11L, 12L, 13L, 14L, 15L], - floatTest: 0.49823147f, + byteTest: 127b, doubleTest: 0.4931287132182315d, + floatTest: 0.49823147f, intTest: 2147483647, "listTest (compound)": [ { @@ -17,6 +14,8 @@ name: "Compound tag #1" } ], + "listTest (long)": [11L, 12L, 13L, 14L, 15L], + longTest: 9223372036854775807L, "nested compound test": { egg: { name: "Eggbert", @@ -27,5 +26,6 @@ value: 0.75f } }, + shortTest: 32767s, stringTest: "HELLO WORLD THIS IS A TEST STRING ÅÄÖ!" } From a87c34ae2b8857c966469bceabf53203bfda4239 Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 6 Jul 2025 12:32:39 +0200 Subject: [PATCH 84/86] chore: replace NBTSerializerOptions#SHADOW_COLOR_MODE with NBTSerializerOptions#EMIT_SHADOW_COLOR, fix: versioned option state of NBTSerializerOptions serializes shadow color as a list by default --- .../serializer/nbt/NBTSerializerOptions.java | 36 ++++--------------- .../serializer/nbt/ShadowColorSerializer.java | 24 +------------ .../text/serializer/nbt/StyleTest.java | 32 ++++++++--------- 3 files changed, 23 insertions(+), 69 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index e6457edbf8..b06c88cf6c 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -39,11 +39,12 @@ public final class NBTSerializerOptions { /** - * How to emit shadow colour data. + * Whether to emit shadow colour data. * * @since 4.24.0 + * @sinceMinecraft 1.21.4 */ - public static final Option SHADOW_COLOR_MODE; + public static final Option EMIT_SHADOW_COLOR; /** * Control how hover event values should be emitted. @@ -95,7 +96,7 @@ public final class NBTSerializerOptions { static { final OptionSchema.Mutable schema = OptionSchema.emptySchema(); - SHADOW_COLOR_MODE = schema.enumOption(key("emit/shadow_color"), ShadowColorEmitMode.class, ShadowColorEmitMode.EMIT_INTEGER); + EMIT_SHADOW_COLOR = schema.booleanOption(key("emit/shadow_color"), true); EMIT_HOVER_EVENT_TYPE = schema.enumOption(key("emit/hover_value_mode"), HoverEventValueMode.class, HoverEventValueMode.SNAKE_CASE); EMIT_CLICK_EVENT_TYPE = schema.enumOption(key("emit/click_value_mode"), ClickEventValueMode.class, ClickEventValueMode.SNAKE_CASE); EMIT_DEFAULT_ITEM_HOVER_QUANTITY = schema.booleanOption(key("emit/default_item_hover_quantity"), true); @@ -106,7 +107,7 @@ public final class NBTSerializerOptions { BY_DATA_VERSION = SCHEMA.versionedStateBuilder() .version( VERSION_23W40A, - builder -> builder.value(SHADOW_COLOR_MODE, ShadowColorEmitMode.NONE) + builder -> builder.value(EMIT_SHADOW_COLOR, false) .value(EMIT_HOVER_EVENT_TYPE, HoverEventValueMode.CAMEL_CASE) .value(EMIT_CLICK_EVENT_TYPE, ClickEventValueMode.CAMEL_CASE) .value(EMIT_DEFAULT_ITEM_HOVER_QUANTITY, false) @@ -123,7 +124,7 @@ public final class NBTSerializerOptions { ) .version( VERSION_24W44A, - builder -> builder.value(SHADOW_COLOR_MODE, ShadowColorEmitMode.EMIT_ARRAY) + builder -> builder.value(EMIT_SHADOW_COLOR, true) ) .version( VERSION_25W02A, @@ -217,31 +218,6 @@ public enum ClickEventValueMode { BOTH, } - /** - * How text shadow colors should be emitted. - * - * @since 4.24.0 - * @sinceMinecraft 1.21.4 - */ - public enum ShadowColorEmitMode { - /** - * Do not emit shadow colours. - */ - NONE, - /** - * Emit as a single packed integer value containing, in order, ARGB bytes. - * - * @since 4.24.0 - */ - EMIT_INTEGER, - /** - * Emit a colour as 4-element float array of the RGBA components of the colour. - * - * @since 4.24.0 - */ - EMIT_ARRAY - } - /** * Configure how to emit show item hovers in {@code hoverEvent} (camelCase) fields. * diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java index 1049ac0bb8..02d5e2f9c8 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/ShadowColorSerializer.java @@ -24,8 +24,6 @@ package net.kyori.adventure.text.serializer.nbt; import net.kyori.adventure.nbt.BinaryTag; -import net.kyori.adventure.nbt.BinaryTagTypes; -import net.kyori.adventure.nbt.FloatBinaryTag; import net.kyori.adventure.nbt.IntBinaryTag; import net.kyori.adventure.nbt.ListBinaryTag; import net.kyori.adventure.text.format.ShadowColor; @@ -55,30 +53,10 @@ private ShadowColorSerializer() { } static @Nullable BinaryTag serialize(final @NotNull ShadowColor color, final @NotNull NBTComponentSerializerImpl serializer) { - final NBTSerializerOptions.ShadowColorEmitMode emitMode = serializer.options().value(NBTSerializerOptions.SHADOW_COLOR_MODE); - switch (emitMode) { - case NONE: - return null; - case EMIT_INTEGER: - return IntBinaryTag.intBinaryTag(color.value()); - case EMIT_ARRAY: - final ListBinaryTag.Builder builder = ListBinaryTag.builder(BinaryTagTypes.FLOAT); - addShadowColorComponent(builder, color.red()); - addShadowColorComponent(builder, color.green()); - addShadowColorComponent(builder, color.blue()); - addShadowColorComponent(builder, color.alpha()); - return builder.build(); - default: - // Never called, but needed for proper compilation - throw new IllegalArgumentException("Unknown shadow color emit mode: " + emitMode); - } + return serializer.options().value(NBTSerializerOptions.EMIT_SHADOW_COLOR) ? IntBinaryTag.intBinaryTag(color.value()) : null; } private static int shadowColorComponent(final @NotNull ListBinaryTag tag, final int index) { return (int) (tag.getFloat(index) * 0xff); } - - private static void addShadowColorComponent(final ListBinaryTag.@NotNull Builder builder, final int element) { - builder.add(FloatBinaryTag.floatBinaryTag((float) element / 0xff)); - } } diff --git a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StyleTest.java b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StyleTest.java index 9a6fd817a7..fef9ea30cf 100644 --- a/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StyleTest.java +++ b/text-serializer-nbt/src/test/java/net/kyori/adventure/text/serializer/nbt/StyleTest.java @@ -46,6 +46,7 @@ import static net.kyori.adventure.text.serializer.nbt.SerializerTests.deserializeStyle; import static net.kyori.adventure.text.serializer.nbt.SerializerTests.name; import static net.kyori.adventure.text.serializer.nbt.SerializerTests.testStyle; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; final class StyleTest { @@ -117,23 +118,22 @@ void testShadowColorInt() { } @Test - void testShadowColorFloats() { - testStyle( - NBTComponentSerializer.builder() - .editOptions(builder -> builder.value(NBTSerializerOptions.SHADOW_COLOR_MODE, NBTSerializerOptions.ShadowColorEmitMode.EMIT_ARRAY)) - .build(), + void testShadowColorFloatList() { + assertEquals( Style.style(ShadowColor.shadowColor(0x80, 0x40, 0xcc, 0xff)), - CompoundBinaryTag.builder() - .put( - ComponentTreeConstants.SHADOW_COLOR, - ListBinaryTag.builder(BinaryTagTypes.FLOAT) - .add(FloatBinaryTag.floatBinaryTag(0.5019608f)) - .add(FloatBinaryTag.floatBinaryTag(0.2509804f)) - .add(FloatBinaryTag.floatBinaryTag(0.8f)) - .add(FloatBinaryTag.floatBinaryTag(1f)) - .build() - ) - .build() + deserializeStyle( + CompoundBinaryTag.builder() + .put( + ComponentTreeConstants.SHADOW_COLOR, + ListBinaryTag.builder(BinaryTagTypes.FLOAT) + .add(FloatBinaryTag.floatBinaryTag(0.5019608f)) + .add(FloatBinaryTag.floatBinaryTag(0.2509804f)) + .add(FloatBinaryTag.floatBinaryTag(0.8f)) + .add(FloatBinaryTag.floatBinaryTag(1f)) + .build() + ) + .build() + ) ); } From 96146cc05cc071d5db026ef974cbe44b669e7da6 Mon Sep 17 00:00:00 2001 From: codestech Date: Sun, 6 Jul 2025 13:27:30 +0200 Subject: [PATCH 85/86] fix: optimized lists are emitted on 25w04a and above --- .../text/serializer/nbt/NBTAggregateCollector.java | 4 ++-- .../serializer/nbt/NBTComponentSerializerImpl.java | 4 ++-- .../text/serializer/nbt/NBTSerializerOptions.java | 14 ++++++++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTAggregateCollector.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTAggregateCollector.java index 88208b2cbb..cedec95d0f 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTAggregateCollector.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTAggregateCollector.java @@ -41,8 +41,8 @@ @NotNull BinaryTag collect(); - static @NotNull NBTAggregateCollector create() { - return new Initial(); + static @NotNull NBTAggregateCollector create(final @NotNull NBTComponentSerializerImpl serializer) { + return serializer.options().value(NBTSerializerOptions.EMIT_OPTIMIZED_LISTS) ? new Initial() : new ListCollector(); } final class Initial implements NBTAggregateCollector { diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java index acea384265..e6b89c775e 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializerImpl.java @@ -257,7 +257,7 @@ static final class Instances { final List arguments = translatable.arguments(); if (!arguments.isEmpty()) { - final NBTAggregateCollector translateWithTagBuilder = NBTAggregateCollector.create(); + final NBTAggregateCollector translateWithTagBuilder = NBTAggregateCollector.create(this); arguments.forEach(argument -> translateWithTagBuilder.add(TranslationArgumentSerializer.serialize(argument, this))); builder.put(TRANSLATE_WITH, translateWithTagBuilder.collect()); } @@ -307,7 +307,7 @@ static final class Instances { final List children = component.children(); if (!children.isEmpty()) { - final NBTAggregateCollector extraTagBuilder = NBTAggregateCollector.create(); + final NBTAggregateCollector extraTagBuilder = NBTAggregateCollector.create(this); children.forEach(child -> extraTagBuilder.add(this.serialize(child))); builder.put(EXTRA, extraTagBuilder.collect()); } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index b06c88cf6c..3e2418c6e6 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -84,6 +84,13 @@ public final class NBTSerializerOptions { */ public static final Option EMIT_SHOW_TEXT_HOVER_TEXT_FIELD; + /** + * Whether to emit array binary tags instead of list binary tags when it's possible. + * + * @since 4.24.0 + */ + public static final Option EMIT_OPTIMIZED_LISTS; + private static final OptionSchema SCHEMA; private static final OptionState.Versioned BY_DATA_VERSION; @@ -93,6 +100,7 @@ public final class NBTSerializerOptions { private static final int VERSION_24W44A = 4174; // 1.21.4 snapshot private static final int VERSION_25W02A = 4298; // 1.21.5 snapshot private static final int VERSION_25W03A = 4304; // 1.21.5 snapshot + private static final int VERSION_25W04A = 4308; // 1.21.5 snapshot static { final OptionSchema.Mutable schema = OptionSchema.emptySchema(); @@ -102,6 +110,7 @@ public final class NBTSerializerOptions { EMIT_DEFAULT_ITEM_HOVER_QUANTITY = schema.booleanOption(key("emit/default_item_hover_quantity"), true); SHOW_ITEM_HOVER_DATA_MODE = schema.enumOption(key("emit/show_item_hover_data"), ShowItemHoverDataMode.class, ShowItemHoverDataMode.EMIT_EITHER); EMIT_SHOW_TEXT_HOVER_TEXT_FIELD = schema.booleanOption(key("emit/show_text_hover_text_field"), false); + EMIT_OPTIMIZED_LISTS = schema.booleanOption(key("emit/optimized_lists"), false); SCHEMA = schema.frozenView(); BY_DATA_VERSION = SCHEMA.versionedStateBuilder() @@ -113,6 +122,7 @@ public final class NBTSerializerOptions { .value(EMIT_DEFAULT_ITEM_HOVER_QUANTITY, false) .value(SHOW_ITEM_HOVER_DATA_MODE, ShowItemHoverDataMode.EMIT_LEGACY_NBT) .value(EMIT_SHOW_TEXT_HOVER_TEXT_FIELD, false) + .value(EMIT_OPTIMIZED_LISTS, true) ) .version( VERSION_24W09A, @@ -136,6 +146,10 @@ public final class NBTSerializerOptions { VERSION_25W03A, builder -> builder.value(EMIT_SHOW_TEXT_HOVER_TEXT_FIELD, false) ) + .version( + VERSION_25W04A, + builder -> builder.value(EMIT_OPTIMIZED_LISTS, false) + ) .build(); } From 6b5c1de1c5ef6cc6296ceb8f850fe6b62cc296b0 Mon Sep 17 00:00:00 2001 From: codestech Date: Mon, 11 Aug 2025 11:14:33 +0200 Subject: [PATCH 86/86] chore: replace adventure version references in the NBT Serializer from "4.24.0" to "4.25.0" --- .../nbt/NBTComponentSerializer.java | 24 +++++----- .../serializer/nbt/NBTDataComponentValue.java | 6 +-- .../serializer/nbt/NBTSerializerOptions.java | 44 +++++++++---------- ...BTDataComponentValueConverterProvider.java | 2 +- .../serializer/nbt/impl/package-info.java | 2 +- .../text/serializer/nbt/package-info.java | 2 +- 6 files changed, 40 insertions(+), 40 deletions(-) diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java index 4ce379d2df..f91c4a30ac 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTComponentSerializer.java @@ -38,7 +38,7 @@ /** * A NBT component serializer. * - * @since 4.24.0 + * @since 4.25.0 * @sinceMinecraft 1.20.3 */ public interface NBTComponentSerializer extends ComponentSerializer { @@ -47,7 +47,7 @@ public interface NBTComponentSerializer extends ComponentSerializer { /** @@ -94,7 +94,7 @@ interface Builder extends AbstractBuilder { * @param flags the flag set to use * @return this builder * @see NBTSerializerOptions - * @since 4.24.0 + * @since 4.25.0 */ @NotNull Builder options(final @NotNull OptionState flags); @@ -104,7 +104,7 @@ interface Builder extends AbstractBuilder { * @param optionEditor the consumer operating on the existing flag set * @return this builder * @see NBTSerializerOptions - * @since 4.24.0 + * @since 4.25.0 */ @NotNull Builder editOptions(final @NotNull Consumer optionEditor); @@ -112,7 +112,7 @@ interface Builder extends AbstractBuilder { * Builds the serializer. * * @return the built serializer - * @since 4.24.0 + * @since 4.25.0 */ @Override @NotNull NBTComponentSerializer build(); @@ -121,7 +121,7 @@ interface Builder extends AbstractBuilder { /** * A {@link NBTComponentSerializer} service provider. * - * @since 4.24.0 + * @since 4.25.0 */ @ApiStatus.Internal @PlatformAPI @@ -130,7 +130,7 @@ interface Provider { * Provides a standard {@link NBTComponentSerializer}. * * @return a {@link NBTComponentSerializer} - * @since 4.24.0 + * @since 4.25.0 */ @ApiStatus.Internal @PlatformAPI @@ -140,7 +140,7 @@ interface Provider { * Completes the building process of {@link Builder}. * * @return a {@link Consumer} - * @since 4.24.0 + * @since 4.25.0 */ @ApiStatus.Internal @PlatformAPI diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java index 2b9398cf1d..350b7864c2 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTDataComponentValue.java @@ -36,7 +36,7 @@ * *

This holder is exposed to allow conversions to/from NBT data holders.

* - * @since 4.24.0 + * @since 4.25.0 * @sinceMinecraft 1.20.3 */ @ApiStatus.NonExtendable @@ -45,7 +45,7 @@ public interface NBTDataComponentValue extends DataComponentValue { * The contained element. * * @return the contained element - * @since 4.24.0 + * @since 4.25.0 */ @NotNull BinaryTag binaryTag(); @@ -54,7 +54,7 @@ public interface NBTDataComponentValue extends DataComponentValue { * * @param data the item data to hold * @return a newly created item data holder instance - * @since 4.24.0 + * @since 4.25.0 */ static @NotNull NBTDataComponentValue nbtDataComponentValue(final @NotNull BinaryTag data) { if (data instanceof EndBinaryTag) { diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java index 3e2418c6e6..ee46fb7cde 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/NBTSerializerOptions.java @@ -33,7 +33,7 @@ * *

See serializer documentation for specific details on which flags are supported.

* - * @since 4.24.0 + * @since 4.25.0 * @sinceMinecraft 1.20.3 */ public final class NBTSerializerOptions { @@ -41,7 +41,7 @@ public final class NBTSerializerOptions { /** * Whether to emit shadow colour data. * - * @since 4.24.0 + * @since 4.25.0 * @sinceMinecraft 1.21.4 */ public static final Option EMIT_SHADOW_COLOR; @@ -49,14 +49,14 @@ public final class NBTSerializerOptions { /** * Control how hover event values should be emitted. * - * @since 4.24.0 + * @since 4.25.0 */ public static final Option EMIT_HOVER_EVENT_TYPE; /** * Control how click event values should be emitted. * - * @since 4.24.0 + * @since 4.25.0 */ public static final Option EMIT_CLICK_EVENT_TYPE; @@ -65,14 +65,14 @@ public final class NBTSerializerOptions { * *

When enabled, this matches Vanilla as of 1.20.5.

* - * @since 4.24.0 + * @since 4.25.0 */ public static final Option EMIT_DEFAULT_ITEM_HOVER_QUANTITY; /** * How to emit show item hovers in {@code hoverEvent} (camelCase) fields. * - * @since 4.24.0 + * @since 4.25.0 */ public static final Option SHOW_ITEM_HOVER_DATA_MODE; @@ -80,14 +80,14 @@ public final class NBTSerializerOptions { * Whether to emit {@code text} field instead of {@code value} field in {@code show_item} * hover events specified in {@code hover_event} (snake_case) fields. * - * @since 4.24.0 + * @since 4.25.0 */ public static final Option EMIT_SHOW_TEXT_HOVER_TEXT_FIELD; /** * Whether to emit array binary tags instead of list binary tags when it's possible. * - * @since 4.24.0 + * @since 4.25.0 */ public static final Option EMIT_OPTIMIZED_LISTS; @@ -164,7 +164,7 @@ private static String key(final String value) { * A schema of available options. * * @return the schema of known NBT serializer options - * @since 4.24.0 + * @since 4.25.0 */ public static @NotNull OptionSchema schema() { return SCHEMA; @@ -174,7 +174,7 @@ private static String key(final String value) { * NBT serializer options delineated by world data version. * * @return the versioned option state - * @since 4.24.0 + * @since 4.25.0 */ public static OptionState.@NotNull Versioned byDataVersion() { return BY_DATA_VERSION; @@ -183,25 +183,25 @@ private static String key(final String value) { /** * Configure how to emit hover event values. * - * @since 4.24.0 + * @since 4.25.0 */ public enum HoverEventValueMode { /** * Only emit the 1.21.5+ hover events using the {@code hover_event} field. * - * @since 4.24.0 + * @since 4.25.0 */ SNAKE_CASE, /** * Only emit the 1.16+ hover events using the {@code hoverEvent} field. * - * @since 4.24.0 + * @since 4.25.0 */ CAMEL_CASE, /** * Include both camel and snake case hover event fields, for maximum compatibility. * - * @since 4.24.0 + * @since 4.25.0 */ BOTH } @@ -209,25 +209,25 @@ public enum HoverEventValueMode { /** * Configure how to emit click event values. * - * @since 4.24.0 + * @since 4.25.0 */ public enum ClickEventValueMode { /** * Only emit the 1.21.5+ click events using the {@code click_event} field. * - * @since 4.24.0 + * @since 4.25.0 */ SNAKE_CASE, /** * Only emit the pre-1.21.5 click events using the {@code clickEvent} field. * - * @since 4.24.0 + * @since 4.25.0 */ CAMEL_CASE, /** * Include both camel and snake case click event fields, for maximum compatibility. * - * @since 4.24.0 + * @since 4.25.0 */ BOTH, } @@ -235,25 +235,25 @@ public enum ClickEventValueMode { /** * Configure how to emit show item hovers in {@code hoverEvent} (camelCase) fields. * - * @since 4.24.0 + * @since 4.25.0 */ public enum ShowItemHoverDataMode { /** * Only emit the pre-1.20.5 item NBT. * - * @since 4.24.0 + * @since 4.25.0 */ EMIT_LEGACY_NBT, /** * Only emit modern data components. * - * @since 4.24.0 + * @since 4.25.0 */ EMIT_DATA_COMPONENTS, /** * Emit whichever of legacy or modern data the item has. * - * @since 4.24.0 + * @since 4.25.0 */ EMIT_EITHER, } diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/NBTDataComponentValueConverterProvider.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/NBTDataComponentValueConverterProvider.java index 00f24c94be..36f5aa92f6 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/NBTDataComponentValueConverterProvider.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/NBTDataComponentValueConverterProvider.java @@ -39,7 +39,7 @@ * *

This is public SPI, not API.

* - * @since 4.24.0 + * @since 4.25.0 */ @AutoService(DataComponentValueConverterRegistry.Provider.class) @ApiStatus.Internal diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/package-info.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/package-info.java index d29533dafb..5f29119a3f 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/package-info.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/impl/package-info.java @@ -24,7 +24,7 @@ /** * Internal classes for the NBT component serializer. * - * @since 4.24.0 + * @since 4.25.0 * @sinceMinecraft 1.20.3 */ @ApiStatus.Internal diff --git a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/package-info.java b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/package-info.java index 75a191b4e0..ac638fb885 100644 --- a/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/package-info.java +++ b/text-serializer-nbt/src/main/java/net/kyori/adventure/text/serializer/nbt/package-info.java @@ -24,7 +24,7 @@ /** * NBT-based component serialization and deserialization. * - * @since 4.24.0 + * @since 4.25.0 * @sinceMinecraft 1.20.3 */ package net.kyori.adventure.text.serializer.nbt;