Update Asynchronous chunk IO and loading for variable world height limits

This commit is contained in:
Spottedleaf 2021-06-16 02:18:08 -07:00 committed by Jason Penilla
parent 3740db03b4
commit 4b17540b42
No known key found for this signature in database
GPG key ID: 0E75A301420E48F8
3 changed files with 26 additions and 27 deletions

View file

@ -2832,7 +2832,7 @@ index bd937505244cc9305611815a9274f91395d3a8f8..b15d5c2a8d4d2184a55a16ff2071fd82
} finally {
chunkMap.callbackExecutor.run();
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index a86757a96fea11de150fb48ac123c3493e5420b7..f1d08ad4f29eb2b94dc24962bac177397df1110c 100644
index e299bf10c0bdd14398d590939d90cc723ecd4ce5..479bea88e497adfe8cfacd53b5de825bba8e4722 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -210,6 +210,79 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
@ -3049,7 +3049,7 @@ index 3af31dc2c82c11ee78d497c5777615c17cb13c7a..3b8c04f6ffd7e6c197465aa1caf633ba
this.type = t;
this.triggerTick = time;
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
index 22d5c4cc3aea19cbf53ea320765ecceb4daf7428..2621739b8dd11860084ea574c243cb8ba167ac40 100644
index 22d5c4cc3aea19cbf53ea320765ecceb4daf7428..21b3da831cd959e3fd85d437e1ba3c7a6c72502f 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -69,7 +69,30 @@ public class ChunkSerializer {
@ -3133,18 +3133,18 @@ index 22d5c4cc3aea19cbf53ea320765ecceb4daf7428..2621739b8dd11860084ea574c243cb8b
} else {
ProtoChunk protochunk1 = (ProtoChunk) object;
@@ -274,11 +311,83 @@ public class ChunkSerializer {
@@ -274,11 +311,82 @@ public class ChunkSerializer {
protochunk1.setCarvingMask(worldgenstage_features, BitSet.valueOf(nbttagcompound5.getByteArray(s1)));
}
- return protochunk1;
+ return new InProgressChunkHolder(protochunk1, tasksToExecuteOnMain); // Paper - Async chunk loading
}
}
+ }
+ }
+
+ // Paper start - async chunk save for unload
+ public static final class AsyncSaveData {
+ public final DataLayer[] blockLight; // null or size of 17 (for indices -1 through 15)
+ public final DataLayer[] blockLight;
+ public final DataLayer[] skyLight;
+
+ public final ListTag blockTickList; // non-null if we had to go to the server's tick list
@ -3169,10 +3169,10 @@ index 22d5c4cc3aea19cbf53ea320765ecceb4daf7428..2621739b8dd11860084ea574c243cb8b
+
+ ThreadedLevelLightEngine lightenginethreaded = world.getChunkSource().getLightEngine();
+
+ DataLayer[] blockLight = new DataLayer[17 - (-1)];
+ DataLayer[] skyLight = new DataLayer[17 - (-1)];
+ DataLayer[] blockLight = new DataLayer[lightenginethreaded.getMaxLightSection() - lightenginethreaded.getMinLightSection()];
+ DataLayer[] skyLight = new DataLayer[lightenginethreaded.getMaxLightSection() - lightenginethreaded.getMinLightSection()];
+
+ for (int i = -1; i < 17; ++i) {
+ for (int i = lightenginethreaded.getMinLightSection(); i < lightenginethreaded.getMaxLightSection(); ++i) {
+ DataLayer blockArray = lightenginethreaded.getLayerListener(LightLayer.BLOCK).getDataLayerData(SectionPos.of(chunkPos, i));
+ DataLayer skyArray = lightenginethreaded.getLayerListener(LightLayer.SKY).getDataLayerData(SectionPos.of(chunkPos, i));
+
@ -3184,9 +3184,8 @@ index 22d5c4cc3aea19cbf53ea320765ecceb4daf7428..2621739b8dd11860084ea574c243cb8b
+ skyArray = skyArray.copy();
+ }
+
+ // apply offset of 1 for -1 starting index
+ blockLight[i + 1] = blockArray;
+ skyLight[i + 1] = skyArray;
+ blockLight[i - lightenginethreaded.getMinLightSection()] = blockArray;
+ skyLight[i - lightenginethreaded.getMinLightSection()] = skyArray;
+ }
+
+ TickList<Block> blockTickList = chunk.getBlockTicks();
@ -3196,7 +3195,7 @@ index 22d5c4cc3aea19cbf53ea320765ecceb4daf7428..2621739b8dd11860084ea574c243cb8b
+ blockTickListSerialized = null;
+ } else {
+ blockTickListSerialized = world.getBlockTicks().save(chunkPos);
+ }
}
+
+ TickList<Fluid> fluidTickList = chunk.getLiquidTicks();
+
@ -3208,8 +3207,8 @@ index 22d5c4cc3aea19cbf53ea320765ecceb4daf7428..2621739b8dd11860084ea574c243cb8b
+ }
+
+ return new AsyncSaveData(blockLight, skyLight, blockTickListSerialized, fluidTickListSerialized, world.getGameTime());
+ }
+
}
public static CompoundTag write(ServerLevel world, ChunkAccess chunk) {
+ return saveChunk(world, chunk, null);
+ }
@ -3218,7 +3217,7 @@ index 22d5c4cc3aea19cbf53ea320765ecceb4daf7428..2621739b8dd11860084ea574c243cb8b
ChunkPos chunkcoordintpair = chunk.getPos();
CompoundTag nbttagcompound = new CompoundTag();
CompoundTag nbttagcompound1 = new CompoundTag();
@@ -287,7 +396,7 @@ public class ChunkSerializer {
@@ -287,7 +395,7 @@ public class ChunkSerializer {
nbttagcompound.put("Level", nbttagcompound1);
nbttagcompound1.putInt("xPos", chunkcoordintpair.x);
nbttagcompound1.putInt("zPos", chunkcoordintpair.z);
@ -3227,7 +3226,7 @@ index 22d5c4cc3aea19cbf53ea320765ecceb4daf7428..2621739b8dd11860084ea574c243cb8b
nbttagcompound1.putLong("InhabitedTime", chunk.getInhabitedTime());
nbttagcompound1.putString("Status", chunk.getStatus().getName());
UpgradeData chunkconverter = chunk.getUpgradeData();
@@ -306,9 +415,17 @@ public class ChunkSerializer {
@@ -306,9 +414,17 @@ public class ChunkSerializer {
LevelChunkSection chunksection = (LevelChunkSection) Arrays.stream(achunksection).filter((chunksection1) -> {
return chunksection1 != null && SectionPos.blockToSectionCoord(chunksection1.bottomBlockY()) == finalI; // CraftBukkit - decompile errors
}).findFirst().orElse(LevelChunk.EMPTY_SECTION);
@ -3241,14 +3240,14 @@ index 22d5c4cc3aea19cbf53ea320765ecceb4daf7428..2621739b8dd11860084ea574c243cb8b
+ nibblearray = lightenginethreaded.getLayerListener(LightLayer.BLOCK).getDataLayerData(SectionPos.of(chunkcoordintpair, i)); /// Paper - diff on method change (see getAsyncSaveData)
+ nibblearray1 = lightenginethreaded.getLayerListener(LightLayer.SKY).getDataLayerData(SectionPos.of(chunkcoordintpair, i)); // Paper - diff on method change (see getAsyncSaveData)
+ } else {
+ nibblearray = asyncsavedata.blockLight[i + 1]; // +1 to offset the -1 starting index
+ nibblearray1 = asyncsavedata.skyLight[i + 1]; // +1 to offset the -1 starting index
+ nibblearray = asyncsavedata.blockLight[i - lightenginethreaded.getMinLightSection()];
+ nibblearray1 = asyncsavedata.skyLight[i - lightenginethreaded.getMinLightSection()];
+ }
+ // Paper end
if (chunksection != LevelChunk.EMPTY_SECTION || nibblearray != null || nibblearray1 != null) {
CompoundTag nbttagcompound2 = new CompoundTag();
@@ -384,6 +501,10 @@ public class ChunkSerializer {
@@ -384,6 +500,10 @@ public class ChunkSerializer {
nbttagcompound1.put("ToBeTicked", ((ProtoTickList) ticklist).save());
} else if (ticklist instanceof ChunkTickList) {
nbttagcompound1.put("TileTicks", ((ChunkTickList) ticklist).save());
@ -3259,7 +3258,7 @@ index 22d5c4cc3aea19cbf53ea320765ecceb4daf7428..2621739b8dd11860084ea574c243cb8b
} else {
nbttagcompound1.put("TileTicks", world.getBlockTicks().save(chunkcoordintpair));
}
@@ -394,6 +515,10 @@ public class ChunkSerializer {
@@ -394,6 +514,10 @@ public class ChunkSerializer {
nbttagcompound1.put("LiquidsToBeTicked", ((ProtoTickList) ticklist1).save());
} else if (ticklist1 instanceof ChunkTickList) {
nbttagcompound1.put("LiquidTicks", ((ChunkTickList) ticklist1).save());
@ -3659,7 +3658,7 @@ index ad9a4d4a9363741cc47f142c24fa6f4858dd947f..a19de8405de8ee29afc112556e4684b0
// Spigot start
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index e57fef24ee5159142ec4f05a9e76a34c6e153386..d0774636b151e8dbd778f2e2f2e3de154ff18494 100644
index 16e8cfb21f090e0c17e55c1b45ff56bed01839eb..7f1d9932e0e4e09c3727544d053ad61a365290af 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -13,6 +13,7 @@ import net.minecraft.nbt.CompoundTag;

View file

@ -150,10 +150,10 @@ index 6e0cf8ee76143301c939fc4af5eeb091abdcbc5c..066f03ee7b4feda9ec2b0984ee7cf63f
return (ChunkStatus) Registry.CHUNK_STATUS.get(ResourceLocation.tryParse(id));
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
index 2621739b8dd11860084ea574c243cb8ba167ac40..fc320450878279a6aa48019fbde35bb183f5f06e 100644
index 21b3da831cd959e3fd85d437e1ba3c7a6c72502f..1c975b686c1e335d46e63ab12e0a97dd2dcaba13 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -545,6 +545,17 @@ public class ChunkSerializer {
@@ -544,6 +544,17 @@ public class ChunkSerializer {
return nbttagcompound;
}

View file

@ -201,10 +201,10 @@ index 88a2a5c3d588c15989f7cf6df9d2afc3d2ed8ae9..25570730f376665ca6477263d3b3f94d
public String toString() {
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
index 1f95ac18990822a64f0bb2af947693c4b88cdf73..e1330caba0574c94e5343ea1e444b511edf07b05 100644
index dfa628aa486dff135a32a023421c803b8259271a..f4f41b8e807c462aa5f06aed6488b1ef52bae330 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -481,11 +481,11 @@ public class ChunkSerializer {
@@ -480,11 +480,11 @@ public class ChunkSerializer {
}
if (nibblearray != null && !nibblearray.isEmpty()) {