From 0416b55959a16880d37f24545d0063e90fe51ce8 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Tue, 4 Feb 2025 16:57:37 +0100 Subject: [PATCH] Fix: Looms modifying default data components causing visual bugs Closes https://github.com/GeyserMC/Geyser/issues/5273 --- .../geyser/inventory/GeyserItemStack.java | 5 +++-- .../updater/AnvilInventoryUpdater.java | 5 ++--- .../inventory/BundleInventoryTranslator.java | 2 +- .../inventory/LoomInventoryTranslator.java | 19 ++++++++----------- 4 files changed, 14 insertions(+), 17 deletions(-) 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 77ca7bfb504..c4a3542d16d 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java @@ -50,6 +50,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.SlotDisplay; import java.util.HashMap; +import java.util.function.Supplier; @Data public class GeyserItemStack { @@ -169,9 +170,9 @@ public T getComponent(@NonNull DataComponentType type) { return value; } - public T getComponentOrFallback(@NonNull DataComponentType type, T def) { + public T getComponentElseGet(@NonNull DataComponentType type, Supplier supplier) { T value = getComponent(type); - return value == null ? def : value; + return value == null ? supplier.get() : value; } public int getNetId() { 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 aadaeb356b1..8282607afc8 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 @@ -47,7 +47,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.HolderSet; import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.Unbreakable; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; import java.util.List; @@ -420,7 +419,7 @@ private boolean isRenaming(GeyserSession session, AnvilContainer anvilContainer, } private int getRepairCost(GeyserItemStack itemStack) { - return itemStack.getComponentOrFallback(DataComponentType.REPAIR_COST, 0); + return itemStack.getComponentElseGet(DataComponentType.REPAIR_COST, () -> 0); } private boolean hasDurability(GeyserItemStack itemStack) { @@ -431,6 +430,6 @@ private boolean hasDurability(GeyserItemStack itemStack) { } private int getDamage(GeyserItemStack itemStack) { - return itemStack.getComponentOrFallback(DataComponentType.DAMAGE, 0); + return itemStack.getComponentElseGet(DataComponentType.DAMAGE, () -> 0); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/BundleInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/BundleInventoryTranslator.java index 1b42e537fce..bbe94ba9591 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/BundleInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/BundleInventoryTranslator.java @@ -314,7 +314,7 @@ private static Fraction calculateWeight(GeyserItemStack itemStack) { return Fraction.ONE; } } - return Fraction.getFraction(1, itemStack.getComponentOrFallback(DataComponentType.MAX_STACK_SIZE, itemStack.asItem().defaultMaxStackSize())); + return Fraction.getFraction(1, itemStack.getComponentElseGet(DataComponentType.MAX_STACK_SIZE, () -> itemStack.asItem().defaultMaxStackSize())); } public static int capacityForItemStack(Fraction bundleWeight, GeyserItemStack itemStack) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java index 1fef4c4fd42..99810815417 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java @@ -93,10 +93,8 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator { PATTERN_TO_INDEX.put("vhr", index++); PATTERN_TO_INDEX.put("hhb", index++); PATTERN_TO_INDEX.put("bo", index++); - index++; // Bordure indented, does not appear to exist in Bedrock? PATTERN_TO_INDEX.put("gra", index++); PATTERN_TO_INDEX.put("gru", index); - // Bricks do not appear to be a pattern on Bedrock, either } public LoomInventoryTranslator() { @@ -120,7 +118,7 @@ protected boolean shouldRejectItemPlace(GeyserSession session, Inventory invento @Override protected boolean shouldHandleRequestFirst(ItemStackRequestAction action, Inventory inventory) { - // If the LOOM_MATERIAL slot is not empty, we are crafting a pattern that does not come from an item + // If the LOOM_MATERIAL slot is empty, we are crafting a pattern that does not come from an item return action.getType() == ItemStackRequestActionType.CRAFT_LOOM && inventory.getItem(2).isEmpty(); } @@ -135,10 +133,6 @@ public ItemStackResponse translateSpecialRequest(GeyserSession session, Inventor return rejectRequest(request); } - // Get the patterns compound tag - List newBlockEntityTag = craftData.getResultItems()[0].getTag().getList("Patterns", NbtType.COMPOUND); - // Get the pattern that the Bedrock client requests - the last pattern in the Patterns list - NbtMap pattern = newBlockEntityTag.get(newBlockEntityTag.size() - 1); String bedrockPattern = ((CraftLoomAction) headerData).getPatternId(); // Get the Java index of this pattern @@ -146,6 +140,12 @@ public ItemStackResponse translateSpecialRequest(GeyserSession session, Inventor if (index == -1) { return rejectRequest(request); } + + // Get the patterns compound tag + List newBlockEntityTag = craftData.getResultItems()[0].getTag().getList("Patterns", NbtType.COMPOUND); + // Get the pattern that the Bedrock client requests - the last pattern in the Patterns list + NbtMap pattern = newBlockEntityTag.get(newBlockEntityTag.size() - 1); + // Java's formula: 4 * row + col // And the Java loom window has a fixed row/width of four // So... Number / 4 = row (so we don't have to bother there), and number % 4 is our column, which leads us back to our index. :) @@ -156,10 +156,7 @@ public ItemStackResponse translateSpecialRequest(GeyserSession session, Inventor inputCopy.setNetId(session.getNextItemNetId()); BannerPatternLayer bannerPatternLayer = BannerItem.getJavaBannerPattern(session, pattern); // TODO if (bannerPatternLayer != null) { - List patternsList = inputCopy.getComponent(DataComponentType.BANNER_PATTERNS); - if (patternsList == null) { - patternsList = new ArrayList<>(); - } + List patternsList = new ArrayList<>(inputCopy.getComponentElseGet(DataComponentType.BANNER_PATTERNS, ArrayList::new)); patternsList.add(bannerPatternLayer); inputCopy.getOrCreateComponents().put(DataComponentType.BANNER_PATTERNS, patternsList); }