aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-Server-Patches-Unmapped/0252-Prevent-Saving-Bad-entities-to-chunks.patch
diff options
context:
space:
mode:
Diffstat (limited to 'Spigot-Server-Patches-Unmapped/0252-Prevent-Saving-Bad-entities-to-chunks.patch')
-rw-r--r--Spigot-Server-Patches-Unmapped/0252-Prevent-Saving-Bad-entities-to-chunks.patch127
1 files changed, 127 insertions, 0 deletions
diff --git a/Spigot-Server-Patches-Unmapped/0252-Prevent-Saving-Bad-entities-to-chunks.patch b/Spigot-Server-Patches-Unmapped/0252-Prevent-Saving-Bad-entities-to-chunks.patch
new file mode 100644
index 0000000000..d16a82a8f8
--- /dev/null
+++ b/Spigot-Server-Patches-Unmapped/0252-Prevent-Saving-Bad-entities-to-chunks.patch
@@ -0,0 +1,127 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Aikar <[email protected]>
+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/level/WorldServer.java b/src/main/java/net/minecraft/server/level/WorldServer.java
+index 14321bc6ecc5ca70e71c1eef9578091822aa94cd..ce7431ea8597c645bb2c97f596796dbf12206e72 100644
+--- a/src/main/java/net/minecraft/server/level/WorldServer.java
++++ b/src/main/java/net/minecraft/server/level/WorldServer.java
+@@ -1157,6 +1157,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
+ List[] aentityslice = chunk.getEntitySlices(); // Spigot
+ int i = aentityslice.length;
+
++ java.util.List<Entity> toMoveChunks = new java.util.ArrayList<>(); // Paper
+ for (int j = 0; j < i; ++j) {
+ List<Entity> entityslice = aentityslice[j]; // Spigot
+ Iterator iterator = entityslice.iterator();
+@@ -1169,11 +1170,25 @@ public class WorldServer extends World implements GeneratorAccessSeed {
+ throw (IllegalStateException) SystemUtils.c((Throwable) (new IllegalStateException("Removing entity while ticking!")));
+ }
+
++ // Paper start - move out entities that shouldn't be in this chunk before it unloads
++ if (!entity.dead && (int) Math.floor(entity.locX()) >> 4 != chunk.getPos().x || (int) Math.floor(entity.locZ()) >> 4 != chunk.getPos().z) {
++ toMoveChunks.add(entity);
++ continue;
++ }
++ // Paper end
++
+ this.entitiesById.remove(entity.getId());
+ this.unregisterEntity(entity);
++
++ if (entity.dead) iterator.remove(); // Paper - don't save dead entities during unload
+ }
+ }
+ }
++ // Paper start - move out entities that shouldn't be in this chunk before it unloads
++ for (Entity entity : toMoveChunks) {
++ this.chunkCheck(entity);
++ }
++ // Paper end
+
+ }
+
+diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkRegionLoader.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkRegionLoader.java
+index f301c7ba4b17b92c6cf2fcee6da1e67081dad4fa..69bc9dc18bab157851d8080a672504598e8572a8 100644
+--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkRegionLoader.java
++++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkRegionLoader.java
+@@ -26,6 +26,7 @@ import net.minecraft.nbt.NBTTagList;
+ import net.minecraft.nbt.NBTTagLongArray;
+ import net.minecraft.nbt.NBTTagShort;
+ import net.minecraft.server.level.ChunkProviderServer;
++import net.minecraft.server.level.EntityPlayer;
+ import net.minecraft.server.level.LightEngineThreaded;
+ import net.minecraft.server.level.WorldServer;
+ import net.minecraft.world.entity.Entity;
+@@ -349,6 +350,7 @@ public class ChunkRegionLoader {
+ nbttagcompound1.set("TileEntities", nbttaglist1);
+ NBTTagList nbttaglist2 = new NBTTagList();
+
++ java.util.List<Entity> toUpdate = new java.util.ArrayList<>(); // Paper
+ if (ichunkaccess.getChunkStatus().getType() == ChunkStatus.Type.LEVELCHUNK) {
+ Chunk chunk = (Chunk) ichunkaccess;
+
+@@ -366,13 +368,28 @@ public class ChunkRegionLoader {
+ while (iterator1.hasNext()) {
+ Entity entity = (Entity) iterator1.next();
+ NBTTagCompound nbttagcompound4 = new NBTTagCompound();
+-
++ // Paper start
++ if ((int) Math.floor(entity.locX()) >> 4 != chunk.getPos().x || (int) Math.floor(entity.locZ()) >> 4 != chunk.getPos().z) {
++ toUpdate.add(entity);
++ continue;
++ }
++ if (entity.dead || hasPlayerPassenger(entity)) {
++ continue;
++ }
++ // Paper end
+ if (entity.d(nbttagcompound4)) {
+ chunk.d(true);
+ nbttaglist2.add(nbttagcompound4);
+ }
+ }
+ }
++
++ // Paper start - move entities to the correct chunk
++ for (Entity entity : toUpdate) {
++ worldserver.chunkCheck(entity);
++ }
++ // Paper end
++
+ } else {
+ ProtoChunk protochunk = (ProtoChunk) ichunkaccess;
+
+@@ -431,6 +448,19 @@ public class ChunkRegionLoader {
+ nbttagcompound1.set("Structures", a(chunkcoordintpair, ichunkaccess.h(), ichunkaccess.v()));
+ return nbttagcompound;
+ }
++ // Paper start - this is saved with the player
++ private static boolean hasPlayerPassenger(Entity entity) {
++ for (Entity passenger : entity.passengers) {
++ if (passenger instanceof EntityPlayer) {
++ return true;
++ }
++ if (hasPlayerPassenger(passenger)) {
++ return true;
++ }
++ }
++ return false;
++ }
++ // Paper end
+
+ public static ChunkStatus.Type a(@Nullable NBTTagCompound nbttagcompound) {
+ if (nbttagcompound != null) {