diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/manager/GeyserSpigotWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/manager/GeyserSpigotWorldManager.java index 13f696fd5..bc76288c5 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/manager/GeyserSpigotWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/manager/GeyserSpigotWorldManager.java @@ -235,6 +235,7 @@ public class GeyserSpigotWorldManager extends GeyserWorldManager { NbtMap blockEntityTag = lecternTag.build(); BlockEntityUtils.updateBlockEntity(session, blockEntityTag, Vector3i.from(x, y, z)); }; + if (isChunkLoad) { // Delay to ensure the chunk is sent first, and then the lectern data Bukkit.getScheduler().runTaskLater(this.plugin, lecternInfoGet, 5); diff --git a/connector/src/main/java/org/geysermc/connector/inventory/GeyserItemStack.java b/connector/src/main/java/org/geysermc/connector/inventory/GeyserItemStack.java index 7cdaf1801..b4e91c1d6 100644 --- a/connector/src/main/java/org/geysermc/connector/inventory/GeyserItemStack.java +++ b/connector/src/main/java/org/geysermc/connector/inventory/GeyserItemStack.java @@ -62,6 +62,10 @@ public class GeyserItemStack { this.netId = netId; } + public static GeyserItemStack from(ItemStack itemStack) { + return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getNbt()); + } + public int getJavaId() { return isEmpty() ? 0 : javaId; } @@ -74,10 +78,6 @@ public class GeyserItemStack { return isEmpty() ? null : nbt; } - public void setNetId(int netId) { - this.netId = netId; - } - public int getNetId() { return isEmpty() ? 0 : netId; } @@ -90,10 +90,6 @@ public class GeyserItemStack { amount -= sub; } - public static GeyserItemStack from(ItemStack itemStack) { - return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getNbt()); - } - public ItemStack getItemStack() { return getItemStack(amount); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockLecternUpdateTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockLecternUpdateTranslator.java index 10af0b610..ae99fec07 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockLecternUpdateTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockLecternUpdateTranslator.java @@ -65,6 +65,7 @@ public class BedrockLecternUpdateTranslator extends PacketTranslator if (ridingEntity instanceof AbstractHorseEntity) { if (ridingEntity.getMetadata().getFlags().getFlag(EntityFlag.TAMED)) { // We should request to open the horse inventory instead - ClientPlayerStatePacket openHorseWindowPacket = new ClientPlayerStatePacket((int)session.getPlayerEntity().getEntityId(), PlayerState.OPEN_HORSE_INVENTORY); + ClientPlayerStatePacket openHorseWindowPacket = new ClientPlayerStatePacket((int) session.getPlayerEntity().getEntityId(), PlayerState.OPEN_HORSE_INVENTORY); session.sendDownstreamPacket(openHorseWindowPacket); } } else { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/InventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/InventoryTranslator.java index 6ec90d24d..5fd44c8b1 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/InventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/InventoryTranslator.java @@ -39,6 +39,7 @@ import com.nukkitx.protocol.bedrock.data.inventory.stackrequestactions.*; import com.nukkitx.protocol.bedrock.packet.ItemStackResponsePacket; import it.unimi.dsi.fastutil.ints.*; import lombok.AllArgsConstructor; +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.inventory.*; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.inventory.click.Click; @@ -171,9 +172,12 @@ public abstract class InventoryTranslator { } else { response = rejectRequest(request); } - if (response.getResult() == ItemStackResponsePacket.ResponseStatus.ERROR) { + + if (response.getResult() != ItemStackResponsePacket.ResponseStatus.OK) { + // Sync our copy of the inventory with Bedrock's to prevent desyncs refresh = true; } + responsePacket.getEntries().add(response); } session.sendUpstreamPacket(responsePacket); @@ -198,11 +202,10 @@ public abstract class InventoryTranslator { transferAction.getSource().getSlot() >= 28 && transferAction.getSource().getSlot() <= 31) { return rejectRequest(request, false); } - session.getConnector().getLogger().error("DEBUG: About to reject TAKE/PLACE request made by " + session.getName()); - session.getConnector().getLogger().error("Source: " + transferAction.getSource().toString() + " Result: " + checkNetId(session, inventory, transferAction.getSource())); - session.getConnector().getLogger().error("Destination: " + transferAction.getDestination().toString() + " Result: " + checkNetId(session, inventory, transferAction.getDestination())); - session.getConnector().getLogger().error("Geyser's record of source slot: " + inventory.getItem(bedrockSlotToJava(transferAction.getSource()))); - session.getConnector().getLogger().error("Geyser's record of destination slot: " + inventory.getItem(bedrockSlotToJava(transferAction.getDestination()))); + if (session.getConnector().getConfig().isDebugMode()) { + session.getConnector().getLogger().error("DEBUG: About to reject TAKE/PLACE request made by " + session.getName()); + dumpStackRequestDetails(session, inventory, transferAction.getSource(), transferAction.getDestination()); + } return rejectRequest(request); } @@ -285,11 +288,10 @@ public abstract class InventoryTranslator { case SWAP: { SwapStackRequestActionData swapAction = (SwapStackRequestActionData) action; if (!(checkNetId(session, inventory, swapAction.getSource()) && checkNetId(session, inventory, swapAction.getDestination()))) { - session.getConnector().getLogger().error("DEBUG: About to reject SWAP request made by " + session.getName()); - session.getConnector().getLogger().error("Source: " + swapAction.getSource().toString() + " Result: " + checkNetId(session, inventory, swapAction.getSource())); - session.getConnector().getLogger().error("Destination: " + swapAction.getDestination().toString() + " Result: " + checkNetId(session, inventory, swapAction.getDestination())); - session.getConnector().getLogger().error("Geyser's record of source slot: " + inventory.getItem(bedrockSlotToJava(swapAction.getSource()))); - session.getConnector().getLogger().error("Geyser's record of destination slot: " + inventory.getItem(bedrockSlotToJava(swapAction.getDestination()))); + if (session.getConnector().getConfig().isDebugMode()) { + session.getConnector().getLogger().error("DEBUG: About to reject SWAP request made by " + session.getName()); + dumpStackRequestDetails(session, inventory, swapAction.getSource(), swapAction.getDestination()); + } return rejectRequest(request); } @@ -756,13 +758,22 @@ public abstract class InventoryTranslator { * as bad (false). */ public static ItemStackResponsePacket.Response rejectRequest(ItemStackRequest request, boolean throwError) { - if (throwError) { - // Currently for debugging, but might be worth it to keep in the future if something goes terribly wrong. + if (throwError && GeyserConnector.getInstance().getConfig().isDebugMode()) { new Throwable("DEBUGGING: ItemStackRequest rejected " + request.toString()).printStackTrace(); } return new ItemStackResponsePacket.Response(ItemStackResponsePacket.ResponseStatus.ERROR, request.getRequestId(), Collections.emptyList()); } + /** + * Print out the contents of an ItemStackRequest, should the net ID check fail. + */ + protected void dumpStackRequestDetails(GeyserSession session, Inventory inventory, StackRequestSlotInfoData source, StackRequestSlotInfoData destination) { + session.getConnector().getLogger().error("Source: " + source.toString() + " Result: " + checkNetId(session, inventory, source)); + session.getConnector().getLogger().error("Destination: " + destination.toString() + " Result: " + checkNetId(session, inventory, destination)); + session.getConnector().getLogger().error("Geyser's record of source slot: " + inventory.getItem(bedrockSlotToJava(source))); + session.getConnector().getLogger().error("Geyser's record of destination slot: " + inventory.getItem(bedrockSlotToJava(destination))); + } + public boolean checkNetId(GeyserSession session, Inventory inventory, StackRequestSlotInfoData slotInfoData) { int netId = slotInfoData.getStackNetworkId(); // "In my testing, sometimes the client thinks the netId of an item in the crafting grid is 1, even though we never said it was. diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/CraftingInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/CraftingInventoryTranslator.java index 81769c00a..363c9b702 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/CraftingInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/CraftingInventoryTranslator.java @@ -39,8 +39,9 @@ public class CraftingInventoryTranslator extends AbstractBlockInventoryTranslato @Override public SlotType getSlotType(int javaSlot) { - if (javaSlot == 0) + if (javaSlot == 0) { return SlotType.OUTPUT; + } return SlotType.NORMAL; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/HorseInventoryUpdater.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/HorseInventoryUpdater.java index d238b4148..db067a74c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/HorseInventoryUpdater.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/HorseInventoryUpdater.java @@ -64,5 +64,4 @@ public class HorseInventoryUpdater extends InventoryUpdater { session.sendUpstreamPacket(slotPacket); return true; } - }