Fix virtual lecterns - again (#4494)

This commit is contained in:
chris 2024-03-14 10:27:49 +01:00 committed by GitHub
parent 39b05e284e
commit c91ee53788
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 39 additions and 3 deletions

View file

@ -26,10 +26,13 @@
package org.geysermc.geyser.inventory; package org.geysermc.geyser.inventory;
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
import org.cloudburstmc.math.vector.Vector3i;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.nbt.NbtMap; 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 { public class LecternContainer extends Container {
@Getter @Setter @Getter @Setter
@ -39,7 +42,34 @@ public class LecternContainer extends Container {
@Getter @Setter @Getter @Setter
private Vector3i position; 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) { public LecternContainer(String title, int id, int size, ContainerType containerType, PlayerInventory playerInventory) {
super(title, id, size, containerType, 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);
}
} }

View file

@ -129,6 +129,11 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator
@Override @Override
public void updateSlot(GeyserSession session, Inventory inventory, int slot) { 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); super.updateSlot(session, inventory, slot);
if (slot == 0) { if (slot == 0) {
updateBook(session, inventory, inventory.getItem(0)); updateBook(session, inventory, inventory.getItem(0));

View file

@ -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 com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket;
import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.inventory.LecternContainer;
import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@ -79,8 +80,8 @@ public class JavaOpenBookTranslator extends PacketTranslator<ClientboundOpenBook
// Should never be null // Should never be null
Objects.requireNonNull(translator, "lectern translator must exist"); Objects.requireNonNull(translator, "lectern translator must exist");
Inventory inventory = translator.createInventory("", FAKE_LECTERN_WINDOW_ID, ContainerType.LECTERN , session.getPlayerInventory()); Inventory inventory = translator.createInventory("", FAKE_LECTERN_WINDOW_ID, ContainerType.LECTERN, session.getPlayerInventory());
inventory.setItem(0, stack, session); ((LecternContainer) inventory).setFakeLecternBook(stack, session);
InventoryUtils.openInventory(session, inventory); InventoryUtils.openInventory(session, inventory);
} }
} }