diff --git a/paper-server/nms-patches/net/minecraft/server/level/ChunkMapDistance.patch b/paper-server/nms-patches/net/minecraft/server/level/ChunkMapDistance.patch index b88b2aebda..bb9ae3fb47 100644 --- a/paper-server/nms-patches/net/minecraft/server/level/ChunkMapDistance.patch +++ b/paper-server/nms-patches/net/minecraft/server/level/ChunkMapDistance.patch @@ -1,6 +1,18 @@ --- a/net/minecraft/server/level/ChunkMapDistance.java +++ b/net/minecraft/server/level/ChunkMapDistance.java -@@ -163,7 +163,7 @@ +@@ -121,6 +121,11 @@ + } + + if (!this.chunksToUpdateFutures.isEmpty()) { ++ // CraftBukkit start - SPIGOT-7780: Call chunk unload events before updateHighestAllowedStatus ++ this.chunksToUpdateFutures.forEach((playerchunk) -> { ++ playerchunk.callEventIfUnloading(playerchunkmap); ++ }); ++ // CraftBukkit end + this.chunksToUpdateFutures.forEach((playerchunk) -> { + playerchunk.updateHighestAllowedStatus(playerchunkmap); + }); +@@ -163,7 +168,7 @@ } } @@ -9,7 +21,7 @@ ArraySetSorted> arraysetsorted = this.getTickets(i); int j = getTicketLevelAt(arraysetsorted); Ticket ticket1 = (Ticket) arraysetsorted.addOrGet(ticket); -@@ -173,13 +173,15 @@ +@@ -173,13 +178,15 @@ this.ticketTracker.update(i, ticket.getTicketLevel(), true); } @@ -27,7 +39,7 @@ } if (arraysetsorted.isEmpty()) { -@@ -187,6 +189,7 @@ +@@ -187,6 +194,7 @@ } this.ticketTracker.update(i, getTicketLevelAt(arraysetsorted), false); @@ -35,7 +47,7 @@ } public void addTicket(TicketType tickettype, ChunkCoordIntPair chunkcoordintpair, int i, T t0) { -@@ -200,19 +203,33 @@ +@@ -200,19 +208,33 @@ } public void addRegionTicket(TicketType tickettype, ChunkCoordIntPair chunkcoordintpair, int i, T t0) { @@ -71,7 +83,7 @@ } private ArraySetSorted> getTickets(long i) { -@@ -251,6 +268,7 @@ +@@ -251,6 +273,7 @@ ChunkCoordIntPair chunkcoordintpair = sectionposition.chunk(); long i = chunkcoordintpair.toLong(); ObjectSet objectset = (ObjectSet) this.playersPerChunk.get(i); @@ -79,7 +91,7 @@ objectset.remove(entityplayer); if (objectset.isEmpty()) { -@@ -380,6 +398,26 @@ +@@ -380,6 +403,26 @@ return !this.tickets.isEmpty(); } diff --git a/paper-server/nms-patches/net/minecraft/server/level/PlayerChunk.patch b/paper-server/nms-patches/net/minecraft/server/level/PlayerChunk.patch index 085ee7e4bc..fa19b6b41a 100644 --- a/paper-server/nms-patches/net/minecraft/server/level/PlayerChunk.patch +++ b/paper-server/nms-patches/net/minecraft/server/level/PlayerChunk.patch @@ -82,13 +82,19 @@ }); }); } -@@ -290,6 +310,30 @@ - FullChunkStatus fullchunkstatus1 = ChunkLevel.fullStatus(this.ticketLevel); - boolean flag = fullchunkstatus.isOrAfter(FullChunkStatus.FULL); - boolean flag1 = fullchunkstatus1.isOrAfter(FullChunkStatus.FULL); -+ // CraftBukkit start -+ // ChunkUnloadEvent: Called before the chunk is unloaded: isChunkLoaded is still true and chunk can still be modified by plugins. -+ if (flag && !flag1) { +@@ -285,6 +305,38 @@ + playerchunkmap.onFullChunkStatusChange(this.pos, fullchunkstatus); + } + ++ // CraftBukkit start ++ // ChunkUnloadEvent: Called before the chunk is unloaded: isChunkLoaded is still true and chunk can still be modified by plugins. ++ // SPIGOT-7780: Moved out of updateFutures to call all chunk unload events before calling updateHighestAllowedStatus for all chunks ++ protected void callEventIfUnloading(PlayerChunkMap playerchunkmap) { ++ FullChunkStatus oldFullChunkStatus = ChunkLevel.fullStatus(this.oldTicketLevel); ++ FullChunkStatus newFullChunkStatus = ChunkLevel.fullStatus(this.ticketLevel); ++ boolean oldIsFull = oldFullChunkStatus.isOrAfter(FullChunkStatus.FULL); ++ boolean newIsFull = newFullChunkStatus.isOrAfter(FullChunkStatus.FULL); ++ if (oldIsFull && !newIsFull) { + this.getFullChunkFuture().thenAccept((either) -> { + Chunk chunk = (Chunk) either.orElse(null); + if (chunk != null) { @@ -109,11 +115,13 @@ + // Run callback right away if the future was already done + playerchunkmap.callbackExecutor.run(); + } -+ // CraftBukkit end - - this.wasAccessibleSinceLastSave |= flag1; - if (!flag && flag1) { -@@ -341,6 +385,26 @@ ++ } ++ // CraftBukkit end ++ + protected void updateFutures(PlayerChunkMap playerchunkmap, Executor executor) { + FullChunkStatus fullchunkstatus = ChunkLevel.fullStatus(this.oldTicketLevel); + FullChunkStatus fullchunkstatus1 = ChunkLevel.fullStatus(this.ticketLevel); +@@ -341,6 +393,26 @@ this.onLevelChange.onLevelChange(this.pos, this::getQueueLevel, this.ticketLevel, this::setQueueLevel); this.oldTicketLevel = this.ticketLevel;