mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-12 01:41:05 +01:00
157 lines
7.7 KiB
Diff
157 lines
7.7 KiB
Diff
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Aikar <aikar@aikar.co>
|
||
|
Date: Sat, 12 Sep 2020 22:20:55 -0400
|
||
|
Subject: [PATCH] Only consider chunks Loaded if at BORDER status
|
||
|
|
||
|
This greatly improves performance as it drastically reduces the amount
|
||
|
of Entities and Tile Entities that are "registered" into the world, as
|
||
|
purely "cached" chunks will no longer have their entities hanging out in the world.
|
||
|
|
||
|
Additionally this fixes our Entity Add To World and Entity Remove From World events
|
||
|
|
||
|
Those events have not been firing correctly since MC changed how chunks work here.
|
||
|
|
||
|
Now the server will only consider a chunk "loaded" if it's got a ticket putting
|
||
|
it at level 33 or lower, which matches the public Bukkit API.
|
||
|
|
||
|
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
||
|
index 299d7d7a55532930e2d4340a6cfe77a5fd8a0a0c..15c0a06139bffc6a7f83a1d47f2a708f14d264ec 100644
|
||
|
--- a/src/main/java/net/minecraft/server/Chunk.java
|
||
|
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
||
|
@@ -791,6 +791,7 @@ public class Chunk implements IChunkAccess {
|
||
|
int chunkX = this.loc.x;
|
||
|
int chunkZ = this.loc.z;
|
||
|
ChunkProviderServer chunkProvider = ((WorldServer)this.world).getChunkProvider();
|
||
|
+ chunkProvider.playerChunkMap.loadChunk(this); // Paper - move load logic from the entering full status to when it enters border status instead
|
||
|
for (int dx = -NEIGHBOUR_CACHE_RADIUS; dx <= NEIGHBOUR_CACHE_RADIUS; ++dx) {
|
||
|
for (int dz = -NEIGHBOUR_CACHE_RADIUS; dz <= NEIGHBOUR_CACHE_RADIUS; ++dz) {
|
||
|
Chunk neighbour = chunkProvider.getChunkAtIfLoadedMainThreadNoCache(chunkX + dx, chunkZ + dz);
|
||
|
@@ -862,6 +863,11 @@ public class Chunk implements IChunkAccess {
|
||
|
this.loadedTicketLevel = false;
|
||
|
this.resetNeighbours();
|
||
|
// Paper end
|
||
|
+ // Paper start - move unload logic from the actual full unload to be when it leaves border status
|
||
|
+ chunkProvider.playerChunkMap.loadedChunks.remove(loc.longKey);
|
||
|
+ setLoaded(false);
|
||
|
+ this.world.unloadChunk(this);
|
||
|
+ // Paper end
|
||
|
}
|
||
|
// CraftBukkit end
|
||
|
|
||
|
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||
|
index 45c142c227bc258bbd5c8c03c6012663dccf8f3f..de5c45ec773474ad6a7b572e9a248c8f8ee0f94f 100644
|
||
|
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||
|
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||
|
@@ -19,6 +19,7 @@ import java.util.function.Supplier;
|
||
|
import javax.annotation.Nullable;
|
||
|
import com.destroystokyo.paper.exception.ServerInternalException;
|
||
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; // Paper
|
||
|
+import it.unimi.dsi.fastutil.longs.LongIterator; // Paper
|
||
|
import org.apache.logging.log4j.LogManager;
|
||
|
import org.apache.logging.log4j.Logger;
|
||
|
|
||
|
@@ -822,7 +823,10 @@ public class ChunkProviderServer extends IChunkProvider {
|
||
|
//List<PlayerChunk> list = Lists.newArrayList(this.playerChunkMap.f()); // Paper
|
||
|
//Collections.shuffle(list); // Paper
|
||
|
// Paper - moved up
|
||
|
- final int[] chunksTicked = {0}; this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping
|
||
|
+ final int[] chunksTicked = {0};
|
||
|
+ this.playerChunkMap.forEachVisibleChunk((playerchunk) -> {
|
||
|
+ //for (LongIterator iterator = this.playerChunkMap.loadedChunks.iterator() ; iterator.hasNext() ; ) { // Paper - iterate only loaded chunks
|
||
|
+ //PlayerChunk playerchunk = this.playerChunkMap.getVisibleChunk(iterator.nextLong());// Paper - iterate only loaded chunks
|
||
|
Optional<Chunk> optional = ((Either) playerchunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
|
||
|
|
||
|
if (optional.isPresent()) {
|
||
|
@@ -850,7 +854,7 @@ public class ChunkProviderServer extends IChunkProvider {
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
- });
|
||
|
+ });// Paper - use for instead of forEachVisibleChunk
|
||
|
this.world.getMethodProfiler().enter("customSpawners");
|
||
|
if (flag1) {
|
||
|
try (co.aikar.timings.Timing ignored = this.world.timings.miscMobSpawning.startTiming()) { // Paper - timings
|
||
|
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||
|
index fcd3388d88aad6e897b73e2c823267ada327cbda..5d3322f9f068fa74a000d58990dec6001f8ad1ab 100644
|
||
|
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||
|
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||
|
@@ -1021,16 +1021,18 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||
|
this.a(i, playerchunk);
|
||
|
} else {
|
||
|
if (this.pendingUnload.remove(i, playerchunk) && ichunkaccess != null) {
|
||
|
+ // Paper start - coment out and move to ChunkUnloadEvent
|
||
|
if (ichunkaccess instanceof Chunk) {
|
||
|
- ((Chunk) ichunkaccess).setLoaded(false);
|
||
|
+ //((Chunk) ichunkaccess).setLoaded(false);
|
||
|
}
|
||
|
|
||
|
//this.saveChunk(ichunkaccess);// Paper - delay
|
||
|
- if (this.loadedChunks.remove(i) && ichunkaccess instanceof Chunk) {
|
||
|
- Chunk chunk = (Chunk) ichunkaccess;
|
||
|
-
|
||
|
- this.world.unloadChunk(chunk);
|
||
|
- }
|
||
|
+// if (this.loadedChunks.remove(i) && ichunkaccess instanceof Chunk) {
|
||
|
+// Chunk chunk = (Chunk) ichunkaccess;
|
||
|
+//
|
||
|
+// this.world.unloadChunk(chunk);
|
||
|
+// }
|
||
|
+ // Paper end
|
||
|
this.autoSaveQueue.remove(playerchunk); // Paper
|
||
|
|
||
|
try {
|
||
|
@@ -1293,6 +1295,20 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||
|
return PlayerChunk.getChunkState(playerchunk.getTicketLevel());
|
||
|
});
|
||
|
chunk.addEntities();
|
||
|
+ // Paper start
|
||
|
+ return chunk;
|
||
|
+ } // Paper
|
||
|
+ });
|
||
|
+ }, (runnable) -> {
|
||
|
+
|
||
|
+ this.mailboxMain.a(ChunkTaskQueueSorter.a(runnable, playerchunk.i().pair(), () -> 1)); // Paper - final loads are always urgent!
|
||
|
+ });
|
||
|
+ }
|
||
|
+ public void loadChunk(Chunk chunk) {
|
||
|
+ if (true) {
|
||
|
+ if (true) {
|
||
|
+ ChunkCoordIntPair chunkcoordintpair = chunk.getPos();
|
||
|
+ // Paper end
|
||
|
if (this.loadedChunks.add(chunkcoordintpair.pair())) {
|
||
|
chunk.setLoaded(true);
|
||
|
this.world.a(chunk.getTileEntities().values());
|
||
|
@@ -1328,17 +1344,21 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||
|
list.forEach(chunk::b);
|
||
|
}
|
||
|
}
|
||
|
-
|
||
|
- return chunk;
|
||
|
- } // Paper
|
||
|
- });
|
||
|
- }, (runnable) -> {
|
||
|
- Mailbox mailbox = this.mailboxMain;
|
||
|
- long i = playerchunk.i().pair();
|
||
|
-
|
||
|
- playerchunk.getClass();
|
||
|
- mailbox.a(ChunkTaskQueueSorter.a(runnable, i, () -> 1)); // Paper - final loads are always urgent!
|
||
|
- });
|
||
|
+ // Paper start
|
||
|
+ }
|
||
|
+ }
|
||
|
+ // Move code up
|
||
|
+// return chunk;
|
||
|
+// } // Paper
|
||
|
+// });
|
||
|
+// }, (runnable) -> {
|
||
|
+// Mailbox mailbox = this.mailboxMain;
|
||
|
+// long i = playerchunk.i().pair();
|
||
|
+//
|
||
|
+// playerchunk.getClass();
|
||
|
+// mailbox.a(ChunkTaskQueueSorter.a(runnable, i, () -> 1)); // Paper - final loads are always urgent!
|
||
|
+// });
|
||
|
+ // Paper end
|
||
|
}
|
||
|
|
||
|
// Paper start
|