2018-08-05 23:46:43 +00:00
|
|
|
From 65f1544c78789ea0348d7059d8d6f82f130155e4 Mon Sep 17 00:00:00 2001
|
2018-08-04 03:02:44 +00:00
|
|
|
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
|
2018-08-05 23:46:43 +00:00
|
|
|
index e510940ab3..db8fbc006d 100644
|
2018-08-04 03:02:44 +00:00
|
|
|
--- a/src/main/java/net/minecraft/server/Chunk.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
2018-08-04 04:33:21 +00:00
|
|
|
@@ -902,6 +902,7 @@ public class Chunk implements IChunkAccess {
|
2018-08-04 03:02:44 +00:00
|
|
|
this.world.b(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
|
2018-08-04 04:33:21 +00:00
|
|
|
@@ -948,10 +949,12 @@ public class Chunk implements IChunkAccess {
|
2018-08-04 03:02:44 +00:00
|
|
|
thisChunk.put(entity.uniqueID, entity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
- // Paper end
|
|
|
|
|
|
|
|
- this.world.a((Collection) entityslice);
|
|
|
|
+ //this.world.a((Collection) entityslice); // Move down, add all entities at same time
|
|
|
|
+ toAdd.addAll(entityslice);
|
|
|
|
+ // Paper end
|
|
|
|
}
|
|
|
|
+ this.world.addChunkEntities(toAdd); // Paper - add all at same time to avoid entities adding to world modifying slice state
|
|
|
|
|
2018-08-04 04:33:21 +00:00
|
|
|
// CraftBukkit start
|
|
|
|
org.bukkit.Server server = this.world.getServer();
|
2018-08-04 03:02:44 +00:00
|
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
2018-08-05 23:46:43 +00:00
|
|
|
index b0053e5e63..004c3ec474 100644
|
2018-08-04 03:02:44 +00:00
|
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
2018-08-04 04:33:21 +00:00
|
|
|
@@ -1069,6 +1069,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
|
2018-08-04 03:02:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2018-08-04 04:33:21 +00:00
|
|
|
@@ -2463,6 +2464,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
|
2018-08-04 03:02:44 +00:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ public void addChunkEntities(Collection<Entity> collection) { a(collection); } // Paper - OBFHELPER
|
|
|
|
public void a(Collection<Entity> collection) {
|
|
|
|
org.spigotmc.AsyncCatcher.catchOp( "entity world add"); // Spigot
|
|
|
|
// CraftBukkit start
|
2018-08-04 04:33:21 +00:00
|
|
|
@@ -2472,7 +2474,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
|
2018-08-04 03:02:44 +00:00
|
|
|
while (iterator.hasNext()) {
|
|
|
|
Entity entity = (Entity) iterator.next();
|
|
|
|
|
|
|
|
- if (entity == null) {
|
|
|
|
+ if (entity == null || entity.dead || entity.valid) { // Paper - prevent adding already added or dead entities
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
this.entityList.add(entity);
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
2018-08-05 23:46:43 +00:00
|
|
|
index 7a9f28421b..6412715b78 100644
|
2018-08-04 03:02:44 +00:00
|
|
|
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
2018-08-04 04:33:21 +00:00
|
|
|
@@ -992,7 +992,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
2018-08-04 03:02:44 +00:00
|
|
|
if (this.entitiesByUUID.containsKey(uuid)) {
|
|
|
|
Entity entity1 = (Entity) this.entitiesByUUID.get(uuid);
|
|
|
|
|
2018-08-04 04:33:21 +00:00
|
|
|
- if (this.g.contains(entity1)) {
|
|
|
|
+ if (this.g.contains(entity1) || entity1.dead) { // Paper - if dupe is dead, overwrite
|
|
|
|
this.g.remove(entity1);
|
2018-08-04 03:02:44 +00:00
|
|
|
} else {
|
|
|
|
if (!(entity instanceof EntityHuman)) {
|
|
|
|
--
|
|
|
|
2.18.0
|
|
|
|
|