aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0977-Fix-equipment-slot-and-group-API.patch
blob: eaaf981851e1e86623d206b03dd101c9d365aca8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 22 May 2024 10:01:19 -0700
Subject: [PATCH] Fix equipment slot and group API

Add test for EquipmentSlotGroup

diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java
index 9d74577af071954e1e37201a96368c1360076209..eafa54c870c3e2aef30c3f9f96f516607a7cae24 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java
@@ -135,6 +135,10 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i
             case HEAD:
                 this.setHelmet(item);
                 break;
+                // Paper start
+            case BODY:
+                throw new IllegalArgumentException("BODY is not valid for players!");
+                // Paper end
             default:
                 throw new IllegalArgumentException("Not implemented. This is a bug");
         }
@@ -162,6 +166,10 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i
                 return java.util.Objects.requireNonNullElseGet(this.getChestplate(), () -> new ItemStack(org.bukkit.Material.AIR)); // Paper - make nonnull
             case HEAD:
                 return java.util.Objects.requireNonNullElseGet(this.getHelmet(), () -> new ItemStack(org.bukkit.Material.AIR)); // Paper - make nonnull
+                // Paper start
+            case BODY:
+                throw new IllegalArgumentException("BODY is not valid for players!");
+                // Paper end
             default:
                 throw new IllegalArgumentException("Not implemented. This is a bug");
         }
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
index 31972619256c09bce46312b55153ddaef11cb236..bcd108cf3a4d10e6bf2058f84c7aa591addd5ced 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
@@ -1405,7 +1405,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
         if (this.attributeModifiers == null) return LinkedHashMultimap.create(); // Paper - don't change the components
         SetMultimap<Attribute, AttributeModifier> result = LinkedHashMultimap.create();
         for (Map.Entry<Attribute, AttributeModifier> entry : this.attributeModifiers.entries()) {
-            if (entry.getValue().getSlot() == null || entry.getValue().getSlot() == slot) {
+            if (entry.getValue().getSlotGroup().test(slot)) { // Paper - correctly test slot against group
                 result.put(entry.getKey(), entry.getValue());
             }
         }
@@ -1473,9 +1473,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
 
         while (iter.hasNext()) {
             Map.Entry<Attribute, AttributeModifier> entry = iter.next();
-            // Explicitly match against null because (as of MC 1.13) AttributeModifiers without a -
-            // set slot are active in any slot.
-            if (entry.getValue().getSlot() == null || entry.getValue().getSlot() == slot) {
+            if (entry.getValue().getSlotGroup().test(slot)) { // Paper - correctly test slot against group
                 iter.remove();
                 ++removed;
             }
diff --git a/src/test/java/io/papermc/paper/inventory/item/EquipmentSlotGroupTest.java b/src/test/java/io/papermc/paper/inventory/item/EquipmentSlotGroupTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ee0bfe4edb134d7ea3a3b97f5102a7f3122c3b99
--- /dev/null
+++ b/src/test/java/io/papermc/paper/inventory/item/EquipmentSlotGroupTest.java
@@ -0,0 +1,51 @@
+package io.papermc.paper.inventory.item;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+import net.minecraft.world.entity.EquipmentSlot;
+import org.bukkit.craftbukkit.CraftEquipmentSlot;
+import org.bukkit.inventory.EquipmentSlotGroup;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class EquipmentSlotGroupTest {
+
+    static List<EquipmentSlotGroup> apiValues() throws ReflectiveOperationException {
+        final List<EquipmentSlotGroup> apiValues = new ArrayList<>();
+        for (final Field field : EquipmentSlotGroup.class.getDeclaredFields()) {
+            if (!Modifier.isStatic(field.getModifiers()) || !Modifier.isFinal(field.getModifiers()) || !field.getType().equals(EquipmentSlotGroup.class)) {
+                continue;
+            }
+            apiValues.add((EquipmentSlotGroup) field.get(null));
+        }
+        if (apiValues.isEmpty()) {
+            throw new RuntimeException("Didn't find any api " + EquipmentSlotGroup.class.getSimpleName());
+        }
+        return apiValues;
+    }
+
+    @ParameterizedTest
+    @MethodSource("apiValues")
+    void testBukkitToNms(final EquipmentSlotGroup slotGroup) {
+        final net.minecraft.world.entity.EquipmentSlotGroup nmsGroup = CraftEquipmentSlot.getNMSGroup(slotGroup);
+        assertNotNull(nmsGroup, "No nms slot group found for " + slotGroup);
+        assertEquals(nmsGroup.getSerializedName(), slotGroup.toString(), "slot group name mismatch");
+        for (final EquipmentSlot slot : EquipmentSlot.values()) {
+            assertEquals(nmsGroup.test(slot), slotGroup.test(CraftEquipmentSlot.getSlot(slot)));
+        }
+    }
+
+    @ParameterizedTest
+    @EnumSource(net.minecraft.world.entity.EquipmentSlotGroup.class)
+    void testNmsToBukkit(final net.minecraft.world.entity.EquipmentSlotGroup slotGroup) {
+        final EquipmentSlotGroup apiGroup = CraftEquipmentSlot.getSlot(slotGroup);
+        assertNotNull(apiGroup, "No api slot group found for " + slotGroup);
+        assertEquals(apiGroup.toString(), slotGroup.getSerializedName(), "slot group name mismatch");
+    }
+}