2024-05-23 19:39:44 +02:00
|
|
|
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
|
|
|
|
|
2024-06-23 22:11:39 +02:00
|
|
|
Adds the following:
|
|
|
|
- Add test for EquipmentSlotGroup
|
|
|
|
- Expose LivingEntity#canUseSlot
|
2024-05-23 19:39:44 +02:00
|
|
|
|
2024-06-23 22:11:39 +02:00
|
|
|
Co-authored-by: SoSeDiK <mrsosedik@gmail.com>
|
|
|
|
|
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
2024-09-21 21:19:02 +02:00
|
|
|
index 0398ba2cac2b69111ce7c5f9e5680119dd27c6cf..7e280955067169f63f15162e9cad1e86e824a8e5 100644
|
2024-06-23 22:11:39 +02:00
|
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
|
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
2024-09-21 21:19:02 +02:00
|
|
|
@@ -1211,4 +1211,11 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
2024-06-23 22:11:39 +02:00
|
|
|
this.getHandle().setYBodyRot(bodyYaw);
|
|
|
|
}
|
|
|
|
// Paper end - body yaw API
|
|
|
|
+
|
|
|
|
+ // Paper start - Expose canUseSlot
|
|
|
|
+ @Override
|
|
|
|
+ public boolean canUseEquipmentSlot(org.bukkit.inventory.EquipmentSlot slot) {
|
|
|
|
+ return this.getHandle().canUseSlot(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot));
|
|
|
|
+ }
|
|
|
|
+ // Paper end - Expose canUseSlot
|
|
|
|
}
|
2024-05-29 20:23:51 +02:00
|
|
|
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");
|
|
|
|
}
|
2024-05-23 19:39:44 +02:00
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
2024-09-15 21:39:53 +02:00
|
|
|
index beeed762e5ba49c317c5f214af17c44174b0c943..042bfdd14c9ff4cc8ed3421f73565f0f03b11bcb 100644
|
2024-05-23 19:39:44 +02:00
|
|
|
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
|
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
2024-08-09 22:05:50 +02:00
|
|
|
@@ -1448,7 +1448,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
2024-05-26 00:58:56 +02:00
|
|
|
if (this.attributeModifiers == null) return LinkedHashMultimap.create(); // Paper - don't change the components
|
2024-05-23 19:39:44 +02:00
|
|
|
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());
|
|
|
|
}
|
|
|
|
}
|
2024-08-09 22:05:50 +02:00
|
|
|
@@ -1522,9 +1522,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
2024-05-23 19:39:44 +02:00
|
|
|
|
|
|
|
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");
|
|
|
|
+ }
|
|
|
|
+}
|