Skip to content

Commit

Permalink
Fix: Default components breaking item stacking while crafting.
Browse files Browse the repository at this point in the history
  • Loading branch information
onebeastchris committed Dec 23, 2024
1 parent 030b935 commit 6bd60d4
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -118,17 +118,7 @@ public void setItemInFrame(EntityMetadata<ItemStack, ?> 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());
Expand Down
11 changes: 9 additions & 2 deletions core/src/main/java/org/geysermc/geyser/item/type/Item.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit 6bd60d4

Please sign in to comment.