Fix close request desyncs with inventories of the same type, and

- Small object optimization in DoubleChestInventoryTranslator
- Sending inventory ID of 0 for inventory translation is valid
This commit is contained in:
Camotoy 2021-03-06 12:24:39 -05:00
parent 7fde39f247
commit 55a1acfcb6
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
3 changed files with 16 additions and 10 deletions

View file

@ -25,7 +25,6 @@
package org.geysermc.connector.network.translators.inventory.translators.chest;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.nbt.NbtMap;
import com.nukkitx.nbt.NbtMapBuilder;
@ -152,8 +151,7 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
}
Vector3i holderPos = inventory.getHolderPosition();
Position pos = new Position(holderPos.getX(), holderPos.getY(), holderPos.getZ());
int realBlock = session.getConnector().getWorldManager().getBlockAt(session, pos.getX(), pos.getY(), pos.getZ());
int realBlock = session.getConnector().getWorldManager().getBlockAt(session, holderPos);
UpdateBlockPacket blockPacket = new UpdateBlockPacket();
blockPacket.setDataLayer(0);
blockPacket.setBlockPosition(holderPos);
@ -161,8 +159,7 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
session.sendUpstreamPacket(blockPacket);
holderPos = holderPos.add(Vector3i.UNIT_X);
pos = new Position(holderPos.getX(), holderPos.getY(), holderPos.getZ());
realBlock = session.getConnector().getWorldManager().getBlockAt(session, pos.getX(), pos.getY(), pos.getZ());
realBlock = session.getConnector().getWorldManager().getBlockAt(session, holderPos);
blockPacket = new UpdateBlockPacket();
blockPacket.setDataLayer(0);
blockPacket.setBlockPosition(holderPos);

View file

@ -63,9 +63,12 @@ public class JavaOpenWindowTranslator extends PacketTranslator<ServerOpenWindowP
Inventory newInventory = newTranslator.createInventory(name, packet.getWindowId(), packet.getType(), session.getPlayerInventory());
if (openInventory != null) {
// If the window type is the same, don't close.
// In rare cases, inventories can do funny things where it keeps the same window type up but change the contents.
if (openInventory.getWindowType() != packet.getType()) {
// Sometimes the server can double-open an inventory with the same ID - don't confirm in that instance.
// If the window type is the same, don't confirm; in rare cases, inventories can do funny things where it keeps the same window type up but change the contents.
InventoryUtils.closeInventory(session, openInventory.getId(), (openInventory.getId() != packet.getWindowId() && openInventory.getWindowType() != packet.getType()));
InventoryUtils.closeInventory(session, openInventory.getId(), openInventory.getId() != packet.getWindowId());
}
}
session.setInventoryTranslator(newTranslator);

View file

@ -80,9 +80,15 @@ public class JavaSetSlotTranslator extends PacketTranslator<ServerSetSlotPacket>
session.setCraftingGridFuture(session.getConnector().getGeneralThreadPool().schedule(() -> session.addInventoryTask(() -> updateCraftingGrid(session, packet, inventory, translator)), 150, TimeUnit.MILLISECONDS));
GeyserItemStack newItem = GeyserItemStack.from(packet.getItem());
if (packet.getWindowId() == 0 && !(translator instanceof PlayerInventoryTranslator)) {
// In rare cases, the window ID can still be 0 but Java treats it as valid
session.getPlayerInventory().setItem(packet.getSlot(), newItem, session);
InventoryTranslator.PLAYER_INVENTORY_TRANSLATOR.updateSlot(session, session.getPlayerInventory(), packet.getSlot());
} else {
inventory.setItem(packet.getSlot(), newItem, session);
translator.updateSlot(session, inventory, packet.getSlot());
}
}
});
}