Peek the unload queue for chunk generation checks (#2332)

This commit is contained in:
Spottedleaf 2019-07-23 20:41:26 -07:00
parent 6d4ae38bae
commit 405dd2640c
2 changed files with 49 additions and 31 deletions

View File

@ -1573,7 +1573,7 @@ index 98590e233a..af934ef8bc 100644
this.a(new PacketPlayOutMultiBlockChange(this.dirtyCount, this.dirtyBlocks, chunk), false);
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 36ce789127..e698e1c931 100644
index 58e31380ab..8aa610bae0 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -1595,7 +1595,7 @@ index 36ce789127..e698e1c931 100644
}
diff --git a/src/main/java/net/minecraft/server/PlayerInteractManager.java b/src/main/java/net/minecraft/server/PlayerInteractManager.java
index f953bd7ceb..596b87bc06 100644
index 1c79890e3f..e5e9de542b 100644
--- a/src/main/java/net/minecraft/server/PlayerInteractManager.java
+++ b/src/main/java/net/minecraft/server/PlayerInteractManager.java
@@ -0,0 +0,0 @@ public class PlayerInteractManager {

View File

@ -8,7 +8,7 @@ This patch also adds a chunk status cache on region files (note that
its only purpose is to cache the status on DISK)
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 220cd197f..775b5f7fe 100644
index 220cd197fa..775b5f7fe3 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider {
@ -58,7 +58,7 @@ index 220cd197f..775b5f7fe 100644
@Nullable
diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
index e778c2e85..73f93e494 100644
index e778c2e857..73f93e4948 100644
--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
@@ -0,0 +0,0 @@ public class ChunkRegionLoader {
@ -80,7 +80,7 @@ index e778c2e85..73f93e494 100644
if (nbttagcompound != null) {
ChunkStatus chunkstatus = ChunkStatus.a(nbttagcompound.getCompound("Level").getString("Status"));
diff --git a/src/main/java/net/minecraft/server/ChunkStatus.java b/src/main/java/net/minecraft/server/ChunkStatus.java
index dd1822d6f..e324989b4 100644
index dd1822d6ff..e324989b46 100644
--- a/src/main/java/net/minecraft/server/ChunkStatus.java
+++ b/src/main/java/net/minecraft/server/ChunkStatus.java
@@ -0,0 +0,0 @@ public class ChunkStatus {
@ -110,7 +110,7 @@ index dd1822d6f..e324989b4 100644
return (ChunkStatus) IRegistry.CHUNK_STATUS.get(MinecraftKey.a(s));
}
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
index 14a176d61..98590e233 100644
index 14a176d61d..98590e233a 100644
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
@@ -0,0 +0,0 @@ public class PlayerChunk {
@ -134,7 +134,7 @@ index 14a176d61..98590e233 100644
public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> getStatusFutureUnchecked(ChunkStatus chunkstatus) {
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 17eee15b2..2032361f8 100644
index 17eee15b2d..8dd934319d 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -191,13 +191,18 @@ index 17eee15b2..2032361f8 100644
+ RegionFile regionFile = this.getRegionFile(chunkPos, false);
+
+ regionFile.setStatus(chunkPos.x, chunkPos.z, ChunkRegionLoader.getStatus(compound));
+ }
+
+ public IChunkAccess getUnloadingChunk(int chunkX, int chunkZ) {
+ PlayerChunk chunkHolder = this.pendingUnload.get(ChunkCoordIntPair.pair(chunkX, chunkZ));
+ return chunkHolder == null ? null : chunkHolder.getAvailableChunkNow();
}
+ // Paper end
boolean isOutsideOfRange(ChunkCoordIntPair chunkcoordintpair) {
// Spigot start
diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java
index b0ec9edf6..41f1e15cb 100644
index b0ec9edf67..41f1e15cb0 100644
--- a/src/main/java/net/minecraft/server/RegionFile.java
+++ b/src/main/java/net/minecraft/server/RegionFile.java
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
@ -256,7 +261,7 @@ index b0ec9edf6..41f1e15cb 100644
}
diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java
index 6f34d8aea..d2b328945 100644
index 6f34d8aea0..d2b3289450 100644
--- a/src/main/java/net/minecraft/server/RegionFileCache.java
+++ b/src/main/java/net/minecraft/server/RegionFileCache.java
@@ -0,0 +0,0 @@ public abstract class RegionFileCache implements AutoCloseable {
@ -289,7 +294,7 @@ index 6f34d8aea..d2b328945 100644
printOversizedLog("ChunkTooLarge even after reduction. Trying in overzealous mode.", regionfile.file, chunkX, chunkZ);
// Eek, major fail. We have retry logic, so reduce threshholds and fall back
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index acf151a25..a734a87c4 100644
index acf151a253..a2b6c3c94a 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -0,0 +0,0 @@ public class CraftWorld implements World {
@ -303,6 +308,9 @@ index acf151a25..a734a87c4 100644
+ }, world.getChunkProvider().serverThreadQueue).join();
+ }
+ IChunkAccess chunk = world.getChunkProvider().getChunkAtImmediately(x, z);
+ if (chunk == null) {
+ chunk = world.getChunkProvider().playerChunkMap.getUnloadingChunk(x, z);
+ }
+ if (chunk != null) {
+ return chunk instanceof ProtoChunkExtension || chunk instanceof net.minecraft.server.Chunk;
+ }
@ -325,20 +333,25 @@ index acf151a25..a734a87c4 100644
- if (chunk instanceof ProtoChunkExtension) {
- // We then cycle through again to get the full chunk immediately, rather than after the ticket addition
- chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, true);
+ IChunkAccess immediate = world.getChunkProvider().getChunkAtImmediately(x, z);
+ if (immediate != null) {
+ if (!(immediate instanceof ProtoChunkExtension) && !(immediate instanceof net.minecraft.server.Chunk)) {
+ return false; // not full status
+ }
+ world.getChunkProvider().addTicket(TicketType.PLUGIN, chunkPos, 1, Unit.INSTANCE);
+ world.getChunkAt(x, z); // make sure we're at ticket level 32 or lower
+ return true;
}
- }
+ if (!generate) {
- if (chunk instanceof net.minecraft.server.Chunk) {
- world.getChunkProvider().addTicket(TicketType.PLUGIN, new ChunkCoordIntPair(x, z), 1, Unit.INSTANCE);
- return true;
+ if (!generate) {
+ IChunkAccess immediate = world.getChunkProvider().getChunkAtImmediately(x, z);
+ if (immediate == null) {
+ immediate = world.getChunkProvider().playerChunkMap.getUnloadingChunk(x, z);
+ }
+ if (immediate != null) {
+ if (!(immediate instanceof ProtoChunkExtension) && !(immediate instanceof net.minecraft.server.Chunk)) {
+ return false; // not full status
+ }
+ world.getChunkProvider().addTicket(TicketType.PLUGIN, chunkPos, 1, Unit.INSTANCE);
+ world.getChunkAt(x, z); // make sure we're at ticket level 32 or lower
+ return true;
+ }
+
+ net.minecraft.server.RegionFile file;
+ try {
+ file = world.getChunkProvider().playerChunkMap.getRegionFile(chunkPos, false);
@ -382,17 +395,20 @@ index acf151a25..a734a87c4 100644
- if (chunk instanceof ProtoChunkExtension) {
- // We then cycle through again to get the full chunk immediately, rather than after the ticket addition
- chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, true);
+ IChunkAccess immediate = world.getChunkProvider().getChunkAtImmediately(x, z);
+ if (immediate != null) {
+ if (!(immediate instanceof ProtoChunkExtension) && !(immediate instanceof net.minecraft.server.Chunk)) {
+ return null; // not full status
+ }
+ return world.getChunkAt(x, z).bukkitChunk; // make sure we're at ticket level 32 or lower
}
- if (chunk instanceof net.minecraft.server.Chunk) {
- return ((net.minecraft.server.Chunk)chunk).bukkitChunk;
- }
+ if (!gen) {
+
+ IChunkAccess immediate = world.getChunkProvider().getChunkAtImmediately(x, z);
+ if (immediate == null) {
+ immediate = world.getChunkProvider().playerChunkMap.getUnloadingChunk(x, z);
+ }
+ if (immediate != null) {
+ if (!(immediate instanceof ProtoChunkExtension) && !(immediate instanceof net.minecraft.server.Chunk)) {
+ return null; // not full status
+ }
+ return world.getChunkAt(x, z).bukkitChunk; // make sure we're at ticket level 33 or lower
+ }
+
+ net.minecraft.server.RegionFile file;
+ try {
+ file = world.getChunkProvider().playerChunkMap.getRegionFile(chunkPos, false);
@ -409,7 +425,9 @@ index acf151a25..a734a87c4 100644
+ if (!(chunk instanceof ProtoChunkExtension) && !(chunk instanceof net.minecraft.server.Chunk)) {
+ return null;
+ }
+
- if (chunk instanceof net.minecraft.server.Chunk) {
- return ((net.minecraft.server.Chunk)chunk).bukkitChunk;
+ // fall through to load
+ // we load at empty so we don't double-load chunk data in this case
}