From c91ee53788a8a45e9348e8367fa1a275c97376b6 Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 14 Mar 2024 10:27:49 +0100 Subject: [PATCH] Fix virtual lecterns - again (#4494) --- .../geyser/inventory/LecternContainer.java | 32 ++++++++++++++++++- .../inventory/LecternInventoryTranslator.java | 5 +++ .../inventory/JavaOpenBookTranslator.java | 5 +-- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/LecternContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/LecternContainer.java index f5aa7b0d6..7ac2fed99 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/LecternContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/LecternContainer.java @@ -26,10 +26,13 @@ package org.geysermc.geyser.inventory; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import org.cloudburstmc.math.vector.Vector3i; import lombok.Getter; import lombok.Setter; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.protocol.java.inventory.JavaOpenBookTranslator; public class LecternContainer extends Container { @Getter @Setter @@ -39,7 +42,34 @@ public class LecternContainer extends Container { @Getter @Setter private Vector3i position; + // Sigh. When the lectern container is created, we don't know (yet) if it's fake or not. + // So... time for a manual check :/ + @Getter + private boolean isFakeLectern = false; + public LecternContainer(String title, int id, int size, ContainerType containerType, PlayerInventory playerInventory) { super(title, id, size, containerType, playerInventory); } + + /** + * When we are using a fake lectern, the Java server expects us to still be in a player inventory. + * We can't use {@link #isUsingRealBlock()} as that may not be determined yet. + */ + @Override + public void setItem(int slot, @NonNull GeyserItemStack newItem, GeyserSession session) { + if (isFakeLectern) { + session.getPlayerInventory().setItem(slot, newItem, session); + } else { + super.setItem(slot, newItem, session); + } + } + + /** + * This is used ONLY once to set the book of a fake lectern in {@link JavaOpenBookTranslator}. + * See {@link LecternContainer#setItem(int, GeyserItemStack, GeyserSession)} as for why this is separate. + */ + public void setFakeLecternBook(GeyserItemStack book, GeyserSession session) { + this.isFakeLectern = true; + super.setItem(0, book, session); + } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java index 7a1ec7573..9d0661b08 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java @@ -129,6 +129,11 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator @Override public void updateSlot(GeyserSession session, Inventory inventory, int slot) { + // If we're not in a real lectern, the Java server thinks we are still in the player inventory. + if (((LecternContainer) inventory).isFakeLectern()) { + InventoryTranslator.PLAYER_INVENTORY_TRANSLATOR.updateSlot(session, session.getPlayerInventory(), slot); + return; + } super.updateSlot(session, inventory, slot); if (slot == 0) { updateBook(session, inventory, inventory.getItem(0)); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java index f9cf4ee28..24b964b7c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java @@ -30,6 +30,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.Cli import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.Inventory; +import org.geysermc.geyser.inventory.LecternContainer; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.session.GeyserSession; @@ -79,8 +80,8 @@ public class JavaOpenBookTranslator extends PacketTranslator