diff options
Diffstat (limited to 'Spigot-Server-Patches/0318-Entity-add-to-world-fixes.patch')
-rw-r--r-- | Spigot-Server-Patches/0318-Entity-add-to-world-fixes.patch | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/Spigot-Server-Patches/0318-Entity-add-to-world-fixes.patch b/Spigot-Server-Patches/0318-Entity-add-to-world-fixes.patch new file mode 100644 index 0000000000..9b8db42564 --- /dev/null +++ b/Spigot-Server-Patches/0318-Entity-add-to-world-fixes.patch @@ -0,0 +1,96 @@ +From caaa22ced1e3cc9e7c6c79192259a5436f1783e3 Mon Sep 17 00:00:00 2001 +From: Aikar <[email protected]> +Date: Fri, 3 Aug 2018 22:47:46 -0400 +Subject: [PATCH] Entity add to world fixes + +1) Chunk Registration might kill an entity, don't add it to the world if it did! + +2) By default, entities are added to the world per slice iteration. +This opens risk of the slices being manipulated during chunk add if an +EntityAddToWorldEvent spawns an entity into this chunk. +Fix this by differing entity add to world for all entities at the same time + +3) If a duplicate entity is attempted to add to the world of an entity, and +the original entity is dead, overwrite it as the logic does for unloaod queued entities. + +diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java +index 01abe5e376..4502ece4dd 100644 +--- a/src/main/java/net/minecraft/server/Chunk.java ++++ b/src/main/java/net/minecraft/server/Chunk.java +@@ -2,6 +2,8 @@ package net.minecraft.server; + + // Paper start + import com.destroystokyo.paper.PaperWorldConfig.DuplicateUUIDMode; ++ ++import java.util.Arrays; + import java.util.HashMap; + import java.util.UUID; + // Paper end +@@ -957,15 +959,16 @@ public class Chunk implements IChunkAccess { + // Paper end + + // CraftBukkit start +- List<Entity> toRemove = new LinkedList<>(); +- this.world.a(entityslice.stream().filter((entity) -> { +- if (this.needsDecoration && !CraftEventFactory.doEntityAddEventCalling(this.world, entity, CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) { // Only call for new chunks +- toRemove.add(entity); +- return false; +- } +- return !(entity instanceof EntityHuman); +- })); +- entityslice.removeAll(toRemove); ++ this.world.addChunkEntities(entityslice.stream() // Paper - add all at same time to avoid entities adding to world modifying slice state, skip already added entities (not normal, but can happen) ++ // Paper start - Inline event into stream ++ .filter((entity) -> { ++ if (!this.needsDecoration) { ++ return true; ++ } ++ return CraftEventFactory.doEntityAddEventCalling(this.world, entity, CreatureSpawnEvent.SpawnReason.CHUNK_GEN); ++ }) ++ // Paper end - Inline event into stream ++ .filter((entity) -> !(entity instanceof EntityHuman || entity.valid))); // Paper - add all at same time to avoid entities adding to world modifying slice state, skip already added entities (not normal, but can happen) + // CraftBukkit end + } + +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 3acea908c2..e31e366249 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -1037,6 +1037,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc + } + + this.getChunkAt(i, j).a(entity); ++ if (entity.dead) return false; // Paper - don't add dead entities, chunk registration may of killed it + this.entityList.add(entity); + this.b(entity); + return true; +@@ -2434,9 +2435,13 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc + return j; + } + ++ public void addChunkEntities(Stream<Entity> collection) { a(collection); } // Paper - OBFHELPER + public void a(Stream<Entity> stream) { + org.spigotmc.AsyncCatcher.catchOp( "entity world add"); // Spigot + stream.forEach((entity) -> { ++ if (entity == null || entity.dead || entity.valid) { // Paper - prevent adding already added or dead entities ++ return; ++ } + this.entityList.add(entity); + this.b(entity); + }); +diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java +index 293818b196..4cda6cee2b 100644 +--- a/src/main/java/net/minecraft/server/WorldServer.java ++++ b/src/main/java/net/minecraft/server/WorldServer.java +@@ -967,7 +967,7 @@ public class WorldServer extends World implements IAsyncTaskHandler { + if (this.entitiesByUUID.containsKey(uuid)) { + Entity entity1 = (Entity) this.entitiesByUUID.get(uuid); + +- if (this.g.contains(entity1)) { ++ if (this.g.contains(entity1) || entity1.dead) { // Paper - if dupe is dead, overwrite + this.g.remove(entity1); + } else { + if (!(entity instanceof EntityHuman)) { +-- +2.21.0 + |