mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-26 22:40:21 +01:00
Update ticklist saving
This commit is contained in:
parent
18c9e5f964
commit
28b02df594
1 changed files with 128 additions and 149 deletions
|
@ -2317,7 +2317,7 @@ index 303125c4d0f8f235703975eab5eccb9aa045ccf8..5b999da8c5ad430f9157276857165596
|
||||||
ChunkHolder.FullChunkStatus playerchunk_state1 = ChunkHolder.getFullChunkStatus(this.ticketLevel);
|
ChunkHolder.FullChunkStatus playerchunk_state1 = ChunkHolder.getFullChunkStatus(this.ticketLevel);
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||||
index 0727c025e87e889861b2f3e78e28d4d17840ff54..67bc31c2313151cfb9afa8d812f74786fe6b3878 100644
|
index 0727c025e87e889861b2f3e78e28d4d17840ff54..a605b0868b8214408e20419e336ad52659b12e4f 100644
|
||||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||||
@@ -492,6 +492,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
@@ -492,6 +492,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
|
@ -2376,8 +2376,93 @@ index 0727c025e87e889861b2f3e78e28d4d17840ff54..67bc31c2313151cfb9afa8d812f74786
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
activityAccountant.endActivity(); // Spigot
|
activityAccountant.endActivity(); // Spigot
|
||||||
@@ -594,6 +601,46 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
@@ -613,7 +620,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
|
((LevelChunk) ichunkaccess).setLoaded(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
- this.save(ichunkaccess);
|
||||||
|
+ // Paper start - async chunk saving
|
||||||
|
+ try {
|
||||||
|
+ this.asyncSave(ichunkaccess);
|
||||||
|
+ } catch (ThreadDeath ex) {
|
||||||
|
+ throw ex; // bye
|
||||||
|
+ } catch (Throwable ex) {
|
||||||
|
+ LOGGER.fatal("Failed to prepare async save, attempting synchronous save", ex);
|
||||||
|
+ this.save(ichunkaccess);
|
||||||
|
+ }
|
||||||
|
+ // Paper end - async chunk saving
|
||||||
|
if (this.entitiesInLevel.remove(pos) && ichunkaccess instanceof LevelChunk) {
|
||||||
|
LevelChunk chunk = (LevelChunk) ichunkaccess;
|
||||||
|
|
||||||
|
@@ -678,20 +694,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> scheduleChunkLoad(ChunkPos pos) {
|
||||||
|
- return CompletableFuture.supplyAsync(() -> {
|
||||||
|
+ // Paper start - Async chunk io
|
||||||
|
+ final java.util.function.BiFunction<ChunkSerializer.InProgressChunkHolder, Throwable, Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> syncLoadComplete = (chunkHolder, ioThrowable) -> {
|
||||||
|
try (Timing ignored = this.level.timings.chunkLoad.startTimingIfSync()) { // Paper
|
||||||
|
this.level.getProfiler().incrementCounter("chunkLoad");
|
||||||
|
- CompoundTag nbttagcompound; // Paper
|
||||||
|
- try (Timing ignored2 = this.level.timings.chunkIO.startTimingIfSync()) { // Paper start - timings
|
||||||
|
- nbttagcompound = this.readChunk(pos);
|
||||||
|
- } // Paper end
|
||||||
|
-
|
||||||
|
- if (nbttagcompound != null) {try (Timing ignored2 = this.level.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings
|
||||||
|
- boolean flag = nbttagcompound.contains("Status", 8);
|
||||||
|
-
|
||||||
|
- if (flag) {
|
||||||
|
- ProtoChunk protochunk = ChunkSerializer.read(this.level, this.poiManager, pos, nbttagcompound);
|
||||||
|
+ // Paper start
|
||||||
|
+ if (ioThrowable != null) {
|
||||||
|
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(ioThrowable);
|
||||||
|
+ }
|
||||||
|
+ this.poiManager.loadInData(pos, chunkHolder.poiData);
|
||||||
|
+ chunkHolder.tasks.forEach(Runnable::run);
|
||||||
|
+ // Paper end
|
||||||
|
|
||||||
|
+ if (chunkHolder.protoChunk != null) {try (Timing ignored2 = this.level.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings // Paper - chunk is created async
|
||||||
|
+ if (true) {
|
||||||
|
+ ProtoChunk protochunk = chunkHolder.protoChunk;
|
||||||
|
this.markPosition(pos, protochunk.getStatus().getChunkType());
|
||||||
|
return Either.left(protochunk);
|
||||||
|
}
|
||||||
|
@@ -713,7 +730,32 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
|
|
||||||
|
this.markPositionReplaceable(pos);
|
||||||
|
return Either.left(new ProtoChunk(pos, UpgradeData.EMPTY, this.level, this.level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), (BlendingData) null));
|
||||||
|
- }, this.mainThreadExecutor);
|
||||||
|
+ // Paper start - Async chunk io
|
||||||
|
+ };
|
||||||
|
+ CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> ret = new CompletableFuture<>();
|
||||||
|
+
|
||||||
|
+ Consumer<ChunkSerializer.InProgressChunkHolder> chunkHolderConsumer = (ChunkSerializer.InProgressChunkHolder holder) -> {
|
||||||
|
+ // Go into the chunk load queue and not server task queue so we can be popped out even faster.
|
||||||
|
+ com.destroystokyo.paper.io.chunk.ChunkTaskManager.queueChunkWaitTask(() -> {
|
||||||
|
+ try {
|
||||||
|
+ ret.complete(syncLoadComplete.apply(holder, null));
|
||||||
|
+ } catch (Exception e) {
|
||||||
|
+ ret.completeExceptionally(e);
|
||||||
|
+ }
|
||||||
|
+ });
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ CompletableFuture<CompoundTag> chunkSaveFuture = this.level.asyncChunkTaskManager.getChunkSaveFuture(pos.x, pos.z);
|
||||||
|
+ if (chunkSaveFuture != null) {
|
||||||
|
+ this.level.asyncChunkTaskManager.scheduleChunkLoad(pos.x, pos.z,
|
||||||
|
+ com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGH_PRIORITY, chunkHolderConsumer, false, chunkSaveFuture);
|
||||||
|
+ this.level.asyncChunkTaskManager.raisePriority(pos.x, pos.z, com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGH_PRIORITY);
|
||||||
|
+ } else {
|
||||||
|
+ this.level.asyncChunkTaskManager.scheduleChunkLoad(pos.x, pos.z,
|
||||||
|
+ com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY, chunkHolderConsumer, false);
|
||||||
|
+ }
|
||||||
|
+ return ret;
|
||||||
|
+ // Paper end
|
||||||
|
}
|
||||||
|
|
||||||
|
private void markPositionReplaceable(ChunkPos pos) {
|
||||||
|
@@ -895,7 +937,48 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
|
return this.tickingGenerated.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
+ // Paper start - async chunk save for unload
|
+ // Paper start - async chunk save for unload
|
||||||
|
@ -2420,97 +2505,6 @@ index 0727c025e87e889861b2f3e78e28d4d17840ff54..67bc31c2313151cfb9afa8d812f74786
|
||||||
+ }
|
+ }
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
+
|
+
|
||||||
private void scheduleUnload(long pos, ChunkHolder holder) {
|
|
||||||
CompletableFuture<ChunkAccess> completablefuture = holder.getChunkToSave();
|
|
||||||
Consumer<ChunkAccess> consumer = (ichunkaccess) -> { // CraftBukkit - decompile error
|
|
||||||
@@ -613,7 +660,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
||||||
((LevelChunk) ichunkaccess).setLoaded(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
- this.save(ichunkaccess);
|
|
||||||
+ // Paper start - async chunk saving
|
|
||||||
+ try {
|
|
||||||
+ this.asyncSave(ichunkaccess);
|
|
||||||
+ } catch (ThreadDeath ex) {
|
|
||||||
+ throw ex; // bye
|
|
||||||
+ } catch (Throwable ex) {
|
|
||||||
+ LOGGER.fatal("Failed to prepare async save, attempting synchronous save", ex);
|
|
||||||
+ this.save(ichunkaccess);
|
|
||||||
+ }
|
|
||||||
+ // Paper end - async chunk saving
|
|
||||||
if (this.entitiesInLevel.remove(pos) && ichunkaccess instanceof LevelChunk) {
|
|
||||||
LevelChunk chunk = (LevelChunk) ichunkaccess;
|
|
||||||
|
|
||||||
@@ -678,20 +734,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
private CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> scheduleChunkLoad(ChunkPos pos) {
|
|
||||||
- return CompletableFuture.supplyAsync(() -> {
|
|
||||||
+ // Paper start - Async chunk io
|
|
||||||
+ final java.util.function.BiFunction<ChunkSerializer.InProgressChunkHolder, Throwable, Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> syncLoadComplete = (chunkHolder, ioThrowable) -> {
|
|
||||||
try (Timing ignored = this.level.timings.chunkLoad.startTimingIfSync()) { // Paper
|
|
||||||
this.level.getProfiler().incrementCounter("chunkLoad");
|
|
||||||
- CompoundTag nbttagcompound; // Paper
|
|
||||||
- try (Timing ignored2 = this.level.timings.chunkIO.startTimingIfSync()) { // Paper start - timings
|
|
||||||
- nbttagcompound = this.readChunk(pos);
|
|
||||||
- } // Paper end
|
|
||||||
-
|
|
||||||
- if (nbttagcompound != null) {try (Timing ignored2 = this.level.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings
|
|
||||||
- boolean flag = nbttagcompound.contains("Status", 8);
|
|
||||||
-
|
|
||||||
- if (flag) {
|
|
||||||
- ProtoChunk protochunk = ChunkSerializer.read(this.level, this.poiManager, pos, nbttagcompound);
|
|
||||||
+ // Paper start
|
|
||||||
+ if (ioThrowable != null) {
|
|
||||||
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(ioThrowable);
|
|
||||||
+ }
|
|
||||||
+ this.poiManager.loadInData(pos, chunkHolder.poiData);
|
|
||||||
+ chunkHolder.tasks.forEach(Runnable::run);
|
|
||||||
+ // Paper end
|
|
||||||
|
|
||||||
+ if (chunkHolder.protoChunk != null) {try (Timing ignored2 = this.level.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings // Paper - chunk is created async
|
|
||||||
+ if (true) {
|
|
||||||
+ ProtoChunk protochunk = chunkHolder.protoChunk;
|
|
||||||
this.markPosition(pos, protochunk.getStatus().getChunkType());
|
|
||||||
return Either.left(protochunk);
|
|
||||||
}
|
|
||||||
@@ -713,7 +770,32 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
||||||
|
|
||||||
this.markPositionReplaceable(pos);
|
|
||||||
return Either.left(new ProtoChunk(pos, UpgradeData.EMPTY, this.level, this.level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), (BlendingData) null));
|
|
||||||
- }, this.mainThreadExecutor);
|
|
||||||
+ // Paper start - Async chunk io
|
|
||||||
+ };
|
|
||||||
+ CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> ret = new CompletableFuture<>();
|
|
||||||
+
|
|
||||||
+ Consumer<ChunkSerializer.InProgressChunkHolder> chunkHolderConsumer = (ChunkSerializer.InProgressChunkHolder holder) -> {
|
|
||||||
+ // Go into the chunk load queue and not server task queue so we can be popped out even faster.
|
|
||||||
+ com.destroystokyo.paper.io.chunk.ChunkTaskManager.queueChunkWaitTask(() -> {
|
|
||||||
+ try {
|
|
||||||
+ ret.complete(syncLoadComplete.apply(holder, null));
|
|
||||||
+ } catch (Exception e) {
|
|
||||||
+ ret.completeExceptionally(e);
|
|
||||||
+ }
|
|
||||||
+ });
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ CompletableFuture<CompoundTag> chunkSaveFuture = this.level.asyncChunkTaskManager.getChunkSaveFuture(pos.x, pos.z);
|
|
||||||
+ if (chunkSaveFuture != null) {
|
|
||||||
+ this.level.asyncChunkTaskManager.scheduleChunkLoad(pos.x, pos.z,
|
|
||||||
+ com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGH_PRIORITY, chunkHolderConsumer, false, chunkSaveFuture);
|
|
||||||
+ this.level.asyncChunkTaskManager.raisePriority(pos.x, pos.z, com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGH_PRIORITY);
|
|
||||||
+ } else {
|
|
||||||
+ this.level.asyncChunkTaskManager.scheduleChunkLoad(pos.x, pos.z,
|
|
||||||
+ com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY, chunkHolderConsumer, false);
|
|
||||||
+ }
|
|
||||||
+ return ret;
|
|
||||||
+ // Paper end
|
|
||||||
}
|
|
||||||
|
|
||||||
private void markPositionReplaceable(ChunkPos pos) {
|
|
||||||
@@ -896,6 +978,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean save(ChunkAccess chunk) {
|
public boolean save(ChunkAccess chunk) {
|
||||||
+ try (co.aikar.timings.Timing ignored = this.level.timings.chunkSave.startTiming()) { // Paper
|
+ try (co.aikar.timings.Timing ignored = this.level.timings.chunkSave.startTiming()) { // Paper
|
||||||
this.poiManager.flush(chunk.getPos());
|
this.poiManager.flush(chunk.getPos());
|
||||||
|
@ -2944,7 +2938,7 @@ index 2a73700b0cd31e2a88c478b884de0a7f3d018259..0a1e667487e2c7849e11c0395816dc8c
|
||||||
HAS_SPACE(PoiRecord::hasSpace),
|
HAS_SPACE(PoiRecord::hasSpace),
|
||||||
IS_OCCUPIED(PoiRecord::isOccupied),
|
IS_OCCUPIED(PoiRecord::isOccupied),
|
||||||
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
|
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 2fd969d1450d1251c139f3721d146fd2e191c4dd..2801737d3fd55d268690f46881c6dd7d3f8d5bf3 100644
|
index 2fd969d1450d1251c139f3721d146fd2e191c4dd..ff53c9238325e025c502886cc5f4bc02b25f8fda 100644
|
||||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||||
@@ -75,7 +75,31 @@ public class ChunkSerializer {
|
@@ -75,7 +75,31 @@ public class ChunkSerializer {
|
||||||
|
@ -3029,37 +3023,25 @@ index 2fd969d1450d1251c139f3721d146fd2e191c4dd..2801737d3fd55d268690f46881c6dd7d
|
||||||
} else {
|
} else {
|
||||||
ProtoChunk protochunk1 = (ProtoChunk) object;
|
ProtoChunk protochunk1 = (ProtoChunk) object;
|
||||||
|
|
||||||
@@ -297,10 +335,89 @@ public class ChunkSerializer {
|
@@ -297,10 +335,67 @@ public class ChunkSerializer {
|
||||||
protochunk1.setCarvingMask(worldgenstage_features, new CarvingMask(nbttagcompound4.getLongArray(s1), ((ChunkAccess) object).getMinBuildHeight()));
|
protochunk1.setCarvingMask(worldgenstage_features, new CarvingMask(nbttagcompound4.getLongArray(s1), ((ChunkAccess) object).getMinBuildHeight()));
|
||||||
}
|
}
|
||||||
|
|
||||||
- return protochunk1;
|
- return protochunk1;
|
||||||
+ return new InProgressChunkHolder(protochunk1, tasksToExecuteOnMain); // Paper - Async chunk loading
|
+ 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;
|
|
||||||
+ public final DataLayer[] skyLight;
|
|
||||||
+
|
|
||||||
+ public final ListTag blockTickList; // non-null if we had to go to the server's tick list
|
|
||||||
+ public final ListTag fluidTickList; // non-null if we had to go to the server's tick list
|
|
||||||
+ public final ListTag blockEntities;
|
|
||||||
+
|
|
||||||
+ public final long worldTime;
|
|
||||||
+
|
|
||||||
+ public AsyncSaveData(DataLayer[] blockLight, DataLayer[] skyLight,
|
|
||||||
+ ListTag blockTickList, ListTag fluidTickList, ListTag blockEntities, long worldTime) {
|
|
||||||
+ this.blockLight = blockLight;
|
|
||||||
+ this.skyLight = skyLight;
|
|
||||||
+ this.blockTickList = blockTickList;
|
|
||||||
+ this.fluidTickList = fluidTickList;
|
|
||||||
+ this.blockEntities = blockEntities;
|
|
||||||
+ this.worldTime = worldTime;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ // Paper start - async chunk save for unload
|
||||||
|
+ public record AsyncSaveData(
|
||||||
|
+ DataLayer[] blockLight,
|
||||||
|
+ DataLayer[] skyLight,
|
||||||
|
+ Tag blockTickList, // non-null if we had to go to the server's tick list
|
||||||
|
+ Tag fluidTickList, // non-null if we had to go to the server's tick list
|
||||||
|
+ ListTag blockEntities,
|
||||||
|
+ long worldTime
|
||||||
|
+ ) {}
|
||||||
|
+
|
||||||
+ // must be called sync
|
+ // must be called sync
|
||||||
+ public static AsyncSaveData getAsyncSaveData(ServerLevel world, ChunkAccess chunk) {
|
+ public static AsyncSaveData getAsyncSaveData(ServerLevel world, ChunkAccess chunk) {
|
||||||
+ org.spigotmc.AsyncCatcher.catchOp("preparation of chunk data for async save");
|
+ org.spigotmc.AsyncCatcher.catchOp("preparation of chunk data for async save");
|
||||||
|
@ -3086,25 +3068,8 @@ index 2fd969d1450d1251c139f3721d146fd2e191c4dd..2801737d3fd55d268690f46881c6dd7d
|
||||||
+ skyLight[i - lightenginethreaded.getMinLightSection()] = skyArray;
|
+ skyLight[i - lightenginethreaded.getMinLightSection()] = skyArray;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ net.minecraft.world.ticks.TickContainerAccess<Block> blockTickList = chunk.getBlockTicks();
|
+ final CompoundTag tickLists = new CompoundTag();
|
||||||
+
|
+ ChunkSerializer.saveTicks(world, tickLists, chunk.getTicksForSerialization());
|
||||||
+ //TODO check ChunkSerializer "block_ticks"
|
|
||||||
+ ListTag blockTickListSerialized = null; // Paper - remove null
|
|
||||||
+ // if (blockTickList instanceof ProtoTickList || blockTickList instanceof ChunkTickList) {
|
|
||||||
+ // blockTickListSerialized = null;
|
|
||||||
+ // } else {
|
|
||||||
+ // blockTickListSerialized = world.getBlockTicks().save(chunkPos);
|
|
||||||
+ // }
|
|
||||||
+
|
|
||||||
+ net.minecraft.world.ticks.TickContainerAccess<Fluid> fluidTickList = chunk.getFluidTicks();
|
|
||||||
+
|
|
||||||
+ //TODO
|
|
||||||
+ ListTag fluidTickListSerialized = null; // Paper - remove null
|
|
||||||
+ // if (fluidTickList instanceof ProtoTickList || fluidTickList instanceof ChunkTickList) {
|
|
||||||
+ // fluidTickListSerialized = null;
|
|
||||||
+ // } else {
|
|
||||||
+ // fluidTickListSerialized = world.getFluidTicks().save(chunkPos);
|
|
||||||
+ // }
|
|
||||||
+
|
+
|
||||||
+ ListTag blockEntitiesSerialized = new ListTag();
|
+ ListTag blockEntitiesSerialized = new ListTag();
|
||||||
+ for (final BlockPos blockPos : chunk.getBlockEntitiesPos()) {
|
+ for (final BlockPos blockPos : chunk.getBlockEntitiesPos()) {
|
||||||
|
@ -3114,24 +3079,31 @@ index 2fd969d1450d1251c139f3721d146fd2e191c4dd..2801737d3fd55d268690f46881c6dd7d
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ return new AsyncSaveData(blockLight, skyLight, blockTickListSerialized, fluidTickListSerialized, blockEntitiesSerialized, world.getGameTime());
|
+ return new AsyncSaveData(
|
||||||
|
+ blockLight,
|
||||||
|
+ skyLight,
|
||||||
|
+ tickLists.get(BLOCK_TICKS_TAG),
|
||||||
|
+ tickLists.get(FLUID_TICKS_TAG),
|
||||||
|
+ blockEntitiesSerialized,
|
||||||
|
+ world.getGameTime()
|
||||||
|
+ );
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
private static void logErrors(ChunkPos chunkPos, int y, String message) {
|
private static void logErrors(ChunkPos chunkPos, int y, String message) {
|
||||||
ChunkSerializer.LOGGER.error("Recoverable errors when loading section [" + chunkPos.x + ", " + y + ", " + chunkPos.z + "]: " + message);
|
ChunkSerializer.LOGGER.error("Recoverable errors when loading section [" + chunkPos.x + ", " + y + ", " + chunkPos.z + "]: " + message);
|
||||||
}
|
}
|
||||||
@@ -310,6 +427,10 @@ public class ChunkSerializer {
|
@@ -310,6 +405,10 @@ public class ChunkSerializer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CompoundTag write(ServerLevel world, ChunkAccess chunk) {
|
public static CompoundTag write(ServerLevel world, ChunkAccess chunk) {
|
||||||
+ return saveChunk(world, chunk, null);
|
+ return saveChunk(world, chunk, null);
|
||||||
+ }
|
+ }
|
||||||
+ public static CompoundTag saveChunk(ServerLevel world, ChunkAccess chunk, AsyncSaveData asyncsavedata) {
|
+ public static CompoundTag saveChunk(ServerLevel world, ChunkAccess chunk, @org.checkerframework.checker.nullness.qual.Nullable AsyncSaveData asyncsavedata) {
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
ChunkPos chunkcoordintpair = chunk.getPos();
|
ChunkPos chunkcoordintpair = chunk.getPos();
|
||||||
CompoundTag nbttagcompound = new CompoundTag();
|
CompoundTag nbttagcompound = new CompoundTag();
|
||||||
|
|
||||||
@@ -317,7 +438,7 @@ public class ChunkSerializer {
|
@@ -317,7 +416,7 @@ public class ChunkSerializer {
|
||||||
nbttagcompound.putInt("xPos", chunkcoordintpair.x);
|
nbttagcompound.putInt("xPos", chunkcoordintpair.x);
|
||||||
nbttagcompound.putInt("yPos", chunk.getMinSection());
|
nbttagcompound.putInt("yPos", chunk.getMinSection());
|
||||||
nbttagcompound.putInt("zPos", chunkcoordintpair.z);
|
nbttagcompound.putInt("zPos", chunkcoordintpair.z);
|
||||||
|
@ -3140,7 +3112,7 @@ index 2fd969d1450d1251c139f3721d146fd2e191c4dd..2801737d3fd55d268690f46881c6dd7d
|
||||||
nbttagcompound.putLong("InhabitedTime", chunk.getInhabitedTime());
|
nbttagcompound.putLong("InhabitedTime", chunk.getInhabitedTime());
|
||||||
nbttagcompound.putString("Status", chunk.getStatus().getName());
|
nbttagcompound.putString("Status", chunk.getStatus().getName());
|
||||||
BlendingData blendingdata = chunk.getBlendingData();
|
BlendingData blendingdata = chunk.getBlendingData();
|
||||||
@@ -360,8 +481,17 @@ public class ChunkSerializer {
|
@@ -360,8 +459,17 @@ public class ChunkSerializer {
|
||||||
for (int i = lightenginethreaded.getMinLightSection(); i < lightenginethreaded.getMaxLightSection(); ++i) {
|
for (int i = lightenginethreaded.getMinLightSection(); i < lightenginethreaded.getMaxLightSection(); ++i) {
|
||||||
int j = chunk.getSectionIndexFromSectionY(i);
|
int j = chunk.getSectionIndexFromSectionY(i);
|
||||||
boolean flag1 = j >= 0 && j < achunksection.length;
|
boolean flag1 = j >= 0 && j < achunksection.length;
|
||||||
|
@ -3160,7 +3132,7 @@ index 2fd969d1450d1251c139f3721d146fd2e191c4dd..2801737d3fd55d268690f46881c6dd7d
|
||||||
|
|
||||||
if (flag1 || nibblearray != null || nibblearray1 != null) {
|
if (flag1 || nibblearray != null || nibblearray1 != null) {
|
||||||
CompoundTag nbttagcompound1 = new CompoundTag();
|
CompoundTag nbttagcompound1 = new CompoundTag();
|
||||||
@@ -399,8 +529,17 @@ public class ChunkSerializer {
|
@@ -399,8 +507,17 @@ public class ChunkSerializer {
|
||||||
nbttagcompound.putBoolean("isLightOn", true);
|
nbttagcompound.putBoolean("isLightOn", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3180,14 +3152,21 @@ index 2fd969d1450d1251c139f3721d146fd2e191c4dd..2801737d3fd55d268690f46881c6dd7d
|
||||||
|
|
||||||
CompoundTag nbttagcompound2;
|
CompoundTag nbttagcompound2;
|
||||||
|
|
||||||
@@ -463,6 +602,7 @@ public class ChunkSerializer {
|
@@ -437,7 +554,14 @@ public class ChunkSerializer {
|
||||||
private static void saveTicks(ServerLevel world, CompoundTag nbt, ChunkAccess.TicksToSave tickSchedulers) {
|
nbttagcompound.put("CarvingMasks", nbttagcompound2);
|
||||||
long i = world.getLevelData().getGameTime();
|
}
|
||||||
|
|
||||||
+ //TODO original patch line 3259
|
+ // Paper start
|
||||||
nbt.put("block_ticks", tickSchedulers.blocks().save(i, (block) -> {
|
+ if (asyncsavedata != null) {
|
||||||
return Registry.BLOCK.getKey(block).toString();
|
+ nbttagcompound.put(BLOCK_TICKS_TAG, asyncsavedata.blockTickList);
|
||||||
}));
|
+ nbttagcompound.put(FLUID_TICKS_TAG, asyncsavedata.fluidTickList);
|
||||||
|
+ } else {
|
||||||
|
ChunkSerializer.saveTicks(world, nbttagcompound, chunk.getTicksForSerialization());
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
nbttagcompound.put("PostProcessing", ChunkSerializer.packOffsets(chunk.getPostProcessing()));
|
||||||
|
CompoundTag nbttagcompound3 = new CompoundTag();
|
||||||
|
Iterator iterator1 = chunk.getHeightmaps().iterator();
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||||
index 0259baec1ceb911f39e733d52d232dec19577550..1fc202caf9051f12192ed479898b01b0a02eebbd 100644
|
index 0259baec1ceb911f39e733d52d232dec19577550..1fc202caf9051f12192ed479898b01b0a02eebbd 100644
|
||||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||||
|
|
Loading…
Reference in a new issue