Folia/patches/server/0020-fixup-Rewrite-chunk-system.patch
Spottedleaf 34039e3709 Fix some issues from Folia test
Player spawn position changing caused any player to log in while
on a boat to trip a thread check. To resolve this, simply reposition
any mounted entities if they are more than 5 blocks away from the player.

In general, this may happen to other entities that are loaded from
chunks as well. In these cases, we can delete the entity if it itself
is not saved in the correct chunk, and we can reposition the mounted
entities if they are not in the correct chunk. For tile entities,
we can simply remove them if they are not in the chunk.

These changes broadly should make loading player/chunk data more
resiliant to bad logic run by plugins.

Also, the Folia test revealed that the chunk generate rate limiter
also affected chunk loading, which was not intended and has been
resolved by exempting already FULL status chunks from the limit.
2023-06-25 14:01:20 -07:00

51 lines
2.8 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sun, 18 Jun 2023 22:56:19 -0700
Subject: [PATCH] fixup! Rewrite chunk system
diff --git a/src/main/java/io/papermc/paper/chunk/system/RegionizedPlayerChunkLoader.java b/src/main/java/io/papermc/paper/chunk/system/RegionizedPlayerChunkLoader.java
index 7b664f32868028758d0c6ee1eaa82efcd83661d2..c5df121d6194a97b20dc390698991b9c72dba538 100644
--- a/src/main/java/io/papermc/paper/chunk/system/RegionizedPlayerChunkLoader.java
+++ b/src/main/java/io/papermc/paper/chunk/system/RegionizedPlayerChunkLoader.java
@@ -788,20 +788,34 @@ public class RegionizedPlayerChunkLoader {
// try to push more chunk generations
final long maxGens = Math.max(0L, Math.min(MAX_RATE, Math.min(this.genQueue.size(), this.getMaxChunkGenerates())));
final int maxGensThisTick = (int)this.chunkGenerateTicketLimiter.takeAllocation(time, genRate, maxGens);
- for (int i = 0; i < maxGensThisTick; ++i) {
- final long chunk = this.genQueue.dequeueLong();
- final byte prev = this.chunkTicketStage.put(chunk, CHUNK_TICKET_STAGE_GENERATING);
+ int ratedGensThisTick = 0;
+ while (!this.genQueue.isEmpty()) {
+ final long chunkKey = this.genQueue.firstLong();
+ final int chunkX = CoordinateUtils.getChunkX(chunkKey);
+ final int chunkZ = CoordinateUtils.getChunkZ(chunkKey);
+ final ChunkAccess chunk = this.world.chunkSource.getChunkAtImmediately(chunkX, chunkZ);
+ if (chunk.getStatus() != ChunkStatus.FULL) {
+ // only rate limit actual generations
+ if ((ratedGensThisTick + 1) > maxGensThisTick) {
+ break;
+ }
+ ++ratedGensThisTick;
+ }
+
+ this.genQueue.dequeueLong();
+
+ final byte prev = this.chunkTicketStage.put(chunkKey, CHUNK_TICKET_STAGE_GENERATING);
if (prev != CHUNK_TICKET_STAGE_LOADED) {
throw new IllegalStateException("Previous state should be " + CHUNK_TICKET_STAGE_LOADED + ", not " + prev);
}
this.pushDelayedTicketOp(
ChunkHolderManager.TicketOperation.addAndRemove(
- chunk,
+ chunkKey,
REGION_PLAYER_TICKET, GENERATED_TICKET_LEVEL, this.idBoxed,
REGION_PLAYER_TICKET, LOADED_TICKET_LEVEL, this.idBoxed
)
);
- this.generatingQueue.enqueue(chunk);
+ this.generatingQueue.enqueue(chunkKey);
}
// try to pull ticking chunks