package net.minestom.server.inventory; import net.minestom.testing.Env; import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.EquipmentSlot; import net.minestom.server.item.ItemStack; import net.minestom.server.item.Material; import net.minestom.server.network.packet.server.play.EntityEquipmentPacket; import net.minestom.server.network.packet.server.play.SetSlotPacket; import net.minestom.server.network.packet.server.play.WindowItemsPacket; import org.junit.jupiter.api.Test; import java.util.Map; import static org.junit.jupiter.api.Assertions.*; @EnvTest public class PlayerInventoryIntegrationTest { private static final ItemStack MAGIC_STACK = ItemStack.of(Material.DIAMOND, 3); @Test public void setSlotDuplicateTest(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 packetTracker = connection.trackIncoming(SetSlotPacket.class); player.getInventory().setItemStack(3, MAGIC_STACK); packetTracker.assertSingle(slot -> assertEquals(MAGIC_STACK, slot.itemStack())); // Setting a slot should send a packet packetTracker = connection.trackIncoming(SetSlotPacket.class); player.getInventory().setItemStack(3, MAGIC_STACK); packetTracker.assertEmpty(); // Setting the same slot to the same ItemStack should not send another packet packetTracker = connection.trackIncoming(SetSlotPacket.class); player.getInventory().setItemStack(3, ItemStack.AIR); packetTracker.assertSingle(slot -> assertEquals(ItemStack.AIR, slot.itemStack())); // Setting a slot should send a packet } @Test public void setCursorItemDuplicateTest(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 packetTracker = connection.trackIncoming(SetSlotPacket.class); 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); 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); player.getInventory().setCursorItem(ItemStack.AIR); packetTracker.assertSingle(slot -> assertEquals(ItemStack.AIR, slot.itemStack())); // Setting a slot should send a packet } @Test public void clearInventoryTest(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().setItemStack(1, MAGIC_STACK); player.getInventory().setItemStack(3, MAGIC_STACK); player.getInventory().setItemStack(19, MAGIC_STACK); player.getInventory().setItemStack(40, MAGIC_STACK); player.getInventory().setCursorItem(MAGIC_STACK); setSlotTracker.assertCount(5); 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()); for (ItemStack item : windowItemsPacket.items()) { assertEquals(ItemStack.AIR, item); } }); // Make sure EntityEquipmentPacket is empty equipmentTracker.assertSingle(entityEquipmentPacket -> { assertEquals(6, entityEquipmentPacket.equipments().size()); for (Map.Entry entry : entityEquipmentPacket.equipments().entrySet()) { assertEquals(ItemStack.AIR, entry.getValue()); } }); } @Test public void equipmentViewTest(Env env) { var instance = env.createFlatInstance(); var connectionArmored = env.createConnection(); var playerArmored = connectionArmored.connect(instance, new Pos(0, 42, 0)).join(); var connectionViewer = env.createConnection(); var playerViewer = connectionViewer.connect(instance, new Pos(0, 42, 0)).join(); assertEquals(instance, playerArmored.getInstance()); assertEquals(instance, playerViewer.getInstance()); var equipmentTracker = connectionViewer.trackIncoming(EntityEquipmentPacket.class); // Setting to an item should send EntityEquipmentPacket to viewer playerArmored.getInventory().setEquipment(EquipmentSlot.HELMET, MAGIC_STACK); equipmentTracker.assertSingle(entityEquipmentPacket -> { assertEquals(MAGIC_STACK, entityEquipmentPacket.equipments().get(EquipmentSlot.HELMET)); }); // Setting to the same item shouldn't send packet equipmentTracker = connectionViewer.trackIncoming(EntityEquipmentPacket.class); playerArmored.getInventory().setEquipment(EquipmentSlot.HELMET, MAGIC_STACK); equipmentTracker.assertEmpty(); // Setting to air should send packet equipmentTracker = connectionViewer.trackIncoming(EntityEquipmentPacket.class); playerArmored.getInventory().setEquipment(EquipmentSlot.HELMET, ItemStack.AIR); equipmentTracker.assertSingle(entityEquipmentPacket -> { assertEquals(ItemStack.AIR, entityEquipmentPacket.equipments().get(EquipmentSlot.HELMET)); }); } @Test public void heldItemViewTest(Env env) { var instance = env.createFlatInstance(); var connectionHolder = env.createConnection(); var playerHolder = connectionHolder.connect(instance, new Pos(0, 42, 0)).join(); var connectionViewer = env.createConnection(); var playerViewer = connectionViewer.connect(instance, new Pos(0, 42, 0)).join(); assertEquals(instance, playerHolder.getInstance()); assertEquals(instance, playerViewer.getInstance()); playerHolder.setHeldItemSlot((byte) 0); // Setting held item var equipmentTracker = connectionViewer.trackIncoming(EntityEquipmentPacket.class); playerHolder.setItemInMainHand(MAGIC_STACK); equipmentTracker.assertSingle(entityEquipmentPacket -> { assertEquals(MAGIC_STACK, entityEquipmentPacket.equipments().get(EquipmentSlot.MAIN_HAND)); }); // Changing held slot to an empty slot should update MAIN_HAND to empty item equipmentTracker = connectionViewer.trackIncoming(EntityEquipmentPacket.class); playerHolder.setHeldItemSlot((byte) 3); equipmentTracker.assertSingle(entityEquipmentPacket -> { assertEquals(ItemStack.AIR, entityEquipmentPacket.equipments().get(EquipmentSlot.MAIN_HAND)); }); // Changing held slot to the original slot should update MAIN_HAND to original item equipmentTracker = connectionViewer.trackIncoming(EntityEquipmentPacket.class); playerHolder.setHeldItemSlot((byte) 0); equipmentTracker.assertSingle(entityEquipmentPacket -> { assertEquals(MAGIC_STACK, entityEquipmentPacket.equipments().get(EquipmentSlot.MAIN_HAND)); }); } }