From 4d585e05876eba9ad7c624684931799e27be2747 Mon Sep 17 00:00:00 2001
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
Date: Sun, 17 Sep 2023 01:27:11 +0200
Subject: [PATCH] Fix silent equipment change for mobs (#9677)

* Fix silent equipment change for mobs

* rebased and added test to make sure all overrides are added

---------

Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
---
 ...Fix-silent-equipment-change-for-mobs.patch | 109 ++++++++++++++++++
 1 file changed, 109 insertions(+)
 create mode 100644 patches/server/Fix-silent-equipment-change-for-mobs.patch

diff --git a/patches/server/Fix-silent-equipment-change-for-mobs.patch b/patches/server/Fix-silent-equipment-change-for-mobs.patch
new file mode 100644
index 0000000000..a62cd59bab
--- /dev/null
+++ b/patches/server/Fix-silent-equipment-change-for-mobs.patch
@@ -0,0 +1,109 @@
+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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/world/entity/Mob.java
++++ b/src/main/java/net/minecraft/world/entity/Mob.java
+@@ -0,0 +0,0 @@ public abstract class Mob extends LivingEntity implements Targeting {
+ 
+     @Override
+     public void setItemSlot(EquipmentSlot slot, ItemStack stack) {
++        // Paper start
++        setItemSlot(slot, stack, false);
++    }
++
++    @Override
++    public void setItemSlot(EquipmentSlot slot, ItemStack stack, boolean silent) {
++        // Paper end
+         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
+                 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
+         }
+ 
+     }
+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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
++++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
+@@ -0,0 +0,0 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
+     // Paper end
+ 
+     @Override
+-    public void setItemSlot(EquipmentSlot slot, ItemStack stack) {
+-        super.setItemSlot(slot, stack);
++    public void setItemSlot(EquipmentSlot slot, ItemStack stack, boolean silent) { // Paper
++        super.setItemSlot(slot, stack, silent); // Paper
+         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..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/test/java/io/papermc/paper/entity/EntitySetItemSlotSilentOverrideTest.java
+@@ -0,0 +0,0 @@
++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 org.bukkit.support.AbstractTestingBase;
++import org.junit.Test;
++import org.junit.runner.RunWith;
++import org.junit.runners.Parameterized;
++
++import static org.junit.Assert.fail;
++
++@RunWith(Parameterized.class)
++public class EntitySetItemSlotSilentOverrideTest extends AbstractTestingBase {
++
++    @Parameterized.Parameter
++    public ClassInfo overridesSetItemSlot;
++
++    @Parameterized.Parameters(name = "{0}")
++    public static Iterable<ClassInfo> parameters() {
++        final List<ClassInfo> 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;
++    }
++
++    @Test
++    public void checkSetItemSlotSilentOverrides() {
++        final MethodInfoList setItemSlot = this.overridesSetItemSlot.getDeclaredMethodInfo("setItemSlot");
++        for (final MethodInfo methodInfo : setItemSlot) {
++            for (final MethodParameterInfo methodParameterInfo : methodInfo.getParameterInfo()) {
++                if ("boolean".equals(methodParameterInfo.getTypeDescriptor().toStringWithSimpleNames())) {
++                    return;
++                }
++            }
++        }
++        fail(this.overridesSetItemSlot.getName() + " needs to override setItemSlot with the boolean silent parameter as well");
++    }
++}