From 099e968bde8e9981c7467b4f82c87a85cd0bc8e0 Mon Sep 17 00:00:00 2001
From: Camotoy <20743703+Camotoy@users.noreply.github.com>
Date: Fri, 19 Apr 2024 19:21:44 -0400
Subject: [PATCH] Initial, incomplete pass at Java 1.20.5

---
 .../geyser/entity/type/FireworkEntity.java    |  2 +-
 .../geyser/entity/type/ItemEntity.java        |  4 +-
 .../geyser/entity/type/ItemFrameEntity.java   |  4 +-
 .../entity/type/ThrowableItemEntity.java      |  2 +-
 .../entity/type/ThrownPotionEntity.java       |  2 +-
 .../geyser/inventory/GeyserItemStack.java     | 31 +++---
 .../geysermc/geyser/inventory/Inventory.java  |  2 +-
 .../geyser/inventory/click/ClickPlan.java     |  2 +-
 .../inventory/recipe/GeyserShapedRecipe.java  |  2 +-
 .../recipe/GeyserShapelessRecipe.java         |  2 +-
 .../recipe/GeyserStonecutterData.java         |  2 +-
 .../geysermc/geyser/item/type/ArmorItem.java  |  6 +-
 .../geysermc/geyser/item/type/ArrowItem.java  |  8 +-
 .../geyser/item/type/AxolotlBucketItem.java   |  7 +-
 .../geysermc/geyser/item/type/BannerItem.java |  6 +-
 .../geysermc/geyser/item/type/ChestItem.java  |  7 +-
 .../geyser/item/type/CompassItem.java         |  8 +-
 .../geyser/item/type/CrossbowItem.java        | 10 +-
 .../geyser/item/type/DecoratedPotItem.java    |  6 +-
 .../geyser/item/type/DyeableArmorItem.java    |  6 +-
 .../item/type/DyeableHorseArmorItem.java      |  6 +-
 .../geyser/item/type/EnchantedBookItem.java   |  6 +-
 .../geyser/item/type/FilledMapItem.java       |  2 +-
 .../geyser/item/type/FireworkRocketItem.java  |  6 +-
 .../geyser/item/type/FireworkStarItem.java    |  6 +-
 .../geyser/item/type/FishingRodItem.java      |  7 +-
 .../geyser/item/type/GoatHornItem.java        |  2 +-
 .../org/geysermc/geyser/item/type/Item.java   | 63 +++++++-----
 .../geysermc/geyser/item/type/MapItem.java    |  6 +-
 .../geyser/item/type/PlayerHeadItem.java      |  6 +-
 .../geysermc/geyser/item/type/PotionItem.java | 16 +--
 .../geysermc/geyser/item/type/ShieldItem.java |  6 +-
 .../geyser/item/type/ShulkerBoxItem.java      | 71 ++++++-------
 .../geyser/item/type/TippedArrowItem.java     |  4 +-
 .../item/type/TropicalFishBucketItem.java     |  6 +-
 .../geyser/item/type/WritableBookItem.java    |  6 +-
 .../geyser/item/type/WrittenBookItem.java     |  6 +-
 .../populator/RecipeRegistryPopulator.java    |  4 +-
 .../geyser/registry/type/ItemMappings.java    |  2 +-
 .../inventory/InventoryTranslator.java        |  2 +-
 .../inventory/PlayerInventoryTranslator.java  |  4 +-
 .../StonecutterInventoryTranslator.java       |  2 +-
 .../item/CustomItemTranslator.java            | 30 +++---
 .../{inventory => }/item/ItemTranslator.java  | 99 +++++++++----------
 .../BedrockBlockPickRequestTranslator.java    |  2 +-
 .../bedrock/BedrockBookEditTranslator.java    |  2 +-
 ...BedrockInventoryTransactionTranslator.java |  4 +-
 .../player/BedrockActionTranslator.java       |  2 +-
 .../java/JavaUpdateRecipesTranslator.java     |  4 +-
 .../entity/JavaSetEquipmentTranslator.java    |  4 +-
 .../JavaContainerSetSlotTranslator.java       |  4 +-
 .../JavaMerchantOffersTranslator.java         |  4 +-
 .../level/JavaLevelParticlesTranslator.java   |  4 +-
 .../geysermc/geyser/util/InventoryUtils.java  |  2 +-
 54 files changed, 285 insertions(+), 234 deletions(-)
 rename core/src/main/java/org/geysermc/geyser/translator/{inventory => }/item/CustomItemTranslator.java (80%)
 rename core/src/main/java/org/geysermc/geyser/translator/{inventory => }/item/ItemTranslator.java (88%)

diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java
index 7a544f23c..171849ce5 100644
--- a/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java
+++ b/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java
@@ -26,7 +26,7 @@
 package org.geysermc.geyser.entity.type;
 
 import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import com.github.steveice10.opennbt.tag.builtin.ListTag;
 import com.github.steveice10.opennbt.tag.builtin.Tag;
diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java
index 69fb3faab..226ad7df8 100644
--- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java
+++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java
@@ -26,7 +26,7 @@
 package org.geysermc.geyser.entity.type;
 
 import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import org.cloudburstmc.math.vector.Vector3f;
 import org.cloudburstmc.math.vector.Vector3i;
 import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
@@ -37,7 +37,7 @@ import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
 import org.geysermc.geyser.entity.EntityDefinition;
 import org.geysermc.geyser.level.block.BlockStateValues;
 import org.geysermc.geyser.session.GeyserSession;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 
 import java.util.UUID;
 import java.util.concurrent.CompletableFuture;
diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java
index ad1d4b928..453125945 100644
--- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java
+++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java
@@ -26,7 +26,7 @@
 package org.geysermc.geyser.entity.type;
 
 import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
 import com.github.steveice10.mc.protocol.data.game.entity.object.Direction;
 import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
@@ -42,7 +42,7 @@ import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
 import lombok.Getter;
 import org.geysermc.geyser.entity.EntityDefinition;
 import org.geysermc.geyser.session.GeyserSession;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 import org.geysermc.geyser.util.InteractionResult;
 import org.geysermc.geyser.util.InventoryUtils;
 
diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java
index 39c8386bd..3c080345e 100644
--- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java
+++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java
@@ -26,7 +26,7 @@
 package org.geysermc.geyser.entity.type;
 
 import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import org.cloudburstmc.math.vector.Vector3f;
 import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
 import org.geysermc.geyser.entity.EntityDefinition;
diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java
index 1b5c1d2d0..cea371963 100644
--- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java
+++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java
@@ -26,7 +26,7 @@
 package org.geysermc.geyser.entity.type;
 
 import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.opennbt.tag.builtin.StringTag;
 import com.github.steveice10.opennbt.tag.builtin.Tag;
 import org.cloudburstmc.math.vector.Vector3f;
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 4ff8db9f0..dd1aaea81 100644
--- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java
+++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java
@@ -25,7 +25,8 @@
 
 package org.geysermc.geyser.inventory;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+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.opennbt.tag.builtin.CompoundTag;
 import lombok.AccessLevel;
 import lombok.Data;
@@ -34,12 +35,13 @@ 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;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.session.GeyserSession;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 
 @Data
 public class GeyserItemStack {
@@ -47,26 +49,26 @@ public class GeyserItemStack {
 
     private final int javaId;
     private int amount;
-    private CompoundTag nbt;
+    private DataComponentPatch components;
     private int netId;
 
     @Getter(AccessLevel.NONE)
     @EqualsAndHashCode.Exclude
     private Item item;
 
-    private GeyserItemStack(int javaId, int amount, CompoundTag nbt) {
-        this(javaId, amount, nbt, 1);
+    private GeyserItemStack(int javaId, int amount, DataComponentPatch components) {
+        this(javaId, amount, components, 1);
     }
 
-    private GeyserItemStack(int javaId, int amount, CompoundTag nbt, int netId) {
+    private GeyserItemStack(int javaId, int amount, DataComponentPatch components, int netId) {
         this.javaId = javaId;
         this.amount = amount;
-        this.nbt = nbt;
+        this.components = components;
         this.netId = netId;
     }
 
     public static @NonNull GeyserItemStack from(@Nullable ItemStack itemStack) {
-        return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getNbt());
+        return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getDataComponentPatch());
     }
 
     public int getJavaId() {
@@ -78,7 +80,12 @@ public class GeyserItemStack {
     }
 
     public @Nullable CompoundTag getNbt() {
-        return isEmpty() ? null : nbt;
+        Thread.dumpStack();
+        return null;
+    }
+
+    public @Nullable DataComponentPatch getComponents() {
+        return isEmpty() ? null : components;
     }
 
     public int getNetId() {
@@ -98,14 +105,14 @@ public class GeyserItemStack {
     }
 
     public @Nullable ItemStack getItemStack(int newAmount) {
-        return isEmpty() ? null : new ItemStack(javaId, newAmount, nbt);
+        return isEmpty() ? null : new ItemStack(javaId, newAmount, components);
     }
 
     public ItemData getItemData(GeyserSession session) {
         if (isEmpty()) {
             return ItemData.AIR;
         }
-        ItemData.Builder itemData = ItemTranslator.translateToBedrock(session, javaId, amount, nbt);
+        ItemData.Builder itemData = ItemTranslator.translateToBedrock(session, javaId, amount, components);
         itemData.netId(getNetId());
         itemData.usingNetId(true);
         return itemData.build();
@@ -131,6 +138,6 @@ public class GeyserItemStack {
     }
 
     public GeyserItemStack copy(int newAmount) {
-        return isEmpty() ? EMPTY : new GeyserItemStack(javaId, newAmount, nbt == null ? null : nbt.clone(), netId);
+        return isEmpty() ? EMPTY : new GeyserItemStack(javaId, newAmount, components == null ? null : components.clone(), netId);
     }
 }
diff --git a/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java b/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java
index 3376d6c26..b78bbe1b3 100644
--- a/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java
+++ b/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java
@@ -38,7 +38,7 @@ import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
 import org.geysermc.geyser.GeyserImpl;
 import org.geysermc.geyser.item.Items;
 import org.geysermc.geyser.session.GeyserSession;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 import org.jetbrains.annotations.Range;
 
 import java.util.Arrays;
diff --git a/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java b/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java
index f31f6d82f..a118670af 100644
--- a/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java
+++ b/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.inventory.click;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.mc.protocol.data.game.inventory.ContainerActionType;
 import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
 import com.github.steveice10.mc.protocol.data.game.inventory.MoveToHotbarAction;
diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java
index 05c17cf9f..d420170f4 100644
--- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java
+++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.inventory.recipe;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient;
 import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapedRecipeData;
 import org.checkerframework.checker.nullness.qual.Nullable;
diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java
index e300e3ec8..e6eabea2d 100644
--- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java
+++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.inventory.recipe;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient;
 import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapelessRecipeData;
 import org.checkerframework.checker.nullness.qual.Nullable;
diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java
index 22163eced..ce044e745 100644
--- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java
+++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.inventory.recipe;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import org.checkerframework.checker.nullness.qual.Nullable;
 
 /**
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 b58f760d1..669791705 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,9 +25,11 @@
 
 package org.geysermc.geyser.item.type;
 
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import com.github.steveice10.opennbt.tag.builtin.StringTag;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.geysermc.geyser.item.ArmorMaterial;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.session.GeyserSession;
@@ -41,8 +43,8 @@ public class ArmorItem extends Item {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
         if (tag.get("Trim") instanceof CompoundTag trim) {
             StringTag material = trim.remove("material");
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 938d4a79a..2462f374c 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
@@ -25,7 +25,9 @@
 
 package org.geysermc.geyser.item.type;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType;
+import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents;
 import com.github.steveice10.opennbt.tag.builtin.StringTag;
 import org.checkerframework.checker.nullness.qual.NonNull;
 import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
@@ -44,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.getNbt());
+            itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getDataComponentPatch());
             StringTag potionTag = new StringTag("Potion", tippedArrowPotion.getJavaIdentifier());
-            itemStack.getNbt().put(potionTag);
+            itemStack.getDataComponentPatch().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 81d7bf116..6e4e6c6fc 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,10 +25,11 @@
 
 package org.geysermc.geyser.item.type;
 
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import com.github.steveice10.opennbt.tag.builtin.ByteTag;
-import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import com.github.steveice10.opennbt.tag.builtin.StringTag;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.geysermc.geyser.session.GeyserSession;
 import org.geysermc.geyser.text.MinecraftLocale;
 
@@ -38,8 +39,8 @@ public class AxolotlBucketItem extends Item {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
         // Bedrock Edition displays the properties of the axolotl. Java does not.
         // To work around this, set the custom name to the Axolotl translation and it's displayed correctly
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 344668836..9cd7aea42 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,6 +25,7 @@
 
 package org.geysermc.geyser.item.type;
 
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import com.github.steveice10.opennbt.tag.builtin.IntTag;
 import com.github.steveice10.opennbt.tag.builtin.ListTag;
@@ -32,6 +33,7 @@ import com.github.steveice10.opennbt.tag.builtin.Tag;
 import org.checkerframework.checker.nullness.qual.NonNull;
 import org.cloudburstmc.nbt.NbtList;
 import org.cloudburstmc.nbt.NbtMap;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.cloudburstmc.nbt.NbtType;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.session.GeyserSession;
@@ -120,8 +122,8 @@ public class BannerItem extends BlockItem {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
         CompoundTag blockEntityTag = tag.remove("BlockEntityTag");
         if (blockEntityTag != null && blockEntityTag.get("Patterns") instanceof ListTag patterns) {
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 99857006c..2611c8ff6 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,8 +25,9 @@
 
 package org.geysermc.geyser.item.type;
 
-import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.geysermc.geyser.session.GeyserSession;
 
 public class ChestItem extends BlockItem {
@@ -36,8 +37,8 @@ public class ChestItem extends BlockItem {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
         // Strip the BlockEntityTag from the chests contents
         // sent to the client. The client does not parse this
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 87da96447..f3933d83b 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
@@ -25,12 +25,14 @@
 
 package org.geysermc.geyser.item.type;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+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.opennbt.tag.builtin.ByteTag;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import com.github.steveice10.opennbt.tag.builtin.IntTag;
 import com.github.steveice10.opennbt.tag.builtin.Tag;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.registry.type.ItemMappings;
@@ -58,8 +60,8 @@ public class CompassItem extends Item {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
         Tag lodestoneTag = tag.get("LodestoneTracked");
         if (lodestoneTag instanceof ByteTag) {
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 e409dccfb..1ea468721 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
@@ -25,14 +25,16 @@
 
 package org.geysermc.geyser.item.type;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+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.opennbt.tag.builtin.*;
 import org.checkerframework.checker.nullness.qual.NonNull;
 import org.checkerframework.checker.nullness.qual.Nullable;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.session.GeyserSession;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 
 public class CrossbowItem extends Item {
     public CrossbowItem(String javaIdentifier, Builder builder) {
@@ -40,8 +42,8 @@ public class CrossbowItem extends Item {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
         ListTag chargedProjectiles = tag.get("ChargedProjectiles");
         if (chargedProjectiles != null) {
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 10d2a1bcc..bfa86d2ad 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,9 +25,11 @@
 
 package org.geysermc.geyser.item.type;
 
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import com.github.steveice10.opennbt.tag.builtin.ListTag;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.geysermc.geyser.session.GeyserSession;
 
 public class DecoratedPotItem extends BlockItem {
@@ -37,8 +39,8 @@ public class DecoratedPotItem extends BlockItem {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
         if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) {
             if (blockEntityTag.remove("sherds") instanceof ListTag sherds) {
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 dbcff7d0b..f1b10474d 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,8 +25,10 @@
 
 package org.geysermc.geyser.item.type;
 
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.geysermc.geyser.item.ArmorMaterial;
 import org.geysermc.geyser.item.DyeableLeatherItem;
 import org.geysermc.geyser.registry.type.ItemMapping;
@@ -38,8 +40,8 @@ public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch 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 0d37f5eab..39787ae2f 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,8 +25,10 @@
 
 package org.geysermc.geyser.item.type;
 
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.geysermc.geyser.item.DyeableLeatherItem;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.session.GeyserSession;
@@ -37,8 +39,8 @@ public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch 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 ac0751c73..c51278947 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,10 +25,12 @@
 
 package org.geysermc.geyser.item.type;
 
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import com.github.steveice10.opennbt.tag.builtin.ListTag;
 import com.github.steveice10.opennbt.tag.builtin.Tag;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.geysermc.geyser.session.GeyserSession;
 
 import java.util.ArrayList;
@@ -40,8 +42,8 @@ public class EnchantedBookItem extends Item {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
         List<Tag> newTags = new ArrayList<>();
         Tag enchantmentTag = tag.remove("StoredEnchantments");
diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java
index 963373523..8125ce101 100644
--- a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java
+++ b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.item.type;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import com.github.steveice10.opennbt.tag.builtin.Tag;
 import org.cloudburstmc.nbt.NbtMap;
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 3559cdf4d..6be1be15d 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,8 +25,10 @@
 
 package org.geysermc.geyser.item.type;
 
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import com.github.steveice10.opennbt.tag.builtin.*;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.geysermc.geyser.level.FireworkColor;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.session.GeyserSession;
@@ -38,8 +40,8 @@ public class FireworkRocketItem extends Item {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
         CompoundTag fireworks = tag.get("Fireworks");
         if (fireworks == null) {
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 9c13d7793..6d4347e9e 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,11 +25,13 @@
 
 package org.geysermc.geyser.item.type;
 
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
 import com.github.steveice10.opennbt.tag.builtin.IntTag;
 import com.github.steveice10.opennbt.tag.builtin.Tag;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.session.GeyserSession;
 
@@ -39,8 +41,8 @@ public class FireworkStarItem extends Item {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
         Tag explosion = tag.remove("Explosion");
         if (explosion instanceof CompoundTag) {
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 f63a1ec5a..50a0bddbc 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,10 +25,11 @@
 
 package org.geysermc.geyser.item.type;
 
-import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import com.github.steveice10.opennbt.tag.builtin.IntTag;
 import com.github.steveice10.opennbt.tag.builtin.Tag;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.geysermc.geyser.session.GeyserSession;
 
 public class FishingRodItem extends Item {
@@ -37,8 +38,8 @@ public class FishingRodItem extends Item {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
         // Fix damage inconsistency
         Tag damage = tag.get("Damage");
diff --git a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java
index aacb906c9..60b201961 100644
--- a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java
+++ b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.item.type;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.opennbt.tag.builtin.StringTag;
 import org.checkerframework.checker.nullness.qual.NonNull;
 import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
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 3701b5189..df3c5effe 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
@@ -26,10 +26,18 @@
 package org.geysermc.geyser.item.type;
 
 import com.github.steveice10.mc.protocol.data.game.Identifier;
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+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.mc.protocol.data.game.item.component.ItemEnchantments;
 import com.github.steveice10.opennbt.tag.builtin.*;
+import net.kyori.adventure.text.Component;
 import org.checkerframework.checker.nullness.qual.NonNull;
 import org.checkerframework.checker.nullness.qual.Nullable;
+import org.cloudburstmc.nbt.NbtList;
+import org.cloudburstmc.nbt.NbtMap;
+import org.cloudburstmc.nbt.NbtMapBuilder;
+import org.cloudburstmc.nbt.NbtType;
 import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
 import org.geysermc.geyser.GeyserImpl;
 import org.geysermc.geyser.inventory.item.Enchantment;
@@ -38,7 +46,7 @@ import org.geysermc.geyser.registry.type.ItemMappings;
 import org.geysermc.geyser.session.GeyserSession;
 import org.geysermc.geyser.text.ChatColor;
 import org.geysermc.geyser.text.MinecraftLocale;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 import org.geysermc.geyser.translator.text.MessageTranslator;
 import org.geysermc.geyser.util.InventoryUtils;
 
@@ -107,7 +115,7 @@ public class Item {
 
     public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) {
         if (itemData.getTag() == null) {
-            return new ItemStack(javaId, itemData.getCount(), new CompoundTag(""));
+            return new ItemStack(javaId, itemData.getCount(), null);
         }
         return new ItemStack(javaId, itemData.getCount(), ItemTranslator.translateToJavaNBT("", itemData.getTag()));
     }
@@ -117,22 +125,31 @@ public class Item {
     }
 
     /**
-     * Takes NBT from Java Edition and converts any value that Bedrock parses differently.
+     * Takes components from Java Edition and map them into Bedrock.
      */
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        if (tag.get("display") instanceof CompoundTag displayTag) {
-            if (displayTag.get("Lore") instanceof ListTag listTag) {
-                List<Tag> lore = new ArrayList<>();
-                for (Tag subTag : listTag.getValue()) {
-                    if (!(subTag instanceof StringTag)) continue;
-                    lore.add(new StringTag("", MessageTranslator.convertMessageLenient(((StringTag) subTag).getValue(), session.locale())));
-                }
-                displayTag.put(new ListTag("Lore", lore));
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch 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) {
+//            customName = components.get(DataComponentType.ITEM_NAME);
+//        }
+//        if (customName != null) {
+//
+//        }
+        List<Component> loreComponents = components.get(DataComponentType.LORE);
+        if (loreComponents != null) {
+            List<String> lore = new ArrayList<>();
+            for (Component loreComponent : loreComponents) {
+                lore.add(MessageTranslator.convertMessage(loreComponent, session.locale()));
             }
+            builder.putList("Lore", NbtType.STRING, lore);
         }
 
         List<Tag> newTags = new ArrayList<>();
-        Tag enchantmentTag = tag.remove("Enchantments");
+        ItemEnchantments enchantments = components.get(DataComponentType.ENCHANTMENTS);
+        if (enchantments != null) {
+
+        }
         if (enchantmentTag instanceof ListTag listTag) {
             for (Tag subTag : listTag.getValue()) {
                 if (!(subTag instanceof CompoundTag)) continue;
@@ -211,10 +228,7 @@ public class Item {
         }
     }
 
-    protected final @Nullable CompoundTag remapEnchantment(GeyserSession session, CompoundTag tag, CompoundTag rootTag) {
-        Tag javaEnchId = tag.get("id");
-        if (!(javaEnchId instanceof StringTag))
-            return null;
+    protected final @Nullable NbtMap remapEnchantment(GeyserSession session, ItemEnchantments, NbtMapBuilder rootBuilder) {
 
         Enchantment enchantment = Enchantment.getByJavaIdentifier(((StringTag) javaEnchId).getValue());
         if (enchantment == null) {
@@ -231,11 +245,10 @@ public class Item {
 
         Tag javaEnchLvl = tag.get("lvl");
 
-        CompoundTag bedrockTag = new CompoundTag("");
-        bedrockTag.put(new ShortTag("id", (short) enchantment.ordinal()));
-        // If the tag cannot parse, Java Edition 1.18.2 sets to 0
-        bedrockTag.put(new ShortTag("lvl", javaEnchLvl != null && javaEnchLvl.getValue() instanceof Number lvl ? lvl.shortValue() : (short) 0));
-        return bedrockTag;
+        NbtMapBuilder builder = NbtMap.builder();
+        builder.putShort("id", (short) enchantment.ordinal());
+        builder.putShort("lvl", );
+        return builder.build();
     }
 
     private void addSweeping(GeyserSession session, CompoundTag itemTag, int level) {
@@ -258,8 +271,8 @@ public class Item {
 
     /* Translation methods end */
 
-    public ItemStack newItemStack(int count, CompoundTag tag) {
-        return new ItemStack(this.javaId, count, tag);
+    public ItemStack newItemStack(int count, DataComponentPatch components) {
+        return new ItemStack(this.javaId, count, components);
     }
 
     public void setJavaId(int javaId) { // TODO like this?
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 4405b66ad..8dbeeb57f 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,8 +25,10 @@
 
 package org.geysermc.geyser.item.type;
 
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import com.github.steveice10.opennbt.tag.builtin.*;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.session.GeyserSession;
 
@@ -36,8 +38,8 @@ public class MapItem extends Item {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
         Tag mapId = tag.remove("map");
         if (mapId == null || !(mapId.getValue() instanceof Number number)) return;
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 662448a52..4aefcf765 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,10 +25,12 @@
 
 package org.geysermc.geyser.item.type;
 
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import com.github.steveice10.opennbt.tag.builtin.StringTag;
 import com.github.steveice10.opennbt.tag.builtin.Tag;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.geysermc.geyser.session.GeyserSession;
 import org.geysermc.geyser.text.ChatColor;
 import org.geysermc.geyser.text.MinecraftLocale;
@@ -40,8 +42,8 @@ public class PlayerHeadItem extends Item {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
         CompoundTag displayTag;
         if (tag.get("display") instanceof CompoundTag existingDisplayTag) {
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 24dd56ef2..26c468fb1 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
@@ -25,7 +25,9 @@
 
 package org.geysermc.geyser.item.type;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType;
+import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents;
 import com.github.steveice10.opennbt.tag.builtin.StringTag;
 import com.github.steveice10.opennbt.tag.builtin.Tag;
 import org.checkerframework.checker.nullness.qual.NonNull;
@@ -35,8 +37,8 @@ import org.geysermc.geyser.GeyserImpl;
 import org.geysermc.geyser.inventory.item.Potion;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.registry.type.ItemMappings;
-import org.geysermc.geyser.translator.inventory.item.CustomItemTranslator;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.CustomItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 
 public class PotionItem extends Item {
     public PotionItem(String javaIdentifier, Builder builder) {
@@ -45,10 +47,10 @@ public class PotionItem extends Item {
 
     @Override
     public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) {
-        if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, mapping, mappings);
-        Tag potionTag = itemStack.getNbt().get("Potion");
-        if (potionTag instanceof StringTag) {
-            ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(itemStack.getNbt(), mapping);
+        if (itemStack.getDataComponentPatch() == null) return super.translateToBedrock(itemStack, mapping, mappings);
+        PotionContents potionContents = itemStack.getDataComponentPatch().get(DataComponentType.POTION_CONTENTS);
+        if (potionContents != null) {
+            ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(itemStack.getDataComponentPatch(), 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 c13dd4fcf..cd940c87c 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,11 +25,13 @@
 
 package org.geysermc.geyser.item.type;
 
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import com.github.steveice10.opennbt.tag.builtin.IntTag;
 import com.github.steveice10.opennbt.tag.builtin.ListTag;
 import com.github.steveice10.opennbt.tag.builtin.Tag;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.geysermc.geyser.item.components.ToolTier;
 import org.geysermc.geyser.session.GeyserSession;
 
@@ -39,8 +41,8 @@ public class ShieldItem extends Item {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
         if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) {
             if (blockEntityTag.get("Patterns") instanceof ListTag patterns) {
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 717bad9a4..e2259eb5d 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
@@ -26,68 +26,61 @@
 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 org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMap;
+import org.cloudburstmc.nbt.NbtMapBuilder;
+import org.cloudburstmc.nbt.NbtType;
+import org.geysermc.geyser.item.Items;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.session.GeyserSession;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 import org.geysermc.geyser.util.MathUtils;
 
+import java.util.ArrayList;
+import java.util.List;
+
 public class ShulkerBoxItem extends BlockItem {
     public ShulkerBoxItem(String javaIdentifier, Builder builder) {
         super(javaIdentifier, builder);
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
-        CompoundTag blockEntityTag = tag.get("BlockEntityTag");
-        if (blockEntityTag == null) {
+        List<ItemStack> contents = components.get(DataComponentType.CONTAINER);
+        if (contents == null || contents.isEmpty()) {
             // Empty shulker box
             return;
         }
-        if (blockEntityTag.get("Items") == null) return;
-        ListTag itemsList = new ListTag("Items");
-        for (Tag item : (ListTag) blockEntityTag.get("Items")) {
-            CompoundTag itemData = (CompoundTag) item; // Information about the item
-            CompoundTag boxItemTag = new CompoundTag(""); // Final item tag to add to the list
-            boxItemTag.put(new ByteTag("Slot", (byte) (MathUtils.getNbtByte(itemData.get("Slot").getValue()) & 255)));
-            boxItemTag.put(new ByteTag("WasPickedUp", (byte) 0)); // ???
-
-            ItemMapping boxMapping = session.getItemMappings().getMapping(Identifier.formalize(((StringTag) itemData.get("id")).getValue()));
-
-            if (boxMapping == null) {
-                // If invalid ID
+        List<NbtMap> itemsList = new ArrayList<>();
+        for (int slot = 0; slot < contents.size(); slot++) {
+            ItemStack item = contents.get(slot);
+            if (item.getId() == Items.AIR_ID) {
                 continue;
             }
+            NbtMapBuilder boxItemNbt = NbtMap.builder(); // Final item tag to add to the list
+            boxItemNbt.putByte("Slot", (byte) slot);
+            boxItemNbt.putByte("WasPickedUp", (byte) 0); // ???
 
-            boxItemTag.put(new StringTag("Name", boxMapping.getBedrockIdentifier()));
-            boxItemTag.put(new ShortTag("Damage", (short) boxMapping.getBedrockData()));
-            boxItemTag.put(new ByteTag("Count", MathUtils.getNbtByte(itemData.get("Count").getValue())));
+            ItemMapping boxMapping = session.getItemMappings().getMapping(item.getId());
+
+            boxItemNbt.putString("Name", boxMapping.getBedrockIdentifier());
+            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
-            CompoundTag displayTag = itemData.get("tag");
-            if (displayTag == null && boxMapping.hasTranslation()) {
-                displayTag = new CompoundTag("tag");
-            }
-            if (displayTag != null) {
-                boxItemTag.put(ItemTranslator.translateDisplayProperties(session, displayTag, boxMapping, '7'));
+            DataComponentPatch boxComponents = item.getDataComponentPatch();
+            if (boxComponents != null) {
+                boxItemNbt.put(ItemTranslator.translateDisplayProperties(session, displayTag, boxMapping, '7'));
             }
 
-            itemsList.add(boxItemTag);
+            itemsList.add(boxItemNbt.build());
         }
-        tag.put(itemsList);
-
-        // Strip the BlockEntityTag from the chests contents
-        // sent to the client. The client does not parse this
-        // or use it for anything, as this tag is fully
-        // server-side, so we remove it to reduce bandwidth and
-        // solve potential issues with very large tags.
-
-        // There was a problem in the past where this would strip
-        // NBT data in creative mode, however with the new server
-        // authoritative inventories, this is no longer a concern.
-        tag.remove("BlockEntityTag");
+        builder.putList("Items", NbtType.COMPOUND, itemsList);
     }
 
     @Override
diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java
index f78836d16..fcf562ba5 100644
--- a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java
+++ b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.item.type;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.opennbt.tag.builtin.StringTag;
 import com.github.steveice10.opennbt.tag.builtin.Tag;
 import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
@@ -33,7 +33,7 @@ import org.geysermc.geyser.GeyserImpl;
 import org.geysermc.geyser.inventory.item.TippedArrowPotion;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.registry.type.ItemMappings;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 
 public class TippedArrowItem extends ArrowItem {
     public TippedArrowItem(String javaIdentifier, Builder builder) {
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 8b4e35d1e..17f90ca12 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,12 +25,14 @@
 
 package org.geysermc.geyser.item.type;
 
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import com.github.steveice10.opennbt.tag.builtin.*;
 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 org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.geysermc.geyser.entity.type.living.animal.TropicalFishEntity;
 import org.geysermc.geyser.session.GeyserSession;
 import org.geysermc.geyser.text.MinecraftLocale;
@@ -47,8 +49,8 @@ public class TropicalFishBucketItem extends Item {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
         // Prevent name from appearing as "Bucket of"
         tag.put(new ByteTag("AppendCustomName", (byte) 1));
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 dfebecf7d..67221b1c6 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,11 +25,13 @@
 
 package org.geysermc.geyser.item.type;
 
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import com.github.steveice10.opennbt.tag.builtin.ListTag;
 import com.github.steveice10.opennbt.tag.builtin.StringTag;
 import com.github.steveice10.opennbt.tag.builtin.Tag;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.session.GeyserSession;
 import org.geysermc.geyser.translator.text.MessageTranslator;
@@ -43,8 +45,8 @@ public class WritableBookItem extends Item {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
-        super.translateNbtToBedrock(session, tag);
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
+        super.translateComponentsToBedrock(session, components, builder);
 
         ListTag pagesTag = tag.remove("pages");
         if (pagesTag == null) {
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 045aaa416..0198e73ff 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,6 +25,7 @@
 
 package org.geysermc.geyser.item.type;
 
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import com.github.steveice10.opennbt.tag.builtin.ListTag;
 import com.github.steveice10.opennbt.tag.builtin.StringTag;
@@ -32,6 +33,7 @@ import com.github.steveice10.opennbt.tag.builtin.Tag;
 import net.kyori.adventure.text.Component;
 import net.kyori.adventure.text.format.NamedTextColor;
 import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.nbt.NbtMapBuilder;
 import org.geysermc.geyser.session.GeyserSession;
 import org.geysermc.geyser.translator.text.MessageTranslator;
 
@@ -48,13 +50,13 @@ public class WrittenBookItem extends WritableBookItem {
     }
 
     @Override
-    public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) {
+    public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) {
         boolean isValid = isValidWrittenBook(tag);
         if (!isValid) {
             tag.remove("pages");
         }
 
-        super.translateNbtToBedrock(session, tag);
+        super.translateComponentsToBedrock(session, components, builder);
 
         if (!isValid) {
             CompoundTag invalidTagPage = new CompoundTag("");
diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java
index 5e4d5fc7a..34e855212 100644
--- a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java
+++ b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java
@@ -26,7 +26,7 @@
 package org.geysermc.geyser.registry.populator;
 
 import com.fasterxml.jackson.databind.JsonNode;
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient;
 import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType;
 import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
@@ -48,7 +48,7 @@ import org.geysermc.geyser.registry.Registries;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.registry.type.ItemMappings;
 import org.geysermc.geyser.text.GeyserLocale;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java
index 40359b437..33908a7e7 100644
--- a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java
+++ b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.registry.type;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
 import lombok.Builder;
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java
index 95ec99412..e6e0c6340 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.translator.inventory;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
 import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient;
 import com.github.steveice10.opennbt.tag.builtin.IntTag;
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java
index 1447f2b5b..429b577ce 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.translator.inventory;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
 import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
 import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket;
@@ -53,7 +53,7 @@ import org.geysermc.geyser.item.Items;
 import org.geysermc.geyser.session.GeyserSession;
 import org.geysermc.geyser.skin.FakeHeadProvider;
 import org.geysermc.geyser.text.GeyserLocale;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 import org.geysermc.geyser.util.InventoryUtils;
 
 import java.util.Arrays;
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java
index 50c040a0b..d3d15680a 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.translator.inventory;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
 import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket;
 import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/CustomItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java
similarity index 80%
rename from core/src/main/java/org/geysermc/geyser/translator/inventory/item/CustomItemTranslator.java
rename to core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java
index 06d1e3aa6..d5f85dcc3 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/CustomItemTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
+ * 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
@@ -23,11 +23,10 @@
  * @link https://github.com/GeyserMC/Geyser
  */
 
-package org.geysermc.geyser.translator.inventory.item;
+package org.geysermc.geyser.translator.item;
 
-import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
-import com.github.steveice10.opennbt.tag.builtin.IntTag;
-import com.github.steveice10.opennbt.tag.builtin.Tag;
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch;
+import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType;
 import it.unimi.dsi.fastutil.Pair;
 import org.checkerframework.checker.nullness.qual.Nullable;
 import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
@@ -44,8 +43,8 @@ import java.util.OptionalInt;
 public final class CustomItemTranslator {
 
     @Nullable
-    public static ItemDefinition getCustomItem(CompoundTag nbt, ItemMapping mapping) {
-        if (nbt == null) {
+    public static ItemDefinition getCustomItem(DataComponentPatch components, ItemMapping mapping) {
+        if (components == null) {
             return null;
         }
         List<Pair<CustomItemOptions, ItemDefinition>> customMappings = mapping.getCustomItemOptions();
@@ -53,10 +52,11 @@ public final class CustomItemTranslator {
             return null;
         }
 
-        int customModelData = nbt.get("CustomModelData") instanceof IntTag customModelDataTag ? customModelDataTag.getValue() : 0;
+        // TODO getOrDefault
+        int customModelData = components.get(DataComponentType.CUSTOM_MODEL_DATA);
         boolean checkDamage = mapping.getJavaItem().maxDamage() > 0;
-        int damage = !checkDamage ? 0 : nbt.get("Damage") instanceof IntTag damageTag ? damageTag.getValue() : 0;
-        boolean unbreakable = checkDamage && !isDamaged(nbt, damage);
+        int damage = !checkDamage ? 0 : components.get(DataComponentType.DAMAGE);
+        boolean unbreakable = checkDamage && !isDamaged(components, damage);
 
         for (Pair<CustomItemOptions, ItemDefinition> mappingTypes : customMappings) {
             CustomItemOptions options = mappingTypes.key();
@@ -105,15 +105,15 @@ public final class CustomItemTranslator {
 
     /* These two functions are based off their Mojmap equivalents from 1.19.2 */
 
-    private static boolean isDamaged(CompoundTag nbt, int damage) {
-        return isDamagableItem(nbt) && damage > 0;
+    private static boolean isDamaged(DataComponentPatch components, int damage) {
+        return isDamagableItem(components) && damage > 0;
     }
 
-    private static boolean isDamagableItem(CompoundTag nbt) {
+    private static boolean isDamagableItem(DataComponentPatch components) {
         // mapping.getMaxDamage > 0 should also be checked (return false if not true) but we already check prior to this function
-        Tag unbreakableTag = nbt.get("Unbreakable");
+        Boolean unbreakable = components.get(DataComponentType.UNBREAKABLE);
         // Tag must either not be present or be set to false
-        return unbreakableTag == null || !(unbreakableTag.getValue() instanceof Number number) || number.byteValue() == 0;
+        return unbreakable == null || !unbreakable;
     }
 
     private CustomItemTranslator() {
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java
similarity index 88%
rename from core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java
rename to core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java
index d1a256551..027c6b5ba 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
+ * 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
@@ -23,11 +23,15 @@
  * @link https://github.com/GeyserMC/Geyser
  */
 
-package org.geysermc.geyser.translator.inventory.item;
+package org.geysermc.geyser.translator.item;
 
 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.entity.metadata.ItemStack;
+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.DataComponentType;
+import com.github.steveice10.mc.protocol.data.game.item.component.ItemAttributeModifiers;
 import com.github.steveice10.opennbt.tag.builtin.ByteArrayTag;
 import com.github.steveice10.opennbt.tag.builtin.ByteTag;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
@@ -133,20 +137,20 @@ public final class ItemTranslator {
                 .build();
     }
 
-    private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, CompoundTag tag) {
-        CompoundTag nbt = tag != null ? tag.clone() : null;
+    private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, DataComponentPatch components) {
+        NbtMapBuilder builder = NbtMap.builder();
 
-        if (nbt != null) {
-            javaItem.translateNbtToBedrock(session, nbt);
+        if (components != null) {
+            javaItem.translateComponentsToBedrock(session, components, builder);
         }
 
-        nbt = translateDisplayProperties(session, nbt, bedrockItem);
+        translateDisplayProperties(session, components, bedrockItem);
 
-        if (nbt != null) {
-            Tag hideFlags = nbt.get("HideFlags");
-            if (hideFlags == null || !hasFlagPresent(hideFlags, HIDE_ATTRIBUTES_FLAG)) {
-                // only add if the hide attribute modifiers flag is not present
-                addAttributeLore(nbt, session.locale());
+        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());
             }
         }
 
@@ -173,10 +177,10 @@ public final class ItemTranslator {
 
         translateCustomItem(nbt, builder, bedrockItem);
 
-        if (nbt != null) {
+        if (components != null) {
             // Translate the canDestroy and canPlaceOn Java NBT
-            ListTag canDestroy = nbt.get("CanDestroy");
-            ListTag canPlaceOn = nbt.get("CanPlaceOn");
+            AdventureModePredicate canDestroy = components.get(DataComponentType.CAN_BREAK);
+            AdventureModePredicate canPlaceOn = components.get(DataComponentType.CAN_PLACE_ON);
             String[] canBreak = getCanModify(canDestroy);
             String[] canPlace = getCanModify(canPlaceOn);
             if (canBreak != null) {
@@ -197,13 +201,8 @@ public final class ItemTranslator {
      * @param nbt the NBT of the ItemStack
      * @param language the locale of the player
      */
-    private static void addAttributeLore(CompoundTag nbt, String language) {
-        ListTag attributeModifiers = nbt.get("AttributeModifiers");
-        if (attributeModifiers == null) {
-            return; // nothing to convert to lore
-        }
-
-        CompoundTag displayTag = nbt.get("display");
+    private static void addAttributeLore(ItemAttributeModifiers modifiers, NbtMapBuilder builder, String language) {
+        CompoundTag displayTag = builder.get("display");
         if (displayTag == null) {
             displayTag = new CompoundTag("display");
         }
@@ -214,25 +213,23 @@ public final class ItemTranslator {
 
         // maps each slot to the modifiers applied when in such slot
         Map<String, List<StringTag>> slotsToModifiers = new HashMap<>();
-        for (Tag modifier : attributeModifiers) {
-            CompoundTag modifierTag = (CompoundTag) modifier;
-
+        for (ItemAttributeModifiers.Entry entry : modifiers.getModifiers()) {
             // convert the modifier tag to a lore entry
-            String loreEntry = attributeToLore(modifierTag, language);
+            String loreEntry = attributeToLore(entry.getModifier(), language);
             if (loreEntry == null) {
                 continue; // invalid or failed
             }
 
             StringTag loreTag = new StringTag("", loreEntry);
-            StringTag slotTag = modifierTag.get("Slot");
-            if (slotTag == null) {
+            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);
                 }
             } else {
                 // modifier applies to only the specified slot
-                slotsToModifiers.computeIfAbsent(slotTag.getValue(), s -> new ArrayList<>()).add(loreTag);
+                slotsToModifiers.computeIfAbsent(slotGroup, s -> new ArrayList<>()).add(loreTag);
             }
         }
 
@@ -262,31 +259,23 @@ public final class ItemTranslator {
     }
 
     @Nullable
-    private static String attributeToLore(CompoundTag modifier, String language) {
-        Tag amountTag = modifier.get("Amount");
-        if (amountTag == null || !(amountTag.getValue() instanceof Number number)) {
-            return null;
-        }
-        double amount = number.doubleValue();
+    private static String attributeToLore(ItemAttributeModifiers.AttributeModifier modifier, String language) {
+        double amount = modifier.getAmount();
         if (amount == 0) {
             return null;
         }
 
-        if (!(modifier.get("AttributeName") instanceof StringTag nameTag)) {
-            return null;
-        }
-        String name = nameTag.getValue().replace("minecraft:", "");
-        // the namespace does not need to be present, but if it is, the java client ignores it
+        String name = modifier.getName().replace("minecraft:", "");
+        // the namespace does not need to be present, but if it is, the java client ignores it as of pre-1.20.5
 
         String operationTotal;
-        Tag operationTag = modifier.get("Operation");
-        ModifierOperation operation;
-        if (operationTag == null || (operation = ModifierOperation.from((int) operationTag.getValue())) == ModifierOperation.ADD) {
+        ModifierOperation operation = modifier.getOperation();
+        if (operation == ModifierOperation.ADD) {
             if (name.equals("generic.knockback_resistance")) {
                 amount *= 10;
             }
             operationTotal = ATTRIBUTE_FORMAT.format(amount);
-        } else if (operation == ModifierOperation.ADD_MULTIPLIED || operation == ModifierOperation.MULTIPLY) {
+        } else if (operation == ModifierOperation.ADD_MULTIPLIED_BASE || operation == ModifierOperation.ADD_MULTIPLIED_TOTAL) {
             operationTotal = ATTRIBUTE_FORMAT.format(amount * 100) + "%";
         } else {
             GeyserImpl.getInstance().getLogger().warning("Unhandled ModifierOperation while adding item attributes: " + operation);
@@ -363,12 +352,22 @@ public final class ItemTranslator {
      * @param canModifyJava the list of items in Java
      * @return the new list of items in Bedrock
      */
-    private static String @Nullable [] getCanModify(ListTag canModifyJava) {
-        if (canModifyJava != null && canModifyJava.size() > 0) {
-            String[] canModifyBedrock = new String[canModifyJava.size()];
+    // TODO this is now more complicated in 1.20.5. Yippee!
+    private static String @Nullable [] getCanModify(@Nullable AdventureModePredicate canModifyJava) {
+        if (canModifyJava == null) {
+            return null;
+        }
+        List<AdventureModePredicate.BlockPredicate> predicates = canModifyJava.getPredicates();
+        if (predicates.size() > 0) {
+            String[] canModifyBedrock = new String[predicates.size()];
             for (int i = 0; i < canModifyBedrock.length; i++) {
                 // Get the Java identifier of the block that can be placed
-                String block = Identifier.formalize(((StringTag) canModifyJava.get(i)).getValue());
+                String location = predicates.get(i).getLocation();
+                if (location == null) {
+                    canModifyBedrock[i] = ""; // So it'll serialize
+                    continue; // ???
+                }
+                String block = Identifier.formalize(location);
                 // Get the Bedrock identifier of the item and replace it.
                 // This will unfortunately be limited - for example, beds and banners will be translated weirdly
                 canModifyBedrock[i] = BlockRegistries.JAVA_TO_BEDROCK_IDENTIFIERS.getOrDefault(block, block).replace("minecraft:", "");
@@ -403,7 +402,7 @@ public final class ItemTranslator {
             }
         }
 
-        ItemDefinition definition = CustomItemTranslator.getCustomItem(itemStack.getNbt(), mapping);
+        ItemDefinition definition = CustomItemTranslator.getCustomItem(itemStack, mapping);
         if (definition == null) {
             // No custom item
             return itemDefinition;
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java
index 381adf2b7..59317fd7c 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.translator.protocol.bedrock;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import com.github.steveice10.opennbt.tag.builtin.ListTag;
 import com.github.steveice10.opennbt.tag.builtin.StringTag;
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java
index 6547044c3..ec1d62d16 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.translator.protocol.bedrock;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundEditBookPacket;
 import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
 import com.github.steveice10.opennbt.tag.builtin.ListTag;
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java
index 4ac835268..8d005e515 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.translator.protocol.bedrock;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.mc.protocol.data.game.entity.object.Direction;
 import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
 import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
@@ -70,7 +70,7 @@ import org.geysermc.geyser.session.GeyserSession;
 import org.geysermc.geyser.session.cache.SkullCache;
 import org.geysermc.geyser.skin.FakeHeadProvider;
 import org.geysermc.geyser.translator.inventory.InventoryTranslator;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 import org.geysermc.geyser.translator.protocol.PacketTranslator;
 import org.geysermc.geyser.translator.protocol.Translator;
 import org.geysermc.geyser.util.BlockUtils;
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java
index 33410f240..f5122b256 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java
@@ -52,7 +52,7 @@ import org.geysermc.geyser.registry.type.BlockMapping;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.session.GeyserSession;
 import org.geysermc.geyser.session.cache.SkullCache;
-import org.geysermc.geyser.translator.inventory.item.CustomItemTranslator;
+import org.geysermc.geyser.translator.item.CustomItemTranslator;
 import org.geysermc.geyser.translator.protocol.PacketTranslator;
 import org.geysermc.geyser.translator.protocol.Translator;
 import org.geysermc.geyser.util.BlockUtils;
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java
index 94c69b780..aca02feab 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.translator.protocol.java;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient;
 import com.github.steveice10.mc.protocol.data.game.recipe.Recipe;
 import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType;
@@ -56,7 +56,7 @@ import org.geysermc.geyser.inventory.recipe.TrimRecipe;
 import org.geysermc.geyser.registry.Registries;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.session.GeyserSession;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 import org.geysermc.geyser.translator.protocol.PacketTranslator;
 import org.geysermc.geyser.translator.protocol.Translator;
 import org.geysermc.geyser.util.InventoryUtils;
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java
index 0c344bddc..c178f27d4 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java
@@ -26,7 +26,7 @@
 package org.geysermc.geyser.translator.protocol.java.entity;
 
 import com.github.steveice10.mc.protocol.data.game.entity.metadata.Equipment;
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundSetEquipmentPacket;
 import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
 import org.geysermc.geyser.entity.type.Entity;
@@ -35,7 +35,7 @@ import org.geysermc.geyser.entity.type.player.PlayerEntity;
 import org.geysermc.geyser.item.Items;
 import org.geysermc.geyser.session.GeyserSession;
 import org.geysermc.geyser.skin.FakeHeadProvider;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 import org.geysermc.geyser.translator.protocol.PacketTranslator;
 import org.geysermc.geyser.translator.protocol.Translator;
 
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java
index 605a40d75..594c99291 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.translator.protocol.java.inventory;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient;
 import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetSlotPacket;
 import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId;
@@ -41,7 +41,7 @@ import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe;
 import org.geysermc.geyser.session.GeyserSession;
 import org.geysermc.geyser.translator.inventory.InventoryTranslator;
 import org.geysermc.geyser.translator.inventory.PlayerInventoryTranslator;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 import org.geysermc.geyser.translator.protocol.PacketTranslator;
 import org.geysermc.geyser.translator.protocol.Translator;
 import org.geysermc.geyser.util.InventoryUtils;
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java
index 17a4314ec..68d2bcab3 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.translator.protocol.java.inventory;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.mc.protocol.data.game.inventory.VillagerTrade;
 import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket;
 import org.cloudburstmc.nbt.NbtMap;
@@ -41,7 +41,7 @@ import org.geysermc.geyser.inventory.MerchantContainer;
 import org.geysermc.geyser.registry.Registries;
 import org.geysermc.geyser.registry.type.ItemMapping;
 import org.geysermc.geyser.session.GeyserSession;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 import org.geysermc.geyser.translator.protocol.PacketTranslator;
 import org.geysermc.geyser.translator.protocol.Translator;
 import org.geysermc.geyser.util.InventoryUtils;
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java
index 11d9dbddf..78290f6bd 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.translator.protocol.java.level;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.mc.protocol.data.game.level.particle.BlockParticleData;
 import com.github.steveice10.mc.protocol.data.game.level.particle.DustParticleData;
 import com.github.steveice10.mc.protocol.data.game.level.particle.FallingDustParticleData;
@@ -49,7 +49,7 @@ import org.geysermc.geyser.entity.type.Entity;
 import org.geysermc.geyser.registry.Registries;
 import org.geysermc.geyser.registry.type.ParticleMapping;
 import org.geysermc.geyser.session.GeyserSession;
-import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.item.ItemTranslator;
 import org.geysermc.geyser.translator.protocol.PacketTranslator;
 import org.geysermc.geyser.translator.protocol.Translator;
 import org.geysermc.geyser.util.DimensionUtils;
diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java
index 25976f0f5..e56aea8c9 100644
--- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java
+++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java
@@ -25,7 +25,7 @@
 
 package org.geysermc.geyser.util;
 
-import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
+import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
 import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
 import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient;
 import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundPickItemPacket;