diff options
Diffstat (limited to 'patch-remap/mache-spigotflower-stripped/net/minecraft/server/level/ChunkHolder.java.patch')
-rw-r--r-- | patch-remap/mache-spigotflower-stripped/net/minecraft/server/level/ChunkHolder.java.patch | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/patch-remap/mache-spigotflower-stripped/net/minecraft/server/level/ChunkHolder.java.patch b/patch-remap/mache-spigotflower-stripped/net/minecraft/server/level/ChunkHolder.java.patch new file mode 100644 index 0000000000..3e97a8baff --- /dev/null +++ b/patch-remap/mache-spigotflower-stripped/net/minecraft/server/level/ChunkHolder.java.patch @@ -0,0 +1,122 @@ +--- a/net/minecraft/server/level/ChunkHolder.java ++++ b/net/minecraft/server/level/ChunkHolder.java +@@ -36,6 +36,10 @@ + import net.minecraft.world.level.chunk.ProtoChunk; + import net.minecraft.world.level.lighting.LevelLightEngine; + ++// CraftBukkit start ++import net.minecraft.server.MinecraftServer; ++// CraftBukkit end ++ + public class ChunkHolder { + + public static final Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> UNLOADED_CHUNK = Either.right(ChunkHolder.ChunkLoadingFailure.UNLOADED); +@@ -90,9 +94,23 @@ + this.changedBlocksPerSection = new ShortSet[levelheightaccessor.getSectionsCount()]; + } + +- public CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> getFutureIfPresentUnchecked(ChunkStatus chunkstatus) { +- CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = (CompletableFuture) this.futures.get(chunkstatus.getIndex()); ++ // CraftBukkit start ++ public LevelChunk getFullChunkNow() { ++ // Note: We use the oldTicketLevel for isLoaded checks. ++ if (!ChunkLevel.fullStatus(this.oldTicketLevel).isOrAfter(FullChunkStatus.FULL)) return null; ++ return this.getFullChunkNowUnchecked(); ++ } + ++ public LevelChunk getFullChunkNowUnchecked() { ++ CompletableFuture<Either<ChunkAccess, ChunkHolder.Failure>> statusFuture = this.getFutureIfPresentUnchecked(ChunkStatus.FULL); ++ Either<ChunkAccess, ChunkHolder.Failure> either = (Either<ChunkAccess, ChunkHolder.Failure>) statusFuture.getNow(null); ++ return (either == null) ? null : (LevelChunk) either.left().orElse(null); ++ } ++ // CraftBukkit end ++ ++ public CompletableFuture<Either<ChunkAccess, ChunkHolder.Failure>> getFutureIfPresentUnchecked(ChunkStatus chunkStatus) { ++ CompletableFuture<Either<ChunkAccess, ChunkHolder.Failure>> completablefuture = (CompletableFuture) this.futures.get(chunkStatus.getIndex()); ++ + return completablefuture == null ? ChunkHolder.UNLOADED_CHUNK_FUTURE : completablefuture; + } + +@@ -179,6 +197,7 @@ + if (levelchunk != null) { + int i = this.levelHeightAccessor.getSectionIndex(blockpos.getY()); + ++ if (i < 0 || i >= this.changedBlocksPerSection.length) return; // CraftBukkit - SPIGOT-6086, SPIGOT-6296 + if (this.changedBlocksPerSection[i] == null) { + this.hasChangedSections = true; + this.changedBlocksPerSection[i] = new ShortOpenHashSet(); +@@ -256,9 +275,12 @@ + LevelChunkSection levelchunksection = levelchunk.getSection(i); + ClientboundSectionBlocksUpdatePacket clientboundsectionblocksupdatepacket = new ClientboundSectionBlocksUpdatePacket(sectionpos, shortset, levelchunksection); + +- this.broadcast(list, clientboundsectionblocksupdatepacket); +- clientboundsectionblocksupdatepacket.runUpdates((blockpos1, blockstate1) -> { +- this.broadcastBlockEntityIfNeeded(list, level, blockpos1, blockstate1); ++ this.broadcast(list, packetplayoutmultiblockchange); ++ // CraftBukkit start ++ List finalList = list; ++ packetplayoutmultiblockchange.runUpdates((blockposition1, iblockdata1) -> { ++ this.broadcastBlockEntityIfNeeded(finalList, world, blockposition1, iblockdata1); ++ // CraftBukkit end + }); + } + } +@@ -411,7 +433,31 @@ + boolean flag1 = ChunkLevel.isLoaded(this.ticketLevel); + FullChunkStatus fullchunkstatus = ChunkLevel.fullStatus(this.oldTicketLevel); + FullChunkStatus fullchunkstatus1 = ChunkLevel.fullStatus(this.ticketLevel); ++ // CraftBukkit start ++ // ChunkUnloadEvent: Called before the chunk is unloaded: isChunkLoaded is still true and chunk can still be modified by plugins. ++ if (fullchunkstatus.isOrAfter(FullChunkStatus.FULL) && !fullchunkstatus1.isOrAfter(FullChunkStatus.FULL)) { ++ this.getFutureIfPresentUnchecked(ChunkStatus.FULL).thenAccept((either) -> { ++ LevelChunk chunk = (LevelChunk)either.left().orElse(null); ++ if (chunk != null) { ++ chunkMap.callbackExecutor.execute(() -> { ++ // Minecraft will apply the chunks tick lists to the world once the chunk got loaded, and then store the tick ++ // lists again inside the chunk once the chunk becomes inaccessible and set the chunk's needsSaving flag. ++ // These actions may however happen deferred, so we manually set the needsSaving flag already here. ++ chunk.setUnsaved(true); ++ chunk.unloadCallback(); ++ }); ++ } ++ }).exceptionally((throwable) -> { ++ // ensure exceptions are printed, by default this is not the case ++ MinecraftServer.LOGGER.error("Failed to schedule unload callback for chunk " + ChunkHolder.this.pos, throwable); ++ return null; ++ }); + ++ // Run callback right away if the future was already done ++ chunkMap.callbackExecutor.run(); ++ } ++ // CraftBukkit end ++ + if (flag) { + Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> either = Either.right(new ChunkHolder.ChunkLoadingFailure() { + @Override +@@ -482,6 +527,26 @@ + + this.onLevelChange.onLevelChange(this.pos, this::getQueueLevel, this.ticketLevel, this::setQueueLevel); + this.oldTicketLevel = this.ticketLevel; ++ // CraftBukkit start ++ // ChunkLoadEvent: Called after the chunk is loaded: isChunkLoaded returns true and chunk is ready to be modified by plugins. ++ if (!fullchunkstatus.isOrAfter(FullChunkStatus.FULL) && fullchunkstatus1.isOrAfter(FullChunkStatus.FULL)) { ++ this.getFutureIfPresentUnchecked(ChunkStatus.FULL).thenAccept((either) -> { ++ LevelChunk chunk = (LevelChunk)either.left().orElse(null); ++ if (chunk != null) { ++ chunkMap.callbackExecutor.execute(() -> { ++ chunk.loadCallback(); ++ }); ++ } ++ }).exceptionally((throwable) -> { ++ // ensure exceptions are printed, by default this is not the case ++ MinecraftServer.LOGGER.error("Failed to schedule load callback for chunk " + ChunkHolder.this.pos, throwable); ++ return null; ++ }); ++ ++ // Run callback right away if the future was already done ++ chunkMap.callbackExecutor.run(); ++ } ++ // CraftBukkit end + } + + public boolean wasAccessibleSinceLastSave() { |