1
0
Fork 0
mirror of https://github.com/GeyserMC/Geyser.git synced 2025-04-17 19:12:14 +02:00

Add getOpenInventory method

This commit is contained in:
onebeastchris 2025-04-09 16:40:42 +02:00
parent 68c2c00561
commit 58996084d7
20 changed files with 61 additions and 43 deletions

View file

@ -50,7 +50,7 @@ public class DebugCommand extends GeyserCommand {
if (session != null) {
var holder = session.getOpenInventory();
var holder = session.getInventoryHolder();
if (holder != null && holder.translator() instanceof SingleChestInventoryTranslator) {
for (int i = 0; i <= holder.inventory().getSize(); i++) {
int bedrockSlot = holder.translator().javaSlotToBedrock(i);

View file

@ -123,7 +123,7 @@ public abstract class Inventory {
// Java wouldn't - e.g. for virtual chest menus that switch pages.
// And, well, we want to avoid reusing Bedrock inventory id's that are currently being used in a closing inventory;
// so to be safe we just deviate in that case as well.
if ((session.getOpenInventory() != null && session.getOpenInventory().bedrockId() == bedrockId) || session.isClosingInventory()) {
if ((session.getInventoryHolder() != null && session.getInventoryHolder().bedrockId() == bedrockId) || session.isClosingInventory()) {
this.bedrockId += 1;
}
}

View file

@ -69,7 +69,7 @@ public final class InventoryHolder<T extends Inventory> {
}
public void markCurrent() {
this.session.setOpenInventory(this);
this.session.setInventoryHolder(this);
}
public boolean shouldSetPending() {
@ -108,7 +108,7 @@ public final class InventoryHolder<T extends Inventory> {
}
public void openInventory() {
if (session.getOpenInventory() != this) {
if (session.getInventoryHolder() != this) {
throw new IllegalStateException("Inventory is not open!");
}
this.translator.openInventory(session, inventory);
@ -117,7 +117,7 @@ public final class InventoryHolder<T extends Inventory> {
}
public void closeInventory() {
if (session.getOpenInventory() != this) {
if (session.getInventoryHolder() != this) {
throw new IllegalStateException("Inventory is not open!");
}
this.translator.closeInventory(session, inventory);

View file

@ -293,11 +293,21 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
*/
private boolean isInWorldBorderWarningArea = false;
/**
* Stores the player inventory and player inventory translator
*/
private final InventoryHolder<PlayerInventory> playerInventoryHolder;
/**
* Stores the current open inventory, including the correct translator.
*/
@Setter
private @Nullable InventoryHolder<? extends Inventory> openInventory;
private @Nullable InventoryHolder<? extends Inventory> inventoryHolder;
/**
* Whether the client is currently closing an inventory.
* Used to open new inventories while another one is currently open.
*/
@Setter
private boolean closingInventory;
@ -718,7 +728,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
collisionManager.updatePlayerBoundingBox(this.playerEntity.getPosition());
this.playerInventoryHolder = new InventoryHolder<>(this, new PlayerInventory(this), InventoryTranslator.PLAYER_INVENTORY_TRANSLATOR);
this.openInventory = null;
this.inventoryHolder = null;
this.craftingRecipes = new Int2ObjectOpenHashMap<>();
this.javaToBedrockRecipeIds = new Int2ObjectOpenHashMap<>();
this.lastRecipeNetId = new AtomicInteger(InventoryUtils.LAST_RECIPE_NET_ID + 1);
@ -1496,10 +1506,17 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
return true;
}
public PlayerInventory getPlayerInventory() {
public @NonNull PlayerInventory getPlayerInventory() {
return this.playerInventoryHolder.inventory();
}
public @Nullable Inventory getOpenInventory() {
if (this.inventoryHolder == null) {
return null;
}
return this.inventoryHolder.inventory();
}
@Override
public boolean sendForm(@NonNull FormBuilder<?, ?, ?> formBuilder) {
formCache.showForm(formBuilder.build());

View file

@ -164,8 +164,7 @@ public class MerchantInventoryTranslator extends BaseInventoryTranslator<Merchan
// so we need to work around that with the delay. Specifically they force a window refresh after a
// trade packet has been sent.
session.scheduleInEventLoop(() -> {
InventoryHolder<? extends Inventory> holder = session.getOpenInventory();
if (holder != null && holder.inventory() instanceof MerchantContainer merchantInventory) {
if (session.getOpenInventory() instanceof MerchantContainer merchantInventory) {
merchantInventory.onTradeSelected(session, tradeChoice);
// Ignore output since we don't want to send a delayed response packet back to the client
translateRequest(session, inventory, request);

View file

@ -55,7 +55,7 @@ public class BedrockContainerCloseTranslator extends PacketTranslator<ContainerC
session.setClosingInventory(false);
// 1.21.70: Bedrock can reject opening inventories - in those cases it replies with -1
InventoryHolder<? extends Inventory> holder = session.getOpenInventory();
InventoryHolder<? extends Inventory> holder = session.getInventoryHolder();
if (bedrockId == -1 && holder != null) {
// 1.16.200 - window ID is always -1 sent from Bedrock for merchant containers
if (holder.translator() instanceof MerchantInventoryTranslator) {
@ -78,7 +78,7 @@ public class BedrockContainerCloseTranslator extends PacketTranslator<ContainerC
return;
} else {
GeyserImpl.getInstance().getLogger().debug(session, "Exceeded 3 attempts to open a virtual inventory!");
GeyserImpl.getInstance().getLogger().debug(session, packet + " " + session.getOpenInventory().getClass().getSimpleName());
GeyserImpl.getInstance().getLogger().debug(session, packet + " " + session.getInventoryHolder().getClass().getSimpleName());
}
}
}

View file

@ -42,16 +42,20 @@ public class BedrockFilterTextTranslator extends PacketTranslator<FilterTextPack
@Override
public void translate(GeyserSession session, FilterTextPacket packet) {
InventoryHolder<?> holder = session.getOpenInventory();
if (holder != null && holder.inventory() instanceof CartographyContainer) {
// We don't want to be able to rename in the cartography table
return;
InventoryHolder<?> holder = session.getInventoryHolder();
if (holder != null) {
if (holder.inventory() instanceof CartographyContainer) {
// We don't want to be able to rename in the cartography table
return;
}
if (holder.inventory() instanceof AnvilContainer anvilContainer) {
packet.setText(anvilContainer.checkForRename(session, packet.getText()));
holder.updateSlot(1);
}
}
packet.setFromServer(true);
if (holder != null && holder.inventory() instanceof AnvilContainer anvilContainer) {
packet.setText(anvilContainer.checkForRename(session, packet.getText()));
holder.updateSlot(1);
}
session.sendUpstreamPacket(packet);
}
}

View file

@ -39,7 +39,7 @@ public class BedrockItemStackRequestTranslator extends PacketTranslator<ItemStac
@Override
public void translate(GeyserSession session, ItemStackRequestPacket packet) {
InventoryHolder<?> holder = session.getOpenInventory();
InventoryHolder<?> holder = session.getInventoryHolder();
if (holder == null)
return;

View file

@ -43,7 +43,7 @@ public class BedrockLecternUpdateTranslator extends PacketTranslator<LecternUpda
@Override
public void translate(GeyserSession session, LecternUpdatePacket packet) {
// Bedrock wants to either move a page or exit
InventoryHolder<?> holder = session.getOpenInventory();
InventoryHolder<?> holder = session.getInventoryHolder();
if (holder == null || !(holder.inventory() instanceof LecternContainer lecternContainer)) {
session.getGeyser().getLogger().debug("Expected lectern but it wasn't open!");
return;

View file

@ -65,7 +65,7 @@ public class BedrockSetLocalPlayerAsInitializedTranslator extends PacketTranslat
session.getEntityCache().updateBossBars();
// Double sigh - https://github.com/GeyserMC/Geyser/issues/2677 - as of Bedrock 1.18
if (session.getOpenInventory() != null) {
if (session.getInventoryHolder() != null) {
InventoryUtils.openPendingInventory(session);
}

View file

@ -37,7 +37,7 @@ public class BedrockToggleCrafterSlotRequestTranslator extends PacketTranslator<
@Override
public void translate(GeyserSession session, ToggleCrafterSlotRequestPacket packet) {
if (session.getOpenInventory() == null || !(session.getOpenInventory().inventory() instanceof CrafterContainer container)) {
if (!(session.getOpenInventory() instanceof CrafterContainer container)) {
return;
}

View file

@ -26,7 +26,6 @@
package org.geysermc.geyser.translator.protocol.bedrock.entity;
import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
import org.geysermc.geyser.inventory.InventoryHolder;
import org.geysermc.geyser.inventory.MerchantContainer;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
@ -52,8 +51,7 @@ public class BedrockEntityEventTranslator extends PacketTranslator<EntityEventPa
session.sendDownstreamGamePacket(selectTradePacket);
session.scheduleInEventLoop(() -> {
InventoryHolder<?> openInventory = session.getOpenInventory();
if (openInventory != null && openInventory.inventory() instanceof MerchantContainer merchantInventory) {
if (session.getOpenInventory() instanceof MerchantContainer merchantInventory) {
merchantInventory.onTradeSelected(session, packet.getData());
}
}, 100, TimeUnit.MILLISECONDS);

View file

@ -121,7 +121,7 @@ public class BedrockInteractTranslator extends PacketTranslator<InteractPacket>
}
break;
case OPEN_INVENTORY:
if (session.getOpenInventory() == null) {
if (session.getInventoryHolder() == null) {
Entity ridingEntity = session.getPlayerEntity().getVehicle();
if (ridingEntity instanceof AbstractHorseEntity || ridingEntity instanceof ChestBoatEntity) {
// This mob has an inventory of its own that we should open instead.

View file

@ -44,7 +44,7 @@ public class BedrockSetPlayerInventoryOptionsTranslator extends PacketTranslator
// This should ensure that we never send these packets when the player inventory is opened while in creative
// Java edition can't craft in the 2x2 grid in creative, and subsequently doesn't have a recipe book
if (session.getGameMode() == GameMode.CREATIVE && session.getPlayerInventoryHolder() == session.getOpenInventory()) {
if (session.getGameMode() == GameMode.CREATIVE && session.getPlayerInventoryHolder() == session.getInventoryHolder()) {
return;
}

View file

@ -61,7 +61,7 @@ public class JavaRespawnTranslator extends PacketTranslator<ClientboundRespawnPa
entity.setHealth(entity.getMaxHealth());
entity.getAttributes().put(GeyserAttributeType.HEALTH, entity.createHealthAttribute());
session.setOpenInventory(null);
session.setInventoryHolder(null);
session.setClosingInventory(false);
entity.setLastDeathPosition(spawnInfo.getLastDeathPos());

View file

@ -25,7 +25,7 @@
package org.geysermc.geyser.translator.protocol.java.inventory;
import org.geysermc.geyser.inventory.InventoryHolder;
import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.inventory.PlayerInventory;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
@ -40,8 +40,8 @@ public class JavaContainerCloseTranslator extends PacketTranslator<ClientboundCo
public void translate(GeyserSession session, ClientboundContainerClosePacket packet) {
// Sometimes the server can request a window close of ID 0... when the window isn't even open
// Don't confirm in this instance
InventoryHolder<?> holder = session.getOpenInventory();
session.setServerRequestedClosePlayerInventory(packet.getContainerId() == 0 && holder != null && holder.inventory() instanceof PlayerInventory);
InventoryUtils.closeInventory(session, packet.getContainerId(), (holder != null && holder.javaId() == packet.getContainerId()));
Inventory inventory = session.getOpenInventory();
session.setServerRequestedClosePlayerInventory(packet.getContainerId() == 0 && inventory instanceof PlayerInventory);
InventoryUtils.closeInventory(session, packet.getContainerId(), (inventory != null && inventory.getJavaId() == packet.getContainerId()));
}
}

View file

@ -57,7 +57,7 @@ public class JavaMerchantOffersTranslator extends PacketTranslator<ClientboundMe
@Override
public void translate(GeyserSession session, ClientboundMerchantOffersPacket packet) {
InventoryHolder<?> holder = session.getOpenInventory();
InventoryHolder<?> holder = session.getInventoryHolder();
if (holder == null) {
return;
}

View file

@ -60,7 +60,7 @@ public class JavaOpenBookTranslator extends PacketTranslator<ClientboundOpenBook
}
if (stack.asItem().equals(Items.WRITTEN_BOOK)) {
InventoryHolder<?> openInventory = session.getOpenInventory();
InventoryHolder<?> openInventory = session.getInventoryHolder();
if (openInventory != null) {
InventoryUtils.closeInventory(session, openInventory.javaId(), true);
InventoryUtils.sendJavaContainerClose(openInventory);

View file

@ -53,7 +53,7 @@ public class JavaOpenScreenTranslator extends PacketTranslator<ClientboundOpenSc
}
InventoryTranslator<? extends Inventory> newTranslator;
InventoryHolder<? extends Inventory> currentInventory = session.getOpenInventory();
InventoryHolder<? extends Inventory> currentInventory = session.getInventoryHolder();
// Hack: ViaVersion translates the old (pre 1.20) smithing table to a anvil (does not work for Bedrock). We can detect this and translate it back to a smithing table.
// (Implementation note: used to be a furnace. Was changed sometime before 1.21.2)

View file

@ -115,7 +115,7 @@ public class InventoryUtils {
* occurred in the time. For example, a queued virtual inventory might be "outdated", so we wouldn't open it.
*/
public static void openPendingInventory(GeyserSession session) {
InventoryHolder<?> holder = session.getOpenInventory();
InventoryHolder<?> holder = session.getInventoryHolder();
if (holder == null || !holder.pending()) {
session.setPendingOrCurrentBedrockInventoryId(-1);
GeyserImpl.getInstance().getLogger().debug(session, "No pending inventory, not opening an inventory! Current inventory: %s", debugInventory(holder));
@ -156,7 +156,7 @@ public class InventoryUtils {
// Can occur if we e.g. did not find a spot to put a fake container in
holder.session().setPendingOrCurrentBedrockInventoryId(-1);
sendJavaContainerClose(holder);
holder.session().setOpenInventory(null);
holder.session().setInventoryHolder(null);
}
}
@ -188,19 +188,19 @@ public class InventoryUtils {
GeyserImpl.getInstance().getLogger().debug(session, "Closed inventory: (java id: %s/bedrock id: %s), waiting on confirm? %s", holder.javaId(), holder.bedrockId(), session.isClosingInventory());
}
session.setOpenInventory(null);
session.setInventoryHolder(null);
}
/**
* A util method to get the an inventory based on a Java id. This is used over
* {@link GeyserSession#getOpenInventory()} when needing to account for player inventories instead of just the open inventory.
* {@link GeyserSession#getInventoryHolder()} when needing to account for player inventories instead of just the open inventory.
*/
public static @Nullable InventoryHolder<?> getInventory(GeyserSession session, int javaId) {
InventoryHolder<?> holder = session.getOpenInventory();
InventoryHolder<?> holder = session.getInventoryHolder();
if (javaId == 0) {
// ugly hack: lecterns aren't their own inventory on Java, and can hence be closed with e.g. an id of 0
if (holder != null && holder.inventory() instanceof LecternContainer) {
return session.getOpenInventory();
return session.getInventoryHolder();
}
return session.getPlayerInventoryHolder();
} else {