mirror of
https://github.com/PaperMC/Folia.git
synced 2024-11-25 12:35:23 +01:00
34039e3709
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.
51 lines
2.8 KiB
Diff
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
|