From 030b935d8a1953bc9735ce4bd95b6c105d047b2d Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Tue, 24 Dec 2024 00:18:26 +0800 Subject: [PATCH 1/2] Fix: item frames showing names for items without a custom name (fixes https://github.com/GeyserMC/Geyser/issues/5194) --- .../geyser/entity/type/ItemFrameEntity.java | 17 +++++++++++++---- .../geyser/item/type/ShulkerBoxItem.java | 2 +- .../geyser/translator/item/ItemTranslator.java | 6 +++--- 3 files changed, 17 insertions(+), 8 deletions(-) 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 f38e727c09e..acb3df2b643 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 @@ -113,14 +113,23 @@ public void setItemInFrame(EntityMetadata entityMetadata) { if (entityMetadata.getValue() != null) { this.heldItem = entityMetadata.getValue(); ItemData itemData = ItemTranslator.translateToBedrock(session, heldItem); - String customIdentifier = session.getItemMappings().getCustomIdMappings().get(itemData.getDefinition().getRuntimeId()); NbtMapBuilder builder = NbtMap.builder(); - builder.putByte("Count", (byte) itemData.getCount()); - if (itemData.getTag() != null) { - builder.put("tag", itemData.getTag()); + NbtMap itemDataTag = itemData.getTag(); + if (itemDataTag != null) { + // Remove custom name that Geyser sets for items due to translating default components + String customName = ItemTranslator.getCustomName(session, heldItem.getDataComponents(), + session.getItemMappings().getMapping(heldItem), 'f', false); + if (customName == null) { + // No custom name found, must modify tag if custom name exists + NbtMapBuilder copy = itemDataTag.toBuilder(); + copy.remove("display"); // Also removes lore, but, should not matter + itemDataTag = copy.build(); + } + + builder.put("tag", itemDataTag); } builder.putShort("Damage", (short) itemData.getDamage()); builder.putString("Name", customIdentifier != null ? customIdentifier : session.getItemMappings().getMapping(entityMetadata.getValue()).getBedrockIdentifier()); 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 c3b739adc45..d8d2c347dab 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 @@ -98,7 +98,7 @@ public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNul // Only the display name is what we have interest in, so just translate that if relevant if (boxComponents != null) { - String customName = ItemTranslator.getCustomName(session, boxComponents, boxMapping, '7'); + String customName = ItemTranslator.getCustomName(session, boxComponents, boxMapping, '7', true); if (customName != null) { boxItemNbt.putCompound("tag", NbtMap.builder() .putCompound("display", NbtMap.builder() diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 691a320e552..96b64f56d6b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -173,7 +173,7 @@ public static ItemData translateToBedrock(GeyserSession session, ItemStack stack javaItem.translateComponentsToBedrock(session, components, nbtBuilder); Rarity rarity = Rarity.fromId(components.getOrDefault(DataComponentType.RARITY, 0)); - String customName = getCustomName(session, components, bedrockItem, rarity.getColor()); + String customName = getCustomName(session, components, bedrockItem, rarity.getColor(), true); if (customName != null) { nbtBuilder.setCustomName(customName); } @@ -493,7 +493,7 @@ public static ItemDefinition getBedrockItemDefinition(GeyserSession session, @No * @param translationColor if this item is not available on Java, the color that the new name should be. * Normally, this should just be white, but for shulker boxes this should be gray. */ - public static String getCustomName(GeyserSession session, DataComponents components, ItemMapping mapping, char translationColor) { + public static String getCustomName(GeyserSession session, DataComponents components, ItemMapping mapping, char translationColor, boolean includeDefault) { if (components != null) { // ItemStack#getHoverName as of 1.20.5 Component customName = components.get(DataComponentType.CUSTOM_NAME); @@ -514,7 +514,7 @@ public static String getCustomName(GeyserSession session, DataComponents compone } } customName = components.get(DataComponentType.ITEM_NAME); - if (customName != null) { + if (customName != null && includeDefault) { // Get the translated name and prefix it with a reset char to prevent italics - matches Java Edition // behavior as of 1.21 return ChatColor.RESET + ChatColor.ESCAPE + translationColor + MessageTranslator.convertMessage(customName, session.locale()); From 6bd60d42339482580dd7f501d5ff436f63945a97 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Tue, 24 Dec 2024 01:43:04 +0800 Subject: [PATCH 2/2] Fix: Default components breaking item stacking while crafting. --- .../geysermc/geyser/entity/type/ItemFrameEntity.java | 12 +----------- .../java/org/geysermc/geyser/item/type/Item.java | 11 +++++++++-- .../translator/inventory/InventoryTranslator.java | 2 +- .../geyser/translator/item/BedrockItemBuilder.java | 5 +++-- .../geyser/translator/item/ItemTranslator.java | 2 +- 5 files changed, 15 insertions(+), 17 deletions(-) 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 acb3df2b643..ba3dfb79d9c 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 @@ -118,17 +118,7 @@ public void setItemInFrame(EntityMetadata entityMetadata) { NbtMapBuilder builder = NbtMap.builder(); builder.putByte("Count", (byte) itemData.getCount()); NbtMap itemDataTag = itemData.getTag(); - if (itemDataTag != null) { - // Remove custom name that Geyser sets for items due to translating default components - String customName = ItemTranslator.getCustomName(session, heldItem.getDataComponents(), - session.getItemMappings().getMapping(heldItem), 'f', false); - if (customName == null) { - // No custom name found, must modify tag if custom name exists - NbtMapBuilder copy = itemDataTag.toBuilder(); - copy.remove("display"); // Also removes lore, but, should not matter - itemDataTag = copy.build(); - } - + if (itemData.getTag() != null) { builder.put("tag", itemDataTag); } builder.putShort("Damage", (short) itemData.getDamage()); 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 19789e0860d..738d577884d 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 @@ -191,7 +191,9 @@ public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNul } Integer repairCost = components.get(DataComponentType.REPAIR_COST); - if (repairCost != null) { + // Java sets repair cost to 0 on all items via default components, that trips up Bedrock crafting. + // See https://github.com/GeyserMC/Geyser/issues/5220 for more details + if (repairCost != null && repairCost != 0) { builder.putInt("RepairCost", repairCost); } @@ -202,7 +204,12 @@ public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNul // Prevents the client from trying to stack items with untranslated components // Relies on correct hash code implementation, and some luck - builder.putInt("GeyserHash", components.hashCode()); // TODO: don't rely on this + // However, we should only set a hash when the components differ from the default ones, + // otherwise Bedrock can't stack these when crafting items since it's predicted recipe output + // does not contain the GeyserHash. See https://github.com/GeyserMC/Geyser/issues/5220 for more details + if (!baseComponents.equals(components)) { + builder.putInt("GeyserHash", components.hashCode()); // TODO: don't rely on this + } } /** 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 f7e3bfc2a34..b4f507af52c 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 @@ -246,7 +246,7 @@ public ItemStackResponse translateRequest(GeyserSession session, Inventory inven boolean isSourceCursor = isCursor(transferAction.getSource()); boolean isDestCursor = isCursor(transferAction.getDestination()); - if ((this) instanceof PlayerInventoryTranslator) { + if (this instanceof PlayerInventoryTranslator) { if (destSlot == 5) { //only set the head if the destination is the head slot GeyserItemStack javaItem = inventory.getItem(sourceSlot); diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java index e989288c2ed..2f51c0007f3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java @@ -122,12 +122,13 @@ public NbtMapBuilder putCompound(String name, NbtMap value) { */ @Nullable public NbtMap build() { - if (customName != null || lore != null) { + boolean validLore = lore != null && !lore.isEmpty(); + if (customName != null || validLore) { NbtMapBuilder display = NbtMap.builder(); if (customName != null) { display.putString("Name", customName); } - if (lore != null) { + if (validLore) { display.putList("Lore", NbtType.STRING, lore); } getOrCreateNbt().put("display", display.build()); diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 96b64f56d6b..b8959c7b8af 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -173,7 +173,7 @@ public static ItemData translateToBedrock(GeyserSession session, ItemStack stack javaItem.translateComponentsToBedrock(session, components, nbtBuilder); Rarity rarity = Rarity.fromId(components.getOrDefault(DataComponentType.RARITY, 0)); - String customName = getCustomName(session, components, bedrockItem, rarity.getColor(), true); + String customName = getCustomName(session, components, bedrockItem, rarity.getColor(), false); if (customName != null) { nbtBuilder.setCustomName(customName); }