Folia/patches/server/0021-Do-not-read-tile-entities-in-chunks-that-are-positio.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
3.2 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sun, 18 Jun 2023 23:04:46 -0700
Subject: [PATCH] Do not read tile entities in chunks that are positioned
outside of the chunk
The tile entities are not accessible and so should not be loaded.
This can happen as a result of users moving regionfiles around,
which would cause a crash on Folia but would appear to function
fine on Paper.
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 bc938c2a4cb30f3151b600ab88ca5c4e9734f326..035b06d00aadc67eb247efd7b25aea92ba0532a2 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -381,6 +381,13 @@ public class ChunkSerializer {
for (int k1 = 0; k1 < nbttaglist3.size(); ++k1) {
CompoundTag nbttagcompound4 = nbttaglist3.getCompound(k1);
+ // Paper start - do not read tile entities positioned outside the chunk
+ BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound4);
+ if ((blockposition.getX() >> 4) != chunkPos.x || (blockposition.getZ() >> 4) != chunkPos.z) {
+ LOGGER.warn("Tile entity serialized in chunk " + chunkPos + " in world '" + world.getWorld().getName() + "' positioned at " + blockposition + " is located outside of the chunk");
+ continue;
+ }
+ // Paper end - do not read tile entities positioned outside the chunk
((ChunkAccess) object1).setBlockEntityNbt(nbttagcompound4);
}
@@ -679,10 +686,19 @@ public class ChunkSerializer {
CompoundTag nbttagcompound1 = nbttaglist1.getCompound(i);
boolean flag = nbttagcompound1.getBoolean("keepPacked");
+ // Paper start - do not read tile entities positioned outside the chunk
+ BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound1); // moved up
+ ChunkPos chunkPos = chunk.getPos();
+ if ((blockposition.getX() >> 4) != chunkPos.x || (blockposition.getZ() >> 4) != chunkPos.z) {
+ LOGGER.warn("Tile entity serialized in chunk " + chunkPos + " in world '" + world.getWorld().getName() + "' positioned at " + blockposition + " is located outside of the chunk");
+ continue;
+ }
+ // Paper end - do not read tile entities positioned outside the chunk
+
if (flag) {
chunk.setBlockEntityNbt(nbttagcompound1);
} else {
- BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound1);
+ // Paper - do not read tile entities positioned outside the chunk - move up
BlockEntity tileentity = BlockEntity.loadStatic(blockposition, chunk.getBlockState(blockposition), nbttagcompound1);
if (tileentity != null) {