Files
Purpur/patches/server/0220-Fix-advancement-triggers-on-entity-death.patch
Ben Kerllenevich 72895cb7b4 Updated Upstream (Paper & Tuinity)
Upstream has released updates that appear to apply and compile correctly

Paper Changes:
0daded2f2 Add more line of sight methods (#5749)
8fd4e70db Improve seed based feature search to not load chunk (#5760)
7ad8498c3 Make item validations configurable (#5775)
3673d6758 Fix Cannot be adventure component serialized when the legacy component is null (#5754)
afb0748a2 [Auto] Updated Upstream (Bukkit)
7d751ad8d Fix dangerous end portal logic (#5776)
12716324d Do not tick Chunk TickS for every chunk
af1a50993 [Auto] Updated Upstream (CraftBukkit)

Tuinity Changes:
2683c775c Use area map for nearby players in mob spawning (#283)
2021-06-05 07:18:48 -04:00

210 lines
9.4 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: BillyGalbreath <blake.galbreath@gmail.com>
Date: Fri, 28 May 2021 12:24:45 -0500
Subject: [PATCH] Fix advancement triggers on entity death
This fixes PaperMC/Paper#3729 and PaperMC/Paper#4252
Paper changes logical order revolving around making the EntityDeathEvent
cancellable. Reordering this logic has ended up with entity equipment being
cleared _before_ advancement criteria can run, causing things like killing
raid captains not giving the voluntary exile advancement.
This fixes the issue by storing a copy of the equipment in a new field just
before doing the death event logic where the equipment is cleared and then
restoring it back to the entity just before the criterion triggers run and
then finally clearing the equipment again right after the criterion is done.
diff --git a/src/main/java/net/minecraft/world/entity/EntityInsentient.java b/src/main/java/net/minecraft/world/entity/EntityInsentient.java
index d96630a64f132eecf5cb4c80302cf9dd6176ad7c..b4afd71340a0c7e1b6aa2e3f01a6a4fc998f3f16 100644
--- a/src/main/java/net/minecraft/world/entity/EntityInsentient.java
+++ b/src/main/java/net/minecraft/world/entity/EntityInsentient.java
@@ -106,9 +106,9 @@ public abstract class EntityInsentient extends EntityLiving {
public PathfinderGoalSelector targetSelector;
private EntityLiving goalTarget;
private final EntitySenses bo;
- private final NonNullList<ItemStack> bp;
+ private final NonNullList<ItemStack> bp; public List<ItemStack> getHandEquipment() { return this.bp; } // Purpur - OBFHELPER
public final float[] dropChanceHand;
- private final NonNullList<ItemStack> bq;
+ private final NonNullList<ItemStack> bq; public List<ItemStack> getArmorEquipment() { return this.bq; } // Purpur - OBFHELPER
public final float[] dropChanceArmor;
// private boolean canPickUpLoot; // CraftBukkit - moved up to EntityLiving
public boolean persistent;
@@ -1004,6 +1004,41 @@ public abstract class EntityInsentient extends EntityLiving {
}
}
+ // Purpur start
+ public List<List<ItemStack>> cloneEquipment() {
+ List<List<ItemStack>> list = new java.util.ArrayList<>();
+ List<ItemStack> handItems = new java.util.ArrayList<>();
+ for (ItemStack item : this.getHandEquipment()) {
+ handItems.add(item.cloneItemStack());
+ }
+ list.add(handItems);
+ List<ItemStack> armorItems = new java.util.ArrayList<>();
+ for (ItemStack item : this.getArmorEquipment()) {
+ armorItems.add(item.cloneItemStack());
+ }
+ list.add(armorItems);
+ return list;
+ }
+
+ public void restoreEquipment(List<List<ItemStack>> list) {
+ this.getHandEquipment().clear();
+ List<ItemStack> handItems = list.get(0);
+ for (int i = 0; i < handItems.size(); i++) {
+ this.getHandEquipment().set(i, handItems.get(1));
+ }
+ this.getArmorEquipment().clear();
+ List<ItemStack> armorItems = list.get(1);
+ for (int i = 0; i < armorItems.size(); i++) {
+ this.getArmorEquipment().set(i, armorItems.get(i));
+ }
+ }
+
+ public void clearEquipment() {
+ this.getHandEquipment().clear();
+ this.getArmorEquipment().clear();
+ }
+ // Purpur end
+
@Override
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
switch (enumitemslot.a()) {
diff --git a/src/main/java/net/minecraft/world/entity/EntityLiving.java b/src/main/java/net/minecraft/world/entity/EntityLiving.java
index 0eaa7facd7a9348d90721a64427c7fdfb59bf8ea..158388410ea14b2df95635914844952bd52b8f87 100644
--- a/src/main/java/net/minecraft/world/entity/EntityLiving.java
+++ b/src/main/java/net/minecraft/world/entity/EntityLiving.java
@@ -1557,10 +1557,13 @@ public abstract class EntityLiving extends Entity {
}
// Paper start
+ List<List<ItemStack>> equipmentSnapshotBefore = this.cloneEquipment(); // Purpur
org.bukkit.event.entity.EntityDeathEvent deathEvent = this.d(damagesource);
if (deathEvent == null || !deathEvent.isCancelled()) {
if (this.getKillCount() >= 0 && entityliving != null) {
+ this.restoreEquipment(equipmentSnapshotBefore); // Purpur
entityliving.runKillTrigger(this, this.getKillCount(), damagesource);
+ this.clearEquipment(); // Purpur
}
if (this.isSleeping()) {
this.entityWakeup();
@@ -2258,6 +2261,12 @@ public abstract class EntityLiving extends Entity {
public abstract ItemStack getEquipment(EnumItemSlot enumitemslot);
+ // Purpur start
+ public abstract List<List<ItemStack>> cloneEquipment();
+ public abstract void restoreEquipment(List<List<ItemStack>> list);
+ public abstract void clearEquipment();
+ // Purpur end
+
// CraftBukkit start
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack, boolean silent) {
this.setSlot(enumitemslot, itemstack);
diff --git a/src/main/java/net/minecraft/world/entity/decoration/EntityArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/EntityArmorStand.java
index ddc1c3383cdc32fa832485f3922c74185731557a..e28a2d983ae7b83f435c9dea606a92e2fbd3391a 100644
--- a/src/main/java/net/minecraft/world/entity/decoration/EntityArmorStand.java
+++ b/src/main/java/net/minecraft/world/entity/decoration/EntityArmorStand.java
@@ -171,6 +171,41 @@ public class EntityArmorStand extends EntityLiving {
}
}
+ // Purpur start
+ public List<List<ItemStack>> cloneEquipment() {
+ List<List<ItemStack>> list = new java.util.ArrayList<>();
+ List<ItemStack> handItems = new java.util.ArrayList<>();
+ for (ItemStack item : this.handItems) {
+ handItems.add(item.cloneItemStack());
+ }
+ list.add(handItems);
+ List<ItemStack> armorItems = new java.util.ArrayList<>();
+ for (ItemStack item : this.armorItems) {
+ armorItems.add(item.cloneItemStack());
+ }
+ list.add(armorItems);
+ return list;
+ }
+
+ public void restoreEquipment(List<List<ItemStack>> list) {
+ this.handItems.clear();
+ List<ItemStack> handItems = list.get(0);
+ for (int i = 0; i < handItems.size(); i++) {
+ this.handItems.set(i, handItems.get(1));
+ }
+ this.armorItems.clear();
+ List<ItemStack> armorItems = list.get(1);
+ for (int i = 0; i < armorItems.size(); i++) {
+ this.armorItems.set(i, armorItems.get(1));
+ }
+ }
+
+ public void clearEquipment() {
+ this.handItems.clear();
+ this.armorItems.clear();
+ }
+ // Purpur end
+
@Override
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
// CraftBukkit start
diff --git a/src/main/java/net/minecraft/world/entity/player/EntityHuman.java b/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
index 24285b1b2264939fdfa6f7d6311772fa67be8680..383b4cacc8c9f4fd5d2a83f683e5174ea5025f61 100644
--- a/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
+++ b/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
@@ -1886,6 +1886,52 @@ public abstract class EntityHuman extends EntityLiving {
return enumitemslot == EnumItemSlot.MAINHAND ? this.inventory.getItemInHand() : (enumitemslot == EnumItemSlot.OFFHAND ? (ItemStack) this.inventory.extraSlots.get(0) : (enumitemslot.a() == EnumItemSlot.Function.ARMOR ? (ItemStack) this.inventory.armor.get(enumitemslot.b()) : ItemStack.b));
}
+ // Purpur start
+ public List<List<ItemStack>> cloneEquipment() {
+ List<List<ItemStack>> list = new java.util.ArrayList<>();
+ List<ItemStack> invItems = new java.util.ArrayList<>();
+ for (ItemStack item : this.inventory.items) {
+ invItems.add(item.cloneItemStack());
+ }
+ list.add(invItems);
+ List<ItemStack> armorItems = new java.util.ArrayList<>();
+ for (ItemStack item : this.inventory.armor) {
+ armorItems.add(item.cloneItemStack());
+ }
+ list.add(armorItems);
+ List<ItemStack> extraItems = new java.util.ArrayList<>();
+ for (ItemStack item : this.inventory.extraSlots) {
+ extraItems.add(item.cloneItemStack());
+ }
+ list.add(extraItems);
+ return list;
+ }
+
+ public void restoreEquipment(List<List<ItemStack>> list) {
+ this.inventory.items.clear();
+ List<ItemStack> invItems = list.get(0);
+ for (int i = 0; i < invItems.size(); i++) {
+ this.inventory.items.set(i, invItems.get(1));
+ }
+ this.inventory.armor.clear();
+ List<ItemStack> armorItems = list.get(1);
+ for (int i = 0; i < armorItems.size(); i++) {
+ this.inventory.armor.set(i, armorItems.get(1));
+ }
+ this.inventory.extraSlots.clear();
+ List<ItemStack> extraItems = list.get(2);
+ for (int i = 0; i < extraItems.size(); i++) {
+ this.inventory.extraSlots.set(i, extraItems.get(1));
+ }
+ }
+
+ public void clearEquipment() {
+ this.inventory.items.clear();
+ this.inventory.armor.clear();
+ this.inventory.extraSlots.clear();
+ }
+ // Purpur end
+
@Override
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
// CraftBukkit start