1
0
Fork 0
mirror of https://github.com/PaperMC/Paper.git synced 2025-04-27 14:22:41 +02:00

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  that indicates issues around
this are having problems.
This commit is contained in:
Aikar 2018-10-17 22:47:27 -04:00
parent ed9a89e82e
commit 00f0a30680
No known key found for this signature in database
GPG key ID: 401ADFC9891FAAFE
2 changed files with 84 additions and 3 deletions

View file

@ -1,4 +1,4 @@
From 14e26ad623fc54b7f4e0c647f40b9cdcca79a88f Mon Sep 17 00:00:00 2001
From eb8942dae2dd6dbc8a32b05c0a502a4a507d7233 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
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<Chunk> {
@ -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<Chunk> {
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<Chunk> {
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<Chunk> {
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<Chunk> {
}
}
@ -86,5 +113,5 @@ index d16fc452e3..2d10f4aa37 100644
return true;
}
--
2.19.0
2.19.1

View file

@ -0,0 +1,54 @@
From 5d6a6cd178b5baef11c1a52c7f91bf71ef789da4 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
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> {
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> {
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<Chunk> {
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<Chunk> {
}
// Paper start
+ } // close if (chunk != null)
if (lastChunkByPos != null && i == lastChunkByPos.chunkKey) {
lastChunkByPos = null;
}
--
2.19.1