From 9927665d911f663435db61b70769f65060d1958b Mon Sep 17 00:00:00 2001 From: themode Date: Mon, 20 Dec 2021 22:51:01 +0100 Subject: [PATCH] Add direct access to nbt for meta subclasses --- .../minestom/server/item/ItemMetaBuilder.java | 93 ++++++++----------- .../server/item/ItemStackBuilder.java | 2 +- .../server/item/metadata/BundleMeta.java | 3 +- .../server/item/metadata/CompassMeta.java | 36 +++---- .../server/item/metadata/CrossbowMeta.java | 14 +-- .../item/metadata/EnchantedBookMeta.java | 2 +- .../item/metadata/FireworkEffectMeta.java | 4 +- .../server/item/metadata/MapMeta.java | 10 +- .../server/item/metadata/PotionMeta.java | 12 +-- .../server/item/metadata/WrittenBookMeta.java | 2 +- src/test/java/item/ItemTest.java | 9 +- 11 files changed, 77 insertions(+), 110 deletions(-) diff --git a/src/main/java/net/minestom/server/item/ItemMetaBuilder.java b/src/main/java/net/minestom/server/item/ItemMetaBuilder.java index a3be20219..d228b7127 100644 --- a/src/main/java/net/minestom/server/item/ItemMetaBuilder.java +++ b/src/main/java/net/minestom/server/item/ItemMetaBuilder.java @@ -39,30 +39,28 @@ public abstract class ItemMetaBuilder implements TagWritable { @Contract("_ -> this") public @NotNull ItemMetaBuilder damage(int damage) { this.damage = damage; - mutateNbt(compound -> compound.setInt("Damage", damage)); + this.nbt.setInt("Damage", damage); return this; } @Contract("_ -> this") public @NotNull ItemMetaBuilder unbreakable(boolean unbreakable) { this.unbreakable = unbreakable; - mutateNbt(compound -> compound.set("Unbreakable", NBT.Boolean(unbreakable))); + this.nbt.set("Unbreakable", NBT.Boolean(unbreakable)); return this; } @Contract("_ -> this") public @NotNull ItemMetaBuilder hideFlag(int hideFlag) { this.hideFlag = hideFlag; - mutateNbt(compound -> compound.setInt("HideFlags", hideFlag)); + this.nbt.setInt("HideFlags", hideFlag); return this; } @Contract("_ -> this") public @NotNull ItemMetaBuilder hideFlag(@NotNull ItemHideFlag... hideFlags) { int result = 0; - for (ItemHideFlag hideFlag : hideFlags) { - result |= hideFlag.getBitFieldPart(); - } + for (ItemHideFlag hideFlag : hideFlags) result |= hideFlag.getBitFieldPart(); return hideFlag(result); } @@ -71,8 +69,7 @@ public abstract class ItemMetaBuilder implements TagWritable { this.displayName = displayName; handleCompound("display", nbtCompound -> { if (displayName != null) { - final String name = GsonComponentSerializer.gson().serialize(displayName); - nbtCompound.setString("Name", name); + nbtCompound.setString("Name", GsonComponentSerializer.gson().serialize(displayName)); } else { nbtCompound.remove("Name"); } @@ -118,16 +115,14 @@ public abstract class ItemMetaBuilder implements TagWritable { @Contract("-> this") public @NotNull ItemMetaBuilder clearEnchantment() { this.enchantmentMap = new HashMap<>(); - enchantments(enchantmentMap); + this.nbt.remove("Enchantments"); return this; } @Contract("_ -> this") public @NotNull ItemMetaBuilder attributes(@NotNull List<@NotNull ItemAttribute> attributes) { this.attributes = new ArrayList<>(attributes); - - handleCollection(attributes, "AttributeModifiers", () -> NBT.List( - NBTType.TAG_Compound, + handleCollection(attributes, "AttributeModifiers", () -> NBT.List(NBTType.TAG_Compound, attributes.stream() .map(itemAttribute -> NBT.Compound(Map.of( "UUID", NBT.IntArray(Utils.uuidToIntArray(itemAttribute.getUuid())), @@ -138,14 +133,13 @@ public abstract class ItemMetaBuilder implements TagWritable { "Name", NBT.String(itemAttribute.getInternalName())))) .toList() )); - return this; } @Contract("_ -> this") public @NotNull ItemMetaBuilder customModelData(int customModelData) { this.customModelData = customModelData; - mutateNbt(compound -> compound.setInt("CustomModelData", customModelData)); + this.nbt.setInt("CustomModelData", customModelData); return this; } @@ -185,7 +179,7 @@ public abstract class ItemMetaBuilder implements TagWritable { @Override public void setTag(@NotNull Tag tag, @Nullable T value) { - mutateNbt(compound -> tag.write(compound, value)); + tag.write(nbt, value); } public @NotNull ItemMetaBuilder set(@NotNull Tag tag, @Nullable T value) { @@ -208,68 +202,59 @@ public abstract class ItemMetaBuilder implements TagWritable { } } + protected MutableNBTCompound mutableNbt() { + return nbt; + } + protected void mutateNbt(Consumer consumer) { consumer.accept(nbt); } - protected @NotNull ItemMeta generate() { - return build(); - } - protected void handleCompound(@NotNull String key, @NotNull Consumer<@NotNull MutableNBTCompound> consumer) { - mutateNbt(nbt -> { - MutableNBTCompound compoundToModify = nbt.get(key) instanceof NBTCompound compound ? - compound.toMutableCompound() : new MutableNBTCompound(); - - consumer.accept(compoundToModify); - if (compoundToModify.isEmpty()) { - nbt.remove(key); - } else { - nbt.set(key, compoundToModify.toCompound()); - } - }); + MutableNBTCompound compoundToModify = nbt.get(key) instanceof NBTCompound compound ? + compound.toMutableCompound() : new MutableNBTCompound(); + consumer.accept(compoundToModify); + if (compoundToModify.isEmpty()) { + this.nbt.remove(key); + } else { + this.nbt.set(key, compoundToModify.toCompound()); + } } protected void handleNullable(@Nullable Object value, @NotNull String key, @NotNull Supplier<@NotNull NBT> supplier) { - mutateNbt(compound -> { - if (value != null) { - compound.set(key, supplier.get()); - } else { - compound.remove(key); - } - }); + if (value != null) { + this.nbt.set(key, supplier.get()); + } else { + this.nbt.remove(key); + } } protected void handleCollection(@NotNull Collection objects, @NotNull String key, @NotNull Supplier<@NotNull NBT> supplier) { - mutateNbt(compound -> { - if (!objects.isEmpty()) { - compound.set(key, supplier.get()); - } else { - compound.remove(key); - } - }); + if (!objects.isEmpty()) { + this.nbt.set(key, supplier.get()); + } else { + this.nbt.remove(key); + } } protected void handleMap(@NotNull Map objects, @NotNull String key, @NotNull Consumer consumer) { - mutateNbt(compound -> { - if (!objects.isEmpty()) { - consumer.accept(compound); - } else { - compound.remove(key); - } - }); + if (!objects.isEmpty()) { + consumer.accept(nbt); + } else { + nbt.remove(key); + } } @ApiStatus.Internal public static void resetMeta(@NotNull ItemMetaBuilder src, @NotNull NBTCompound nbtCompound) { - src.nbt = nbtCompound.toMutableCompound(); + src.nbt.copyFrom(nbtCompound); appendMeta(src, nbtCompound); } @@ -339,8 +324,6 @@ public abstract class ItemMetaBuilder implements TagWritable { if (nbt.get("CustomModelData") instanceof NBTInt customModelData) { metaBuilder.customModelData = customModelData.getValue(); } - // Meta specific fields - metaBuilder.read(nbt); // CanPlaceOn if (nbt.get("CanPlaceOn") instanceof NBTList canPlaceOn && canPlaceOn.getSubtagType() == NBTType.TAG_String) { @@ -357,6 +340,8 @@ public abstract class ItemMetaBuilder implements TagWritable { metaBuilder.canDestroy.add(block); } } + // Meta specific fields + metaBuilder.read(nbt); } public interface Provider { diff --git a/src/main/java/net/minestom/server/item/ItemStackBuilder.java b/src/main/java/net/minestom/server/item/ItemStackBuilder.java index f57780c09..de3734868 100644 --- a/src/main/java/net/minestom/server/item/ItemStackBuilder.java +++ b/src/main/java/net/minestom/server/item/ItemStackBuilder.java @@ -116,7 +116,7 @@ public final class ItemStackBuilder { @Contract(value = "-> new", pure = true) public @NotNull ItemStack build() { if (amount < 1) return ItemStack.AIR; - return new ItemStack(material, amount, metaBuilder.generate(), stackingRule); + return new ItemStack(material, amount, metaBuilder.build(), stackingRule); } private static final class DefaultMeta extends ItemMetaBuilder { diff --git a/src/main/java/net/minestom/server/item/metadata/BundleMeta.java b/src/main/java/net/minestom/server/item/metadata/BundleMeta.java index 72e15e1d1..f4405469e 100644 --- a/src/main/java/net/minestom/server/item/metadata/BundleMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/BundleMeta.java @@ -57,8 +57,7 @@ public class BundleMeta extends ItemMeta implements ItemMetaBuilder.Provider compound.set("Items", NBT.List(NBTType.TAG_Compound, - items.size(), i -> items.get(i).toItemNBT()))); + mutableNbt().set("Items", NBT.List(NBTType.TAG_Compound, items.size(), i -> items.get(i).toItemNBT())); } @Override diff --git a/src/main/java/net/minestom/server/item/metadata/CompassMeta.java b/src/main/java/net/minestom/server/item/metadata/CompassMeta.java index 13b036951..ae861cf5e 100644 --- a/src/main/java/net/minestom/server/item/metadata/CompassMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/CompassMeta.java @@ -49,38 +49,30 @@ public class CompassMeta extends ItemMeta implements ItemMetaBuilder.Provider compound.setByte("LodestoneTracked", (byte) (lodestoneTracked ? 1 : 0))); + mutableNbt().setByte("LodestoneTracked", (byte) (lodestoneTracked ? 1 : 0)); return this; } public Builder lodestoneDimension(@Nullable String lodestoneDimension) { this.lodestoneDimension = lodestoneDimension; - - mutateNbt(compound -> { - if (lodestoneDimension != null) { - compound.setString("LodestoneDimension", lodestoneDimension); - } else { - compound.remove("LodestoneDimension"); - } - }); - + if (lodestoneDimension != null) { + mutableNbt().setString("LodestoneDimension", lodestoneDimension); + } else { + mutableNbt().remove("LodestoneDimension"); + } return this; } public Builder lodestonePosition(@Nullable Point lodestonePosition) { this.lodestonePosition = lodestonePosition; - - mutateNbt(compound -> { - if (lodestonePosition != null) { - compound.set("LodestonePos", NBT.Compound(Map.of( - "X", NBT.Int(lodestonePosition.blockX()), - "Y", NBT.Int(lodestonePosition.blockY()), - "Z", NBT.Int(lodestonePosition.blockZ())))); - } else { - compound.remove("LodestonePos"); - } - }); - + if (lodestonePosition != null) { + mutableNbt().set("LodestonePos", NBT.Compound(Map.of( + "X", NBT.Int(lodestonePosition.blockX()), + "Y", NBT.Int(lodestonePosition.blockY()), + "Z", NBT.Int(lodestonePosition.blockZ())))); + } else { + mutableNbt().remove("LodestonePos"); + } return this; } diff --git a/src/main/java/net/minestom/server/item/metadata/CrossbowMeta.java b/src/main/java/net/minestom/server/item/metadata/CrossbowMeta.java index d65ce22fb..07559eb16 100644 --- a/src/main/java/net/minestom/server/item/metadata/CrossbowMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/CrossbowMeta.java @@ -90,11 +90,8 @@ public class CrossbowMeta extends ItemMeta implements ItemMetaBuilder.Provider chargedProjectiles = - projectile.isAir() ? List.of() : List.of(getItemCompound(projectile)); - mutateNbt(compound -> compound.set("ChargedProjectiles", NBT.List(NBTType.TAG_Compound, chargedProjectiles))); - + mutableNbt().set("ChargedProjectiles", NBT.List(NBTType.TAG_Compound, + projectile.isAir() ? List.of() : List.of(getItemCompound(projectile)))); return this; } @@ -109,16 +106,13 @@ public class CrossbowMeta extends ItemMeta implements ItemMetaBuilder.Provider chargedProjectiles = List.of(getItemCompound(projectile1), getItemCompound(projectile2), getItemCompound(projectile3)); - mutateNbt(compound -> compound.set("ChargedProjectiles", NBT.List(NBTType.TAG_Compound, chargedProjectiles))); - + mutableNbt().set("ChargedProjectiles", NBT.List(NBTType.TAG_Compound, chargedProjectiles)); return this; } @@ -129,7 +123,7 @@ public class CrossbowMeta extends ItemMeta implements ItemMetaBuilder.Provider compound.setByte("Charged", (byte) (charged ? 1 : 0))); + mutableNbt().set("Charged", NBT.Boolean(charged)); return this; } diff --git a/src/main/java/net/minestom/server/item/metadata/EnchantedBookMeta.java b/src/main/java/net/minestom/server/item/metadata/EnchantedBookMeta.java index 6f8e87919..7e6e7729c 100644 --- a/src/main/java/net/minestom/server/item/metadata/EnchantedBookMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/EnchantedBookMeta.java @@ -37,7 +37,7 @@ public class EnchantedBookMeta extends ItemMeta implements ItemMetaBuilder.Provi public @NotNull Builder enchantments(@NotNull Map enchantments) { this.enchantments = enchantments; - mutateNbt(compound -> NBTUtils.writeEnchant(compound, "StoredEnchantments", enchantments)); + NBTUtils.writeEnchant(mutableNbt(), "StoredEnchantments", enchantments); return this; } diff --git a/src/main/java/net/minestom/server/item/metadata/FireworkEffectMeta.java b/src/main/java/net/minestom/server/item/metadata/FireworkEffectMeta.java index e90084543..74b22d10a 100644 --- a/src/main/java/net/minestom/server/item/metadata/FireworkEffectMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/FireworkEffectMeta.java @@ -7,6 +7,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jglrxavpok.hephaistos.nbt.NBTCompound; +import java.util.Objects; + public class FireworkEffectMeta extends ItemMeta implements ItemMetaBuilder.Provider { private final FireworkEffect fireworkEffect; @@ -26,7 +28,7 @@ public class FireworkEffectMeta extends ItemMeta implements ItemMetaBuilder.Prov public Builder effect(@Nullable FireworkEffect fireworkEffect) { this.fireworkEffect = fireworkEffect; - mutateNbt(compound -> compound.set("Explosion", this.fireworkEffect.asCompound())); + handleNullable(fireworkEffect, "Explosion", () -> Objects.requireNonNull(fireworkEffect).asCompound()); return this; } diff --git a/src/main/java/net/minestom/server/item/metadata/MapMeta.java b/src/main/java/net/minestom/server/item/metadata/MapMeta.java index abfa337dc..7f57c673d 100644 --- a/src/main/java/net/minestom/server/item/metadata/MapMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/MapMeta.java @@ -75,21 +75,19 @@ public class MapMeta extends ItemMeta implements ItemMetaBuilder.Provider compound.setInt("map", mapId)); + mutableNbt().setInt("map", mapId); return this; } public Builder mapScaleDirection(int value) { this.mapScaleDirection = value; - mutateNbt(compound -> compound.setInt("map_scale_direction", value)); + mutableNbt().setInt("map_scale_direction", value); return this; } public Builder decorations(List value) { this.decorations = new ArrayList<>(value); - - mutateNbt(compound -> compound.set("Decorations", NBT.List( - NBTType.TAG_Compound, + mutableNbt().set("Decorations", NBT.List(NBTType.TAG_Compound, decorations.stream() .map(decoration -> NBT.Compound(Map.of( "id", NBT.String(decoration.id()), @@ -98,7 +96,7 @@ public class MapMeta extends ItemMeta implements ItemMetaBuilder.Provider compound.setString("Potion", potionType.name())); + mutableNbt().setString("Potion", potionType.name()); return this; } public Builder effects(@NotNull List customPotionEffects) { this.customPotionEffects = customPotionEffects; - - NBTList potionList = NBT.List( - NBTType.TAG_Compound, + mutableNbt().set("CustomPotionEffects", NBT.List(NBTType.TAG_Compound, customPotionEffects.stream() .map(customPotionEffect -> NBT.Compound(Map.of( "Id", NBT.Byte(customPotionEffect.id()), @@ -67,15 +65,13 @@ public class PotionMeta extends ItemMeta implements ItemMetaBuilder.Provider compound.set("CustomPotionEffects", potionList)); - + )); return this; } public Builder color(@NotNull Color color) { this.color = color; - mutateNbt(compound -> compound.setInt("CustomPotionColor", color.asRGB())); + mutableNbt().setInt("CustomPotionColor", color.asRGB()); return this; } diff --git a/src/main/java/net/minestom/server/item/metadata/WrittenBookMeta.java b/src/main/java/net/minestom/server/item/metadata/WrittenBookMeta.java index f6a6c3215..42f558caa 100644 --- a/src/main/java/net/minestom/server/item/metadata/WrittenBookMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/WrittenBookMeta.java @@ -89,7 +89,7 @@ public class WrittenBookMeta extends ItemMeta implements ItemMetaBuilder.Provide public Builder resolved(boolean resolved) { this.resolved = resolved; - mutateNbt(compound -> compound.setByte("resolved", (byte) (resolved ? 1 : 0))); + mutableNbt().set("resolved", NBT.Boolean(resolved)); return this; } diff --git a/src/test/java/item/ItemTest.java b/src/test/java/item/ItemTest.java index 41c2bc1af..5e2e833f8 100644 --- a/src/test/java/item/ItemTest.java +++ b/src/test/java/item/ItemTest.java @@ -2,10 +2,7 @@ package item; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; -import net.minestom.server.item.Enchantment; -import net.minestom.server.item.ItemHideFlag; -import net.minestom.server.item.ItemStack; -import net.minestom.server.item.Material; +import net.minestom.server.item.*; import org.junit.jupiter.api.Test; import java.util.Map; @@ -102,6 +99,10 @@ public class ItemTest { item = item.withMeta(meta -> meta.enchantment(Enchantment.EFFICIENCY, (short) 10)); enchantments = item.getMeta().getEnchantmentMap(); assertEquals(enchantments.get(Enchantment.EFFICIENCY), (short) 10); + + item = item.withMeta(ItemMetaBuilder::clearEnchantment); + enchantments = item.getMeta().getEnchantmentMap(); + assertTrue(enchantments.isEmpty()); } @Test