Add ticket on player join to avoid chunk load-unload-load cycle

Adding the entity will add and then immediately remove an entity load ticket, which would result in the chunk loading and then unloading before being loaded again once the player chunk loader reacts (delay can vary based on rate limit configs)

By adding a ticket with a short removal delay we attempt to keep the chunk loaded until the player chunk loader reacts, but this is not a guarantee due to the aforementioned rate limit configs. Plugins should still handle load/unload events as normal, however this will reduce redundant calls.

The delay is currently set to 2 seconds, however we may want to adjust this before merging
This commit is contained in:
Jason Penilla 2024-09-13 14:32:32 -07:00
parent 4ff58c4c48
commit fcf48a9c94
No known key found for this signature in database
GPG key ID: 0E75A301420E48F8
7 changed files with 35 additions and 15 deletions

View file

@ -4767,10 +4767,10 @@ index 0000000000000000000000000000000000000000..003a857e70ead858e8437e3c1bfaf22f
+}
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
new file mode 100644
index 0000000000000000000000000000000000000000..852d75a73dae7448cbe1e2f5e164b235efa8a969
index 0000000000000000000000000000000000000000..5120655cd2feed764c7429f41b615a42cf4d6ee0
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
@@ -0,0 +1,1082 @@
@@ -0,0 +1,1084 @@
+package ca.spottedleaf.moonrise.patches.chunk_system.player;
+
+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor;
@ -4802,6 +4802,7 @@ index 0000000000000000000000000000000000000000..852d75a73dae7448cbe1e2f5e164b235
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.server.level.TicketType;
+import net.minecraft.server.network.PlayerChunkSender;
+import net.minecraft.util.Unit;
+import net.minecraft.world.level.ChunkPos;
+import net.minecraft.world.level.GameRules;
+import net.minecraft.world.level.chunk.ChunkAccess;
@ -4818,6 +4819,7 @@ index 0000000000000000000000000000000000000000..852d75a73dae7448cbe1e2f5e164b235
+
+ public static final TicketType<Long> PLAYER_TICKET = TicketType.create("chunk_system:player_ticket", Long::compareTo);
+ public static final TicketType<Long> PLAYER_TICKET_DELAYED = TicketType.create("chunk_system:player_ticket_delayed", Long::compareTo, 5 * 20);
+ public static final TicketType<Unit> PLAYER_JOIN = TicketType.create("chunk_system:player_join", (a, b) -> 0, 2 * 20);
+
+ public static final int MIN_VIEW_DISTANCE = 2;
+ public static final int MAX_VIEW_DISTANCE = 32;
@ -26731,6 +26733,24 @@ index cdd66e6ce96e2613afe7f06ca8da3cfaa6704b2d..32634e45ac8433648e49e47e20081e15
handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), null, null));
// Paper start - PlayerChunkLoadEvent
if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) {
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index c9d72ab365dcfc2482764463b116451187684b3c..55913fb2246abc372f852436eedbdfd4704a7878 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -333,6 +333,13 @@ public abstract class PlayerList {
// Paper start - Fire PlayerJoinEvent when Player is actually ready; correctly register player BEFORE PlayerJoinEvent, so the entity is valid and doesn't require tick delay hacks
player.supressTrackerForLogin = true;
+ // Paper start - rewrite chunk system
+ worldserver1.moonrise$getChunkTaskScheduler().chunkHolderManager.addTicketAtLevel(
+ ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PLAYER_JOIN,
+ player.chunkPosition(),
+ ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.TICK_TICKET_LEVEL,
+ net.minecraft.util.Unit.INSTANCE);
+ // Paper end - rewrite chunk system
worldserver1.addNewPlayer(player);
this.server.getCustomBossEvents().onPlayerConnect(player); // see commented out section below worldserver.addPlayerJoin(entityplayer);
this.mountSavedVehicle(player, worldserver1, optional);
diff --git a/src/main/java/net/minecraft/util/BitStorage.java b/src/main/java/net/minecraft/util/BitStorage.java
index 68648c5a5e3ff079f832092af0f2f801c42d1ede..19661e106612b8e4e152085fb398db7bd06acc23 100644
--- a/src/main/java/net/minecraft/util/BitStorage.java

View file

@ -1155,10 +1155,10 @@ index 32634e45ac8433648e49e47e20081e15ad41ff15..dafa2cf7d3c49fc5bdcd68d2a9528127
if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) {
new io.papermc.paper.event.packet.PlayerChunkLoadEvent(new org.bukkit.craftbukkit.CraftChunk(chunk), handler.getPlayer().getBukkitEntity()).callEvent();
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 4b597ed9a71908ecec3b6da5b6a4a735cf22498b..96eea87534b6e28a56c9eea0f30bfb41793440e7 100644
index 55913fb2246abc372f852436eedbdfd4704a7878..2d10d16b9f12c0e0fe42062252fe71c112cea318 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -414,7 +414,7 @@ public abstract class PlayerList {
@@ -421,7 +421,7 @@ public abstract class PlayerList {
.getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS);
player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket(
new net.minecraft.world.level.chunk.EmptyLevelChunk(worldserver1, player.chunkPosition(), plains),

View file

@ -14,10 +14,10 @@ movement will load only the chunk the player enters anyways and avoids loading
massive amounts of surrounding chunks due to large AABB lookups.
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 59f09e8d08453ef25b7f9f49db0aa7513014779c..cad21e40aafc9c34de10007d881135657ed3d910 100644
index 2d10d16b9f12c0e0fe42062252fe71c112cea318..32317b2662efa897da1a37a0208a34102628c1f8 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -869,6 +869,7 @@ public abstract class PlayerList {
@@ -876,6 +876,7 @@ public abstract class PlayerList {
Vec3 vec3d = dimensiontransition.pos();
entityplayer1.forceSetPositionRotation(vec3d.x, vec3d.y, vec3d.z, dimensiontransition.yRot(), dimensiontransition.xRot());

View file

@ -5,10 +5,10 @@ Subject: [PATCH] API for checking sent chunks
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
index 852d75a73dae7448cbe1e2f5e164b235efa8a969..a608f57ebca98eda88ad749d0aad021678be54f9 100644
index 5120655cd2feed764c7429f41b615a42cf4d6ee0..6ad8697ebd92206d01bae7e826efda256663294d 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
@@ -1078,5 +1078,10 @@ public final class RegionizedPlayerChunkLoader {
@@ -1080,5 +1080,10 @@ public final class RegionizedPlayerChunkLoader {
// now all tickets should be removed, which is all of our external state
}

View file

@ -102,10 +102,10 @@ index 0034483685ba626e5883b857de96ffd36e57e150..4c04eb531b6989f7e618d201ecaa8429
}
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 24ff10c4ed69deed2ce9ba25835575419165e2af..83759ce35c66e45d04eaa494bd8bc95e51e9836a 100644
index 32317b2662efa897da1a37a0208a34102628c1f8..828b8406dbab6d9c9e6f0f13dbdda8c3af49982b 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -393,7 +393,7 @@ public abstract class PlayerList {
@@ -400,7 +400,7 @@ public abstract class PlayerList {
((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - Fire PlayerJoinEvent when Player is actually ready; track entity now
// CraftBukkit end

View file

@ -304,10 +304,10 @@ index 7d2896918ff5fed37e5de5a22c37b0c7f32634a8..d43b98bdfcb00603737a309c0fb7793d
}
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 83759ce35c66e45d04eaa494bd8bc95e51e9836a..eb94c0a962de4dc389eb309d264b6e1c6c7229aa 100644
index 828b8406dbab6d9c9e6f0f13dbdda8c3af49982b..9d6ec785ffa6609a2a7a1fc87e72c7eacef9347e 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -604,7 +604,7 @@ public abstract class PlayerList {
@@ -611,7 +611,7 @@ public abstract class PlayerList {
this.cserver.getPluginManager().callEvent(playerQuitEvent);
entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());

View file

@ -108,10 +108,10 @@ index 8dc3ba983fd4c61e463867be8d224aa90424215a..6c280abdef5f80b668d6090f9d35283a
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
private static final int FLY_STAT_RECORDING_SPEED = 25;
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 0184b807cc23719e91a1b1fdf1788e97e505346a..8d0e2bb3ed6651d4fb0dce02bbad36915a04f8ee 100644
index 9d6ec785ffa6609a2a7a1fc87e72c7eacef9347e..82463dc833f1a5d401e2ebd013104f5d34eb1c04 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -569,6 +569,7 @@ public abstract class PlayerList {
@@ -576,6 +576,7 @@ public abstract class PlayerList {
protected void save(ServerPlayer player) {
if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit
@ -119,7 +119,7 @@ index 0184b807cc23719e91a1b1fdf1788e97e505346a..8d0e2bb3ed6651d4fb0dce02bbad3691
this.playerIo.save(player);
ServerStatsCounter serverstatisticmanager = (ServerStatsCounter) player.getStats(); // CraftBukkit
@@ -1187,10 +1188,22 @@ public abstract class PlayerList {
@@ -1194,10 +1195,22 @@ public abstract class PlayerList {
}
public void saveAll() {