From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Thu, 31 Aug 2023 17:32:48 +0200 Subject: [PATCH] Fix silent equipment change for mobs diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java index 66814adfb2cf92067702fc2695b083661cf859c0..bca70fff39409617e9c2b8ea66c1de4b9376d261 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java @@ -1153,19 +1153,26 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti @Override public void setItemSlot(EquipmentSlot slot, ItemStack stack) { + // Paper start - Fix silent equipment change + setItemSlot(slot, stack, false); + } + + @Override + public void setItemSlot(EquipmentSlot slot, ItemStack stack, boolean silent) { + // Paper end - Fix silent equipment change this.verifyEquippedItem(stack); switch (slot.getType()) { case HAND: - this.onEquipItem(slot, (ItemStack) this.handItems.set(slot.getIndex(), stack), stack); + this.onEquipItem(slot, (ItemStack) this.handItems.set(slot.getIndex(), stack), stack, silent); // Paper - Fix silent equipment change break; case ARMOR: - this.onEquipItem(slot, (ItemStack) this.armorItems.set(slot.getIndex(), stack), stack); + this.onEquipItem(slot, (ItemStack) this.armorItems.set(slot.getIndex(), stack), stack, silent); // Paper - Fix silent equipment change break; case BODY: ItemStack itemstack1 = this.bodyArmorItem; this.bodyArmorItem = stack; - this.onEquipItem(slot, itemstack1, stack); + this.onEquipItem(slot, itemstack1, stack, silent); // Paper - Fix silent equipment change } } diff --git a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java index 87ada535362303097862e811d3d573997983064f..0c5fe46d2da113beff3e220843593d616e37d4ca 100644 --- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java +++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java @@ -250,8 +250,8 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo // Paper end - shouldBurnInDay API @Override - public void setItemSlot(EquipmentSlot slot, ItemStack stack) { - super.setItemSlot(slot, stack); + public void setItemSlot(EquipmentSlot slot, ItemStack stack, boolean silent) { // Paper - Fix silent equipment change + super.setItemSlot(slot, stack, silent); // Paper - Fix silent equipment change if (!this.level().isClientSide) { this.reassessWeaponGoal(); } diff --git a/src/test/java/io/papermc/paper/entity/EntitySetItemSlotSilentOverrideTest.java b/src/test/java/io/papermc/paper/entity/EntitySetItemSlotSilentOverrideTest.java new file mode 100644 index 0000000000000000000000000000000000000000..81947843d1f2f7dc6f59d7b52f327d60b17d0dcc --- /dev/null +++ b/src/test/java/io/papermc/paper/entity/EntitySetItemSlotSilentOverrideTest.java @@ -0,0 +1,51 @@ +package io.papermc.paper.entity; + +import io.github.classgraph.ClassGraph; +import io.github.classgraph.ClassInfo; +import io.github.classgraph.MethodInfo; +import io.github.classgraph.MethodInfoList; +import io.github.classgraph.MethodParameterInfo; +import io.github.classgraph.ScanResult; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; +import org.bukkit.support.AbstractTestingBase; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.fail; + +public class EntitySetItemSlotSilentOverrideTest extends AbstractTestingBase { + + public static Stream parameters() { + final List classInfo = new ArrayList<>(); + try (ScanResult scanResult = new ClassGraph() + .enableClassInfo() + .enableMethodInfo() + .whitelistPackages("net.minecraft") + .scan() + ) { + for (final ClassInfo subclass : scanResult.getSubclasses("net.minecraft.world.entity.LivingEntity")) { + final MethodInfoList setItemSlot = subclass.getDeclaredMethodInfo("setItemSlot"); + if (!setItemSlot.isEmpty()) { + classInfo.add(subclass); + } + } + } + return classInfo.stream(); + } + + @ParameterizedTest + @MethodSource("parameters") + public void checkSetItemSlotSilentOverrides(ClassInfo overridesSetItemSlot) { + final MethodInfoList setItemSlot = overridesSetItemSlot.getDeclaredMethodInfo("setItemSlot"); + for (final MethodInfo methodInfo : setItemSlot) { + for (final MethodParameterInfo methodParameterInfo : methodInfo.getParameterInfo()) { + if ("boolean".equals(methodParameterInfo.getTypeDescriptor().toStringWithSimpleNames())) { + return; + } + } + } + fail(overridesSetItemSlot.getName() + " needs to override setItemSlot with the boolean silent parameter as well"); + } +}