From 00f0a30680fe8cea6272a75cf84875e01ad76e3e Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 17 Oct 2018 22:47:27 -0400 Subject: [PATCH] Ensure chunk neighbor counts do not get desynced Mojang was not checking that the chunk did not overwrite, or was successfully removed. We're seeing odd reports in #1561 that indicates issues around this are having problems. --- .../0078-Optimize-Chunk-Access.patch | 33 ++++++++++-- ...-neighbor-counts-do-not-get-desynced.patch | 54 +++++++++++++++++++ 2 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 Spigot-Server-Patches/0396-Ensure-chunk-neighbor-counts-do-not-get-desynced.patch diff --git a/Spigot-Server-Patches/0078-Optimize-Chunk-Access.patch b/Spigot-Server-Patches/0078-Optimize-Chunk-Access.patch index 522e7b4dda..4bfae5f308 100644 --- a/Spigot-Server-Patches/0078-Optimize-Chunk-Access.patch +++ b/Spigot-Server-Patches/0078-Optimize-Chunk-Access.patch @@ -1,4 +1,4 @@ -From 14e26ad623fc54b7f4e0c647f40b9cdcca79a88f Mon Sep 17 00:00:00 2001 +From eb8942dae2dd6dbc8a32b05c0a502a4a507d7233 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 27 Aug 2015 01:15:02 -0400 Subject: [PATCH] Optimize Chunk Access @@ -9,7 +9,7 @@ getChunkAt is called for the same chunk multiple times in a row, often from getT Optimize this look up by using a Last Access cache. diff --git a/src/main/java/net/minecraft/server/ChunkMap.java b/src/main/java/net/minecraft/server/ChunkMap.java -index 4b8b77710b..df967ff07d 100644 +index 4b8b77710b..71ddaf591e 100644 --- a/src/main/java/net/minecraft/server/ChunkMap.java +++ b/src/main/java/net/minecraft/server/ChunkMap.java @@ -15,6 +15,7 @@ public class ChunkMap extends Long2ObjectOpenHashMap { @@ -20,6 +20,33 @@ index 4b8b77710b..df967ff07d 100644 Chunk chunk1 = (Chunk) super.put(i, chunk); ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i); +@@ -22,7 +23,7 @@ public class ChunkMap extends Long2ObjectOpenHashMap { + for (int k = chunkcoordintpair.z - 1; k <= chunkcoordintpair.z + 1; ++k) { + if (j != chunkcoordintpair.x || k != chunkcoordintpair.z) { + long l = ChunkCoordIntPair.a(j, k); +- Chunk chunk2 = (Chunk) this.get(l); ++ Chunk chunk2 = (Chunk) super.get(l); // Paper - use super to avoid polluting last access cache + + if (chunk2 != null) { + chunk.H(); +@@ -40,7 +41,7 @@ public class ChunkMap extends Long2ObjectOpenHashMap { + continue; + } + +- Chunk neighbor = this.get(ChunkCoordIntPair.a(chunkcoordintpair.x + x, chunkcoordintpair.z + z)); ++ Chunk neighbor = super.get(ChunkCoordIntPair.a(chunkcoordintpair.x + x, chunkcoordintpair.z + z)); // Paper - use super to avoid polluting last access cache + if (neighbor != null) { + neighbor.setNeighborLoaded(-x, -z); + chunk.setNeighborLoaded(x, z); +@@ -64,7 +65,7 @@ public class ChunkMap extends Long2ObjectOpenHashMap { + for (int j = chunkcoordintpair.x - 1; j <= chunkcoordintpair.x + 1; ++j) { + for (int k = chunkcoordintpair.z - 1; k <= chunkcoordintpair.z + 1; ++k) { + if (j != chunkcoordintpair.x || k != chunkcoordintpair.z) { +- Chunk chunk1 = (Chunk) this.get(ChunkCoordIntPair.a(j, k)); ++ Chunk chunk1 = (Chunk) super.get(ChunkCoordIntPair.a(j, k)); // Paper - use super to avoid polluting last access cache + + if (chunk1 != null) { + chunk1.I(); @@ -73,8 +74,22 @@ public class ChunkMap extends Long2ObjectOpenHashMap { } } @@ -86,5 +113,5 @@ index d16fc452e3..2d10f4aa37 100644 return true; } -- -2.19.0 +2.19.1 diff --git a/Spigot-Server-Patches/0396-Ensure-chunk-neighbor-counts-do-not-get-desynced.patch b/Spigot-Server-Patches/0396-Ensure-chunk-neighbor-counts-do-not-get-desynced.patch new file mode 100644 index 0000000000..7b37a28bb1 --- /dev/null +++ b/Spigot-Server-Patches/0396-Ensure-chunk-neighbor-counts-do-not-get-desynced.patch @@ -0,0 +1,54 @@ +From 5d6a6cd178b5baef11c1a52c7f91bf71ef789da4 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Wed, 17 Oct 2018 22:31:54 -0400 +Subject: [PATCH] Ensure chunk neighbor counts do not get desynced + +Mojang was not checking that the chunk did not overwrite, or +was successfully removed. + +We're seeing odd reports in #1561 that indicates issues around +this are having problems. + +diff --git a/src/main/java/net/minecraft/server/ChunkMap.java b/src/main/java/net/minecraft/server/ChunkMap.java +index 39ac032b0b..1fb0770015 100644 +--- a/src/main/java/net/minecraft/server/ChunkMap.java ++++ b/src/main/java/net/minecraft/server/ChunkMap.java +@@ -17,6 +17,7 @@ public class ChunkMap extends Long2ObjectOpenHashMap { + chunk.world.timings.syncChunkLoadPostTimer.startTiming(); // Paper + lastChunkByPos = chunk; // Paper + Chunk chunk1 = (Chunk) super.put(i, chunk); ++ if (chunk1 == null) { // Paper - we should never be overwriting chunks + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i); + + for (int j = chunkcoordintpair.x - 1; j <= chunkcoordintpair.x + 1; ++j) { +@@ -47,7 +48,11 @@ public class ChunkMap extends Long2ObjectOpenHashMap { + chunk.setNeighborLoaded(x, z); + } + } ++ // Paper start ++ } } else { ++ a.error("Overwrote existing chunk! (" + chunk.world.getWorld().getName() + ":" + chunk.locX+"," + chunk.locZ + ")", new IllegalStateException()); + } ++ // Paper end + // Paper start - if this is a spare chunk (not part of any players view distance), go ahead and queue it for unload. + if (!((WorldServer)chunk.world).getPlayerChunkMap().isChunkInUse(chunk.locX, chunk.locZ)) { + if (chunk.world.paperConfig.delayChunkUnloadsBy > 0) { +@@ -69,6 +74,7 @@ public class ChunkMap extends Long2ObjectOpenHashMap { + + public Chunk a(long i) { + Chunk chunk = (Chunk) super.remove(i); ++ if (chunk != null) { // Paper - don't decrement if we didn't remove anything + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i); + + for (int j = chunkcoordintpair.x - 1; j <= chunkcoordintpair.x + 1; ++j) { +@@ -84,6 +90,7 @@ public class ChunkMap extends Long2ObjectOpenHashMap { + } + + // Paper start ++ } // close if (chunk != null) + if (lastChunkByPos != null && i == lastChunkByPos.chunkKey) { + lastChunkByPos = null; + } +-- +2.19.1 +