diff options
author | Riley Park <[email protected]> | 2024-05-15 17:06:59 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2024-05-15 17:06:59 -0700 |
commit | f17519338bc589c045e0b32bfc37e048b23544d5 (patch) | |
tree | e50182ec698b4a9de8f366f485ee089b1901bbd9 /patches/server/0353-Fix-item-duplication-and-teleport-issues.patch | |
parent | 3fc93581bb876e8149b2ca423375a98f5ca12d27 (diff) | |
download | Paper-f17519338bc589c045e0b32bfc37e048b23544d5.tar.gz Paper-f17519338bc589c045e0b32bfc37e048b23544d5.zip |
Expose server build information (#10729)
* Expose server build information
* squash patches
* final tweaks
---------
Co-authored-by: Jake Potrebic <[email protected]>
Co-authored-by: masmc05 <[email protected]>
Diffstat (limited to 'patches/server/0353-Fix-item-duplication-and-teleport-issues.patch')
-rw-r--r-- | patches/server/0353-Fix-item-duplication-and-teleport-issues.patch | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/patches/server/0353-Fix-item-duplication-and-teleport-issues.patch b/patches/server/0353-Fix-item-duplication-and-teleport-issues.patch new file mode 100644 index 0000000000..b59b420d07 --- /dev/null +++ b/patches/server/0353-Fix-item-duplication-and-teleport-issues.patch @@ -0,0 +1,167 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar <[email protected]> +Date: Sat, 25 Apr 2020 06:46:35 -0400 +Subject: [PATCH] Fix item duplication and teleport issues + +This notably fixes the newest "Donkey Dupe", but also fixes a lot +of dupe bugs in general around nether portals and entity world transfer + +We also fix item duplication generically by anytime we clone an item +to drop it on the ground, destroy the source item. + +This avoid an itemstack ever existing twice in the world state pre +clean up stage. + +So even if something NEW comes up, it would be impossible to drop the +same item twice because the source was destroyed. + +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index 511208e323b26df24263b87eeb7d2645572d9ff8..c6877df96229eb922fa0d4029f31d9698eab78ab 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -2447,11 +2447,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } else { + // CraftBukkit start - Capture drops for death event + if (this instanceof net.minecraft.world.entity.LivingEntity && !((net.minecraft.world.entity.LivingEntity) this).forceDrops) { +- ((net.minecraft.world.entity.LivingEntity) this).drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(stack)); ++ ((net.minecraft.world.entity.LivingEntity) this).drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack)); // Paper - mirror so we can destroy it later + return null; + } + // CraftBukkit end +- ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY() + (double) yOffset, this.getZ(), stack); ++ ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY() + (double) yOffset, this.getZ(), stack.copy()); // Paper - copy so we can destroy original ++ stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe + + entityitem.setDefaultPickUpDelay(); + // CraftBukkit start +@@ -3238,6 +3239,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + @Nullable + public Entity teleportTo(ServerLevel worldserver, Vec3 location) { + // CraftBukkit end ++ // Paper start - Fix item duplication and teleport issues ++ if (!this.isAlive() || !this.valid) { ++ LOGGER.warn("Illegal Entity Teleport " + this + " to " + worldserver + ":" + location, new Throwable()); ++ return null; ++ } ++ // Paper end - Fix item duplication and teleport issues + if (this.level() instanceof ServerLevel && !this.isRemoved()) { + this.level().getProfiler().push("changeDimension"); + // CraftBukkit start +@@ -3264,6 +3271,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + // CraftBukkit end + + this.level().getProfiler().popPush("reloading"); ++ // Paper start - Fix item duplication and teleport issues ++ if (this instanceof Mob) { ++ ((Mob) this).dropLeash(true, true); // Paper drop lead ++ } ++ // Paper end - Fix item duplication and teleport issues + Entity entity = this.getType().create(worldserver); + + if (entity != null) { +@@ -3281,10 +3293,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + // CraftBukkit start - Forward the CraftEntity to the new entity + this.getBukkitEntity().setHandle(entity); + entity.bukkitEntity = this.getBukkitEntity(); +- +- if (this instanceof Mob) { +- ((Mob) this).dropLeash(true, false); // Unleash to prevent duping of leads. +- } + // CraftBukkit end + } + +@@ -3405,7 +3413,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + + public boolean canChangeDimensions() { +- return !this.isPassenger() && !this.isVehicle(); ++ return !this.isPassenger() && !this.isVehicle() && isAlive() && valid; // Paper - Fix item duplication and teleport issues + } + + public float getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState, float max) { +diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java +index 2f3615cb8e4206ed2eb87c1341de4258879d3907..c640d68c35b4454bfa0ae1764dee341041d9c31e 100644 +--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java ++++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java +@@ -1740,9 +1740,9 @@ public abstract class LivingEntity extends Entity implements Attackable { + // Paper start + org.bukkit.event.entity.EntityDeathEvent deathEvent = this.dropAllDeathLoot(damageSource); + if (deathEvent == null || !deathEvent.isCancelled()) { +- if (this.deathScore >= 0 && entityliving != null) { +- entityliving.awardKillScore(this, this.deathScore, damageSource); +- } ++ // if (this.deathScore >= 0 && entityliving != null) { // Paper - Fix item duplication and teleport issues; moved to be run earlier in #dropAllDeathLoot before destroying the drop items in CraftEventFactory#callEntityDeathEvent ++ // entityliving.awardKillScore(this, this.deathScore, damageSource); ++ // } + // Paper start - clear equipment if event is not cancelled + if (this instanceof Mob) { + for (EquipmentSlot slot : this.clearedEquipmentSlots) { +@@ -1843,8 +1843,13 @@ public abstract class LivingEntity extends Entity implements Attackable { + this.dropCustomDeathLoot(source, i, flag); + this.clearEquipmentSlots = prev; // Paper + } +- // CraftBukkit start - Call death event +- org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, source, this.drops); // Paper ++ // CraftBukkit start - Call death event // Paper start - call advancement triggers with correct entity equipment ++ org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, source, this.drops, () -> { ++ final LivingEntity entityliving = this.getKillCredit(); ++ if (this.deathScore >= 0 && entityliving != null) { ++ entityliving.awardKillScore(this, this.deathScore, source); ++ } ++ }); // Paper end + this.postDeathDropItems(deathEvent); // Paper + this.drops = new ArrayList<>(); + // CraftBukkit end +diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +index 029d5756f424dba57b4a974b09453c2f0cf0e8e2..e1f6853c450a2e6a0d7607f1faec7bc5c82d9621 100644 +--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java ++++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +@@ -628,7 +628,7 @@ public class ArmorStand extends LivingEntity { + for (i = 0; i < this.handItems.size(); ++i) { + itemstack = (ItemStack) this.handItems.get(i); + if (!itemstack.isEmpty()) { +- this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops ++ this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe + this.handItems.set(i, ItemStack.EMPTY); + } + } +@@ -636,7 +636,7 @@ public class ArmorStand extends LivingEntity { + for (i = 0; i < this.armorItems.size(); ++i) { + itemstack = (ItemStack) this.armorItems.get(i); + if (!itemstack.isEmpty()) { +- this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops ++ this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe + this.armorItems.set(i, ItemStack.EMPTY); + } + } +diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +index 74fc73549b504eb2b7fcaa141aa125f84a077ed9..ac4a8c9d4f727f3caa16f6dc5497d69f9db52aab 100644 +--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java ++++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +@@ -894,6 +894,11 @@ public class CraftEventFactory { + } + + public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops) { ++ // Paper start ++ return CraftEventFactory.callEntityDeathEvent(victim, damageSource, drops, com.google.common.util.concurrent.Runnables.doNothing()); ++ } ++ public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops, Runnable lootCheck) { ++ // Paper end + CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity(); + CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource); + EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward()); +@@ -908,11 +913,13 @@ public class CraftEventFactory { + playDeathSound(victim, event); + // Paper end + victim.expToDrop = event.getDroppedExp(); ++ lootCheck.run(); // Paper - advancement triggers before destroying items + + for (org.bukkit.inventory.ItemStack stack : event.getDrops()) { + if (stack == null || stack.getType() == Material.AIR || stack.getAmount() == 0) continue; + +- world.dropItem(entity.getLocation(), stack); ++ world.dropItem(entity.getLocation(), stack); // Paper - note: dropItem already clones due to this being bukkit -> NMS ++ if (stack instanceof CraftItemStack) stack.setAmount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe, but don't nuke bukkit stacks of manually added items + } + + return event; |