Merge branch 'master' into pre/1.13

* master:
  Prevent Saving Bad entities to chunks
This commit is contained in:
Aikar 2018-07-26 00:57:16 -04:00
commit 7c5cc1ece7
No known key found for this signature in database
GPG key ID: 401ADFC9891FAAFE
2 changed files with 108 additions and 22 deletions

View file

@ -1,31 +1,12 @@
From 50bd6c799a35435682d288098ad5a3999f888f42 Mon Sep 17 00:00:00 2001
From 92aaeae9ce1a4ceaf3e1e9ec95789677187ece51 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sat, 21 Jul 2018 08:25:40 -0400
Subject: [PATCH] Add Debug Entities option to debug dupe uuid issues
Add -Ddebug.entities=true to your JVM flags to gain more information
diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
index ea8684747..5fd0c0cf5 100644
--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
@@ -566,6 +566,14 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next();
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
+ // Paper start
+ if (entity.getChunkX() != chunk.locX || entity.getChunkZ() != chunk.locZ) {
+ LogManager.getLogger().error(entity + " is not actually in this chunk! Report this to https://github.com/PaperMC/Paper/issues/1223", new Throwable());
+ }
+ if ((int)Math.floor(entity.locX) >> 4 != chunk.locX || (int)Math.floor(entity.locZ) >> 4 != chunk.locZ) {
+ LogManager.getLogger().error(entity + " will be leaving this chunk but saved to it. Report this to https://github.com/PaperMC/Paper/issues/1223", new Throwable());
+ }
+ // Paper end
if (entity.d(nbttagcompound1)) {
chunk.f(true);
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 47ce5cda7..b308f4416 100644
index a2101d44f9..f05545e357 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -71,6 +71,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
@ -37,7 +18,7 @@ index 47ce5cda7..b308f4416 100644
if (bukkitEntity == null) {
bukkitEntity = CraftEntity.getEntity(world.getServer(), this);
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index b048343b7..747d99dbe 100644
index b048343b7c..747d99dbe6 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -53,6 +53,10 @@ public class WorldServer extends World implements IAsyncTaskHandler {

View file

@ -0,0 +1,105 @@
From a03528da903b6a8261c06c40ad9fde7267b3434e Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Thu, 26 Jul 2018 00:11:12 -0400
Subject: [PATCH] Prevent Saving Bad entities to chunks
See https://github.com/PaperMC/Paper/issues/1223
Minecraft is saving invalid entities to the chunk files.
Avoid saving bad data, and also make improvements to handle
loading these chunks. Any invalid entity will be instant killed,
so lets avoid adding it to the world...
This lets us be safer about the dupe UUID resolver too, as now
we can ignore instant killed entities and avoid risk of duplicating
an invalid entity.
This should reduce log occurrences of dupe uuid messages.
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 56a74c6062..fd1e53febb 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -911,11 +911,12 @@ public class Chunk implements IChunkAccess {
Map<UUID, Entity> thisChunk = new HashMap<>();
for (Iterator<Entity> iterator = ((List<Entity>) entityslice).iterator(); iterator.hasNext(); ) {
Entity entity = iterator.next();
+ if (entity.dead) continue;
Entity other = ((WorldServer) world).entitiesByUUID.get(entity.uniqueID);
if (other == null) {
other = thisChunk.get(entity.uniqueID);
}
- if (other != null) {
+ if (other != null && !other.dead) {
switch (mode) {
case REGEN: {
entity.setUUID(UUID.randomUUID());
diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
index a97e024ec4..bd52bf6561 100644
--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
@@ -561,11 +561,22 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
Iterator iterator;
+ java.util.List<Entity> toUpdate = new java.util.ArrayList<>(); // Paper
for (int j = 0; j < chunk.getEntitySlices().length; ++j) {
iterator = chunk.getEntitySlices()[j].iterator();
while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next();
+ // Paper start
+ if ((int)Math.floor(entity.locX) >> 4 != chunk.locX || (int)Math.floor(entity.locZ) >> 4 != chunk.locZ) {
+ LogManager.getLogger().warn(entity + " is not in this chunk, skipping save. This a bug fix to a vanilla bug. Do not report this to PaperMC please.");
+ toUpdate.add(entity);
+ continue;
+ }
+ if (entity.dead) {
+ continue;
+ }
+ // Paper end
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
if (entity.d(nbttagcompound1)) {
@@ -574,6 +585,11 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
}
}
}
+ // Paper start - move entities to the correct chunk
+ for (Entity entity : toUpdate) {
+ world.entityJoinedWorld(entity, false);
+ }
+ // Paper end
nbttagcompound.set("Entities", nbttaglist1);
NBTTagList nbttaglist2 = new NBTTagList();
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 6d80e55c19..27398806d3 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1053,7 +1053,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
}
this.getChunkAt(i, j).a(entity);
- this.entityList.add(entity);
+ if (!entity.dead) this.entityList.add(entity); // Paper - don't add dead entities, chunk registration may of killed it
this.b(entity);
return true;
}
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 7a9f28421b..b57e1ff364 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -992,7 +992,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 - overwrite the current dead one
this.g.remove(entity1);
} else {
if (!(entity instanceof EntityHuman)) {
--
2.18.0