From 79c595c0c33b2f0ea98c8d8219bbb3f298bc6504 Mon Sep 17 00:00:00 2001 From: DerFrZocker Date: Thu, 25 Apr 2024 21:06:52 +0200 Subject: [PATCH] SPIGOT-7637: Bad logic in checking nullability of AttributeModifier slots Also fix Class loading order issues, which resulted in EquipmentSlot#getGroup returning null, since EquipmentSlot and EquipmentSlotGroup referencing each other on class init. This caused EquipmentSlot to being init first, when the fields in EquipmentSlotGroup are still null, resulting in the group being null. --- .../bukkit/attribute/AttributeModifier.java | 5 +++-- .../org/bukkit/inventory/EquipmentSlot.java | 21 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/bukkit/attribute/AttributeModifier.java b/src/main/java/org/bukkit/attribute/AttributeModifier.java index 7dd6f3de..8ba00f74 100644 --- a/src/main/java/org/bukkit/attribute/AttributeModifier.java +++ b/src/main/java/org/bukkit/attribute/AttributeModifier.java @@ -28,7 +28,7 @@ public class AttributeModifier implements ConfigurationSerializable { } public AttributeModifier(@NotNull UUID uuid, @NotNull String name, double amount, @NotNull Operation operation) { - this(uuid, name, amount, operation, (EquipmentSlotGroup) null); + this(uuid, name, amount, operation, (EquipmentSlot) null); } public AttributeModifier(@NotNull UUID uuid, @NotNull String name, double amount, @NotNull Operation operation, @Nullable EquipmentSlot slot) { @@ -39,6 +39,7 @@ public class AttributeModifier implements ConfigurationSerializable { Preconditions.checkArgument(uuid != null, "UUID cannot be null"); Preconditions.checkArgument(name != null, "Name cannot be null"); Preconditions.checkArgument(operation != null, "Operation cannot be null"); + Preconditions.checkArgument(slot != null, "EquipmentSlotGroup cannot be null"); this.uuid = uuid; this.name = name; this.amount = amount; @@ -95,7 +96,7 @@ public class AttributeModifier implements ConfigurationSerializable { @Nullable @Deprecated public EquipmentSlot getSlot() { - return slot.getExample(); + return slot == EquipmentSlotGroup.ANY ? null : slot.getExample(); } /** diff --git a/src/main/java/org/bukkit/inventory/EquipmentSlot.java b/src/main/java/org/bukkit/inventory/EquipmentSlot.java index d776a0c1..5642d8af 100644 --- a/src/main/java/org/bukkit/inventory/EquipmentSlot.java +++ b/src/main/java/org/bukkit/inventory/EquipmentSlot.java @@ -1,24 +1,25 @@ package org.bukkit.inventory; +import java.util.function.Supplier; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; public enum EquipmentSlot { - HAND(EquipmentSlotGroup.MAINHAND), - OFF_HAND(EquipmentSlotGroup.OFFHAND), - FEET(EquipmentSlotGroup.FEET), - LEGS(EquipmentSlotGroup.LEGS), - CHEST(EquipmentSlotGroup.CHEST), - HEAD(EquipmentSlotGroup.HEAD), + HAND(() -> EquipmentSlotGroup.MAINHAND), + OFF_HAND(() -> EquipmentSlotGroup.OFFHAND), + FEET(() -> EquipmentSlotGroup.FEET), + LEGS(() -> EquipmentSlotGroup.LEGS), + CHEST(() -> EquipmentSlotGroup.CHEST), + HEAD(() -> EquipmentSlotGroup.HEAD), /** * Only for certain entities such as horses and wolves. */ - BODY(EquipmentSlotGroup.ARMOR); + BODY(() -> EquipmentSlotGroup.ARMOR); - private final EquipmentSlotGroup group; + private final Supplier group; // Supplier because of class loading order, since EquipmentSlot and EquipmentSlotGroup reference each other on class init - private EquipmentSlot(/*@NotNull*/ EquipmentSlotGroup group) { + private EquipmentSlot(/*@NotNull*/ Supplier group) { this.group = group; } @@ -30,6 +31,6 @@ public enum EquipmentSlot { @NotNull @ApiStatus.Internal public EquipmentSlotGroup getGroup() { - return group; + return group.get(); } }