diff --git a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java index 9e0b83768..3c7b7e4bd 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java @@ -29,6 +29,7 @@ import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; import lombok.Getter; import lombok.Setter; +import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; @@ -72,7 +73,7 @@ public class AnvilContainer extends Container { String correctRename; newName = rename; - String originalName = ItemUtils.getCustomName(getInput().getNbt()); + Component originalName = ItemUtils.getCustomName(getInput().getComponents()); String plainOriginalName = MessageTranslator.convertToPlainTextLenient(originalName, session.locale()); String plainNewName = MessageTranslator.convertToPlainText(rename); 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 7e621d3aa..a1ecc6f58 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.inventory; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import lombok.AccessLevel; @@ -87,6 +88,30 @@ public class GeyserItemStack { return isEmpty() ? null : components; } + public boolean getComponent(DataComponentType type, boolean def) { + if (components == null) { + return def; + } + + Boolean result = components.get(type); + if (result != null) { + return result; + } + return def; + } + + public int getComponent(DataComponentType type, int def) { + if (components == null) { + return def; + } + + Integer result = components.get(type); + if (result != null) { + return result; + } + return def; + } + public int getNetId() { return isEmpty() ? 0 : netId; } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java index 96ef12861..9bf001f42 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.inventory.updater; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -34,6 +35,7 @@ import com.github.steveice10.opennbt.tag.builtin.Tag; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMaps; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import net.kyori.adventure.text.Component; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId; @@ -118,7 +120,8 @@ public class AnvilInventoryUpdater extends InventoryUpdater { // Changing the item in the input slot resets the name field on Bedrock, but // does not result in a FilterTextPacket - String originalName = MessageTranslator.convertToPlainTextLenient(ItemUtils.getCustomName(input.getNbt()), session.locale()); + // TODO test + String originalName = MessageTranslator.convertToPlainText(ItemUtils.getCustomName(input.getComponents())); ServerboundRenameItemPacket renameItemPacket = new ServerboundRenameItemPacket(originalName); session.sendDownstreamGamePacket(renameItemPacket); @@ -424,38 +427,27 @@ public class AnvilInventoryUpdater extends InventoryUpdater { } // This should really check the name field in all cases, but that requires the localized name // of the item which can change depending on NBT and Minecraft Edition - String originalName = ItemUtils.getCustomName(anvilContainer.getInput().getNbt()); + Component originalName = ItemUtils.getCustomName(anvilContainer.getInput().getComponents()); if (bedrock && originalName != null && anvilContainer.getNewName() != null) { // Check text and formatting - String legacyOriginalName = MessageTranslator.convertMessageLenient(originalName, session.locale()); + String legacyOriginalName = MessageTranslator.convertMessage(originalName, session.locale()); return !legacyOriginalName.equals(anvilContainer.getNewName()); } - return !Objects.equals(originalName, ItemUtils.getCustomName(anvilContainer.getResult().getNbt())); - } - - @SuppressWarnings("SameParameterValue") - private int getTagIntValueOr(GeyserItemStack itemStack, String tagName, int defaultValue) { - if (itemStack.getNbt() != null) { - Tag tag = itemStack.getNbt().get(tagName); - if (tag != null && tag.getValue() instanceof Number value) { - return value.intValue(); - } - } - return defaultValue; + return !Objects.equals(originalName, ItemUtils.getCustomName(anvilContainer.getResult().getComponents())); } private int getRepairCost(GeyserItemStack itemStack) { - return getTagIntValueOr(itemStack, "RepairCost", 0); + return itemStack.getComponent(DataComponentType.REPAIR_COST, 0); } private boolean hasDurability(GeyserItemStack itemStack) { if (itemStack.asItem().maxDamage() > 0) { - return getTagIntValueOr(itemStack, "Unbreakable", 0) == 0; + return itemStack.getComponent(DataComponentType.UNBREAKABLE, false); } return false; } private int getDamage(GeyserItemStack itemStack) { - return getTagIntValueOr(itemStack, "Damage", 0); + return itemStack.getComponent(DataComponentType.DAMAGE, 0); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java index d93123cff..ed6b9404d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java @@ -245,6 +245,16 @@ public class MessageTranslator { return GSON_SERIALIZER.serialize(component); } + /** + * Convert legacy format message to plain text + * + * @param message Message to convert + * @return The plain text of the message + */ + public static String convertToPlainText(Component message) { + return PlainTextComponentSerializer.plainText().serialize(message); + } + /** * Convert legacy format message to plain text * 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 08c2b6cdb..2b619714e 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -180,7 +180,7 @@ public class InventoryUtils { public static boolean canStack(GeyserItemStack item1, GeyserItemStack item2) { if (item1.isEmpty() || item2.isEmpty()) return false; - return item1.getJavaId() == item2.getJavaId() && Objects.equals(item1.getNbt(), item2.getNbt()); + return item1.getJavaId() == item2.getJavaId() && Objects.equals(item1.getComponents(), item2.getComponents()); } /** diff --git a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java index a116c5cf2..2138103d4 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java @@ -25,10 +25,13 @@ package org.geysermc.geyser.util; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; +import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.FishingRodItem; @@ -70,17 +73,13 @@ public class ItemUtils { } /** - * @param itemTag the NBT tag of the item + * @param components the data components of the item * @return the custom name of the item */ - public static @Nullable String getCustomName(CompoundTag itemTag) { - if (itemTag != null) { - if (itemTag.get("display") instanceof CompoundTag displayTag) { - if (displayTag.get("Name") instanceof StringTag nameTag) { - return nameTag.getValue(); - } - } + public static @Nullable Component getCustomName(DataComponents components) { + if (components == null) { + return null; } - return null; + return components.get(DataComponentType.CUSTOM_NAME); } }