2021-09-03 16:55:22 +02:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Shane Freeder <theboyetronic@gmail.com>
|
|
|
|
Date: Fri, 3 Sep 2021 15:50:25 +0100
|
|
|
|
Subject: [PATCH] Do not process entity loads in CraftChunk#getEntities
|
|
|
|
|
|
|
|
This re-introduces the issue behind #5872 but fixes #6543
|
|
|
|
The logic here is generally flawed however somewhat of a nuance,
|
|
|
|
upstream uses managedBlock which is basically needed to process
|
|
|
|
the posted entity adds, but, has the side-effect of processing any
|
|
|
|
chunk loads which has the naunce of stacking up and either causing a
|
|
|
|
massive performance hit, or can potentially lead the server to crash.
|
|
|
|
|
|
|
|
This issue is particularly noticable on paper due to the cumulative efforts
|
|
|
|
to drastically improve chunk loading speeds which means that there is much more
|
|
|
|
of a chance that we're about to eat a dirtload of chunk load callbacks, thus
|
|
|
|
making this issue much more of an issue
|
|
|
|
|
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
2022-03-01 04:25:13 +01:00
|
|
|
index 0085a4dd0f0def1ba71342e20aecdd46a3761b02..0cf67d55ab30ab145ffb2ff562c26c47c2e2879e 100644
|
2021-09-03 16:55:22 +02:00
|
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
|
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
2022-03-01 06:43:03 +01:00
|
|
|
@@ -129,46 +129,6 @@ public class CraftChunk implements Chunk {
|
2021-09-03 16:55:22 +02:00
|
|
|
this.getWorld().getChunkAt(x, z); // Transient load for this tick
|
|
|
|
}
|
|
|
|
|
|
|
|
- PersistentEntitySectionManager<net.minecraft.world.entity.Entity> entityManager = this.getCraftWorld().getHandle().entityManager;
|
|
|
|
- long pair = ChunkPos.asLong(x, z);
|
|
|
|
-
|
2021-11-25 09:10:26 +01:00
|
|
|
- if (entityManager.areEntitiesLoaded(pair)) {
|
2021-09-03 16:55:22 +02:00
|
|
|
- return getCraftWorld().getHandle().getChunkEntities(this.x, this.z); // Paper - optimise this
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- entityManager.ensureChunkQueuedForLoad(pair); // Start entity loading
|
|
|
|
-
|
2021-11-05 15:08:24 +01:00
|
|
|
- // SPIGOT-6772: Use entity mailbox and re-schedule entities if they get unloaded
|
|
|
|
- ProcessorMailbox<Runnable> mailbox = ((EntityStorage) entityManager.permanentStorage).entityDeserializerQueue;
|
|
|
|
- BooleanSupplier supplier = () -> {
|
2021-09-03 16:55:22 +02:00
|
|
|
- // only execute inbox if our entities are not present
|
2021-11-05 15:08:24 +01:00
|
|
|
- if (entityManager.areEntitiesLoaded(pair)) {
|
2021-09-03 16:55:22 +02:00
|
|
|
- return true;
|
|
|
|
- }
|
2021-11-05 15:08:24 +01:00
|
|
|
-
|
|
|
|
- if (!entityManager.isPending(pair)) {
|
|
|
|
- // Our entities got unloaded, this should normally not happen.
|
|
|
|
- entityManager.ensureChunkQueuedForLoad(pair); // Re-start entity loading
|
|
|
|
- }
|
|
|
|
-
|
2021-09-03 16:55:22 +02:00
|
|
|
- // tick loading inbox, which loads the created entities to the world
|
|
|
|
- // (if present)
|
|
|
|
- entityManager.tick();
|
|
|
|
- // check if our entities are loaded
|
|
|
|
- return entityManager.areEntitiesLoaded(pair);
|
2021-11-05 15:08:24 +01:00
|
|
|
- };
|
|
|
|
-
|
|
|
|
- // now we wait until the entities are loaded,
|
|
|
|
- // the converting from NBT to entity object is done on the main Thread which is why we wait
|
|
|
|
- while (!supplier.getAsBoolean()) {
|
2021-11-25 09:10:26 +01:00
|
|
|
- if (mailbox.size() != 0) {
|
2021-11-05 15:08:24 +01:00
|
|
|
- mailbox.run();
|
|
|
|
- } else {
|
|
|
|
- Thread.yield();
|
|
|
|
- LockSupport.parkNanos("waiting for entity loading", 100000L);
|
|
|
|
- }
|
|
|
|
- }
|
2021-09-03 16:55:22 +02:00
|
|
|
-
|
|
|
|
return getCraftWorld().getHandle().getChunkEntities(this.x, this.z); // Paper - optimise this
|
|
|
|
}
|
|
|
|
|