Cleanup async chunks (#3456)

Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
This commit is contained in:
Spottedleaf 2020-05-28 16:34:58 -07:00 committed by GitHub
parent c3c005c947
commit 0d5ec65372
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 61 additions and 175 deletions

View File

@ -334,10 +334,10 @@ index 0000000000000000000000000000000000000000..5af0ac3d9e87c06053e65433060f1577
+}
diff --git a/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java b/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java
new file mode 100644
index 0000000000000000000000000000000000000000..4f10a8311ea931026079c85bb59e223b0122a4a9
index 0000000000000000000000000000000000000000..a6434b4e28a73ecab4350862c5747b7494761ba0
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java
@@ -0,0 +1,661 @@
@@ -0,0 +1,607 @@
+package com.destroystokyo.paper.io;
+
+import net.minecraft.server.ChunkCoordIntPair;
@ -447,48 +447,6 @@ index 0000000000000000000000000000000000000000..4f10a8311ea931026079c85bb59e223b
+ }
+ }
+
+ // Hack start
+ /**
+ * if {@code waitForRead} is true, then this task will wait on an available read task, else it will wait on an available
+ * write task
+ * if {@code poiTask} is true, then this task will wait on a poi task, else it will wait on chunk data task
+ * @deprecated API is garbage and will only work for main thread queueing of tasks (which is vanilla), plugins messing
+ * around asynchronously will give unexpected results
+ * @return whether the task succeeded, or {@code null} if there is no task
+ */
+ @Deprecated
+ public Boolean waitForIOToComplete(final WorldServer world, final int chunkX, final int chunkZ, final boolean waitForRead,
+ final boolean poiTask) {
+ final ChunkDataTask task;
+
+ final Long key = IOUtil.getCoordinateKey(chunkX, chunkZ);
+ if (poiTask) {
+ task = world.poiDataController.tasks.get(key);
+ } else {
+ task = world.chunkDataController.tasks.get(key);
+ }
+
+ if (task == null) {
+ return null;
+ }
+
+ if (waitForRead) {
+ ChunkDataController.InProgressRead read = task.inProgressRead;
+ if (read == null) {
+ return null;
+ }
+ return Boolean.valueOf(read.readFuture.join() != PaperFileIOThread.FAILURE_VALUE);
+ }
+
+ // wait for write
+ ChunkDataController.InProgressWrite write = task.inProgressWrite;
+ if (write == null) {
+ return null;
+ }
+ return Boolean.valueOf(write.wrote.join() != PaperFileIOThread.FAILURE_VALUE);
+ }
+ // Hack end
+
+ public NBTTagCompound getPendingWrite(final WorldServer world, final int chunkX, final int chunkZ, final boolean poiData) {
+ final ChunkDataController taskController = poiData ? world.poiDataController : world.chunkDataController;
+
@ -826,11 +784,6 @@ index 0000000000000000000000000000000000000000..4f10a8311ea931026079c85bb59e223b
+ public static final class InProgressWrite {
+ public long writeCounter;
+ public NBTTagCompound data;
+
+ // Hack start
+ @Deprecated
+ public CompletableFuture<NBTTagCompound> wrote = new CompletableFuture<>();
+ // Hack end
+ }
+
+ public static final class InProgressRead {
@ -883,7 +836,6 @@ index 0000000000000000000000000000000000000000..4f10a8311ea931026079c85bb59e223b
+ void reschedule(final int priority) {
+ // priority is checked before this stage // TODO what
+ this.queue.lazySet(null);
+ this.inProgressWrite.wrote = new CompletableFuture<>(); // Hack
+ this.priority.lazySet(priority);
+ PaperFileIOThread.Holder.INSTANCE.queueTask(this);
+ }
@ -936,7 +888,6 @@ index 0000000000000000000000000000000000000000..4f10a8311ea931026079c85bb59e223b
+ LOGGER.fatal("Couldn't save chunk; already in use by another instance of Minecraft?", ex);
+ // we don't need to set the write counter to -1 as we know at this stage there's no point in re-scheduling
+ // writes since they'll fail anyways.
+ write.wrote.complete(PaperFileIOThread.FAILURE_VALUE); // Hack - However we need to fail the write
+ return;
+ }
+
@ -966,19 +917,14 @@ index 0000000000000000000000000000000000000000..4f10a8311ea931026079c85bb59e223b
+
+ ChunkDataTask inMap = this.taskController.tasks.compute(chunkKey, (final Long keyInMap, final ChunkDataTask valueInMap) -> {
+ if (valueInMap == null) {
+ ChunkDataTask.this.inProgressWrite.wrote.complete(PaperFileIOThread.FAILURE_VALUE); // Hack
+ throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkDataTask.this.toString() + ", report this!");
+ }
+ if (valueInMap != ChunkDataTask.this) {
+ ChunkDataTask.this.inProgressWrite.wrote.complete(PaperFileIOThread.FAILURE_VALUE); // Hack
+ throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkDataTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!");
+ }
+ if (valueInMap.inProgressWrite.writeCounter == writeCounter) {
+ if (finalFailWrite) {
+ valueInMap.inProgressWrite.writeCounter = -1L;
+ valueInMap.inProgressWrite.wrote.complete(PaperFileIOThread.FAILURE_VALUE);
+ } else {
+ valueInMap.inProgressWrite.wrote.complete(data);
+ }
+
+ return null;
@ -3107,7 +3053,7 @@ index 52ea4f05a0c7f29f62f31bb032a5ceb905107e60..0f1576effe10795bcb8ed3b519f4dbaf
completablefuture = (CompletableFuture) this.statusFutures.get(i);
if (completablefuture != null) {
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8a501429a 100644
index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3e381cb5a 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -63,7 +63,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -3308,21 +3254,21 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8
-
- if (nbttagcompound != null) {try (Timing ignored2 = this.world.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings
- boolean flag = nbttagcompound.hasKeyOfType("Level", 10) && nbttagcompound.getCompound("Level").hasKeyOfType("Status", 8);
-
- if (flag) {
- ProtoChunk protochunk = ChunkRegionLoader.loadChunk(this.world, this.definedStructureManager, this.m, chunkcoordintpair, nbttagcompound);
+ if (ioThrowable != null) {
+ com.destroystokyo.paper.io.IOUtil.rethrow(ioThrowable);
+ }
- protochunk.setLastSaved(this.world.getTime());
- return Either.left(protochunk);
- }
- if (flag) {
- ProtoChunk protochunk = ChunkRegionLoader.loadChunk(this.world, this.definedStructureManager, this.m, chunkcoordintpair, nbttagcompound);
+ this.getVillagePlace().loadInData(chunkcoordintpair, chunkHolder.poiData);
+ chunkHolder.tasks.forEach(Runnable::run);
+ // Paper - async load completes this
+ // Paper end
- protochunk.setLastSaved(this.world.getTime());
- return Either.left(protochunk);
- }
-
- PlayerChunkMap.LOGGER.error("Chunk file at {} is missing level data, skipping", chunkcoordintpair);
- }} // Paper
+ // Paper start - This is done async
@ -3368,44 +3314,12 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8
}
private CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> b(PlayerChunk playerchunk, ChunkStatus chunkstatus) {
@@ -823,18 +921,43 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
return this.u.get();
@@ -824,17 +922,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
+ // Paper start - async chunk io
+ private boolean writeDataAsync(ChunkCoordIntPair chunkPos, NBTTagCompound poiData, NBTTagCompound chunkData, boolean async) {
+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.world, chunkPos.x, chunkPos.z,
+ poiData, chunkData, !async ? com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGHEST_PRIORITY : com.destroystokyo.paper.io.PrioritizedTaskQueue.LOW_PRIORITY);
+
+ if (async) {
+ return true;
+ }
+
+ try (co.aikar.timings.Timing ignored = this.world.timings.chunkSaveIOWait.startTiming()) { // Paper
+ Boolean successPoi = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.waitForIOToComplete(this.world, chunkPos.x, chunkPos.z, true, true);
+ Boolean successChunk = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.waitForIOToComplete(this.world, chunkPos.x, chunkPos.z, true, false);
+
+ if (successPoi == Boolean.FALSE || successChunk == Boolean.FALSE) {
+ return false;
+ }
+
+ // null indicates no task existed, which means our write completed before we waited on it
+
+ return true;
+ } // Paper
+ }
+ // Paper end
+
public boolean saveChunk(IChunkAccess ichunkaccess) {
- this.m.a(ichunkaccess.getPos());
+ // Paper start - async param
+ return this.saveChunk(ichunkaccess, true);
+ }
+ public boolean saveChunk(IChunkAccess ichunkaccess, boolean async) {
+ try (co.aikar.timings.Timing ignored = this.world.timings.chunkSave.startTiming()) {
+ NBTTagCompound poiData = this.getVillagePlace().getData(ichunkaccess.getPos()); // Paper
+ //this.m.a(ichunkaccess.getPos()); // Delay
+ // Paper end
+ try (co.aikar.timings.Timing ignored = this.world.timings.chunkSave.startTiming()) { // Paper
this.m.a(ichunkaccess.getPos());
if (!ichunkaccess.isNeedsSaving()) {
return false;
} else {
@ -3420,7 +3334,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8
ichunkaccess.setLastSaved(this.world.getTime());
ichunkaccess.setNeedsSaving(false);
@@ -845,28 +968,35 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -845,6 +938,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
NBTTagCompound nbttagcompound;
if (chunkstatus.getType() != ChunkStatus.Type.LEVELCHUNK) {
@ -3428,29 +3342,24 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8
// Paper start - Optimize save by using status cache
ChunkStatus statusOnDisk = this.getChunkStatusOnDisk(chunkcoordintpair);
if (statusOnDisk != null && statusOnDisk.getType() == ChunkStatus.Type.LEVELCHUNK) {
// Paper end
+ this.writeDataAsync(ichunkaccess.getPos(), poiData, null, async); // Paper - Async chunk io
return false;
}
if (chunkstatus == ChunkStatus.EMPTY && ichunkaccess.h().values().stream().noneMatch(StructureStart::e)) {
+ this.writeDataAsync(ichunkaccess.getPos(), poiData, null, async); // Paper - Async chunk io
return false;
@@ -857,9 +951,15 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
}
this.world.getMethodProfiler().c("chunkSave");
+ } // Paper
this.world.getMethodProfiler().c("chunkSave");
+ try (co.aikar.timings.Timing ignored1 = this.world.timings.chunkSaveDataSerialization.startTiming()) { // Paper
nbttagcompound = ChunkRegionLoader.saveChunk(this.world, ichunkaccess);
- this.a(chunkcoordintpair, nbttagcompound);
- return true;
+ } // Paper
+ return this.writeDataAsync(ichunkaccess.getPos(), poiData, nbttagcompound, async); // Paper - Async chunk io
+ //return true; // Paper
+ // Paper start - async chunk io
+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.world, chunkcoordintpair.x, chunkcoordintpair.z,
+ null, nbttagcompound, com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY);
+ // Paper end - async chunk io
return true;
} catch (Exception exception) {
PlayerChunkMap.LOGGER.error("Failed to save chunk {},{}", chunkcoordintpair.x, chunkcoordintpair.z, exception);
com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception); // Paper
@@ -867,6 +967,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
return false;
}
}
@ -3458,7 +3367,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8
}
protected void setViewDistance(int i) {
@@ -970,6 +1100,42 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -970,6 +1071,35 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
}
@ -3485,13 +3394,6 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8
+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(
+ this.world, chunkcoordintpair.x, chunkcoordintpair.z, null, nbttagcompound,
+ com.destroystokyo.paper.io.IOUtil.getPriorityForCurrentThread());
+
+ Boolean ret = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.waitForIOToComplete(this.world,
+ chunkcoordintpair.x, chunkcoordintpair.z, true, false);
+
+ if (ret == Boolean.FALSE) {
+ throw new IOException("See logs for further detail");
+ }
+ return;
+ }
+ super.write(chunkcoordintpair, nbttagcompound);
@ -3501,7 +3403,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8
@Nullable
public NBTTagCompound readChunkData(ChunkCoordIntPair chunkcoordintpair) throws IOException { // Paper - private -> public
NBTTagCompound nbttagcompound = this.read(chunkcoordintpair);
@@ -992,33 +1158,55 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -992,33 +1122,55 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
// Paper start - chunk status cache "api"
public ChunkStatus getChunkStatusOnDiskIfCached(ChunkCoordIntPair chunkPos) {
@ -3568,7 +3470,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8
}
public IChunkAccess getUnloadingChunk(int chunkX, int chunkZ) {
@@ -1027,6 +1215,39 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1027,6 +1179,39 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
// Paper end
@ -3608,7 +3510,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..71ab7537313bbaf29f13ba3fae45bfb8
boolean isOutsideOfRange(ChunkCoordIntPair chunkcoordintpair) {
// Spigot start
return isOutsideOfRange(chunkcoordintpair, false);
@@ -1374,6 +1595,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1374,6 +1559,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
@ -3954,7 +3856,7 @@ index 75ab9f185b3231113dfa387c956a707b403bb2db..8055f5998213ab1c6c10d03d88d2b14d
public static <T> TicketType<T> a(String s, Comparator<T> comparator) {
return new TicketType<>(s, comparator, 0L);
diff --git a/src/main/java/net/minecraft/server/VillagePlace.java b/src/main/java/net/minecraft/server/VillagePlace.java
index c999f8c9bf8a59e19b3d6d1b7ad8b5fb6e48b928..b59ef1a63338aa150d39e8014e12b2275da26d50 100644
index c999f8c9bf8a59e19b3d6d1b7ad8b5fb6e48b928..1a5ec6152c15a6ece227d4bac00c3b02bd9c5c95 100644
--- a/src/main/java/net/minecraft/server/VillagePlace.java
+++ b/src/main/java/net/minecraft/server/VillagePlace.java
@@ -24,8 +24,16 @@ public class VillagePlace extends RegionFileSection<VillagePlaceSection> {
@ -3999,7 +3901,7 @@ index c999f8c9bf8a59e19b3d6d1b7ad8b5fb6e48b928..b59ef1a63338aa150d39e8014e12b227
this.a.a();
}
@@ -229,6 +253,42 @@ public class VillagePlace extends RegionFileSection<VillagePlaceSection> {
@@ -229,6 +253,35 @@ public class VillagePlace extends RegionFileSection<VillagePlaceSection> {
}
}
@ -4026,13 +3928,6 @@ index c999f8c9bf8a59e19b3d6d1b7ad8b5fb6e48b928..b59ef1a63338aa150d39e8014e12b227
+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(
+ this.world, chunkcoordintpair.x, chunkcoordintpair.z, nbttagcompound, null,
+ com.destroystokyo.paper.io.IOUtil.getPriorityForCurrentThread());
+
+ Boolean ret = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.waitForIOToComplete(this.world,
+ chunkcoordintpair.x, chunkcoordintpair.z, true, true);
+
+ if (ret == Boolean.FALSE) {
+ throw new java.io.IOException("See logs for further detail");
+ }
+ return;
+ }
+ super.write(chunkcoordintpair, nbttagcompound);

View File

@ -8,10 +8,10 @@ Sets tracking range of watermobs to animals instead of misc and simplifies code
Also ignores Enderdragon, defaulting it to Mojang's setting
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 7984dedfde6ba41db873f2de99ba01b6622ea6c7..b1f1372a76167a29f63917cedd1d6bfc99a97eba 100644
index c20acd86beb8f28345d1359d0a2b68b7d8e0e410..4ba661c5a89bebe29c8802387bc93c10094b7606 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -1738,6 +1738,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1702,6 +1702,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next();
int j = entity.getEntityType().getChunkRange() * 16;

View File

@ -7,10 +7,10 @@ Suspected case would be around the technique used in .stopRiding
Stack will identify any causer of this and warn instead of crashing.
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index b1f1372a76167a29f63917cedd1d6bfc99a97eba..c900bfb9edf957ebdbd83cc44280440648288250 100644
index 4ba661c5a89bebe29c8802387bc93c10094b7606..6a2cf0c6f649e7a74b58fc292f57a08c0663b0a4 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -1447,6 +1447,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1411,6 +1411,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
protected void addEntity(Entity entity) {
org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot

View File

@ -83,7 +83,7 @@ index 9f8c0e10e42d233a8b74ee5a71fb8fb6ea8e7480..0d1065688b19ceca9440bc8bf2bf6591
List<PlayerChunk> allChunks = new ArrayList<>(visibleChunks.values());
List<EntityPlayer> players = world.players;
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index c900bfb9edf957ebdbd83cc44280440648288250..8cd77117cdb81e3fbd196415f8ac82d3aeddcb12 100644
index 6a2cf0c6f649e7a74b58fc292f57a08c0663b0a4..ea6b310e8e4741c8bb301e5bc586faca8bea5e06 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -55,8 +55,33 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -227,7 +227,7 @@ index c900bfb9edf957ebdbd83cc44280440648288250..8cd77117cdb81e3fbd196415f8ac82d3
this.updatingChunksModified = false;
return true;
}
@@ -1077,12 +1159,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1048,12 +1130,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
protected Iterable<PlayerChunk> f() {

View File

@ -225,7 +225,7 @@ index b701db638370c0d07d5be0f61c6cbf19168cde8e..4ea3468614df36e1c148a44bb15d2201
}
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 8cd77117cdb81e3fbd196415f8ac82d3aeddcb12..00ad80bb74bd581e3fa1bf82356ee5b7bc656bfe 100644
index ea6b310e8e4741c8bb301e5bc586faca8bea5e06..6bdaaf8daef15cd7c11943254e412e0e2d2898fb 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -485,6 +485,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -236,15 +236,6 @@ index 8cd77117cdb81e3fbd196415f8ac82d3aeddcb12..00ad80bb74bd581e3fa1bf82356ee5b7
mutableboolean.setFalse();
list.stream().map((playerchunk) -> {
CompletableFuture completablefuture;
@@ -497,7 +498,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
return (IChunkAccess) completablefuture.join();
}).filter((ichunkaccess) -> {
return ichunkaccess instanceof ProtoChunkExtension || ichunkaccess instanceof Chunk;
- }).filter(this::saveChunk).forEach((ichunkaccess) -> {
+ }).filter(ichunkaccess1 -> saveChunk(ichunkaccess1, !isShuttingDown)).forEach((ichunkaccess) -> { // Paper - dont save async during shutdown
mutableboolean.setTrue();
});
} while (mutableboolean.isTrue());
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index ab2831830ad3a4cec0671d189e0534c843b47f5e..78040e83899f1ef1a6d5c456beb9d13959307c18 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java

View File

@ -40,10 +40,10 @@ index 64e00275edf38739fe6e2d79dbcb93243e765678..a87aa07b17205b52e85f7d082fa4d516
// CraftBukkit end
public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 9e2998f2214d6129e38acc0cbb59ce19f4c38759..50375629186e5cbe9fd6a36cae348f018cdac9d5 100644
index 48f858388029e77f710365e73905f8570f1103f5..2caa53a7e143aae32918ecbefc1bdadcab8d61ed 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -1539,6 +1539,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1503,6 +1503,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
.printStackTrace();
return;
}

View File

@ -44,7 +44,7 @@ index 3a88c9a67062eb73ad8257ea786efca7e7e99f65..6d3b34ead9cc95dcc1152dffa8c6c4a8
List<Entity> list = this.tracker.getPassengers();
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac721a684ab5 100644
index 3f1a5e48676d1b4b01fbbc25fc9c9cf556cbf0eb..f09bb1329cf993034661fb8cfbf87571fe5f1ebe 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -143,21 +143,51 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -145,7 +145,7 @@ index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac72
}
public void updatePlayerMobTypeMap(Entity entity) {
@@ -1436,17 +1504,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1400,17 +1468,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
public void movePlayer(EntityPlayer entityplayer) {
@ -164,7 +164,7 @@ index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac72
int i = MathHelper.floor(entityplayer.locX()) >> 4;
int j = MathHelper.floor(entityplayer.locZ()) >> 4;
@@ -1563,7 +1621,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1527,7 +1585,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker
this.trackedEntities.put(entity.getId(), playerchunkmap_entitytracker);
@ -173,7 +173,7 @@ index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac72
if (entity instanceof EntityPlayer) {
EntityPlayer entityplayer = (EntityPlayer) entity;
@@ -1607,7 +1665,37 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1571,7 +1629,37 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
entity.tracker = null; // Paper - We're no longer tracked
}
@ -211,7 +211,7 @@ index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac72
List<EntityPlayer> list = Lists.newArrayList();
List<EntityPlayer> list1 = this.world.getPlayers();
@@ -1675,23 +1763,31 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1639,23 +1727,31 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
PacketDebug.a(this.world, chunk.getPos());
List<Entity> list = Lists.newArrayList();
List<Entity> list1 = Lists.newArrayList();
@ -255,7 +255,7 @@ index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac72
Iterator iterator;
Entity entity1;
@@ -1729,7 +1825,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1693,7 +1789,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
public class EntityTracker {
@ -264,7 +264,7 @@ index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac72
private final Entity tracker;
private final int trackingDistance;
private SectionPosition e;
@@ -1746,6 +1842,42 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1710,6 +1806,42 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.e = SectionPosition.a(entity);
}
@ -307,7 +307,7 @@ index a28158d7abb9465f4bd8e6f5c1a789d0a4dad125..7e0e9b74327a76c79658e0bcc61fac72
public boolean equals(Object object) {
return object instanceof PlayerChunkMap.EntityTracker ? ((PlayerChunkMap.EntityTracker) object).tracker.getId() == this.tracker.getId() : false;
}
@@ -1842,7 +1974,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1806,7 +1938,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
int j = entity.getEntityType().getChunkRange() * 16;
j = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, j); // Paper

View File

@ -192,7 +192,7 @@ index afc92dd031cdaf725b85c0b301d5a5a21da54720..6980d19f36c18cdbed6679dbdf04afd6
// Paper start
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 7e0e9b74327a76c79658e0bcc61fac721a684ab5..7380270ae89f3fe134ec76a265f8074b6406f558 100644
index f09bb1329cf993034661fb8cfbf87571fe5f1ebe..74b868d7cec0260a10ca7718f48308f4ec54d56b 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -153,6 +153,17 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -308,7 +308,7 @@ index 7e0e9b74327a76c79658e0bcc61fac721a684ab5..7380270ae89f3fe134ec76a265f8074b
}
if (playerchunk != null) {
@@ -1433,30 +1488,53 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1397,30 +1452,53 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
return isOutsideOfRange(chunkcoordintpair, false);
}

View File

@ -207,7 +207,7 @@ index 6980d19f36c18cdbed6679dbdf04afd694e078b6..03fb688fe4bdc19b4bc36b1f1d5b40c6
public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> a(ChunkStatus chunkstatus, PlayerChunkMap playerchunkmap) {
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae414275164a 100644
index 74b868d7cec0260a10ca7718f48308f4ec54d56b..f832e7cdfc6741a932787f02754f145202ff7887 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -94,7 +94,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -358,7 +358,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41
});
return completablefuture1;
}
@@ -1234,32 +1316,38 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1205,32 +1287,38 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
} // Paper
}
@ -412,7 +412,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41
protected void sendChunk(EntityPlayer entityplayer, ChunkCoordIntPair chunkcoordintpair, Packet<?>[] apacket, boolean flag, boolean flag1) {
if (entityplayer.world == this.world) {
@@ -1267,7 +1355,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1238,7 +1326,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
PlayerChunk playerchunk = this.getVisibleChunk(chunkcoordintpair.pair());
if (playerchunk != null) {
@ -421,7 +421,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41
if (chunk != null) {
this.a(entityplayer, apacket, chunk);
@@ -1536,6 +1624,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1500,6 +1588,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
// Paper end - optimise isOutsideOfRange
@ -429,7 +429,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41
private boolean b(EntityPlayer entityplayer) {
return entityplayer.isSpectator() && !this.world.getGameRules().getBoolean(GameRules.SPECTATORS_GENERATE_CHUNKS);
}
@@ -1563,13 +1652,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1527,13 +1616,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.removePlayerFromDistanceMaps(entityplayer); // Paper - distance maps
}
@ -444,7 +444,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41
}
@@ -1577,7 +1660,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1541,7 +1624,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
SectionPosition sectionposition = SectionPosition.a((Entity) entityplayer);
entityplayer.a(sectionposition);
@ -453,7 +453,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41
return sectionposition;
}
@@ -1622,6 +1705,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1586,6 +1669,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
int k1;
int l1;
@ -461,7 +461,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41
if (Math.abs(i1 - i) <= this.viewDistance * 2 && Math.abs(j1 - j) <= this.viewDistance * 2) {
k1 = Math.min(i, i1) - this.viewDistance;
l1 = Math.min(j, j1) - this.viewDistance;
@@ -1659,7 +1743,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1623,7 +1707,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.sendChunk(entityplayer, chunkcoordintpair1, new Packet[2], false, true);
}
}
@ -470,7 +470,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41
this.updateMaps(entityplayer); // Paper - distance maps
@@ -1667,11 +1751,46 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1631,11 +1715,46 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@Override
public Stream<EntityPlayer> a(ChunkCoordIntPair chunkcoordintpair, boolean flag) {
@ -521,7 +521,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41
}
protected void addEntity(Entity entity) {
@@ -1831,6 +1950,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1795,6 +1914,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
@ -529,7 +529,7 @@ index 7380270ae89f3fe134ec76a265f8074b6406f558..e90c5e1048b0564cd0d703d550a3ae41
private void a(EntityPlayer entityplayer, Packet<?>[] apacket, Chunk chunk) {
if (apacket[0] == null) {
apacket[0] = new PacketPlayOutMapChunk(chunk, 65535);
@@ -2016,7 +2136,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1980,7 +2100,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(this.tracker.chunkX, this.tracker.chunkZ);
PlayerChunk playerchunk = PlayerChunkMap.this.getVisibleChunk(chunkcoordintpair.pair());

View File

@ -39,10 +39,10 @@ index 6d3b34ead9cc95dcc1152dffa8c6c4a8c7f1d58b..5cc89c0cf9e9e632212a9653391437cb
if (!flag4 && this.o <= 400 && !this.q && this.r == this.tracker.onGround) {
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 1c3526dda5c20264e21d079fd1aff1a735a9e496..2dd7999b6a540efd1e2e974f33ed87a6d0a8e8f1 100644
index f361939b9ae451bdccf7922e9cca09344c6152b5..68dd9220bb360c75057919fed0598b415b947e4d 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -2132,9 +2132,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -2096,9 +2096,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
public void updatePlayer(EntityPlayer entityplayer) {
org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
if (entityplayer != this.tracker) {

View File

@ -37,7 +37,7 @@ index b7b06e082e59f8518be2036637385c7710d524ea..71da9f00b8a969e84414066fb1852cec
return chunksection == Chunk.a || chunksection.c();
}
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 2dd7999b6a540efd1e2e974f33ed87a6d0a8e8f1..4a9d6f0c193c6d8a65d548ac1dd1461e7056f0a4 100644
index 68dd9220bb360c75057919fed0598b415b947e4d..0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -402,7 +402,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -49,7 +49,7 @@ index 2dd7999b6a540efd1e2e974f33ed87a6d0a8e8f1..4a9d6f0c193c6d8a65d548ac1dd1461e
},
(EntityPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ,
com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> newState) -> {
@@ -1957,12 +1957,112 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1921,12 +1921,112 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}