Remove cursor items from individual inventories (#2294)

* Remove cursor items from individual inventories

* Remove unused method and re-add but deprecate old cursor methods

* Fix links and remove unused import
This commit is contained in:
GoldenStack 2024-07-24 17:51:16 +00:00 committed by GitHub
parent 99ca16e263
commit 6406b369f5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 92 additions and 106 deletions

View File

@ -1785,14 +1785,9 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
Inventory openInventory = getOpenInventory();
// Drop cursor item when closing inventory
ItemStack cursorItem;
if (openInventory == null) {
cursorItem = getInventory().getCursorItem();
getInventory().setCursorItem(ItemStack.AIR);
} else {
cursorItem = openInventory.getCursorItem(this);
openInventory.setCursorItem(this, ItemStack.AIR);
}
ItemStack cursorItem = getInventory().getCursorItem();
getInventory().setCursorItem(ItemStack.AIR);
if (!cursorItem.isAir()) {
// Add item to inventory if he hasn't been able to drop it
if (!dropItem(cursorItem)) {

View File

@ -16,7 +16,6 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;
@ -41,8 +40,6 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
// the players currently viewing this inventory
private final Set<Player> viewers = new CopyOnWriteArraySet<>();
private final Set<Player> unmodifiableViewers = Collections.unmodifiableSet(viewers);
// (player -> cursor item) map, used by the click listeners
private final ConcurrentHashMap<Player, ItemStack> cursorPlayersItem = new ConcurrentHashMap<>();
public Inventory(@NotNull InventoryType inventoryType, @NotNull Component title) {
super(inventoryType.getSize());
@ -103,12 +100,6 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
return id;
}
@Override
public synchronized void clear() {
this.cursorPlayersItem.clear();
super.clear();
}
/**
* Refreshes the inventory for all viewers.
*/
@ -156,38 +147,30 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
@Override
public boolean removeViewer(@NotNull Player player) {
final boolean result = this.viewers.remove(player);
setCursorItem(player, ItemStack.AIR);
this.clickProcessor.clearCache(player);
return result;
}
/**
* Gets the cursor item of a viewer.
* Gets the cursor item of a player.
*
* @param player the player to get the cursor item from
* @return the player cursor item, air item if the player is not a viewer
* @deprecated normal inventories no longer store cursor items
* @see <a href="https://github.com/Minestom/Minestom/pull/2294">the relevant PR</a>
*/
@Deprecated
public @NotNull ItemStack getCursorItem(@NotNull Player player) {
return cursorPlayersItem.getOrDefault(player, ItemStack.AIR);
return player.getInventory().getCursorItem();
}
/**
* Changes the cursor item of a viewer,
* does nothing if <code>player</code> is not a viewer.
* Changes the cursor item of a player.
*
* @param player the player to change the cursor item
* @param cursorItem the new player cursor item
* @deprecated normal inventories no longer store cursor items
* @see <a href="https://github.com/Minestom/Minestom/pull/2294">the relevant PR</a>
*/
@Deprecated
public void setCursorItem(@NotNull Player player, @NotNull ItemStack cursorItem) {
final ItemStack currentCursorItem = cursorPlayersItem.getOrDefault(player, ItemStack.AIR);
if (!currentCursorItem.equals(cursorItem)) {
player.sendPacket(SetSlotPacket.createCursorPacket(cursorItem));
}
if (!cursorItem.isAir()) {
this.cursorPlayersItem.put(player, cursorItem);
} else {
this.cursorPlayersItem.remove(player);
}
player.getInventory().setCursorItem(cursorItem);
}
@Override
@ -197,7 +180,7 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
}
private @NotNull WindowItemsPacket createNewWindowItemsPacket(Player player) {
return new WindowItemsPacket(getWindowId(), 0, List.of(getItemStacks()), cursorPlayersItem.getOrDefault(player, ItemStack.AIR));
return new WindowItemsPacket(getWindowId(), 0, List.of(getItemStacks()), player.getInventory().getCursorItem());
}
/**
@ -214,7 +197,7 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
@Override
public boolean leftClick(@NotNull Player player, int slot) {
final PlayerInventory playerInventory = player.getInventory();
final ItemStack cursor = getCursorItem(player);
final ItemStack cursor = playerInventory.getCursorItem();
final boolean isInWindow = isClickInWindow(slot);
final int clickSlot = isInWindow ? slot : PlayerInventoryUtils.convertSlot(slot, offset);
final ItemStack clicked = isInWindow ? getItemStack(slot) : playerInventory.getItemStack(clickSlot);
@ -229,7 +212,7 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
} else {
playerInventory.setItemStack(clickSlot, clickResult.getClicked());
}
this.cursorPlayersItem.put(player, clickResult.getCursor());
playerInventory.setCursorItem(clickResult.getCursor());
callClickEvent(player, isInWindow ? this : null, slot, ClickType.LEFT_CLICK, clicked, cursor);
return true;
}
@ -237,7 +220,7 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
@Override
public boolean rightClick(@NotNull Player player, int slot) {
final PlayerInventory playerInventory = player.getInventory();
final ItemStack cursor = getCursorItem(player);
final ItemStack cursor = playerInventory.getCursorItem();
final boolean isInWindow = isClickInWindow(slot);
final int clickSlot = isInWindow ? slot : PlayerInventoryUtils.convertSlot(slot, offset);
final ItemStack clicked = isInWindow ? getItemStack(slot) : playerInventory.getItemStack(clickSlot);
@ -252,7 +235,7 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
} else {
playerInventory.setItemStack(clickSlot, clickResult.getClicked());
}
this.cursorPlayersItem.put(player, clickResult.getCursor());
playerInventory.setCursorItem(clickResult.getCursor());
callClickEvent(player, isInWindow ? this : null, slot, ClickType.RIGHT_CLICK, clicked, cursor);
return true;
}
@ -263,7 +246,7 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
final boolean isInWindow = isClickInWindow(slot);
final int clickSlot = isInWindow ? slot : PlayerInventoryUtils.convertSlot(slot, offset);
final ItemStack clicked = isInWindow ? getItemStack(slot) : playerInventory.getItemStack(clickSlot);
final ItemStack cursor = getCursorItem(player); // Isn't used in the algorithm
final ItemStack cursor = playerInventory.getCursorItem(); // Isn't used in the algorithm
final InventoryClickResult clickResult = clickProcessor.shiftClick(
isInWindow ? this : playerInventory,
isInWindow ? playerInventory : this,
@ -279,7 +262,7 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
playerInventory.setItemStack(clickSlot, clickResult.getClicked());
}
updateAll(player); // FIXME: currently not properly client-predicted
this.cursorPlayersItem.put(player, clickResult.getCursor());
playerInventory.setCursorItem(clickResult.getCursor());
return true;
}
@ -303,7 +286,7 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
playerInventory.setItemStack(clickSlot, clickResult.getClicked());
}
playerInventory.setItemStack(convertedKey, clickResult.getCursor());
callClickEvent(player, isInWindow ? this : null, slot, ClickType.CHANGE_HELD, clicked, getCursorItem(player));
callClickEvent(player, isInWindow ? this : null, slot, ClickType.CHANGE_HELD, clicked, playerInventory.getCursorItem());
return true;
}
@ -322,7 +305,7 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
final int clickSlot = isInWindow ? slot : PlayerInventoryUtils.convertSlot(slot, offset);
final ItemStack clicked = outsideDrop ?
ItemStack.AIR : (isInWindow ? getItemStack(slot) : playerInventory.getItemStack(clickSlot));
final ItemStack cursor = getCursorItem(player);
final ItemStack cursor = playerInventory.getCursorItem();
final InventoryClickResult clickResult = clickProcessor.drop(player,
isInWindow ? this : playerInventory, all, clickSlot, button, clicked, cursor);
if (clickResult.isCancel()) {
@ -337,7 +320,7 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
playerInventory.setItemStack(clickSlot, resultClicked);
}
}
this.cursorPlayersItem.put(player, clickResult.getCursor());
playerInventory.setCursorItem(clickResult.getCursor());
return true;
}
@ -349,7 +332,7 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
final ItemStack clicked = slot != -999 ?
(isInWindow ? getItemStack(slot) : playerInventory.getItemStack(clickSlot)) :
ItemStack.AIR;
final ItemStack cursor = getCursorItem(player);
final ItemStack cursor = playerInventory.getCursorItem();
final InventoryClickResult clickResult = clickProcessor.dragging(player,
slot != -999 ? (isInWindow ? this : playerInventory) : null,
clickSlot, button,
@ -358,7 +341,7 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
updateAll(player);
return false;
}
this.cursorPlayersItem.put(player, clickResult.getCursor());
playerInventory.setCursorItem(clickResult.getCursor());
updateAll(player); // FIXME: currently not properly client-predicted
return true;
}
@ -371,14 +354,14 @@ public non-sealed class Inventory extends AbstractInventory implements Viewable
final ItemStack clicked = slot != -999 ?
(isInWindow ? getItemStack(slot) : playerInventory.getItemStack(clickSlot)) :
ItemStack.AIR;
final ItemStack cursor = getCursorItem(player);
final ItemStack cursor = playerInventory.getCursorItem();
final InventoryClickResult clickResult = clickProcessor.doubleClick(isInWindow ? this : playerInventory,
this, player, clickSlot, clicked, cursor);
if (clickResult.isCancel()) {
updateAll(player);
return false;
}
this.cursorPlayersItem.put(player, clickResult.getCursor());
playerInventory.setCursorItem(clickResult.getCursor());
updateAll(player); // FIXME: currently not properly client-predicted
return true;
}

View File

@ -55,7 +55,7 @@ public class WindowListener {
} else if (clickType == ClientClickWindowPacket.ClickType.CLONE) {
successful = player.getGameMode() == GameMode.CREATIVE;
if (successful) {
setCursor(player, inventory, packet.clickedItem());
player.getInventory().setCursorItem(packet.clickedItem());
}
} else if (clickType == ClientClickWindowPacket.ClickType.THROW) {
successful = inventory.drop(player, false, slot, button);
@ -74,7 +74,8 @@ public class WindowListener {
}
// Prevent the player from picking a ghost item in cursor
refreshCursorItem(player, inventory);
ItemStack cursorItem = player.getInventory().getCursorItem();
player.sendPacket(SetSlotPacket.createCursorPacket(cursorItem));
// (Why is the ping packet necessary?)
player.sendPacket(new PingPacket((1 << 30) | (windowId << 16)));
@ -96,30 +97,4 @@ public class WindowListener {
player.openInventory(newInventory);
}
/**
* @param player the player to refresh the cursor item
* @param inventory the player open inventory, null if not any (could be player inventory)
*/
private static void refreshCursorItem(Player player, AbstractInventory inventory) {
ItemStack cursorItem;
if (inventory instanceof PlayerInventory playerInventory) {
cursorItem = playerInventory.getCursorItem();
} else if (inventory instanceof Inventory standardInventory) {
cursorItem = standardInventory.getCursorItem(player);
} else {
throw new RuntimeException("Invalid inventory: " + inventory.getClass());
}
final SetSlotPacket setSlotPacket = SetSlotPacket.createCursorPacket(cursorItem);
player.sendPacket(setSlotPacket);
}
private static void setCursor(Player player, AbstractInventory inventory, ItemStack itemStack) {
if (inventory instanceof PlayerInventory playerInventory) {
playerInventory.setCursorItem(itemStack);
} else if (inventory instanceof Inventory standardInventory) {
standardInventory.setCursorItem(player, itemStack);
} else {
throw new RuntimeException("Invalid inventory: " + inventory.getClass());
}
}
}

View File

@ -56,15 +56,15 @@ public class InventoryIntegrationTest {
assertEquals(inventory, player.getOpenInventory());
var packetTracker = connection.trackIncoming(SetSlotPacket.class);
inventory.setCursorItem(player, MAGIC_STACK);
player.getInventory().setCursorItem(MAGIC_STACK);
packetTracker.assertSingle(slot -> assertEquals(MAGIC_STACK, slot.itemStack())); // Setting a slot should send a packet
packetTracker = connection.trackIncoming(SetSlotPacket.class);
inventory.setCursorItem(player, MAGIC_STACK);
player.getInventory().setCursorItem(MAGIC_STACK);
packetTracker.assertEmpty(); // Setting the same slot to the same ItemStack should not send another packet
packetTracker = connection.trackIncoming(SetSlotPacket.class);
inventory.setCursorItem(player, ItemStack.AIR);
player.getInventory().setCursorItem(ItemStack.AIR);
packetTracker.assertSingle(slot -> assertEquals(ItemStack.AIR, slot.itemStack())); // Setting a slot should send a packet
}
@ -85,7 +85,7 @@ public class InventoryIntegrationTest {
inventory.setItemStack(3, MAGIC_STACK);
inventory.setItemStack(19, MAGIC_STACK);
inventory.setItemStack(40, MAGIC_STACK);
inventory.setCursorItem(player, MAGIC_STACK);
player.getInventory().setCursorItem(MAGIC_STACK);
setSlotTracker.assertCount(5);
@ -99,9 +99,9 @@ public class InventoryIntegrationTest {
// Make sure not individual SetSlotPackets get sent
setSlotTracker.assertEmpty();
// Make sure WindowItemsPacket is empty
// Make sure WindowItemsPacket is empty except for cursor (clearing the player inventory itself clears the cursor)
updateWindowTracker.assertSingle(windowItemsPacket -> {
assertEquals(ItemStack.AIR, windowItemsPacket.carriedItem());
assertEquals(MAGIC_STACK, windowItemsPacket.carriedItem());
for (ItemStack item : windowItemsPacket.items()) {
assertEquals(ItemStack.AIR, item);
}
@ -111,6 +111,39 @@ public class InventoryIntegrationTest {
equipmentTracker.assertEmpty();
}
@Test
public void clearingPlayerInventoryClearsCursorTest(Env env) {
var instance = env.createFlatInstance();
var connection = env.createConnection();
var player = connection.connect(instance, new Pos(0, 42, 0)).join();
assertEquals(instance, player.getInstance());
var setSlotTracker = connection.trackIncoming(SetSlotPacket.class);
player.getInventory().setCursorItem(MAGIC_STACK);
setSlotTracker.assertCount(1);
setSlotTracker = connection.trackIncoming(SetSlotPacket.class);
var updateWindowTracker = connection.trackIncoming(WindowItemsPacket.class);
var equipmentTracker = connection.trackIncoming(EntityEquipmentPacket.class);
// Perform the clear operation we are testing
player.getInventory().clear();
// Make sure not individual SetSlotPackets get sent
setSlotTracker.assertEmpty();
// Make sure WindowItemsPacket is empty
updateWindowTracker.assertSingle(windowItemsPacket -> {
assertEquals(ItemStack.AIR, windowItemsPacket.carriedItem());
});
// Make sure EntityEquipmentPacket is sent
equipmentTracker.assertSingle();
}
@Test
public void closeInventoryTest(Env env) {
var instance = env.createFlatInstance();
@ -132,14 +165,14 @@ public class InventoryIntegrationTest {
final var firstInventory = new Inventory(InventoryType.CHEST_1_ROW, "title");
player.openInventory(firstInventory);
assertSame(firstInventory, player.getOpenInventory());
firstInventory.setCursorItem(player, ItemStack.of(Material.STONE));
player.getInventory().setCursorItem(ItemStack.of(Material.STONE));
listener.followup();
player.closeInventory();
assertNull(player.getOpenInventory());
player.openInventory(firstInventory);
firstInventory.setCursorItem(player, ItemStack.of(Material.STONE));
player.getInventory().setCursorItem(ItemStack.of(Material.STONE));
final var secondInventory = new Inventory(InventoryType.CHEST_1_ROW, "title");
listener.followup(event -> event.getPlayer().openInventory(secondInventory));
player.closeInventory();

View File

@ -113,10 +113,10 @@ public class HeldClickIntegrationTest {
if (event.getInventory() != null) assertEquals(inventory, event.getInventory());
assertEquals(0, event.getSlot());
assertEquals(ClickType.CHANGE_HELD, event.getClickType());
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem());
});
heldClickOpenInventory(player, 0, 0);
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem());
assertEquals(ItemStack.AIR, inventory.getItemStack(0));
}
// Swap empty
@ -124,10 +124,10 @@ public class HeldClickIntegrationTest {
listener.followup(event -> {
if (event.getInventory() != null) assertEquals(inventory, event.getInventory());
assertTrue(event.getSlot() == 1 || event.getSlot() == 0);
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem());
});
heldClickOpenInventory(player, 1, 0);
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem());
assertEquals(ItemStack.AIR, inventory.getItemStack(1));
assertEquals(ItemStack.of(Material.DIAMOND), playerInv.getItemStack(0));
}
@ -136,10 +136,10 @@ public class HeldClickIntegrationTest {
listener.followup(event -> {
if (event.getInventory() != null) assertEquals(inventory, event.getInventory());
assertTrue(event.getSlot() == 2 || event.getSlot() == 0);
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem());
});
heldClickOpenInventory(player, 2, 0);
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem());
assertEquals(ItemStack.of(Material.DIAMOND), inventory.getItemStack(2));
assertEquals(ItemStack.of(Material.GOLD_INGOT), playerInv.getItemStack(0));
}
@ -157,7 +157,7 @@ public class HeldClickIntegrationTest {
{
listener.followup(event -> event.setCancelled(true));
heldClickOpenInventory(player, 2, 0);
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem());
assertEquals(ItemStack.of(Material.DIAMOND), inventory.getItemStack(2));
assertEquals(ItemStack.of(Material.GOLD_INGOT), playerInv.getItemStack(0));
}

View File

@ -95,7 +95,7 @@ public class LeftClickIntegrationTest {
assertNull(event.getInventory()); // Player inventory
assertEquals(0, event.getSlot());
assertEquals(ClickType.LEFT_CLICK, event.getClickType());
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem());
});
leftClick(player, 0);
}
@ -105,12 +105,12 @@ public class LeftClickIntegrationTest {
assertEquals(inventory, event.getInventory());
assertEquals(1, event.getSlot());
// Ensure that the inventory didn't change yet
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem());
assertEquals(ItemStack.of(Material.DIAMOND), inventory.getItemStack(1));
});
leftClickOpenInventory(player, 1);
// Verify inventory changes
assertEquals(ItemStack.of(Material.DIAMOND), inventory.getCursorItem(player));
assertEquals(ItemStack.of(Material.DIAMOND), player.getInventory().getCursorItem());
assertEquals(ItemStack.AIR, inventory.getItemStack(1));
}
// Place it back
@ -118,18 +118,18 @@ public class LeftClickIntegrationTest {
listener.followup(event -> {
assertEquals(inventory, event.getInventory());
assertEquals(1, event.getSlot());
assertEquals(ItemStack.of(Material.DIAMOND), inventory.getCursorItem(player));
assertEquals(ItemStack.of(Material.DIAMOND), player.getInventory().getCursorItem());
assertEquals(ItemStack.AIR, inventory.getItemStack(1));
});
leftClickOpenInventory(player, 1);
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem());
assertEquals(ItemStack.of(Material.DIAMOND), inventory.getItemStack(1));
}
// Cancel event
{
listener.followup(event -> event.setCancelled(true));
leftClickOpenInventory(player, 1);
assertEquals(ItemStack.AIR, inventory.getCursorItem(player), "Left click cancellation did not work");
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem(), "Left click cancellation did not work");
assertEquals(ItemStack.of(Material.DIAMOND), inventory.getItemStack(1));
}
// Change items
@ -141,7 +141,7 @@ public class LeftClickIntegrationTest {
event.setCursorItem(ItemStack.of(Material.DIAMOND));
});
leftClick(player, 9);
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem());
assertEquals(ItemStack.of(Material.DIAMOND, 6), player.getInventory().getItemStack(9));
}
}

View File

@ -117,7 +117,7 @@ public class RightClickIntegrationTest {
assertNull(event.getInventory()); // Player inventory
assertEquals(0, event.getSlot());
assertEquals(ClickType.RIGHT_CLICK, event.getClickType());
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem());
});
rightClick(player, 0);
}
@ -126,11 +126,11 @@ public class RightClickIntegrationTest {
listener.followup(event -> {
assertEquals(inventory, event.getInventory());
assertEquals(1, event.getSlot());
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem());
assertEquals(ItemStack.of(Material.DIAMOND), inventory.getItemStack(1));
});
rightClickOpenInventory(player, 1);
assertEquals(ItemStack.of(Material.DIAMOND), inventory.getCursorItem(player));
assertEquals(ItemStack.of(Material.DIAMOND), player.getInventory().getCursorItem());
assertEquals(ItemStack.AIR, inventory.getItemStack(1));
}
// Place back to player inv
@ -138,12 +138,12 @@ public class RightClickIntegrationTest {
listener.followup(event -> {
assertNull(event.getInventory());
assertEquals(1, event.getSlot());
assertEquals(ItemStack.of(Material.DIAMOND), inventory.getCursorItem(player));
assertEquals(ItemStack.of(Material.DIAMOND), player.getInventory().getCursorItem());
assertEquals(ItemStack.AIR, inventory.getItemStack(1));
assertEquals(ItemStack.AIR, player.getInventory().getItemStack(1));
});
rightClick(player, 1);
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem());
assertEquals(ItemStack.of(Material.DIAMOND), player.getInventory().getItemStack(1));
}
// Cancel event
@ -151,7 +151,7 @@ public class RightClickIntegrationTest {
listener.followup(event -> event.setCancelled(true));
rightClick(player, 1);
assertEquals(ItemStack.of(Material.DIAMOND), player.getInventory().getItemStack(1), "Left click cancellation did not work");
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem());
}
// Change items
{
@ -162,7 +162,7 @@ public class RightClickIntegrationTest {
event.setCursorItem(ItemStack.of(Material.DIAMOND));
});
rightClick(player, 9);
assertEquals(ItemStack.AIR, inventory.getCursorItem(player));
assertEquals(ItemStack.AIR, player.getInventory().getCursorItem());
assertEquals(ItemStack.of(Material.DIAMOND, 6), player.getInventory().getItemStack(9));
}
}