geforkt von Mirrors/Paper
fcc2e46edd
this is originally what I thought #1333 was, but wasn't, but this is still valid fix
86 Zeilen
4.0 KiB
Diff
86 Zeilen
4.0 KiB
Diff
From f2d6b77d7f061d9dc7ceb3fce2f58a25f33f3fc0 Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
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 e8af8f4196..56c3783412 100644
|
|
--- a/src/main/java/net/minecraft/server/Chunk.java
|
|
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
|
@@ -905,6 +905,7 @@ public class Chunk implements IChunkAccess {
|
|
this.world.a(this.tileEntities.values());
|
|
List[] aentityslice = this.entitySlices; // Spigot
|
|
int i = aentityslice.length;
|
|
+ List<Entity> toAdd = new java.util.ArrayList<>(32); // Paper
|
|
|
|
for (int j = 0; j < i; ++j) {
|
|
List entityslice = aentityslice[j]; // Spigot
|
|
@@ -952,12 +953,11 @@ public class Chunk implements IChunkAccess {
|
|
thisChunk.put(entity.uniqueID, entity);
|
|
}
|
|
}
|
|
- // Paper end
|
|
|
|
- this.world.a(entityslice.stream().filter((entity) -> {
|
|
- return !(entity instanceof EntityHuman);
|
|
- }));
|
|
+ toAdd.addAll(entityslice);
|
|
+ // Paper end
|
|
}
|
|
+ this.world.addChunkEntities(toAdd.stream().filter((entity) -> !(entity instanceof EntityHuman))); // Paper - add all at same time to avoid entities adding to world modifying slice state
|
|
|
|
// CraftBukkit start
|
|
org.bukkit.Server server = this.world.getServer();
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
|
index aa94e399af..85570e4a5d 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -1102,6 +1102,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;
|
|
@@ -2507,9 +2508,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 2692d0a1b6..911d03c70b 100644
|
|
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
|
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
|
@@ -987,7 +987,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.19.0
|
|
|