diff --git a/Spigot-Server-Patches/0299-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch b/Spigot-Server-Patches/0299-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch index 4d07bb811..a45f35960 100644 --- a/Spigot-Server-Patches/0299-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch +++ b/Spigot-Server-Patches/0299-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch @@ -1,31 +1,12 @@ -From 50bd6c799a35435682d288098ad5a3999f888f42 Mon Sep 17 00:00:00 2001 +From 92aaeae9ce1a4ceaf3e1e9ec95789677187ece51 Mon Sep 17 00:00:00 2001 From: Aikar 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 { diff --git a/Spigot-Server-Patches/0314-Prevent-Saving-Bad-entities-to-chunks.patch b/Spigot-Server-Patches/0314-Prevent-Saving-Bad-entities-to-chunks.patch new file mode 100644 index 000000000..66d6b3f18 --- /dev/null +++ b/Spigot-Server-Patches/0314-Prevent-Saving-Bad-entities-to-chunks.patch @@ -0,0 +1,105 @@ +From a03528da903b6a8261c06c40ad9fde7267b3434e Mon Sep 17 00:00:00 2001 +From: Aikar +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 thisChunk = new HashMap<>(); + for (Iterator iterator = ((List) 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 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 +