From f1e1782d9581e843c5f8695fbef7a3394decbbbd Mon Sep 17 00:00:00 2001 From: Burbulinis Date: Sat, 25 Jan 2025 13:29:25 +0200 Subject: [PATCH 1/5] Init Commit --- .../njol/skript/conditions/CondIsWearing.java | 1 + ...issingCheckIfEntityCanUseSlot7524Test.java | 65 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 src/test/java/org/skriptlang/skript/test/tests/regression/MissingCheckIfEntityCanUseSlot7524Test.java diff --git a/src/main/java/ch/njol/skript/conditions/CondIsWearing.java b/src/main/java/ch/njol/skript/conditions/CondIsWearing.java index ece4ba03a29..8010b28de30 100644 --- a/src/main/java/ch/njol/skript/conditions/CondIsWearing.java +++ b/src/main/java/ch/njol/skript/conditions/CondIsWearing.java @@ -59,6 +59,7 @@ public boolean check(Event event) { return false; // spigot nullability, no identifier as to why this occurs ItemStack[] contents = Arrays.stream(EquipmentSlot.values()) + .filter(entity::canUseEquipmentSlot) .map(equipment::getItem) .toArray(ItemStack[]::new); diff --git a/src/test/java/org/skriptlang/skript/test/tests/regression/MissingCheckIfEntityCanUseSlot7524Test.java b/src/test/java/org/skriptlang/skript/test/tests/regression/MissingCheckIfEntityCanUseSlot7524Test.java new file mode 100644 index 00000000000..84ba838ddc7 --- /dev/null +++ b/src/test/java/org/skriptlang/skript/test/tests/regression/MissingCheckIfEntityCanUseSlot7524Test.java @@ -0,0 +1,65 @@ +package org.skriptlang.skript.test.tests.regression; + +import ch.njol.skript.lang.Condition; +import ch.njol.skript.lang.util.ContextlessEvent; +import ch.njol.skript.test.runner.SkriptJUnitTest; +import ch.njol.skript.variables.Variables; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class MissingCheckIfEntityCanUseSlot7524Test extends SkriptJUnitTest { + + private Player player; + private EntityEquipment equipment; + private Condition isWearingCondition; + + @Before + public void setup() { + player = EasyMock.niceMock(Player.class); + equipment = EasyMock.niceMock(EntityEquipment.class); + + isWearingCondition = Condition.parse("{_player} is wearing diamond chestplate", null); + if (isWearingCondition == null) + throw new IllegalStateException(); + } + + @Test + public void test() { + ContextlessEvent event = ContextlessEvent.get(); + Variables.setVariable("player", player, event, true); + + EasyMock.expect(player.isValid()).andStubReturn(true); + EasyMock.expect(player.getEquipment()).andReturn(equipment); + + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.CHEST)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.LEGS)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.FEET)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.HEAD)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.HAND)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.OFF_HAND)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.BODY)).andReturn(false); + + EasyMock.expect(equipment.getItem(EquipmentSlot.CHEST)).andReturn(new ItemStack(Material.DIAMOND_CHESTPLATE)); + EasyMock.expect(equipment.getItem(EquipmentSlot.LEGS)).andReturn(new ItemStack(Material.DIAMOND_LEGGINGS)); + EasyMock.expect(equipment.getItem(EquipmentSlot.FEET)).andReturn(new ItemStack(Material.DIAMOND_BOOTS)); + EasyMock.expect(equipment.getItem(EquipmentSlot.HEAD)).andReturn(new ItemStack(Material.DIAMOND_HELMET)); + EasyMock.expect(equipment.getItem(EquipmentSlot.HAND)).andReturn(new ItemStack(Material.DIAMOND_SWORD)); + EasyMock.expect(equipment.getItem(EquipmentSlot.OFF_HAND)).andReturn(new ItemStack(Material.DIAMOND_SHOVEL)); + + EasyMock.replay(player, equipment); + + isWearingCondition.run(event); + + EasyMock.verify(player, equipment); + + Assert.assertTrue(isWearingCondition.evaluate(event).isTrue()); + } + +} From 5af9fdc9bdda69a0177a5fe522280f3ef7298e5e Mon Sep 17 00:00:00 2001 From: Burbulinis Date: Sat, 25 Jan 2025 14:02:01 +0200 Subject: [PATCH 2/5] Fix JUnit test and don't use the #canUseEquipmentSlot method if it does not exist --- .../njol/skript/conditions/CondIsWearing.java | 16 +++++++++- ...issingCheckIfEntityCanUseSlot7524Test.java | 29 +++++++++---------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/main/java/ch/njol/skript/conditions/CondIsWearing.java b/src/main/java/ch/njol/skript/conditions/CondIsWearing.java index 8010b28de30..0c52be5b885 100644 --- a/src/main/java/ch/njol/skript/conditions/CondIsWearing.java +++ b/src/main/java/ch/njol/skript/conditions/CondIsWearing.java @@ -1,5 +1,6 @@ package ch.njol.skript.conditions; +import ch.njol.skript.Skript; import ch.njol.skript.aliases.ItemType; import ch.njol.skript.conditions.base.PropertyCondition; import ch.njol.skript.conditions.base.PropertyCondition.PropertyType; @@ -12,7 +13,9 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.util.Kleenean; +import org.bukkit.entity.Donkey; import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Mule; import org.bukkit.event.Event; import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.EquipmentSlot; @@ -30,6 +33,8 @@ }) @Since("1.0") public class CondIsWearing extends Condition { + + private static final boolean HAS_CAN_USE_SLOT_METHOD = Skript.methodExists(LivingEntity.class, "canUseEquipmentSlot", EquipmentSlot.class); static { PropertyCondition.register(CondIsWearing.class, "wearing %itemtypes%", "livingentities"); @@ -59,7 +64,16 @@ public boolean check(Event event) { return false; // spigot nullability, no identifier as to why this occurs ItemStack[] contents = Arrays.stream(EquipmentSlot.values()) - .filter(entity::canUseEquipmentSlot) + .filter(slot -> { + if (HAS_CAN_USE_SLOT_METHOD) + return entity.canUseEquipmentSlot(slot); + + // according to wiki it appears to be that these are the only ones with a body equipment slot + if (slot == EquipmentSlot.BODY) + return entity instanceof Donkey || entity instanceof Mule; + + return false; + }) .map(equipment::getItem) .toArray(ItemStack[]::new); diff --git a/src/test/java/org/skriptlang/skript/test/tests/regression/MissingCheckIfEntityCanUseSlot7524Test.java b/src/test/java/org/skriptlang/skript/test/tests/regression/MissingCheckIfEntityCanUseSlot7524Test.java index 84ba838ddc7..f0f4af67864 100644 --- a/src/test/java/org/skriptlang/skript/test/tests/regression/MissingCheckIfEntityCanUseSlot7524Test.java +++ b/src/test/java/org/skriptlang/skript/test/tests/regression/MissingCheckIfEntityCanUseSlot7524Test.java @@ -1,10 +1,12 @@ package org.skriptlang.skript.test.tests.regression; +import ch.njol.skript.Skript; import ch.njol.skript.lang.Condition; import ch.njol.skript.lang.util.ContextlessEvent; import ch.njol.skript.test.runner.SkriptJUnitTest; import ch.njol.skript.variables.Variables; import org.bukkit.Material; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.EquipmentSlot; @@ -16,6 +18,8 @@ public class MissingCheckIfEntityCanUseSlot7524Test extends SkriptJUnitTest { + private static final boolean HAS_CAN_USE_SLOT_METHOD = Skript.methodExists(LivingEntity.class, "canUseEquipmentSlot", EquipmentSlot.class); + private Player player; private EntityEquipment equipment; private Condition isWearingCondition; @@ -38,28 +42,23 @@ public void test() { EasyMock.expect(player.isValid()).andStubReturn(true); EasyMock.expect(player.getEquipment()).andReturn(equipment); - EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.CHEST)).andReturn(true); - EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.LEGS)).andReturn(true); - EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.FEET)).andReturn(true); - EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.HEAD)).andReturn(true); - EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.HAND)).andReturn(true); - EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.OFF_HAND)).andReturn(true); - EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.BODY)).andReturn(false); + if (HAS_CAN_USE_SLOT_METHOD) { + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.CHEST)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.LEGS)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.FEET)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.HEAD)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.HAND)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.OFF_HAND)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.BODY)).andReturn(false); + } EasyMock.expect(equipment.getItem(EquipmentSlot.CHEST)).andReturn(new ItemStack(Material.DIAMOND_CHESTPLATE)); - EasyMock.expect(equipment.getItem(EquipmentSlot.LEGS)).andReturn(new ItemStack(Material.DIAMOND_LEGGINGS)); - EasyMock.expect(equipment.getItem(EquipmentSlot.FEET)).andReturn(new ItemStack(Material.DIAMOND_BOOTS)); - EasyMock.expect(equipment.getItem(EquipmentSlot.HEAD)).andReturn(new ItemStack(Material.DIAMOND_HELMET)); - EasyMock.expect(equipment.getItem(EquipmentSlot.HAND)).andReturn(new ItemStack(Material.DIAMOND_SWORD)); - EasyMock.expect(equipment.getItem(EquipmentSlot.OFF_HAND)).andReturn(new ItemStack(Material.DIAMOND_SHOVEL)); EasyMock.replay(player, equipment); - isWearingCondition.run(event); + assert isWearingCondition.check(event); EasyMock.verify(player, equipment); - - Assert.assertTrue(isWearingCondition.evaluate(event).isTrue()); } } From c2191ec1faa4c80f98b882e6c8a10ea7bab25458 Mon Sep 17 00:00:00 2001 From: Burbulinis Date: Sat, 25 Jan 2025 14:13:06 +0200 Subject: [PATCH 3/5] Fix using Body EquipmentSlot because it was added in 1.20.5 --- .../java/ch/njol/skript/conditions/CondIsWearing.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/njol/skript/conditions/CondIsWearing.java b/src/main/java/ch/njol/skript/conditions/CondIsWearing.java index 0c52be5b885..911bb544bf5 100644 --- a/src/main/java/ch/njol/skript/conditions/CondIsWearing.java +++ b/src/main/java/ch/njol/skript/conditions/CondIsWearing.java @@ -35,6 +35,7 @@ public class CondIsWearing extends Condition { private static final boolean HAS_CAN_USE_SLOT_METHOD = Skript.methodExists(LivingEntity.class, "canUseEquipmentSlot", EquipmentSlot.class); + private static final boolean HAS_BODY_SLOT = Skript.fieldExists(EquipmentSlot.class, "BODY"); static { PropertyCondition.register(CondIsWearing.class, "wearing %itemtypes%", "livingentities"); @@ -56,6 +57,7 @@ public boolean init(Expression[] vars, int matchedPattern, Kleenean isDelayed @Override public boolean check(Event event) { + Skript.info(HAS_BODY_SLOT ? "Has body slot" : "Does not have body slot"); ItemType[] cachedTypes = types.getAll(event); return entities.check(event, entity -> { @@ -65,14 +67,16 @@ public boolean check(Event event) { ItemStack[] contents = Arrays.stream(EquipmentSlot.values()) .filter(slot -> { + // this method was added in 1.20.6 if (HAS_CAN_USE_SLOT_METHOD) return entity.canUseEquipmentSlot(slot); // according to wiki it appears to be that these are the only ones with a body equipment slot - if (slot == EquipmentSlot.BODY) + // body slot was added in 1.20.5 + if (HAS_BODY_SLOT && slot == EquipmentSlot.BODY) return entity instanceof Donkey || entity instanceof Mule; - return false; + return true; }) .map(equipment::getItem) .toArray(ItemStack[]::new); From 0e0b6151b4215f53cfe4c65196415c1e8ee49c4d Mon Sep 17 00:00:00 2001 From: Burbulinis Date: Sat, 25 Jan 2025 14:16:39 +0200 Subject: [PATCH 4/5] Remove info message, oops... --- src/main/java/ch/njol/skript/conditions/CondIsWearing.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/conditions/CondIsWearing.java b/src/main/java/ch/njol/skript/conditions/CondIsWearing.java index 911bb544bf5..022393b6cef 100644 --- a/src/main/java/ch/njol/skript/conditions/CondIsWearing.java +++ b/src/main/java/ch/njol/skript/conditions/CondIsWearing.java @@ -57,7 +57,6 @@ public boolean init(Expression[] vars, int matchedPattern, Kleenean isDelayed @Override public boolean check(Event event) { - Skript.info(HAS_BODY_SLOT ? "Has body slot" : "Does not have body slot"); ItemType[] cachedTypes = types.getAll(event); return entities.check(event, entity -> { From d0c0461d9bf7aca756197dc2a9ce62016b165381 Mon Sep 17 00:00:00 2001 From: Burbulinis Date: Sat, 25 Jan 2025 23:37:04 +0200 Subject: [PATCH 5/5] Replace the instance checks with actual entities that use the body slot --- .../java/ch/njol/skript/conditions/CondIsWearing.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/ch/njol/skript/conditions/CondIsWearing.java b/src/main/java/ch/njol/skript/conditions/CondIsWearing.java index 022393b6cef..3b48d4eec2d 100644 --- a/src/main/java/ch/njol/skript/conditions/CondIsWearing.java +++ b/src/main/java/ch/njol/skript/conditions/CondIsWearing.java @@ -13,9 +13,7 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.util.Kleenean; -import org.bukkit.entity.Donkey; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Mule; +import org.bukkit.entity.*; import org.bukkit.event.Event; import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.EquipmentSlot; @@ -70,10 +68,13 @@ public boolean check(Event event) { if (HAS_CAN_USE_SLOT_METHOD) return entity.canUseEquipmentSlot(slot); - // according to wiki it appears to be that these are the only ones with a body equipment slot // body slot was added in 1.20.5 if (HAS_BODY_SLOT && slot == EquipmentSlot.BODY) - return entity instanceof Donkey || entity instanceof Mule; + // this may change in the future, but for now this is the only way to figure out + // if the entity can use the body slot + return entity instanceof Horse + || entity instanceof Wolf + || entity instanceof Llama; return true; })