fix: fix to closing inventories serverside while sending updates

(cherry picked from commit f5727c207b)
This commit is contained in:
mworzala 2024-01-27 10:04:52 -05:00 committed by Matt Worzala
parent 48d87db6e9
commit 38076fe707
2 changed files with 9 additions and 36 deletions

View File

@ -769,6 +769,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
/**
* Queues the given chunk to be sent to the player.
*
* @param chunk The chunk to send
*/
public void sendChunk(@NotNull Chunk chunk) {
@ -1724,6 +1725,11 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
* It closes the player inventory (when opened) if {@link #getOpenInventory()} returns null.
*/
public void closeInventory() {
closeInventory(false);
}
@ApiStatus.Internal
public void closeInventory(boolean fromClient) {
Inventory openInventory = getOpenInventory();
// Drop cursor item when closing inventory
@ -1751,45 +1757,12 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
openInventory.removeViewer(this); // Clear cache
this.openInventory = null;
}
sendPacket(closeWindowPacket);
if (!fromClient) sendPacket(closeWindowPacket);
inventory.update();
this.didCloseInventory = true;
}
}
/**
* Updates the player's inventory state, given a window id to compare against.
* Note: This should only be used when receiving a {@link net.minestom.server.network.packet.client.play.ClientCloseWindowPacket}.
* Use {@link #closeInventory()} instead for more general use.
* @param windowId The window id to compare against.
*/
public void updateCloseInventoryState(byte windowId) {
if (windowId == 0) {
// Put cursor item back in inventory if possible
ItemStack stack = getInventory().getCursorItem();
boolean success = getInventory().addItemStack(stack);
// Drop if inventory is full
if (!success) {
dropItem(stack);
}
getInventory().setCursorItem(ItemStack.AIR);
} else {
if (getOpenInventory() != null && windowId == getOpenInventory().getWindowId()) {
ItemStack stack = getOpenInventory().getCursorItem(this);
// Try to put item into our inventory
boolean success = getInventory().addItemStack(stack);
// Drop if inventory is full
if (!success) {
dropItem(stack);
}
getOpenInventory().setCursorItem(this, ItemStack.AIR);
} else {
// Something has gone wrong
logger.warn("Tried to update inventory state with invalid window id!");
}
}
}
/**
* Used internally to prevent an inventory click to be processed
* when the inventory listeners closed the inventory.

View File

@ -7,9 +7,9 @@ import net.minestom.server.inventory.AbstractInventory;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.PlayerInventory;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.packet.client.common.ClientPongPacket;
import net.minestom.server.network.packet.client.play.ClientClickWindowPacket;
import net.minestom.server.network.packet.client.play.ClientCloseWindowPacket;
import net.minestom.server.network.packet.client.common.ClientPongPacket;
import net.minestom.server.network.packet.server.common.PingPacket;
import net.minestom.server.network.packet.server.play.SetSlotPacket;
@ -88,7 +88,7 @@ public class WindowListener {
InventoryCloseEvent inventoryCloseEvent = new InventoryCloseEvent(player.getOpenInventory(), player);
EventDispatcher.call(inventoryCloseEvent);
player.updateCloseInventoryState(packet.windowId());
player.closeInventory(true);
Inventory newInventory = inventoryCloseEvent.getNewInventory();
if (newInventory != null)