From c1edf20734099c7d75933c25c2e388a6d2a9f5f8 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 20 Apr 2024 13:29:14 -0400 Subject: [PATCH] Here's the idea so far --- .../geyser/inventory/GeyserItemStack.java | 13 +- .../geysermc/geyser/item/type/ArmorItem.java | 4 +- .../geysermc/geyser/item/type/ArrowItem.java | 4 +- .../geyser/item/type/AxolotlBucketItem.java | 4 +- .../geysermc/geyser/item/type/BannerItem.java | 4 +- .../geysermc/geyser/item/type/ChestItem.java | 4 +- .../geyser/item/type/CompassItem.java | 4 +- .../geyser/item/type/CrossbowItem.java | 4 +- .../geyser/item/type/DecoratedPotItem.java | 4 +- .../geyser/item/type/DyeableArmorItem.java | 4 +- .../item/type/DyeableHorseArmorItem.java | 4 +- .../geyser/item/type/EnchantedBookItem.java | 4 +- .../geyser/item/type/FireworkRocketItem.java | 4 +- .../geyser/item/type/FireworkStarItem.java | 4 +- .../geyser/item/type/FishingRodItem.java | 4 +- .../org/geysermc/geyser/item/type/Item.java | 14 +- .../geysermc/geyser/item/type/MapItem.java | 4 +- .../geyser/item/type/PlayerHeadItem.java | 4 +- .../geysermc/geyser/item/type/PotionItem.java | 6 +- .../geysermc/geyser/item/type/ShieldItem.java | 4 +- .../geyser/item/type/ShulkerBoxItem.java | 19 +- .../item/type/TropicalFishBucketItem.java | 4 +- .../geyser/item/type/WritableBookItem.java | 4 +- .../geyser/item/type/WrittenBookItem.java | 4 +- .../translator/item/BedrockItemBuilder.java | 93 ++++++++ .../translator/item/CustomItemTranslator.java | 13 +- .../translator/item/ItemTranslator.java | 207 +++++++----------- 27 files changed, 241 insertions(+), 204 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java diff --git a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java index dd1aaea81..7e621d3aa 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.inventory; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import lombok.AccessLevel; import lombok.Data; @@ -35,7 +35,6 @@ import lombok.Getter; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; -import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.registry.Registries; @@ -49,18 +48,18 @@ public class GeyserItemStack { private final int javaId; private int amount; - private DataComponentPatch components; + private DataComponents components; private int netId; @Getter(AccessLevel.NONE) @EqualsAndHashCode.Exclude private Item item; - private GeyserItemStack(int javaId, int amount, DataComponentPatch components) { + private GeyserItemStack(int javaId, int amount, DataComponents components) { this(javaId, amount, components, 1); } - private GeyserItemStack(int javaId, int amount, DataComponentPatch components, int netId) { + private GeyserItemStack(int javaId, int amount, DataComponents components, int netId) { this.javaId = javaId; this.amount = amount; this.components = components; @@ -68,7 +67,7 @@ public class GeyserItemStack { } public static @NonNull GeyserItemStack from(@Nullable ItemStack itemStack) { - return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getDataComponentPatch()); + return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getDataComponents()); } public int getJavaId() { @@ -84,7 +83,7 @@ public class GeyserItemStack { return null; } - public @Nullable DataComponentPatch getComponents() { + public @Nullable DataComponents getComponents() { return isEmpty() ? null : components; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index 669791705..eb5233b88 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -43,7 +43,7 @@ public class ArmorItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); if (tag.get("Trim") instanceof CompoundTag trim) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java index 2462f374c..cf66b036b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java @@ -46,9 +46,9 @@ public class ArrowItem extends Item { TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByBedrockId(itemData.getDamage()); ItemStack itemStack = super.translateToJava(itemData, mapping, mappings); if (tippedArrowPotion != null) { - itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getDataComponentPatch()); + itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getDataComponents()); StringTag potionTag = new StringTag("Potion", tippedArrowPotion.getJavaIdentifier()); - itemStack.getDataComponentPatch().put(DataComponentType.POTION_CONTENTS, new PotionContents()); + itemStack.getDataComponents().put(DataComponentType.POTION_CONTENTS, new PotionContents()); } return itemStack; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java index 6e4e6c6fc..d0aa1e901 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.ByteTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -39,7 +39,7 @@ public class AxolotlBucketItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Bedrock Edition displays the properties of the axolotl. Java does not. diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 9cd7aea42..2a8ca9f15 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -122,7 +122,7 @@ public class BannerItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); CompoundTag blockEntityTag = tag.remove("BlockEntityTag"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java index 2611c8ff6..8644ec8be 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; @@ -37,7 +37,7 @@ public class ChestItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Strip the BlockEntityTag from the chests contents diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java index f3933d83b..605d19852 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.ByteTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; @@ -60,7 +60,7 @@ public class CompassItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); Tag lodestoneTag = tag.get("LodestoneTracked"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java index 1ea468721..c38e2f2ba 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -42,7 +42,7 @@ public class CrossbowItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); ListTag chargedProjectiles = tag.get("ChargedProjectiles"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java index bfa86d2ad..74cabc3d9 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -39,7 +39,7 @@ public class DecoratedPotItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java index f1b10474d..fbe0222bc 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -40,7 +40,7 @@ public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); DyeableLeatherItem.translateNbtToBedrock(tag); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java index 39787ae2f..09878e652 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -39,7 +39,7 @@ public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); DyeableLeatherItem.translateNbtToBedrock(tag); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java index c51278947..d3aa72cbc 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; @@ -42,7 +42,7 @@ public class EnchantedBookItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); List newTags = new ArrayList<>(); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index 6be1be15d..b44dc08eb 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -40,7 +40,7 @@ public class FireworkRocketItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); CompoundTag fireworks = tag.get("Fireworks"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java index 6d4347e9e..80a32fc44 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; @@ -41,7 +41,7 @@ public class FireworkStarItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); Tag explosion = tag.remove("Explosion"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java index 50a0bddbc..0e1a4cc0e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -38,7 +38,7 @@ public class FishingRodItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Fix damage inconsistency diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index df3c5effe..3ecf3be1b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -27,7 +27,7 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import com.github.steveice10.opennbt.tag.builtin.*; @@ -103,12 +103,12 @@ public class Item { .definition(mapping.getBedrockDefinition()) .damage(mapping.getBedrockData()) .count(itemStack.getAmount()); - if (itemStack.getNbt() != null) { - builder.tag(ItemTranslator.translateNbtToBedrock(itemStack.getNbt())); + if (itemStack.getDataComponents() != null) { + builder.tag(ItemTranslator.translateNbtToBedrock(itemStack.getDataComponents())); } - CompoundTag nbt = itemStack.getNbt(); - ItemTranslator.translateCustomItem(nbt, builder, mapping); + DataComponents components = itemStack.getDataComponents(); + ItemTranslator.translateCustomItem(components, builder, mapping); return builder; } @@ -127,7 +127,7 @@ public class Item { /** * Takes components from Java Edition and map them into Bedrock. */ - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { // // Basing off of ItemStack#getHoverName as of 1.20.5. VERIFY?? // Component customName = components.get(DataComponentType.CUSTOM_NAME); // if (customName == null) { @@ -271,7 +271,7 @@ public class Item { /* Translation methods end */ - public ItemStack newItemStack(int count, DataComponentPatch components) { + public ItemStack newItemStack(int count, DataComponents components) { return new ItemStack(this.javaId, count, components); } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java index 8dbeeb57f..64e505800 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -38,7 +38,7 @@ public class MapItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); Tag mapId = tag.remove("map"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java index 4aefcf765..6ebc728cb 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; @@ -42,7 +42,7 @@ public class PlayerHeadItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); CompoundTag displayTag; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java index 26c468fb1..bed2945ba 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java @@ -47,10 +47,10 @@ public class PotionItem extends Item { @Override public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - if (itemStack.getDataComponentPatch() == null) return super.translateToBedrock(itemStack, mapping, mappings); - PotionContents potionContents = itemStack.getDataComponentPatch().get(DataComponentType.POTION_CONTENTS); + if (itemStack.getDataComponents() == null) return super.translateToBedrock(itemStack, mapping, mappings); + PotionContents potionContents = itemStack.getDataComponents().get(DataComponentType.POTION_CONTENTS); if (potionContents != null) { - ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(itemStack.getDataComponentPatch(), mapping); + ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(itemStack.getDataComponents(), mapping); if (customItemDefinition == null) { Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); if (potion != null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java index cd940c87c..b3f9f57e3 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -41,7 +41,7 @@ public class ShieldItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java index e2259eb5d..3d5fa2444 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java @@ -25,11 +25,10 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.opennbt.tag.builtin.*; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -38,7 +37,6 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.ItemTranslator; -import org.geysermc.geyser.util.MathUtils; import java.util.ArrayList; import java.util.List; @@ -49,7 +47,7 @@ public class ShulkerBoxItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); List contents = components.get(DataComponentType.CONTAINER); @@ -73,9 +71,16 @@ public class ShulkerBoxItem extends BlockItem { boxItemNbt.putShort("Damage", (short) boxMapping.getBedrockData()); boxItemNbt.putByte("Count", (byte) item.getAmount()); // Only the display name is what we have interest in, so just translate that if relevant - DataComponentPatch boxComponents = item.getDataComponentPatch(); + DataComponents boxComponents = item.getDataComponents(); if (boxComponents != null) { - boxItemNbt.put(ItemTranslator.translateDisplayProperties(session, displayTag, boxMapping, '7')); + String customName = ItemTranslator.getCustomName(session, boxComponents, boxMapping, '7'); + if (customName != null) { + boxItemNbt.putCompound("tag", NbtMap.builder() + .putCompound("display", NbtMap.builder() + .putString("Name", customName) + .build()) + .build()); + } } itemsList.add(boxItemNbt.build()); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java index 17f90ca12..2ce0dd071 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -49,7 +49,7 @@ public class TropicalFishBucketItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Prevent name from appearing as "Bucket of" diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java index 67221b1c6..46b9b80ce 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; @@ -45,7 +45,7 @@ public class WritableBookItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); ListTag pagesTag = tag.remove("pages"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index 0198e73ff..46eceaa86 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; @@ -50,7 +50,7 @@ public class WrittenBookItem extends WritableBookItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { boolean isValid = isValidWrittenBook(tag); if (!isValid) { tag.remove("pages"); diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java new file mode 100644 index 000000000..162d57120 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * 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. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.translator.item; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; + +import java.util.ArrayList; +import java.util.List; + +/** + * An intermediary class made to allow easy access to work-in-progress NBT, such as lore and display. + */ +public final class BedrockItemBuilder { + // All Bedrock-style + @Nullable + private String customName; + @Nullable + private List lore; + /** + * Miscellaneous NBT that will be put into the final item. + */ + @Nullable + private NbtMapBuilder builder; + + public BedrockItemBuilder setCustomName(String customName) { + this.customName = customName; + return this; + } + + @NonNull + public List getOrCreateLore() { + if (lore == null) { + lore = new ArrayList<>(); + } + return lore; + } + + @NonNull + public NbtMapBuilder getOrCreateNbt() { + if (builder == null) { + builder = NbtMap.builder(); + } + return builder; + } + + /** + * @return null if no NBT is needed on this item. + */ + @Nullable + public NbtMap build() { + if (customName != null || lore != null) { + NbtMapBuilder display = NbtMap.builder(); + if (customName != null) { + display.putString("Name", customName); + } + if (lore != null) { + display.putList("Lore", NbtType.STRING, lore); + } + getOrCreateNbt().put("display", display.build()); + } + if (builder == null) { + return null; + } + return builder.build(); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java index d5f85dcc3..8a541fb9b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.item; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import it.unimi.dsi.fastutil.Pair; import org.checkerframework.checker.nullness.qual.Nullable; @@ -43,7 +43,7 @@ import java.util.OptionalInt; public final class CustomItemTranslator { @Nullable - public static ItemDefinition getCustomItem(DataComponentPatch components, ItemMapping mapping) { + public static ItemDefinition getCustomItem(DataComponents components, ItemMapping mapping) { if (components == null) { return null; } @@ -52,10 +52,9 @@ public final class CustomItemTranslator { return null; } - // TODO getOrDefault - int customModelData = components.get(DataComponentType.CUSTOM_MODEL_DATA); + int customModelData = components.getOrDefault(DataComponentType.CUSTOM_MODEL_DATA, 0); boolean checkDamage = mapping.getJavaItem().maxDamage() > 0; - int damage = !checkDamage ? 0 : components.get(DataComponentType.DAMAGE); + int damage = !checkDamage ? 0 : components.getOrDefault(DataComponentType.DAMAGE, 0); boolean unbreakable = checkDamage && !isDamaged(components, damage); for (Pair mappingTypes : customMappings) { @@ -105,11 +104,11 @@ public final class CustomItemTranslator { /* These two functions are based off their Mojmap equivalents from 1.19.2 */ - private static boolean isDamaged(DataComponentPatch components, int damage) { + private static boolean isDamaged(DataComponents components, int damage) { return isDamagableItem(components) && damage > 0; } - private static boolean isDamagableItem(DataComponentPatch components) { + private static boolean isDamagableItem(DataComponents components) { // mapping.getMaxDamage > 0 should also be checked (return false if not true) but we already check prior to this function Boolean unbreakable = components.get(DataComponentType.UNBREAKABLE); // Tag must either not be present or be set to false diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 027c6b5ba..b52861b35 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -25,11 +25,12 @@ package org.geysermc.geyser.translator.item; +import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOperation; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.item.component.AdventureModePredicate; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.ItemAttributeModifiers; import com.github.steveice10.opennbt.tag.builtin.ByteArrayTag; @@ -83,7 +84,6 @@ public final class ItemTranslator { */ private static final String[] ALL_SLOTS = new String[]{"mainhand", "offhand", "feet", "legs", "chest", "head"}; private static final DecimalFormat ATTRIBUTE_FORMAT = new DecimalFormat("0.#####"); - private static final byte HIDE_ATTRIBUTES_FLAG = 1 << 1; private ItemTranslator() { } @@ -102,23 +102,23 @@ public final class ItemTranslator { ItemStack itemStack = javaItem.translateToJava(data, bedrockItem, mappings); - if (itemStack.getNbt() != null) { - javaItem.translateNbtToJava(itemStack.getNbt(), bedrockItem); - if (itemStack.getNbt().isEmpty()) { - // Otherwise, seems to cause issues with villagers accepting books, and I don't see how this will break anything else. - Camotoy - itemStack = new ItemStack(itemStack.getId(), itemStack.getAmount(), null); - } - } +// if (itemStack.getNbt() != null) { +// javaItem.translateNbtToJava(itemStack.getNbt(), bedrockItem); +// if (itemStack.getNbt().isEmpty()) { +// // Otherwise, seems to cause issues with villagers accepting books, and I don't see how this will break anything else. - Camotoy +// itemStack = new ItemStack(itemStack.getId(), itemStack.getAmount(), null); +// } +// } return itemStack; } - public static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, int javaId, int count, CompoundTag tag) { + public static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, int javaId, int count, DataComponents components) { ItemMapping bedrockItem = session.getItemMappings().getMapping(javaId); if (bedrockItem == ItemMapping.AIR) { session.getGeyser().getLogger().debug("ItemMapping returned air: " + javaId); return ItemData.builder(); } - return translateToBedrock(session, Registries.JAVA_ITEMS.get().get(javaId), bedrockItem, count, tag); + return translateToBedrock(session, Registries.JAVA_ITEMS.get().get(javaId), bedrockItem, count, components); } @NonNull @@ -133,32 +133,35 @@ public final class ItemTranslator { return ItemData.AIR; } // Java item needs to be loaded separately. The mapping for tipped arrow would - return translateToBedrock(session, Registries.JAVA_ITEMS.get().get(stack.getId()), bedrockItem, stack.getAmount(), stack.getNbt()) + return translateToBedrock(session, Registries.JAVA_ITEMS.get().get(stack.getId()), bedrockItem, stack.getAmount(), stack.getDataComponents()) .build(); } - private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, DataComponentPatch components) { - NbtMapBuilder builder = NbtMap.builder(); + private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, DataComponents components) { + BedrockItemBuilder nbtBuilder = new BedrockItemBuilder(); if (components != null) { - javaItem.translateComponentsToBedrock(session, components, builder); + javaItem.translateComponentsToBedrock(session, components, nbtBuilder.getOrCreateNbt()); } - translateDisplayProperties(session, components, bedrockItem); + String customName = getCustomName(session, components, bedrockItem); + if (customName != null) { + nbtBuilder.setCustomName(customName); + } if (components != null) { ItemAttributeModifiers attributeModifiers = components.get(DataComponentType.ATTRIBUTE_MODIFIERS); if (attributeModifiers != null && attributeModifiers.isShowInTooltip()) { // only add if attribute modifiers do not indicate to hide them - addAttributeLore(attributeModifiers, builder, session.locale()); + addAttributeLore(attributeModifiers, nbtBuilder, session.locale()); } } if (session.isAdvancedTooltips()) { - nbt = addAdvancedTooltips(nbt, javaItem, session.locale()); + addAdvancedTooltips(components, nbtBuilder, javaItem, session.locale()); } - ItemStack itemStack = new ItemStack(javaItem.javaId(), count, nbt); + ItemStack itemStack = new ItemStack(javaItem.javaId(), count, components); ItemData.Builder builder = javaItem.translateToBedrock(itemStack, bedrockItem, session.getItemMappings()); if (bedrockItem.isBlock()) { @@ -172,10 +175,10 @@ public final class ItemTranslator { } if (bedrockItem.getJavaItem().equals(Items.PLAYER_HEAD)) { - translatePlayerHead(session, nbt, builder); + translatePlayerHead(session, components, builder); } - translateCustomItem(nbt, builder, bedrockItem); + translateCustomItem(components, builder, bedrockItem); if (components != null) { // Translate the canDestroy and canPlaceOn Java NBT @@ -198,21 +201,12 @@ public final class ItemTranslator { * Bedrock Edition does not see attribute modifiers like Java Edition does, * so we add them as lore instead. * - * @param nbt the NBT of the ItemStack + * @param modifiers the attribute modifiers of the ItemStack * @param language the locale of the player */ - private static void addAttributeLore(ItemAttributeModifiers modifiers, NbtMapBuilder builder, String language) { - CompoundTag displayTag = builder.get("display"); - if (displayTag == null) { - displayTag = new CompoundTag("display"); - } - ListTag lore = displayTag.get("Lore"); - if (lore == null) { - lore = new ListTag("Lore"); - } - + private static void addAttributeLore(ItemAttributeModifiers modifiers, BedrockItemBuilder builder, String language) { // maps each slot to the modifiers applied when in such slot - Map> slotsToModifiers = new HashMap<>(); + Map> slotsToModifiers = new HashMap<>(); for (ItemAttributeModifiers.Entry entry : modifiers.getModifiers()) { // convert the modifier tag to a lore entry String loreEntry = attributeToLore(entry.getModifier(), language); @@ -220,23 +214,22 @@ public final class ItemTranslator { continue; // invalid or failed } - StringTag loreTag = new StringTag("", loreEntry); ItemAttributeModifiers.EquipmentSlotGroup slotGroup = entry.getSlot(); if (slotGroup == ItemAttributeModifiers.EquipmentSlotGroup.ANY) { // modifier applies to all slots implicitly - for (String slot : ALL_SLOTS) { - slotsToModifiers.computeIfAbsent(slot, s -> new ArrayList<>()).add(loreTag); + for (String slot : ALL_SLOTS) { // TODO SOMEONE LOOK HERE PLZ + //slotsToModifiers.computeIfAbsent(slot, s -> new ArrayList<>()).add(loreEntry); } } else { // modifier applies to only the specified slot - slotsToModifiers.computeIfAbsent(slotGroup, s -> new ArrayList<>()).add(loreTag); + slotsToModifiers.computeIfAbsent(slotGroup, s -> new ArrayList<>()).add(loreEntry); } } // iterate through the small array, not the map, so that ordering matches Java Edition for (String slot : ALL_SLOTS) { - List modifiers = slotsToModifiers.get(slot); - if (modifiers == null || modifiers.isEmpty()) { + List modifierStrings = slotsToModifiers.get(slot); + if (modifierStrings == null || modifierStrings.isEmpty()) { continue; } @@ -246,16 +239,13 @@ public final class ItemTranslator { .color(NamedTextColor.GRAY) .append(Component.newline(), Component.translatable("item.modifiers." + slot)) .build(); - lore.add(new StringTag("", MessageTranslator.convertMessage(slotComponent, language))); + builder.getOrCreateLore().add(MessageTranslator.convertMessage(slotComponent, language)); // Then list all the modifiers when used in this slot - for (StringTag modifier : modifiers) { - lore.add(modifier); + for (String modifier : modifierStrings) { + builder.getOrCreateLore().add(modifier); } } - - displayTag.put(lore); - nbt.put(displayTag); } @Nullable @@ -294,29 +284,13 @@ public final class ItemTranslator { return MessageTranslator.convertMessage(attributeComponent, language); } - private static CompoundTag addAdvancedTooltips(CompoundTag nbt, Item item, String language) { - CompoundTag newNbt = nbt; - if (newNbt == null) { - newNbt = new CompoundTag("nbt"); - CompoundTag display = new CompoundTag("display"); - display.put(new ListTag("Lore")); - newNbt.put(display); - } - CompoundTag compoundTag = newNbt.get("display"); - if (compoundTag == null) { - compoundTag = new CompoundTag("display"); - } - ListTag listTag = compoundTag.get("Lore"); - - if (listTag == null) { - listTag = new ListTag("Lore"); - } + private static void addAdvancedTooltips(DataComponents components, BedrockItemBuilder builder, Item item, String language) { int maxDurability = item.maxDamage(); if (maxDurability != 0) { - Tag durabilityTag = newNbt.get("Damage"); - if (durabilityTag instanceof IntTag) { - int durability = maxDurability - ((IntTag) durabilityTag).getValue(); + Integer durabilityComponent = components.get(DataComponentType.DAMAGE); + if (durabilityComponent != null) { + int durability = maxDurability - durabilityComponent; if (durability != maxDurability) { Component component = Component.text() .resetStyle() @@ -325,24 +299,21 @@ public final class ItemTranslator { Component.text(durability), Component.text(maxDurability))) .build(); - listTag.add(new StringTag("", MessageTranslator.convertMessage(component, language))); + builder.getOrCreateLore().add(MessageTranslator.convertMessage(component, language)); } } } - listTag.add(new StringTag("", ChatColor.RESET + ChatColor.DARK_GRAY + item.javaIdentifier())); - if (nbt != null) { + builder.getOrCreateLore().add(ChatColor.RESET + ChatColor.DARK_GRAY + item.javaIdentifier()); + if (components != null) { Component component = Component.text() .resetStyle() .color(NamedTextColor.DARK_GRAY) - .append(Component.translatable("item.nbt_tags", - Component.text(nbt.size()))) + .append(Component.translatable("item.nbt_tags", // TODO + Component.text(components.getDataComponents().size()))) .build(); - listTag.add(new StringTag("", MessageTranslator.convertMessage(component, language))); + builder.getOrCreateLore().add(MessageTranslator.convertMessage(component, language)); } - compoundTag.put(listTag); - newNbt.put(compoundTag); - return newNbt; } /** @@ -396,13 +367,13 @@ public final class ItemTranslator { } if (mapping.getJavaItem().equals(Items.PLAYER_HEAD)) { - CustomSkull customSkull = getCustomSkull(session, itemStack.getNbt()); + CustomSkull customSkull = getCustomSkull(session, itemStack.getComponents()); if (customSkull != null) { itemDefinition = session.getItemMappings().getCustomBlockItemDefinitions().get(customSkull.getCustomBlockData()); } } - ItemDefinition definition = CustomItemTranslator.getCustomItem(itemStack, mapping); + ItemDefinition definition = CustomItemTranslator.getCustomItem(itemStack.getComponents(), mapping); if (definition == null) { // No custom item return itemDefinition; @@ -533,65 +504,45 @@ public final class ItemTranslator { /** * Translates the display name of the item * @param session the Bedrock client's session - * @param tag the tag to translate + * @param components the components to translate * @param mapping the item entry, in case it requires translation - * - * @return the new tag to use, should the current one be null */ - public static CompoundTag translateDisplayProperties(GeyserSession session, CompoundTag tag, ItemMapping mapping) { - return translateDisplayProperties(session, tag, mapping, 'f'); + public static String getCustomName(GeyserSession session, DataComponents components, ItemMapping mapping) { + return getCustomName(session, components, mapping, 'f'); } /** * @param translationColor if this item is not available on Java, the color that the new name should be. * Normally, this should just be white, but for shulker boxes this should be gray. */ - public static CompoundTag translateDisplayProperties(GeyserSession session, CompoundTag tag, ItemMapping mapping, char translationColor) { - boolean hasCustomName = false; - if (tag != null) { - if (tag.get("display") instanceof CompoundTag display && display.get("Name") instanceof StringTag tagName) { - String name = tagName.getValue(); - - // Get the translated name and prefix it with a reset char - name = MessageTranslator.convertMessageLenient(name, session.locale()); - - // Add the new name tag - display.put(new StringTag("Name", name)); - // Indicate that a custom name is present - hasCustomName = true; - - // Add to the new root tag - tag.put(display); + public static String getCustomName(GeyserSession session, DataComponents components, ItemMapping mapping, char translationColor) { + if (components != null) { + // ItemStack#getHoverName as of 1.20.5 + Component customName = components.get(DataComponentType.CUSTOM_NAME); + if (customName == null) { + customName = components.get(DataComponentType.ITEM_NAME); + } + if (customName != null) { + // Get the translated name and prefix it with a reset char TODO test + return MessageTranslator.convertMessage(customName, session.locale()); } } - if (!hasCustomName && mapping.hasTranslation()) { + if (mapping.hasTranslation()) { // No custom name, but we need to localize the item's name - if (tag == null) { - tag = new CompoundTag(""); - } - CompoundTag display; - if (tag.get("display") instanceof CompoundTag oldDisplay) { - display = oldDisplay; - } else { - display = new CompoundTag("display"); - // Add to the new root tag - tag.put(display); - } - String translationKey = mapping.getTranslationString(); // Reset formatting since Bedrock defaults to italics - display.put(new StringTag("Name", ChatColor.RESET + ChatColor.ESCAPE + translationColor + MinecraftLocale.getLocaleString(translationKey, session.locale()))); + return ChatColor.RESET + ChatColor.ESCAPE + translationColor + MinecraftLocale.getLocaleString(translationKey, session.locale()); } - - return tag; + // No custom name + return null; } /** * Translates the custom model data of an item */ - public static void translateCustomItem(CompoundTag nbt, ItemData.Builder builder, ItemMapping mapping) { - ItemDefinition definition = CustomItemTranslator.getCustomItem(nbt, mapping); + public static void translateCustomItem(DataComponents components, ItemData.Builder builder, ItemMapping mapping) { + ItemDefinition definition = CustomItemTranslator.getCustomItem(components, mapping); if (definition != null) { builder.definition(definition); builder.blockDefinition(null); @@ -608,8 +559,12 @@ public final class ItemTranslator { builder.blockDefinition(blockDefinition); } - private static @Nullable CustomSkull getCustomSkull(GeyserSession session, CompoundTag nbt) { - if (nbt != null && nbt.contains("SkullOwner")) { + private static @Nullable CustomSkull getCustomSkull(GeyserSession session, DataComponents components) { + if (components == null) { + return null; + } + GameProfile profile = components.get(DataComponentType.PROFILE); + if (profile != null) { if (!(nbt.get("SkullOwner") instanceof CompoundTag skullOwner)) { // It's a username give up d: return null; @@ -626,8 +581,8 @@ public final class ItemTranslator { return null; } - private static void translatePlayerHead(GeyserSession session, CompoundTag nbt, ItemData.Builder builder) { - CustomSkull customSkull = getCustomSkull(session, nbt); + private static void translatePlayerHead(GeyserSession session, DataComponents components, ItemData.Builder builder) { + CustomSkull customSkull = getCustomSkull(session, components); if (customSkull != null) { CustomBlockData customBlockData = customSkull.getCustomBlockData(); ItemDefinition itemDefinition = session.getItemMappings().getCustomBlockItemDefinitions().get(customBlockData); @@ -636,18 +591,4 @@ public final class ItemTranslator { builder.blockDefinition(blockDefinition); } } - - /** - * Checks if the NBT of a Java item stack has the given hide flag. - * - * @param hideFlags the "HideFlags", which may not be null - * @param flagMask the flag to check for, as a bit mask - * @return true if the flag is present, false if not or if the tag value is not a number - */ - private static boolean hasFlagPresent(Tag hideFlags, byte flagMask) { - if (hideFlags.getValue() instanceof Number flags) { - return (flags.byteValue() & flagMask) == flagMask; - } - return false; - } }