3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-12-27 08:30:12 +01:00

Fix: Virtual lecterns not displaying book contents (#5169)

Dieser Commit ist enthalten in:
chris 2024-11-29 11:43:58 +08:00 committet von GitHub
Ursprung c145c3f495
Commit c240c1cfb5
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: B5690EEEBB952194
3 geänderte Dateien mit 16 neuen und 19 gelöschten Zeilen

Datei anzeigen

@ -34,17 +34,15 @@ import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.java.inventory.JavaOpenBookTranslator; import org.geysermc.geyser.translator.protocol.java.inventory.JavaOpenBookTranslator;
import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType;
@Getter
public class LecternContainer extends Container { public class LecternContainer extends Container {
@Getter @Setter @Setter
private int currentBedrockPage = 0; private int currentBedrockPage = 0;
@Getter @Setter @Setter
private NbtMap blockEntityTag; private NbtMap blockEntityTag;
@Getter @Setter @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; 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) {
@ -52,8 +50,8 @@ public class LecternContainer extends Container {
} }
/** /**
* When we are using a fake lectern, the Java server expects us to still be in a player inventory. * When the Java server asks the client to open a book in their hotbar, we create a fake lectern to show it to the client.
* We can't use {@link #isUsingRealBlock()} as that may not be determined yet. * We can't use the {@link #isUsingRealBlock()} check as we may also be dealing with a real virtual lectern (with its own inventory).
*/ */
@Override @Override
public void setItem(int slot, @NonNull GeyserItemStack newItem, GeyserSession session) { public void setItem(int slot, @NonNull GeyserItemStack newItem, GeyserSession session) {

Datei anzeigen

@ -157,7 +157,7 @@ public class BlockInventoryHolder extends InventoryHolder {
@Override @Override
public void closeInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) { public void closeInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) {
if (inventory instanceof Container container) { if (inventory instanceof Container container) {
if (container.isUsingRealBlock() && !(inventory instanceof LecternContainer)) { if (container.isUsingRealBlock() && !(container instanceof LecternContainer)) {
// No need to reset a block since we didn't change any blocks // No need to reset a block since we didn't change any blocks
// But send a container close packet because we aren't destroying the original. // But send a container close packet because we aren't destroying the original.
ContainerClosePacket packet = new ContainerClosePacket(); ContainerClosePacket packet = new ContainerClosePacket();

Datei anzeigen

@ -30,8 +30,6 @@ import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.geysermc.erosion.util.LecternUtils; import org.geysermc.erosion.util.LecternUtils;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.inventory.Container;
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.inventory.LecternContainer;
@ -55,7 +53,7 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator
* Hack: Java opens a lectern first, and then follows it up with a ClientboundContainerSetContentPacket * Hack: Java opens a lectern first, and then follows it up with a ClientboundContainerSetContentPacket
* to actually send the book's contents. We delay opening the inventory until the book was sent. * to actually send the book's contents. We delay opening the inventory until the book was sent.
*/ */
private boolean initialized = false; private boolean receivedBook = false;
public LecternInventoryTranslator() { public LecternInventoryTranslator() {
super(1, Blocks.LECTERN, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.LECTERN , ContainerInventoryUpdater.INSTANCE); super(1, Blocks.LECTERN, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.LECTERN , ContainerInventoryUpdater.INSTANCE);
@ -64,11 +62,12 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator
@Override @Override
public boolean prepareInventory(GeyserSession session, Inventory inventory) { public boolean prepareInventory(GeyserSession session, Inventory inventory) {
super.prepareInventory(session, inventory); super.prepareInventory(session, inventory);
if (((Container) inventory).isUsingRealBlock()) { if (((LecternContainer) inventory).isFakeLectern()) {
initialized = false; // We have to wait until we get the book to show to the client // See JavaOpenBookTranslator; this isn't a lectern but a book in the player inventory
updateBook(session, inventory, inventory.getItem(0));
receivedBook = true;
} else { } else {
updateBook(session, inventory, inventory.getItem(0)); // See JavaOpenBookTranslator; placed here manually receivedBook = false; // We have to wait until we get the book
initialized = true;
} }
return true; return true;
} }
@ -79,7 +78,7 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator
// "initialized" indicates whether we've received the book from the Java server yet. // "initialized" indicates whether we've received the book from the Java server yet.
// dropping lectern book is the fun workaround when we have to enter the gui to drop the book. // dropping lectern book is the fun workaround when we have to enter the gui to drop the book.
// Since we leave it immediately... don't open it! // Since we leave it immediately... don't open it!
if (initialized && !session.isDroppingLecternBook()) { if (receivedBook && !session.isDroppingLecternBook()) {
super.openInventory(session, inventory); super.openInventory(session, inventory);
} }
} }
@ -122,8 +121,8 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator
boolean isDropping = session.isDroppingLecternBook(); boolean isDropping = session.isDroppingLecternBook();
updateBook(session, inventory, itemStack); updateBook(session, inventory, itemStack);
if (!initialized && !isDropping) { if (!receivedBook && !isDropping) {
initialized = true; receivedBook = true;
openInventory(session, inventory); openInventory(session, inventory);
} }
} }