From 836586d59b9a116f25059939050c11cb06e37dd2 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Thu, 13 Jul 2023 13:09:26 -0700 Subject: [PATCH] Fix missing item types in SlotType for armor change event (#9379) Also added 2 parameterized tests to make sure this doesn't happen again. --- .../api/0073-Add-PlayerArmorChangeEvent.patch | 4 +- .../0161-Add-PlayerArmorChangeEvent.patch | 122 ++++++++++++++++++ 2 files changed, 124 insertions(+), 2 deletions(-) diff --git a/patches/api/0073-Add-PlayerArmorChangeEvent.patch b/patches/api/0073-Add-PlayerArmorChangeEvent.patch index 4e9d795db..b31e387cb 100644 --- a/patches/api/0073-Add-PlayerArmorChangeEvent.patch +++ b/patches/api/0073-Add-PlayerArmorChangeEvent.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add PlayerArmorChangeEvent diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerArmorChangeEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerArmorChangeEvent.java new file mode 100644 -index 0000000000000000000000000000000000000000..e406ce639a2e88b78f82f25e71678a669d0a958b +index 0000000000000000000000000000000000000000..faea096dac02d339667c02a0011b6f8313fd8c12 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerArmorChangeEvent.java @@ -0,0 +1,137 @@ @@ -93,7 +93,7 @@ index 0000000000000000000000000000000000000000..e406ce639a2e88b78f82f25e71678a66 + } + + public enum SlotType { -+ HEAD(NETHERITE_HELMET, DIAMOND_HELMET, GOLDEN_HELMET, IRON_HELMET, CHAINMAIL_HELMET, LEATHER_HELMET, CARVED_PUMPKIN, PLAYER_HEAD, SKELETON_SKULL, ZOMBIE_HEAD, CREEPER_HEAD, WITHER_SKELETON_SKULL, TURTLE_HELMET), ++ HEAD(NETHERITE_HELMET, DIAMOND_HELMET, GOLDEN_HELMET, IRON_HELMET, CHAINMAIL_HELMET, LEATHER_HELMET, CARVED_PUMPKIN, PLAYER_HEAD, SKELETON_SKULL, ZOMBIE_HEAD, CREEPER_HEAD, WITHER_SKELETON_SKULL, TURTLE_HELMET, DRAGON_HEAD, PIGLIN_HEAD), + CHEST(NETHERITE_CHESTPLATE, DIAMOND_CHESTPLATE, GOLDEN_CHESTPLATE, IRON_CHESTPLATE, CHAINMAIL_CHESTPLATE, LEATHER_CHESTPLATE, ELYTRA), + LEGS(NETHERITE_LEGGINGS, DIAMOND_LEGGINGS, GOLDEN_LEGGINGS, IRON_LEGGINGS, CHAINMAIL_LEGGINGS, LEATHER_LEGGINGS), + FEET(NETHERITE_BOOTS, DIAMOND_BOOTS, GOLDEN_BOOTS, IRON_BOOTS, CHAINMAIL_BOOTS, LEATHER_BOOTS); diff --git a/patches/server/0161-Add-PlayerArmorChangeEvent.patch b/patches/server/0161-Add-PlayerArmorChangeEvent.patch index 3f458457b..0cb8c79fe 100644 --- a/patches/server/0161-Add-PlayerArmorChangeEvent.patch +++ b/patches/server/0161-Add-PlayerArmorChangeEvent.patch @@ -29,3 +29,125 @@ index 39c69fa6d164b1bcad97a9410953c8998e415d3c..b2dc7a83d475c0fcdaec8d1e11bf5bda if (map == null) { map = Maps.newEnumMap(EquipmentSlot.class); } +diff --git a/src/test/java/io/papermc/paper/inventory/item/ExtraArmorSlotTypeMaterialTest.java b/src/test/java/io/papermc/paper/inventory/item/ExtraArmorSlotTypeMaterialTest.java +new file mode 100644 +index 0000000000000000000000000000000000000000..36cde1a68b0fb388cca40399fcb4297b4d799262 +--- /dev/null ++++ b/src/test/java/io/papermc/paper/inventory/item/ExtraArmorSlotTypeMaterialTest.java +@@ -0,0 +1,53 @@ ++package io.papermc.paper.inventory.item; ++ ++import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent; ++import java.util.ArrayList; ++import java.util.List; ++import net.minecraft.world.entity.EquipmentSlot; ++import net.minecraft.world.item.Equipable; ++import net.minecraft.world.item.Item; ++import net.minecraft.world.item.ItemStack; ++import org.bukkit.Material; ++import org.bukkit.craftbukkit.util.CraftMagicNumbers; ++import org.bukkit.support.AbstractTestingBase; ++import org.junit.Test; ++import org.junit.runner.RunWith; ++import org.junit.runners.Parameterized; ++ ++import static org.junit.Assert.assertEquals; ++import static org.junit.Assert.assertNotNull; ++ ++@RunWith(Parameterized.class) ++public class ExtraArmorSlotTypeMaterialTest extends AbstractTestingBase { ++ ++ @Parameterized.Parameter(0) ++ public PlayerArmorChangeEvent.SlotType slotType; ++ ++ @Parameterized.Parameter(1) ++ public Material item; ++ ++ @Parameterized.Parameters(name = "{0}: {1}") ++ public static Iterable parameters() { ++ final List parameters = new ArrayList<>(); ++ for (final PlayerArmorChangeEvent.SlotType slotType : PlayerArmorChangeEvent.SlotType.values()) { ++ for (final Material item : slotType.getTypes()) { ++ parameters.add(new Object[]{ slotType, item }); ++ } ++ } ++ return parameters; ++ } ++ ++ @Test ++ public void test() { ++ final Item nmsItem = CraftMagicNumbers.getItem(this.item); ++ final Equipable equipable = Equipable.get(new ItemStack(nmsItem)); ++ assertNotNull(this.item + " isn't equipable", equipable); ++ final EquipmentSlot slot = switch (this.slotType) { ++ case HEAD -> EquipmentSlot.HEAD; ++ case CHEST -> EquipmentSlot.CHEST; ++ case LEGS -> EquipmentSlot.LEGS; ++ case FEET -> EquipmentSlot.FEET; ++ }; ++ assertEquals(this.item + " isn't set to the right slot", equipable.getEquipmentSlot(), slot); ++ } ++} +diff --git a/src/test/java/io/papermc/paper/inventory/item/MissingArmorSlotTypeMaterialTest.java b/src/test/java/io/papermc/paper/inventory/item/MissingArmorSlotTypeMaterialTest.java +new file mode 100644 +index 0000000000000000000000000000000000000000..f05cfe2e4a9f876a7e6425c612a56f86d5ac3915 +--- /dev/null ++++ b/src/test/java/io/papermc/paper/inventory/item/MissingArmorSlotTypeMaterialTest.java +@@ -0,0 +1,57 @@ ++package io.papermc.paper.inventory.item; ++ ++import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent; ++import java.util.ArrayList; ++import java.util.List; ++import net.minecraft.core.registries.BuiltInRegistries; ++import net.minecraft.world.entity.EquipmentSlot; ++import net.minecraft.world.item.Equipable; ++import net.minecraft.world.item.Item; ++import net.minecraft.world.item.ItemStack; ++import org.bukkit.craftbukkit.util.CraftMagicNumbers; ++import org.bukkit.support.AbstractTestingBase; ++import org.junit.Test; ++import org.junit.runner.RunWith; ++import org.junit.runners.Parameterized; ++ ++import static org.junit.Assert.assertTrue; ++ ++/** ++ * Test for {@link com.destroystokyo.paper.event.player.PlayerArmorChangeEvent.SlotType} ++ */ ++@RunWith(Parameterized.class) ++public class MissingArmorSlotTypeMaterialTest extends AbstractTestingBase { ++ ++ @Parameterized.Parameter(0) ++ public Equipable equipable; ++ ++ @Parameterized.Parameter(1) ++ public Item item; ++ ++ @Parameterized.Parameters(name = "{1}") ++ public static Iterable parameters() { ++ final List parameters = new ArrayList<>(); ++ for (final Item item : BuiltInRegistries.ITEM) { ++ final Equipable equipable = Equipable.get(new ItemStack(item)); ++ if (equipable != null) { ++ parameters.add(new Object[]{ equipable, item }); ++ } ++ } ++ return parameters; ++ } ++ ++ @Test ++ public void test() { ++ final EquipmentSlot equipmentSlot = this.equipable.getEquipmentSlot(); ++ PlayerArmorChangeEvent.SlotType slotType = switch (equipmentSlot) { ++ case HEAD -> PlayerArmorChangeEvent.SlotType.HEAD; ++ case CHEST -> PlayerArmorChangeEvent.SlotType.CHEST; ++ case LEGS -> PlayerArmorChangeEvent.SlotType.LEGS; ++ case FEET -> PlayerArmorChangeEvent.SlotType.FEET; ++ default -> null; ++ }; ++ if (slotType != null) { ++ assertTrue("SlotType " + slotType + " doesn't include " + this.item, slotType.getTypes().contains(CraftMagicNumbers.getMaterial(this.item))); ++ } ++ } ++}