Paper/Spigot-Server-Patches/0374-PlayerDeathEvent-getItemsToKeep.patch
Shane Freeder 0708fa363b
Updated Upstream (CraftBukkit/Spigot)
Upstream has released updates that appears to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

CraftBukkit Changes:
eb2e6578 SPIGOT-5116: Fix concurrent modification exception inside ChunkMapDistance
989f9b3d SPIGOT-4849: Fix server crash when accessing chunks during chunk load/unload/populate events
f554183c SPIGOT-5171: Don't fire PlayerTeleportEvent if not actually moving
2349feb8 SPIGOT-5163: Cancelling PlayerBucketFillEvent visually removes the targeted block

Spigot Changes:
9a643a6a Remove DataWatcher Locking
2019-07-16 23:09:32 +01:00

78 lines
3.1 KiB
Diff

From 93be0e0fb65e38208bdb8aa2dac283ea26cbe64e Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 27 Mar 2019 23:01:33 -0400
Subject: [PATCH] PlayerDeathEvent#getItemsToKeep
Exposes a mutable array on items a player should keep on death
Example Usage: https://gist.github.com/aikar/5bb202de6057a051a950ce1f29feb0b4
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 7c8774d22..633fe836d 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -510,6 +510,46 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
});
}
+ // Paper start - process inventory
+ private static void processKeep(org.bukkit.event.entity.PlayerDeathEvent event, NonNullList<ItemStack> inv) {
+ List<org.bukkit.inventory.ItemStack> itemsToKeep = event.getItemsToKeep();
+ if (inv == null) {
+ // remainder of items left in toKeep - plugin added stuff on death that wasn't in the initial loot?
+ if (!itemsToKeep.isEmpty()) {
+ for (org.bukkit.inventory.ItemStack itemStack : itemsToKeep) {
+ event.getEntity().getInventory().addItem(itemStack);
+ }
+ }
+
+ return;
+ }
+
+ for (int i = 0; i < inv.size(); ++i) {
+ ItemStack item = inv.get(i);
+ if (EnchantmentManager.shouldNotDrop(item) || itemsToKeep.isEmpty() || item.isEmpty()) {
+ inv.set(i, ItemStack.NULL_ITEM);
+ continue;
+ }
+
+ final org.bukkit.inventory.ItemStack bukkitStack = item.getBukkitStack();
+ boolean keep = false;
+ final Iterator<org.bukkit.inventory.ItemStack> iterator = itemsToKeep.iterator();
+ while (iterator.hasNext()) {
+ final org.bukkit.inventory.ItemStack itemStack = iterator.next();
+ if (bukkitStack.equals(itemStack)) {
+ iterator.remove();
+ keep = true;
+ break;
+ }
+ }
+
+ if (!keep) {
+ inv.set(i, ItemStack.NULL_ITEM);
+ }
+ }
+ }
+ // Paper end
+
@Override
public void die(DamageSource damagesource) {
boolean flag = this.world.getGameRules().getBoolean(GameRules.SHOW_DEATH_MESSAGES);
@@ -594,7 +634,12 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
this.releaseShoulderEntities();
// we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory.
if (!event.getKeepInventory()) {
- this.inventory.clear();
+ // Paper start - replace logic
+ for (NonNullList<ItemStack> inv : this.inventory.getComponents()) {
+ processKeep(event, inv);
+ }
+ processKeep(event, null);
+ // Paper end
}
this.setSpectatorTarget(this); // Remove spectated target
--
2.22.0