diff --git a/src/main/java/net/minestom/server/item/ItemMetaBuilder.java b/src/main/java/net/minestom/server/item/ItemMetaBuilder.java index 86a5fb28b..9a47dc135 100644 --- a/src/main/java/net/minestom/server/item/ItemMetaBuilder.java +++ b/src/main/java/net/minestom/server/item/ItemMetaBuilder.java @@ -78,7 +78,7 @@ public abstract class ItemMetaBuilder implements TagWritable { } @Contract("_ -> this") - public @NotNull ItemMetaBuilder lore(@NotNull List<@NotNull Component> lore) { + public @NotNull ItemMetaBuilder lore(@NotNull List lore) { this.lore = new ArrayList<>(lore); handleCompound("display", nbtCompound -> { final NBTList loreNBT = NBT.List(NBTType.TAG_String, @@ -86,7 +86,11 @@ public abstract class ItemMetaBuilder implements TagWritable { .map(line -> new NBTString(GsonComponentSerializer.gson().serialize(line))) .toList() ); - nbtCompound.set("Lore", loreNBT); + if (loreNBT.isEmpty()) { + nbtCompound.remove("Lore"); + } else { + nbtCompound.set("Lore", loreNBT); + } }); return this; } diff --git a/src/main/java/net/minestom/server/item/ItemStack.java b/src/main/java/net/minestom/server/item/ItemStack.java index dd795a30a..93ab5020c 100644 --- a/src/main/java/net/minestom/server/item/ItemStack.java +++ b/src/main/java/net/minestom/server/item/ItemStack.java @@ -168,7 +168,7 @@ public final class ItemStack implements TagReadable, HoverEventSource lore) { + public @NotNull ItemStack withLore(@NotNull List lore) { return builder().lore(lore).build(); } diff --git a/src/main/java/net/minestom/server/item/ItemStackBuilder.java b/src/main/java/net/minestom/server/item/ItemStackBuilder.java index de3734868..094cba504 100644 --- a/src/main/java/net/minestom/server/item/ItemStackBuilder.java +++ b/src/main/java/net/minestom/server/item/ItemStackBuilder.java @@ -95,7 +95,7 @@ public final class ItemStackBuilder { } @Contract(value = "_ -> this") - public @NotNull ItemStackBuilder lore(@NotNull List<@NotNull Component> lore) { + public @NotNull ItemStackBuilder lore(@NotNull List lore) { this.metaBuilder.lore(lore); return this; } diff --git a/src/test/java/net/minestom/server/item/ItemTest.java b/src/test/java/net/minestom/server/item/ItemTest.java index ecaf69db7..47e5302d5 100644 --- a/src/test/java/net/minestom/server/item/ItemTest.java +++ b/src/test/java/net/minestom/server/item/ItemTest.java @@ -2,9 +2,13 @@ package net.minestom.server.item; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import org.jglrxavpok.hephaistos.nbt.NBTString; import org.junit.jupiter.api.Test; +import java.util.List; import java.util.Map; +import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.*; @@ -108,6 +112,47 @@ public class ItemTest { assertTrue(enchantments.isEmpty()); } + @Test + public void testLore() { + var item = ItemStack.of(Material.DIAMOND_SWORD); + assertEquals(List.of(), item.getLore()); + assertNull(item.getMeta().toNBT().get("display")); + + { + var lore = List.of(Component.text("Hello")); + item = item.withLore(lore); + assertEquals(lore, item.getLore()); + var loreNbt = item.getMeta().toNBT().getCompound("display").getList("Lore"); + assertNotNull(loreNbt); + assertEquals(loreNbt.getSize(), 1); + assertEquals(lore, loreNbt.asListView().stream().map(line -> GsonComponentSerializer.gson().deserialize(line.getValue())).toList()); + } + + { + var lore = List.of(Component.text("Hello"), Component.text("World")); + item = item.withLore(lore); + assertEquals(lore, item.getLore()); + var loreNbt = item.getMeta().toNBT().getCompound("display").getList("Lore"); + assertNotNull(loreNbt); + assertEquals(loreNbt.getSize(), 2); + assertEquals(lore, loreNbt.asListView().stream().map(line -> GsonComponentSerializer.gson().deserialize(line.getValue())).toList()); + } + + { + var lore = Stream.of("string test").map(Component::text).toList(); + item = item.withLore(lore); + assertEquals(lore, item.getLore()); + var loreNbt = item.getMeta().toNBT().getCompound("display").getList("Lore"); + assertNotNull(loreNbt); + assertEquals(loreNbt.getSize(), 1); + assertEquals(lore, loreNbt.asListView().stream().map(line -> GsonComponentSerializer.gson().deserialize(line.getValue())).toList()); + } + + // Ensure that lore can be properly removed without residual (display compound) + item = item.withLore(List.of()); + assertNull(item.getMeta().toNBT().get("display")); + } + @Test public void testBuilderReuse() { var builder = ItemStack.builder(Material.DIAMOND);