From 5ddb0ad90a7098ed5822e630b51717f6ebb9592d Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 14 Nov 2022 15:12:46 -0500 Subject: [PATCH] Allow virtual inventories to be opened when player at world height commit c53bb38a47d1a48f0b5a72059e81c4354c2b8e90 Author: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon Nov 14 15:12:29 2022 -0500 Final touch commit f9ff9553eda7c80620a8e6f63e14f01adb39ac8b Merge: b57109ddf 886d7e5b4 Author: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon Nov 14 14:54:28 2022 -0500 Merge branch 'master' of https://github.com/GeyserMC/Geyser into pull/3281 commit b57109ddf7dabe77ca97f36de48d7266eaec08a1 Author: Kevin Ludwig Date: Mon Sep 12 12:23:36 2022 +0200 Revert use entities for single chest inventories commit fda66e83b90984505bdc3d87cf41e986dd10424b Author: Kevin Ludwig Date: Sat Sep 10 11:49:40 2022 +0200 Use entities for single chest inventories, check if a block for server-side opened inventories can be placed either above or below, otherwise, close the inventory (same logic as with inventory translator found) --- .../holder/BlockInventoryHolder.java | 28 +++++++++++++++---- .../inventory/holder/InventoryHolder.java | 2 +- .../AbstractBlockInventoryTranslator.java | 4 +-- .../inventory/InventoryTranslator.java | 2 +- .../inventory/LecternInventoryTranslator.java | 3 +- .../MerchantInventoryTranslator.java | 4 ++- .../inventory/PlayerInventoryTranslator.java | 3 +- .../chest/DoubleChestInventoryTranslator.java | 27 ++++++++++++++---- .../chest/SingleChestInventoryTranslator.java | 4 +-- .../AbstractHorseInventoryTranslator.java | 3 +- .../geysermc/geyser/util/InventoryUtils.java | 4 +-- 11 files changed, 61 insertions(+), 23 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java b/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java index 379eb2566..eb15fa477 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java @@ -35,6 +35,7 @@ import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket; import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.inventory.Container; import org.geysermc.geyser.inventory.Inventory; +import org.geysermc.geyser.level.BedrockDimension; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.InventoryTranslator; @@ -49,6 +50,8 @@ import java.util.Set; * This class will attempt to use a real block first, if possible. */ public class BlockInventoryHolder extends InventoryHolder { + private static final int FAKE_BLOCK_DISTANCE = 1; + /** * The default Java block ID to translate as a fake block */ @@ -70,7 +73,7 @@ public class BlockInventoryHolder extends InventoryHolder { } @Override - public void prepareInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) { + public boolean prepareInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) { // Check to see if there is an existing block we can use that the player just selected. // First, verify that the player's position has not changed, so we don't try to select a block wildly out of range. // (This could be a virtual inventory that the player is opening) @@ -83,13 +86,26 @@ public class BlockInventoryHolder extends InventoryHolder { inventory.setHolderPosition(session.getLastInteractionBlockPosition()); ((Container) inventory).setUsingRealBlock(true, javaBlockString[0]); setCustomName(session, session.getLastInteractionBlockPosition(), inventory, javaBlockId); - return; + + return true; + } + } + + // Check if a fake block can be placed, either above the player or beneath. + BedrockDimension dimension = session.getChunkCache().getBedrockDimension(); + int minY = dimension.minY(), maxY = minY + dimension.height(); + Vector3i flatPlayerPosition = session.getPlayerEntity().getPosition().toInt(); + Vector3i position = flatPlayerPosition.add(Vector3i.UP); + if (position.getY() < minY) { + return false; + } + if (position.getY() >= maxY) { + position = flatPlayerPosition.sub(0, 4, 0); + if (position.getY() >= maxY) { + return false; } } - // Otherwise, time to conjure up a fake block! - Vector3i position = session.getPlayerEntity().getPosition().toInt(); - position = position.add(Vector3i.UP); UpdateBlockPacket blockPacket = new UpdateBlockPacket(); blockPacket.setDataLayer(0); blockPacket.setBlockPosition(position); @@ -99,6 +115,8 @@ public class BlockInventoryHolder extends InventoryHolder { inventory.setHolderPosition(position); setCustomName(session, position, inventory, defaultJavaBlockState); + + return true; } /** diff --git a/core/src/main/java/org/geysermc/geyser/inventory/holder/InventoryHolder.java b/core/src/main/java/org/geysermc/geyser/inventory/holder/InventoryHolder.java index fe54e1dc0..986df53db 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/holder/InventoryHolder.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/holder/InventoryHolder.java @@ -30,7 +30,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.InventoryTranslator; public abstract class InventoryHolder { - public abstract void prepareInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory); + public abstract boolean prepareInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory); public abstract void openInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory); public abstract void closeInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/AbstractBlockInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/AbstractBlockInventoryTranslator.java index c1fabcf0f..a24178161 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/AbstractBlockInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/AbstractBlockInventoryTranslator.java @@ -65,8 +65,8 @@ public abstract class AbstractBlockInventoryTranslator extends BaseInventoryTran } @Override - public void prepareInventory(GeyserSession session, Inventory inventory) { - holder.prepareInventory(this, session, inventory); + public boolean prepareInventory(GeyserSession session, Inventory inventory) { + return holder.prepareInventory(this, session, inventory); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java index 8c7ee1c80..e6cc010f5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java @@ -101,7 +101,7 @@ public abstract class InventoryTranslator { public final int size; - public abstract void prepareInventory(GeyserSession session, Inventory inventory); + public abstract boolean prepareInventory(GeyserSession session, Inventory inventory); public abstract void openInventory(GeyserSession session, Inventory inventory); public abstract void closeInventory(GeyserSession session, Inventory inventory); public abstract void updateProperty(GeyserSession session, Inventory inventory, int key, int value); 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 7b2f861f5..59fe81751 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 @@ -55,7 +55,8 @@ public class LecternInventoryTranslator extends BaseInventoryTranslator { } @Override - public void prepareInventory(GeyserSession session, Inventory inventory) { + public boolean prepareInventory(GeyserSession session, Inventory inventory) { + return true; } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/MerchantInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/MerchantInventoryTranslator.java index 5e9c99ae9..857b96e55 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/MerchantInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/MerchantInventoryTranslator.java @@ -94,7 +94,7 @@ public class MerchantInventoryTranslator extends BaseInventoryTranslator { } @Override - public void prepareInventory(GeyserSession session, Inventory inventory) { + public boolean prepareInventory(GeyserSession session, Inventory inventory) { MerchantContainer merchantInventory = (MerchantContainer) inventory; if (merchantInventory.getVillager() == null) { long geyserId = session.getEntityCache().getNextEntityId().incrementAndGet(); @@ -117,6 +117,8 @@ public class MerchantInventoryTranslator extends BaseInventoryTranslator { merchantInventory.setVillager(villager); } + + return true; } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index ee7d6a7c6..8432b0253 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -514,7 +514,8 @@ public class PlayerInventoryTranslator extends InventoryTranslator { } @Override - public void prepareInventory(GeyserSession session, Inventory inventory) { + public boolean prepareInventory(GeyserSession session, Inventory inventory) { + return true; } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java index 0dd8553fd..5bf96fd39 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java @@ -35,11 +35,12 @@ import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket; import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.inventory.Container; import org.geysermc.geyser.inventory.Inventory; +import org.geysermc.geyser.level.BedrockDimension; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.DoubleChestValue; -import org.geysermc.geyser.registry.BlockRegistries; -import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.level.block.entity.DoubleChestBlockEntityTranslator; +import org.geysermc.geyser.registry.BlockRegistries; public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { private final int defaultJavaBlockState; @@ -50,7 +51,7 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { } @Override - public void prepareInventory(GeyserSession session, Inventory inventory) { + public boolean prepareInventory(GeyserSession session, Inventory inventory) { // See BlockInventoryHolder - same concept there except we're also dealing with a specific block state if (session.getLastInteractionPlayerPosition().equals(session.getPlayerEntity().getPosition())) { int javaBlockId = session.getGeyser().getWorldManager().getBlockAt(session, session.getLastInteractionBlockPosition()); @@ -76,11 +77,25 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { dataPacket.setData(tag.build()); dataPacket.setBlockPosition(session.getLastInteractionBlockPosition()); session.sendUpstreamPacket(dataPacket); - return; + + return true; + } + } + + // Check if a fake block can be placed, either above the player or beneath. + BedrockDimension dimension = session.getChunkCache().getBedrockDimension(); + int minY = dimension.minY(), maxY = minY + dimension.height(); + Vector3i position = session.getPlayerEntity().getPosition().toInt().add(0, 5, 0); + if (position.getY() < minY) { + return false; + } + if (position.getY() >= maxY) { + position = session.getPlayerEntity().getPosition().toInt().sub(0, 5, 0); + if (position.getY() >= maxY) { + return false; } } - Vector3i position = session.getPlayerEntity().getPosition().toInt().add(Vector3i.UP); Vector3i pairPosition = position.add(Vector3i.UNIT_X); int bedrockBlockId = session.getBlockMappings().getBedrockBlockId(defaultJavaBlockState); @@ -125,6 +140,8 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { session.sendUpstreamPacket(dataPacket); inventory.setHolderPosition(position); + + return true; } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/SingleChestInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/SingleChestInventoryTranslator.java index 41e7bfb9f..ae914ed8c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/SingleChestInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/SingleChestInventoryTranslator.java @@ -52,8 +52,8 @@ public class SingleChestInventoryTranslator extends ChestInventoryTranslator { } @Override - public void prepareInventory(GeyserSession session, Inventory inventory) { - holder.prepareInventory(this, session, inventory); + public boolean prepareInventory(GeyserSession session, Inventory inventory) { + return holder.prepareInventory(this, session, inventory); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/horse/AbstractHorseInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/horse/AbstractHorseInventoryTranslator.java index 0ad6ba137..538133e0e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/horse/AbstractHorseInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/horse/AbstractHorseInventoryTranslator.java @@ -40,7 +40,8 @@ public abstract class AbstractHorseInventoryTranslator extends BaseInventoryTran } @Override - public void prepareInventory(GeyserSession session, Inventory inventory) { + public boolean prepareInventory(GeyserSession session, Inventory inventory) { + return true; } @Override diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index 56da67bec..ce88bc69c 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -85,8 +85,7 @@ public class InventoryUtils { public static void displayInventory(GeyserSession session, Inventory inventory) { InventoryTranslator translator = session.getInventoryTranslator(); - if (translator != null) { - translator.prepareInventory(session, inventory); + if (translator != null && translator.prepareInventory(session, inventory)) { if (translator instanceof DoubleChestInventoryTranslator && !((Container) inventory).isUsingRealBlock()) { session.scheduleInEventLoop(() -> { Inventory openInv = session.getOpenInventory(); @@ -103,7 +102,6 @@ public class InventoryUtils { translator.updateInventory(session, inventory); } } else { - // Precaution - as of 1.16 every inventory should be translated so this shouldn't happen session.setOpenInventory(null); } }