9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-19 15:09:25 +00:00

[ci skip] cleanup

This commit is contained in:
Dreeam
2025-03-21 08:54:57 -04:00
parent db4ee06274
commit c276c2ba48
14 changed files with 435 additions and 705 deletions

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Leaf config
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 3446d5bb24fac345b65ac78927155f60fe437b2c..0f4bc6a5b87a72f521f6ca04cfe14147b4e35fe4 100644 index 52485a1bce522cf9a61c3e67673aafb1a5e1a82b..f2fcb836ca69bb0f49b79c92bf4e291f2a4448d6 100644
--- a/src/main/java/org/bukkit/Server.java --- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java
@@ -2414,6 +2414,14 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi @@ -2412,6 +2412,14 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
// Paper end // Paper end

View File

@@ -70,10 +70,10 @@ index 6b2f6ab137ae37ff0db4827886614436b7ed5dcb..66a9fc729182476c4f601cdb32bcb109
/** /**
* The brand id for Pufferfish. * The brand id for Pufferfish.
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index e4db2817be2411116ff29cc85ce97e515eb6e51f..0825a913b4f7d5e81d485df6415ab68a4e1530ce 100644 index ee9985b276b0e5ac5fab871598a596e6c444b01e..d109070e6ea9057d031c2c8edfeeefb423dca9fb 100644
--- a/src/main/java/org/bukkit/Bukkit.java --- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java
@@ -3061,4 +3061,133 @@ public final class Bukkit { @@ -3064,4 +3064,133 @@ public final class Bukkit {
public static void restart() { public static void restart() {
server.restart(); server.restart();
} }
@@ -444,10 +444,10 @@ index ed8e11001c8d3c475dc851aedf6e6812a872dc54..c597c298795fb9893447bc822d941c17
+ // Purpur end - OfflinePlayer API + // Purpur end - OfflinePlayer API
} }
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 0f4bc6a5b87a72f521f6ca04cfe14147b4e35fe4..42bc72411462f3699a7a60f987eeca6046f4cf75 100644 index f2fcb836ca69bb0f49b79c92bf4e291f2a4448d6..2e750b3187d93d9001d5aa5c0d80a99a1a888377 100644
--- a/src/main/java/org/bukkit/Server.java --- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java
@@ -2414,6 +2414,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi @@ -2412,6 +2412,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
// Paper end // Paper end
@@ -466,7 +466,7 @@ index 0f4bc6a5b87a72f521f6ca04cfe14147b4e35fe4..42bc72411462f3699a7a60f987eeca60
// Leaf start - Leaf config - API // Leaf start - Leaf config - API
@NotNull @NotNull
public org.bukkit.configuration.file.YamlConfiguration getLeafConfig() public org.bukkit.configuration.file.YamlConfiguration getLeafConfig()
@@ -2783,4 +2795,111 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi @@ -2781,4 +2793,111 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
*/ */
long getLastTickOversleepTime(); long getLastTickOversleepTime();
// Gale end - YAPFA - last tick time - API // Gale end - YAPFA - last tick time - API
@@ -1321,7 +1321,7 @@ index f1f97a85ec713c05c882d7588f4a3e4a017f4795..813f6cd253322538bdf96eb323dd23a7
+ // Purpur end + // Purpur end
} }
diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java
index 5644b350151570eb790472cb48e7c701f68204df..c27bbccf032b5dc2e3c845216b4c14627c83cca2 100644 index dc50f83e9604b69a30b6c6f3495000e4b7082b0d..472806b902a90931293b96a558d27fc0b54412ae 100644
--- a/src/main/java/org/bukkit/inventory/ItemStack.java --- a/src/main/java/org/bukkit/inventory/ItemStack.java
+++ b/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java
@@ -21,6 +21,13 @@ import org.bukkit.material.MaterialData; @@ -21,6 +21,13 @@ import org.bukkit.material.MaterialData;

View File

@@ -11,10 +11,10 @@ Original project: https://github.com/LeavesMC/Leaves
This patch is Powered by ReplayMod(https://github.com/ReplayMod) This patch is Powered by ReplayMod(https://github.com/ReplayMod)
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index 0825a913b4f7d5e81d485df6415ab68a4e1530ce..f40e06c63a82dbbd6bbcadf2a71b7d2825f2b3a9 100644 index d109070e6ea9057d031c2c8edfeeefb423dca9fb..49ef3c579e8ccd51e463cabd0a3ac64434415028 100644
--- a/src/main/java/org/bukkit/Bukkit.java --- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java
@@ -3190,4 +3190,10 @@ public final class Bukkit { @@ -3193,4 +3193,10 @@ public final class Bukkit {
server.clearBlockHighlights(); server.clearBlockHighlights();
} }
// Purpur end - Debug Marker API // Purpur end - Debug Marker API
@@ -26,10 +26,10 @@ index 0825a913b4f7d5e81d485df6415ab68a4e1530ce..f40e06c63a82dbbd6bbcadf2a71b7d28
+ // Leaves end - Photographer API + // Leaves end - Photographer API
} }
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 42bc72411462f3699a7a60f987eeca6046f4cf75..b4ef18cac662c089ac975a0fae0df93e692fc9bc 100644 index 2e750b3187d93d9001d5aa5c0d80a99a1a888377..6044de3373d52455813b30305a47d523803e7ad5 100644
--- a/src/main/java/org/bukkit/Server.java --- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java
@@ -2902,4 +2902,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi @@ -2900,4 +2900,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
*/ */
void clearBlockHighlights(); void clearBlockHighlights();
// Purpur end - Debug Marker API // Purpur end - Debug Marker API

View File

@@ -12,22 +12,14 @@ In non-strict test, this can give ~60-110% improvement (524ms on Paper, 204ms on
under 625 villagers situation. under 625 villagers situation.
diff --git a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java diff --git a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
index b0c5e41fefc7c9adf1a61bd5b52861736657d37e..7f9550af4dce9c6442080c39d19e824f63115d7c 100644 index b0c5e41fefc7c9adf1a61bd5b52861736657d37e..83af90c7a2e425b775abd7907895d211ced07955 100644
--- a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java --- a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
+++ b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java +++ b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
@@ -1,7 +1,7 @@ @@ -13,18 +13,102 @@ import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities;
package net.minecraft.world.entity.ai.sensing;
import com.google.common.collect.ImmutableSet;
-import java.util.Comparator;
+import java.util.Arrays;
import java.util.List;
import java.util.Set;
import net.minecraft.server.level.ServerLevel;
@@ -13,18 +13,101 @@ import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
public class NearestLivingEntitySensor<T extends LivingEntity> extends Sensor<T> { public class NearestLivingEntitySensor<T extends LivingEntity> extends Sensor<T> {
+
+ // Leaf start - Optimized entity sorting with buffer reuse + // Leaf start - Optimized entity sorting with buffer reuse
+ private static final int SMALL_ARRAY_THRESHOLD = 2; + private static final int SMALL_ARRAY_THRESHOLD = 2;
+ private LivingEntity[] entityBuffer = new LivingEntity[0]; + private LivingEntity[] entityBuffer = new LivingEntity[0];
@@ -49,7 +41,7 @@ index b0c5e41fefc7c9adf1a61bd5b52861736657d37e..7f9550af4dce9c6442080c39d19e824f
- entitiesOfClass.sort(Comparator.comparingDouble(entity::distanceToSqr)); - entitiesOfClass.sort(Comparator.comparingDouble(entity::distanceToSqr));
+ +
+ LivingEntity[] sorted = smartSort(entities, entity); + LivingEntity[] sorted = smartSort(entities, entity);
+ List<LivingEntity> sortedList = Arrays.asList(sorted); + List<LivingEntity> sortedList = java.util.Arrays.asList(sorted);
+ +
Brain<?> brain = entity.getBrain(); Brain<?> brain = entity.getBrain();
- brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, entitiesOfClass); - brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, entitiesOfClass);
@@ -76,7 +68,7 @@ index b0c5e41fefc7c9adf1a61bd5b52861736657d37e..7f9550af4dce9c6442080c39d19e824f
+ +
+ fastRadixSort(entityBuffer, bitsBuffer, 0, size - 1, 62); + fastRadixSort(entityBuffer, bitsBuffer, 0, size - 1, 62);
+ +
+ return Arrays.copyOf(entityBuffer, size); + return java.util.Arrays.copyOf(entityBuffer, size);
+ } + }
+ +
+ private void fastRadixSort(LivingEntity[] ents, long[] bits, int low, int high, int bit) { + private void fastRadixSort(LivingEntity[] ents, long[] bits, int low, int high, int bit) {

View File

@@ -1,15 +1,16 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Taiyou06 <kaandindar21@gmail.com> From: Taiyou06 <kaandindar21@gmail.com>
Date: Thu, 6 Mar 2025 00:26:19 +0100 Date: Thu, 6 Mar 2025 00:26:19 +0100
Subject: [PATCH] Track each world MSPT Subject: [PATCH] SparklyPaper: Track each world MSPT
Original project: https://github.com/SparklyPower/SparklyPaper
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index dd1c55e983bc1ddc9a77a0b825b78eba62c201ec..f7a3cdb3953a959fb258fcb0eeea81ea2c8b217a 100644 index f2d1025a13649c35991a662c267a7653e75d19a2..7739b4955dcb489c6bba9c9db65ba87025f7c669 100644
--- a/net/minecraft/server/MinecraftServer.java --- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java
@@ -1687,7 +1687,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -1687,7 +1687,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Leaf - SparklyPaper parallel world ticking mod (move level ticking logic out for branch convergence) // Leaf start - SparklyPaper - parallel world ticking mod (move level ticking logic out for branch convergence)
private void tickLevel(ServerLevel serverLevel, BooleanSupplier hasTimeLeft) { private void tickLevel(ServerLevel serverLevel, BooleanSupplier hasTimeLeft) {
try { try {
+ long i = Util.getNanos(); // SparklyPaper - track world's MSPT + long i = Util.getNanos(); // SparklyPaper - track world's MSPT
@@ -21,51 +22,39 @@ index dd1c55e983bc1ddc9a77a0b825b78eba62c201ec..f7a3cdb3953a959fb258fcb0eeea81ea
+ serverLevel.tickTimes5s.add(this.tickCount, j); + serverLevel.tickTimes5s.add(this.tickCount, j);
+ serverLevel.tickTimes10s.add(this.tickCount, j); + serverLevel.tickTimes10s.add(this.tickCount, j);
+ serverLevel.tickTimes60s.add(this.tickCount, j); + serverLevel.tickTimes60s.add(this.tickCount, j);
+ // SparklyPaper end + // SparklyPaper end - track world's MSPT
} catch (Throwable levelTickingException) { } catch (Throwable levelTickingException) {
CrashReport crashReport = CrashReport.forThrowable(levelTickingException, "Exception ticking world"); CrashReport crashReport = CrashReport.forThrowable(levelTickingException, "Exception ticking world");
serverLevel.fillReportDetails(crashReport); serverLevel.fillReportDetails(crashReport);
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 3c0975e419b8ce58371e0cfae07abdad498bf5df..a37547b6cd228ab0e157a44b66d4a25b3a88751e 100644 index 4ecb9a4125233f91379fd2792112aca6bbb3e33f..b5a61261083ddab70582c1a1d5cac0b9ced9b652 100644
--- a/net/minecraft/server/level/ServerLevel.java --- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java
@@ -574,6 +574,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -573,6 +573,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
} }
// Paper end - chunk tick iteration // Paper end - chunk tick iteration
+ // SparklyPaper start - track world's MSPT + // SparklyPaper start - track world's MSPT
+ public final MinecraftServer.TickTimes tickTimes5s = new MinecraftServer.TickTimes(100); + public final MinecraftServer.TickTimes tickTimes5s = new MinecraftServer.TickTimes(100);
+ public final MinecraftServer.TickTimes tickTimes10s = new MinecraftServer.TickTimes(200); + public final MinecraftServer.TickTimes tickTimes10s = new MinecraftServer.TickTimes(200);
+ public final MinecraftServer.TickTimes tickTimes60s = new MinecraftServer.TickTimes(1200); + public final MinecraftServer.TickTimes tickTimes60s = new MinecraftServer.TickTimes(1200);
+ // SparklyPaper end + // SparklyPaper end - track world's MSPT
+ +
public ServerLevel( public ServerLevel(
MinecraftServer server, MinecraftServer server,
Executor dispatcher, Executor dispatcher,
diff --git a/org/purpurmc/purpur/task/TPSBarTask.java b/org/purpurmc/purpur/task/TPSBarTask.java diff --git a/org/purpurmc/purpur/task/TPSBarTask.java b/org/purpurmc/purpur/task/TPSBarTask.java
index 8769993e7ca59da309087051a3cd38fc562c15d1..b05f30f973c771641cda031332d033f14ea0572a 100644 index 8769993e7ca59da309087051a3cd38fc562c15d1..b65c839e45402c618020c77fe63b89bd19cc7d96 100644
--- a/org/purpurmc/purpur/task/TPSBarTask.java --- a/org/purpurmc/purpur/task/TPSBarTask.java
+++ b/org/purpurmc/purpur/task/TPSBarTask.java +++ b/org/purpurmc/purpur/task/TPSBarTask.java
@@ -7,6 +7,9 @@ import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; @@ -28,6 +28,44 @@ public class TPSBarTask extends BossBarTask {
import org.purpurmc.purpur.PurpurConfig;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
+import org.bukkit.craftbukkit.CraftWorld;
+import net.minecraft.server.level.ServerLevel;
+import org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking;
public class TPSBarTask extends BossBarTask {
private static TPSBarTask instance;
@@ -28,13 +31,51 @@ public class TPSBarTask extends BossBarTask {
@Override @Override
void updateBossBar(BossBar bossbar, Player player) { void updateBossBar(BossBar bossbar, Player player) {
- bossbar.progress(getBossBarProgress()); + // SparklyPaper start - track world's MSPT
- bossbar.color(getBossBarColor()); + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) {
- bossbar.name(MiniMessage.miniMessage().deserialize(PurpurConfig.commandTPSBarTitle,
+ if (SparklyPaperParallelWorldTicking.enabled) {
+ // Get player's current world + // Get player's current world
+ ServerLevel serverLevel = ((CraftWorld)player.getWorld()).getHandle(); + net.minecraft.server.level.ServerLevel serverLevel = ((org.bukkit.craftbukkit.CraftWorld) player.getWorld()).getHandle();
+ +
+ // Calculate world-specific MSPT and TPS + // Calculate world-specific MSPT and TPS
+ double worldMspt = calculateWorldMSPT(serverLevel); + double worldMspt = calculateWorldMSPT(serverLevel);
@@ -100,23 +89,24 @@ index 8769993e7ca59da309087051a3cd38fc562c15d1..b05f30f973c771641cda031332d033f1
+ } + }
+ } else { + } else {
+ // Default behavior + // Default behavior
+ bossbar.progress(getBossBarProgress()); bossbar.progress(getBossBarProgress());
+ bossbar.color(getBossBarColor()); bossbar.color(getBossBarColor());
+ bossbar.name(MiniMessage.miniMessage().deserialize(PurpurConfig.commandTPSBarTitle, bossbar.name(MiniMessage.miniMessage().deserialize(PurpurConfig.commandTPSBarTitle,
Placeholder.component("tps", getTPSColor()), @@ -35,6 +73,8 @@ public class TPSBarTask extends BossBarTask {
Placeholder.component("mspt", getMSPTColor()), Placeholder.component("mspt", getMSPTColor()),
Placeholder.component("ping", getPingColor(player.getPing())) Placeholder.component("ping", getPingColor(player.getPing()))
- )); ));
+ ));
+ } + }
+ // SparklyPaper end - track world's MSPT
} }
@Override @Override
@@ -136,6 +177,22 @@ public class TPSBarTask extends BossBarTask { @@ -136,6 +176,25 @@ public class TPSBarTask extends BossBarTask {
return MiniMessage.miniMessage().deserialize(color, Placeholder.parsed("text", String.format("%s", ping))); return MiniMessage.miniMessage().deserialize(color, Placeholder.parsed("text", String.format("%s", ping)));
} }
+ private double calculateWorldMSPT(ServerLevel serverLevel) { + // SparklyPaper start - track world's MSPT
+ private double calculateWorldMSPT(net.minecraft.server.level.ServerLevel serverLevel) {
+ long[] times = serverLevel.tickTimes5s.getTimes(); + long[] times = serverLevel.tickTimes5s.getTimes();
+ long total = 0L; + long total = 0L;
+ int count = 0; + int count = 0;
@@ -129,8 +119,10 @@ index 8769993e7ca59da309087051a3cd38fc562c15d1..b05f30f973c771641cda031332d033f1
+ } + }
+ +
+ if (count == 0) return 0.0; + if (count == 0) return 0.0;
+
+ return (double) total / (double) count * 1.0E-6D; + return (double) total / (double) count * 1.0E-6D;
+ } + }
+ // SparklyPaper end - track world's MSPT
+ +
public enum FillMode { public enum FillMode {
TPS, MSPT, PING TPS, MSPT, PING

View File

@@ -229,10 +229,10 @@ index f20c38c1ff978d00dc0c9810c050506deed44ebd..e58a40623c3a259c80d0f96686797445
player.getInventory().removeItem(ammo); player.getInventory().removeItem(ammo);
} }
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index da579769cee175cfbf342efd643efe6f87e0a822..cfd66b5987a38bb3a4e32aa4c161e06a2d6be4be 100644 index 4821ab14c6a7d5738f0fc93523aede5ea904aa84..e0d9d7075b2c10f686c8c144c9869fa574cd19d3 100644
--- a/net/minecraft/world/level/Level.java --- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java
@@ -183,6 +183,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl @@ -182,6 +182,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
private int tileTickPosition; private int tileTickPosition;
public final Map<ServerExplosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions public final Map<ServerExplosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Faster redstone torch rapid clock removal; Move from Map in BlockRedstoneTorch to here public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Faster redstone torch rapid clock removal; Move from Map in BlockRedstoneTorch to here

View File

@@ -10,10 +10,10 @@ Leaf (After): ~628ms (-96%)
This should help for massive hopper chains or hopper matrix. This should help for massive hopper chains or hopper matrix.
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index 23446968f9b42f904da189fb6bc3a6fe15c01fe7..919ad58aef8f3c9705cb67f209e22760ec50ab1d 100644 index 47528dec6b1a2b36e71013a9372425a70cbc6a33..546fb78339c005ed71142cb3c894f816b8c72d08 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java --- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -1013,15 +1013,29 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p @@ -1012,15 +1012,29 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
static class RebindableTickingBlockEntityWrapper implements TickingBlockEntity { static class RebindableTickingBlockEntityWrapper implements TickingBlockEntity {
private TickingBlockEntity ticker; private TickingBlockEntity ticker;
private BlockPos cachedPos; // Leaf - Cache tile entity position private BlockPos cachedPos; // Leaf - Cache tile entity position
@@ -43,7 +43,7 @@ index 23446968f9b42f904da189fb6bc3a6fe15c01fe7..919ad58aef8f3c9705cb67f209e22760
} }
@Override @Override
@@ -1031,6 +1045,11 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p @@ -1030,6 +1044,11 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
@Override @Override
public boolean isRemoved() { public boolean isRemoved() {

View File

@@ -13,7 +13,7 @@ To avoid the hefty ArrayDeque's size() call, we check if we *really* need to exe
Most entities won't have any scheduled tasks, so this is a nice performance bonus. These optimizations, however, wouldn't work in a Folia environment, but because in SparklyPaper executeTick is always executed on the main thread, it ain't an issue for us (yay). Most entities won't have any scheduled tasks, so this is a nice performance bonus. These optimizations, however, wouldn't work in a Folia environment, but because in SparklyPaper executeTick is always executed on the main thread, it ain't an issue for us (yay).
diff --git a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java diff --git a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java
index c03608fec96b51e1867f43d8f42e5aefb1520e46..bb56c56cdbd8a15803e85412b9c15b59a28e9e59 100644 index c03608fec96b51e1867f43d8f42e5aefb1520e46..56268cf8d184e0b6cd46de8c2e893ad3da8ec64f 100644
--- a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java --- a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java
+++ b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java +++ b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java
@@ -36,6 +36,7 @@ public final class EntityScheduler { @@ -36,6 +36,7 @@ public final class EntityScheduler {
@@ -74,6 +74,19 @@ index c03608fec96b51e1867f43d8f42e5aefb1520e46..bb56c56cdbd8a15803e85412b9c15b59
if (this.tickCount == RETIRED_TICK_COUNT) { if (this.tickCount == RETIRED_TICK_COUNT) {
throw new IllegalStateException("Ticking retired scheduler"); throw new IllegalStateException("Ticking retired scheduler");
} }
@@ -178,4 +190,12 @@ public final class EntityScheduler {
}
}
}
+
+ // Leaf start - SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run
+ public boolean hasTasks() {
+ synchronized (this.stateLock) {
+ return !this.currentlyExecuting.isEmpty() || !this.oneTimeDelayed.isEmpty();
+ }
+ }
+ // Leaf end - SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index cc024874fbde9678bdddfdca7c25080869d66de2..edcd209798740f31cb302f36d7864a0d8ea1d561 100644 index cc024874fbde9678bdddfdca7c25080869d66de2..edcd209798740f31cb302f36d7864a0d8ea1d561 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java

View File

@@ -3,34 +3,26 @@ From: Altiami <yoshimo.kristin@gmail.com>
Date: Wed, 5 Mar 2025 13:16:44 -0800 Date: Wed, 5 Mar 2025 13:16:44 -0800
Subject: [PATCH] SparklyPaper: Parallel world ticking Subject: [PATCH] SparklyPaper: Parallel world ticking
Original project: https://github.com/SparklyPower/SparklyPaper
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..8d2694977f29b680d9daf83f2c8cc3502d3cb7dd 100644 index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..2fb65ce228da94eb7d9364ee0f94582300178f1d 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java --- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
@@ -6,6 +6,7 @@ import net.minecraft.world.level.ChunkPos; @@ -14,6 +14,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
+import org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -14,6 +15,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class TickThread extends Thread { public class TickThread extends Thread {
private static final Logger LOGGER = LoggerFactory.getLogger(TickThread.class); private static final Logger LOGGER = LoggerFactory.getLogger(TickThread.class);
+ public static final boolean HARD_THROW = !SparklyPaperParallelWorldTicking.disableHardThrow; // SparklyPaper - parallel world ticking - THIS SHOULD NOT BE DISABLED SINCE IT CAN CAUSE DATA CORRUPTION!!! Anyhow, for production servers, if you want to make a test run to see if the server could crash, you can test it with this disabled + private static final boolean HARD_THROW = !org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.disableHardThrow; // SparklyPaper - parallel world ticking - THIS SHOULD NOT BE DISABLED SINCE IT CAN CAUSE DATA CORRUPTION!!! Anyhow, for production servers, if you want to make a test run to see if the server could crash, you can test it with this disabled
private static String getThreadContext() { private static String getThreadContext() {
return "thread=" + Thread.currentThread().getName(); return "thread=" + Thread.currentThread().getName();
@@ -26,14 +28,15 @@ public class TickThread extends Thread { @@ -26,14 +27,14 @@ public class TickThread extends Thread {
public static void ensureTickThread(final String reason) { public static void ensureTickThread(final String reason) {
if (!isTickThread()) { if (!isTickThread()) {
LOGGER.error("Thread failed main thread check: " + reason + ", context=" + getThreadContext(), new Throwable()); LOGGER.error("Thread failed main thread check: " + reason + ", context=" + getThreadContext(), new Throwable());
- throw new IllegalStateException(reason); - throw new IllegalStateException(reason);
+ if (HARD_THROW) + if (HARD_THROW) throw new IllegalStateException(reason); // SparklyPaper - parallel world ticking
+ throw new IllegalStateException(reason); // SparklyPaper - parallel world ticking
} }
} }
@@ -38,90 +30,86 @@ index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..8d2694977f29b680d9daf83f2c8cc350
if (!isTickThreadFor(world, pos)) { if (!isTickThreadFor(world, pos)) {
final String ex = "Thread failed main thread check: " + final String ex = "Thread failed main thread check: " +
- reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos; - reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos;
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + " - " + getTickThreadInformation(world.getServer()); + reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + " - " + getTickThreadInformation(world.getServer()); // SparklyPaper - parallel world ticking
LOGGER.error(ex, new Throwable()); LOGGER.error(ex, new Throwable());
throw new IllegalStateException(ex); throw new IllegalStateException(ex);
} }
@@ -42,7 +45,7 @@ public class TickThread extends Thread { @@ -42,7 +43,7 @@ public class TickThread extends Thread {
public static void ensureTickThread(final Level world, final BlockPos pos, final int blockRadius, final String reason) { public static void ensureTickThread(final Level world, final BlockPos pos, final int blockRadius, final String reason) {
if (!isTickThreadFor(world, pos, blockRadius)) { if (!isTickThreadFor(world, pos, blockRadius)) {
final String ex = "Thread failed main thread check: " + final String ex = "Thread failed main thread check: " +
- reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + ", block_radius=" + blockRadius; - reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + ", block_radius=" + blockRadius;
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + ", block_radius=" + blockRadius + " - " + getTickThreadInformation(world.getServer()); + reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + ", block_radius=" + blockRadius + " - " + getTickThreadInformation(world.getServer()); // SparklyPaper - parallel world ticking
LOGGER.error(ex, new Throwable()); LOGGER.error(ex, new Throwable());
throw new IllegalStateException(ex); throw new IllegalStateException(ex);
} }
@@ -51,7 +54,7 @@ public class TickThread extends Thread { @@ -51,7 +52,7 @@ public class TickThread extends Thread {
public static void ensureTickThread(final Level world, final ChunkPos pos, final String reason) { public static void ensureTickThread(final Level world, final ChunkPos pos, final String reason) {
if (!isTickThreadFor(world, pos)) { if (!isTickThreadFor(world, pos)) {
final String ex = "Thread failed main thread check: " + final String ex = "Thread failed main thread check: " +
- reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + pos; - reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + pos;
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + pos + " - " + getTickThreadInformation(world.getServer()); + reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + pos + " - " + getTickThreadInformation(world.getServer()); // SparklyPaper - parallel world ticking
LOGGER.error(ex, new Throwable()); LOGGER.error(ex, new Throwable());
throw new IllegalStateException(ex); throw new IllegalStateException(ex);
} }
@@ -60,7 +63,7 @@ public class TickThread extends Thread { @@ -60,7 +61,7 @@ public class TickThread extends Thread {
public static void ensureTickThread(final Level world, final int chunkX, final int chunkZ, final String reason) { public static void ensureTickThread(final Level world, final int chunkX, final int chunkZ, final String reason) {
if (!isTickThreadFor(world, chunkX, chunkZ)) { if (!isTickThreadFor(world, chunkX, chunkZ)) {
final String ex = "Thread failed main thread check: " + final String ex = "Thread failed main thread check: " +
- reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + new ChunkPos(chunkX, chunkZ); - reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + new ChunkPos(chunkX, chunkZ);
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + new ChunkPos(chunkX, chunkZ) + " - " + getTickThreadInformation(world.getServer()); + reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + new ChunkPos(chunkX, chunkZ) + " - " + getTickThreadInformation(world.getServer()); // SparklyPaper - parallel world ticking
LOGGER.error(ex, new Throwable()); LOGGER.error(ex, new Throwable());
throw new IllegalStateException(ex); throw new IllegalStateException(ex);
} }
@@ -69,7 +72,7 @@ public class TickThread extends Thread { @@ -69,7 +70,7 @@ public class TickThread extends Thread {
public static void ensureTickThread(final Entity entity, final String reason) { public static void ensureTickThread(final Entity entity, final String reason) {
if (!isTickThreadFor(entity)) { if (!isTickThreadFor(entity)) {
final String ex = "Thread failed main thread check: " + final String ex = "Thread failed main thread check: " +
- reason + ", context=" + getThreadContext() + ", entity=" + EntityUtil.dumpEntity(entity); - reason + ", context=" + getThreadContext() + ", entity=" + EntityUtil.dumpEntity(entity);
+ reason + ", context=" + getThreadContext() + ", entity=" + EntityUtil.dumpEntity(entity) + " - " + getTickThreadInformation(entity.getServer()); + reason + ", context=" + getThreadContext() + ", entity=" + EntityUtil.dumpEntity(entity) + " - " + getTickThreadInformation(entity.getServer()); // SparklyPaper - parallel world ticking
LOGGER.error(ex, new Throwable()); LOGGER.error(ex, new Throwable());
throw new IllegalStateException(ex); throw new IllegalStateException(ex);
} }
@@ -78,7 +81,7 @@ public class TickThread extends Thread { @@ -78,7 +79,7 @@ public class TickThread extends Thread {
public static void ensureTickThread(final Level world, final AABB aabb, final String reason) { public static void ensureTickThread(final Level world, final AABB aabb, final String reason) {
if (!isTickThreadFor(world, aabb)) { if (!isTickThreadFor(world, aabb)) {
final String ex = "Thread failed main thread check: " + final String ex = "Thread failed main thread check: " +
- reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", aabb=" + aabb; - reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", aabb=" + aabb;
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", aabb=" + aabb + " - " + getTickThreadInformation(world.getServer()); + reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", aabb=" + aabb + " - " + getTickThreadInformation(world.getServer()); // SparklyPaper - parallel world ticking
LOGGER.error(ex, new Throwable()); LOGGER.error(ex, new Throwable());
throw new IllegalStateException(ex); throw new IllegalStateException(ex);
} }
@@ -87,12 +90,74 @@ public class TickThread extends Thread { @@ -87,12 +88,70 @@ public class TickThread extends Thread {
public static void ensureTickThread(final Level world, final double blockX, final double blockZ, final String reason) { public static void ensureTickThread(final Level world, final double blockX, final double blockZ, final String reason) {
if (!isTickThreadFor(world, blockX, blockZ)) { if (!isTickThreadFor(world, blockX, blockZ)) {
final String ex = "Thread failed main thread check: " + final String ex = "Thread failed main thread check: " +
- reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + new Vec3(blockX, 0.0, blockZ); - reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + new Vec3(blockX, 0.0, blockZ);
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + new Vec3(blockX, 0.0, blockZ) + " - " + getTickThreadInformation(world.getServer()); + reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + new Vec3(blockX, 0.0, blockZ) + " - " + getTickThreadInformation(world.getServer()); // SparklyPaper - parallel world ticking
LOGGER.error(ex, new Throwable()); LOGGER.error(ex, new Throwable());
throw new IllegalStateException(ex); throw new IllegalStateException(ex);
} }
} }
+ // SparklyPaper - parallel world ticking + // SparklyPaper start - parallel world ticking
+ // This is an additional method to check if the tick thread is bound to a specific world because, by default, Paper's isTickThread methods do not provide this information + // This is an additional method to check if the tick thread is bound to a specific world because, by default, Paper's isTickThread methods do not provide this information
+ // Because we only tick worlds in parallel (instead of regions), we can use this for our checks + // Because we only tick worlds in parallel (instead of regions), we can use this for our checks
+ public static void ensureTickThread(final net.minecraft.server.level.ServerLevel world, final String reason) { + public static void ensureTickThread(final net.minecraft.server.level.ServerLevel world, final String reason) {
+ if (!isTickThreadFor(world)) { + if (!isTickThreadFor(world)) {
+ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ world " + world.getWorld().getName() + " - " + getTickThreadInformation(world.getServer()), new Throwable()); + LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ world " + world.getWorld().getName() + " - " + getTickThreadInformation(world.getServer()), new Throwable()); // SparklyPaper - parallel world ticking
+ if (HARD_THROW) + if (HARD_THROW) throw new IllegalStateException(reason);
+ throw new IllegalStateException(reason);
+ } + }
+ } + }
+ +
+ // SparklyPaper - parallel world ticking
+ // This is an additional method to check if it is a tick thread but ONLY a tick thread + // This is an additional method to check if it is a tick thread but ONLY a tick thread
+ public static void ensureOnlyTickThread(final String reason) { + public static void ensureOnlyTickThread(final String reason) {
+ boolean isTickThread = isTickThread(); + boolean isTickThread = isTickThread();
+ boolean isServerLevelTickThread = isServerLevelTickThread(); + boolean isServerLevelTickThread = isServerLevelTickThread();
+ if (!isTickThread || isServerLevelTickThread) { + if (!isTickThread || isServerLevelTickThread) {
+ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread ONLY tick thread check: " + reason, new Throwable()); + LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread ONLY tick thread check: " + reason, new Throwable());
+ if (HARD_THROW) + if (HARD_THROW) throw new IllegalStateException(reason);
+ throw new IllegalStateException(reason);
+ } + }
+ } + }
+ +
+ // SparklyPaper - parallel world ticking
+ // This is an additional method to check if the tick thread is bound to a specific world or if it is an async thread. + // This is an additional method to check if the tick thread is bound to a specific world or if it is an async thread.
+ public static void ensureTickThreadOrAsyncThread(final net.minecraft.server.level.ServerLevel world, final String reason) { + public static void ensureTickThreadOrAsyncThread(final net.minecraft.server.level.ServerLevel world, final String reason) {
+ boolean isValidTickThread = isTickThreadFor(world); + boolean isValidTickThread = isTickThreadFor(world);
@@ -129,8 +117,7 @@ index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..8d2694977f29b680d9daf83f2c8cc350
+ boolean isValid = isAsyncThread || isValidTickThread; + boolean isValid = isAsyncThread || isValidTickThread;
+ if (!isValid) { + if (!isValid) {
+ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread or async thread check: " + reason + " @ world " + world.getWorld().getName() + " - " + getTickThreadInformation(world.getServer()), new Throwable()); + LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread or async thread check: " + reason + " @ world " + world.getWorld().getName() + " - " + getTickThreadInformation(world.getServer()), new Throwable());
+ if (HARD_THROW) + if (HARD_THROW) throw new IllegalStateException(reason);
+ throw new IllegalStateException(reason);
+ } + }
+ } + }
+ +
@@ -159,70 +146,73 @@ index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..8d2694977f29b680d9daf83f2c8cc350
+ public static boolean isServerLevelTickThread() { + public static boolean isServerLevelTickThread() {
+ return Thread.currentThread() instanceof ServerLevelTickThread; + return Thread.currentThread() instanceof ServerLevelTickThread;
+ } + }
+ // SparklyPaper end - parallel world ticking
+ +
public final int id; /* We don't override getId as the spec requires that it be unique (with respect to all other threads) */ public final int id; /* We don't override getId as the spec requires that it be unique (with respect to all other threads) */
private static final AtomicInteger ID_GENERATOR = new AtomicInteger(); private static final AtomicInteger ID_GENERATOR = new AtomicInteger();
@@ -133,46 +198,73 @@ public class TickThread extends Thread { @@ -133,46 +192,74 @@ public class TickThread extends Thread {
} }
public static boolean isTickThreadFor(final Level world, final BlockPos pos) { public static boolean isTickThreadFor(final Level world, final BlockPos pos) {
- return isTickThread(); - return isTickThread();
+ return isTickThreadFor(world); // Leaf - SparklyPaper parallel world ticking mod (use methods for what they were made for) + return isTickThreadFor(world); // Leaf - SparklyPaper - parallel world ticking mod (use methods for what they were made for)
} }
public static boolean isTickThreadFor(final Level world, final BlockPos pos, final int blockRadius) { public static boolean isTickThreadFor(final Level world, final BlockPos pos, final int blockRadius) {
- return isTickThread(); - return isTickThread();
+ return isTickThreadFor(world); // Leaf - SparklyPaper parallel world ticking mod (add missing replacement / use methods for what they were made for) + return isTickThreadFor(world); // Leaf - SparklyPaper - parallel world ticking mod (add missing replacement / use methods for what they were made for)
} }
public static boolean isTickThreadFor(final Level world, final ChunkPos pos) { public static boolean isTickThreadFor(final Level world, final ChunkPos pos) {
- return isTickThread(); - return isTickThread();
+ return isTickThreadFor(world); // Leaf - SparklyPaper parallel world ticking mod (use methods for what they were made for) + return isTickThreadFor(world); // Leaf - SparklyPaper - parallel world ticking mod (use methods for what they were made for)
} }
public static boolean isTickThreadFor(final Level world, final Vec3 pos) { public static boolean isTickThreadFor(final Level world, final Vec3 pos) {
- return isTickThread(); - return isTickThread();
+ return isTickThreadFor(world); // Leaf - SparklyPaper parallel world ticking mod (use methods for what they were made for) + return isTickThreadFor(world); // Leaf - SparklyPaper - parallel world ticking mod (use methods for what they were made for)
} }
public static boolean isTickThreadFor(final Level world, final int chunkX, final int chunkZ) { public static boolean isTickThreadFor(final Level world, final int chunkX, final int chunkZ) {
- return isTickThread(); - return isTickThread();
+ return isTickThreadFor(world); // Leaf - SparklyPaper parallel world ticking mod (use methods for what they were made for) + return isTickThreadFor(world); // Leaf - SparklyPaper - parallel world ticking mod (use methods for what they were made for)
} }
public static boolean isTickThreadFor(final Level world, final AABB aabb) { public static boolean isTickThreadFor(final Level world, final AABB aabb) {
- return isTickThread(); - return isTickThread();
+ return isTickThreadFor(world); // Leaf - SparklyPaper parallel world ticking mod (use methods for what they were made for) + return isTickThreadFor(world); // Leaf - SparklyPaper - parallel world ticking mod (use methods for what they were made for)
} }
public static boolean isTickThreadFor(final Level world, final double blockX, final double blockZ) { public static boolean isTickThreadFor(final Level world, final double blockX, final double blockZ) {
- return isTickThread(); - return isTickThread();
+ return isTickThreadFor(world); // Leaf - SparklyPaper parallel world ticking mod (use methods for what they were made for) + return isTickThreadFor(world); // Leaf - SparklyPaper - parallel world ticking mod (use methods for what they were made for)
} }
public static boolean isTickThreadFor(final Level world, final Vec3 position, final Vec3 deltaMovement, final int buffer) { public static boolean isTickThreadFor(final Level world, final Vec3 position, final Vec3 deltaMovement, final int buffer) {
- return isTickThread(); - return isTickThread();
+ return isTickThreadFor(world); // Leaf - SparklyPaper parallel world ticking mod (use methods for what they were made for) + return isTickThreadFor(world); // Leaf - SparklyPaper - parallel world ticking mod (use methods for what they were made for)
} }
public static boolean isTickThreadFor(final Level world, final int fromChunkX, final int fromChunkZ, final int toChunkX, final int toChunkZ) { public static boolean isTickThreadFor(final Level world, final int fromChunkX, final int fromChunkZ, final int toChunkX, final int toChunkZ) {
- return isTickThread(); - return isTickThread();
+ return isTickThreadFor(world); // Leaf - SparklyPaper parallel world ticking mod (use methods for what they were made for) + return isTickThreadFor(world); // Leaf - SparklyPaper - parallel world ticking mod (use methods for what they were made for)
} }
public static boolean isTickThreadFor(final Level world, final int chunkX, final int chunkZ, final int radius) { public static boolean isTickThreadFor(final Level world, final int chunkX, final int chunkZ, final int radius) {
- return isTickThread(); - return isTickThread();
+ return isTickThreadFor(world); // Leaf - SparklyPaper parallel world ticking mod (use methods for what they were made for) + return isTickThreadFor(world); // Leaf - SparklyPaper - parallel world ticking mod (use methods for what they were made for)
+ } + }
+ +
+ // SparklyPaper - parallel world ticking + // SparklyPaper start - parallel world ticking
+ // This is an additional method to check if the tick thread is bound to a specific world because, by default, Paper's isTickThread methods do not provide this information + // This is an additional method to check if the tick thread is bound to a specific world because, by default, Paper's isTickThread methods do not provide this information
+ // Because we only tick worlds in parallel (instead of regions), we can use this for our checks + // Because we only tick worlds in parallel (instead of regions), we can use this for our checks
+ public static boolean isTickThreadFor(final Level world) { + public static boolean isTickThreadFor(final Level world) {
+ if (Thread.currentThread() instanceof ServerLevelTickThread serverLevelTickThread) { + if (Thread.currentThread() instanceof ServerLevelTickThread serverLevelTickThread) {
+ return serverLevelTickThread.currentlyTickingServerLevel == world; + return serverLevelTickThread.currentlyTickingServerLevel == world;
+ } else return isTickThread(); + } else {
+ return isTickThread();
+ }
} }
public static boolean isTickThreadFor(final Entity entity) { public static boolean isTickThreadFor(final Entity entity) {
@@ -231,10 +221,9 @@ index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..8d2694977f29b680d9daf83f2c8cc350
+ return true; + return true;
+ } + }
+ +
+ return isTickThreadFor(entity.level()); // Leaf - SparklyPaper parallel world ticking mod (use methods for what they were made for) + return isTickThreadFor(entity.level()); // Leaf - SparklyPaper - parallel world ticking mod (use methods for what they were made for)
+ } + }
+ +
+ // SparklyPaper start - parallel world ticking
+ public static class ServerLevelTickThread extends TickThread { + public static class ServerLevelTickThread extends TickThread {
+ public ServerLevelTickThread(String name) { + public ServerLevelTickThread(String name) {
+ super(name); + super(name);
@@ -246,144 +235,128 @@ index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..8d2694977f29b680d9daf83f2c8cc350
+ +
+ public net.minecraft.server.level.ServerLevel currentlyTickingServerLevel; + public net.minecraft.server.level.ServerLevel currentlyTickingServerLevel;
} }
+ // SparklyPaper end + // SparklyPaper end - parallel world ticking
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 15673166e566b2a6d5093210d99b154e69fab0ad..3c80b73f969318ec12b4f39b50cf1e215b5ca23f 100644 index 15673166e566b2a6d5093210d99b154e69fab0ad..49abf1100271452e9c79c8643a25af3ce519773b 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -145,6 +145,7 @@ import org.bukkit.util.NumberConversions; @@ -455,7 +455,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
import org.bukkit.util.RayTraceResult;
import org.bukkit.util.StructureSearchResult;
import org.bukkit.util.Vector;
+import org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -455,7 +456,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
} }
private boolean unloadChunk0(int x, int z, boolean save) { private boolean unloadChunk0(int x, int z, boolean save) {
- org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot - org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot
+ // Leaf start - SparklyPaper parallel world ticking mod (make configurable) + // Leaf start - SparklyPaper - parallel world ticking mod (make configurable)
+ if (SparklyPaperParallelWorldTicking.enabled) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x, z, "Cannot unload chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs) + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x, z, "Cannot unload chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
+ else + else
+ org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot + org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot
+ // Leaf end + // Leaf end - SparklyPaper - parallel world ticking mod (make configurable)
if (!this.isChunkLoaded(x, z)) { if (!this.isChunkLoaded(x, z)) {
return true; return true;
} }
@@ -472,6 +478,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -472,6 +477,8 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override @Override
public boolean refreshChunk(int x, int z) { public boolean refreshChunk(int x, int z) {
+ if (SparklyPaperParallelWorldTicking.enabled) // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x, z, "Cannot refresh chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs) + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x, z, "Cannot refresh chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z)); ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z));
if (playerChunk == null) return false; if (playerChunk == null) return false;
@@ -522,7 +530,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -522,7 +529,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override @Override
public boolean loadChunk(int x, int z, boolean generate) { public boolean loadChunk(int x, int z, boolean generate) {
- org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot - org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
+ // Leaf start - SparklyPaper parallel world ticking mod (make configurable) + // Leaf start - SparklyPaper - parallel world ticking mod (make configurable)
+ if (SparklyPaperParallelWorldTicking.enabled) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.getHandle(), x, z, "May not sync load chunks asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs) + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.getHandle(), x, z, "May not sync load chunks asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
+ else + else
+ org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot + org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
+ // Leaf end + // Leaf end - SparklyPaper - parallel world ticking mod (make configurable)
warnUnsafeChunk("loading a faraway chunk", x, z); // Paper warnUnsafeChunk("loading a faraway chunk", x, z); // Paper
ChunkAccess chunk = this.world.getChunkSource().getChunk(x, z, generate || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true); // Paper ChunkAccess chunk = this.world.getChunkSource().getChunk(x, z, generate || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true); // Paper
@@ -750,6 +763,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -750,6 +762,8 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override @Override
public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) { public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) {
+ if (SparklyPaperParallelWorldTicking.enabled) // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, loc.getX(), loc.getZ(), "Cannot generate tree asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs) + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, loc.getX(), loc.getZ(), "Cannot generate tree asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
this.world.captureTreeGeneration = true; this.world.captureTreeGeneration = true;
this.world.captureBlockStates = true; this.world.captureBlockStates = true;
boolean grownTree = this.generateTree(loc, type); boolean grownTree = this.generateTree(loc, type);
@@ -865,6 +880,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -865,6 +879,8 @@ public class CraftWorld extends CraftRegionAccessor implements World {
} }
public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks, Entity source, Consumer<net.minecraft.world.level.ServerExplosion> configurator) { public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks, Entity source, Consumer<net.minecraft.world.level.ServerExplosion> configurator) {
// Paper end - expand explosion API // Paper end - expand explosion API
+ if (SparklyPaperParallelWorldTicking.enabled) // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x, z, "Cannot create explosion asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs) + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x, z, "Cannot create explosion asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
net.minecraft.world.level.Level.ExplosionInteraction explosionType; net.minecraft.world.level.Level.ExplosionInteraction explosionType;
if (!breakBlocks) { if (!breakBlocks) {
explosionType = net.minecraft.world.level.Level.ExplosionInteraction.NONE; // Don't break blocks explosionType = net.minecraft.world.level.Level.ExplosionInteraction.NONE; // Don't break blocks
@@ -956,6 +973,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -956,6 +972,8 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override @Override
public int getHighestBlockYAt(int x, int z, org.bukkit.HeightMap heightMap) { public int getHighestBlockYAt(int x, int z, org.bukkit.HeightMap heightMap) {
+ if (SparklyPaperParallelWorldTicking.enabled) // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x >> 4, z >> 4, "Cannot retrieve chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs) + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x >> 4, z >> 4, "Cannot retrieve chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
warnUnsafeChunk("getting a faraway chunk", x >> 4, z >> 4); // Paper warnUnsafeChunk("getting a faraway chunk", x >> 4, z >> 4); // Paper
// Transient load for this tick // Transient load for this tick
return this.world.getChunk(x >> 4, z >> 4).getHeight(CraftHeightMap.toNMS(heightMap), x, z); return this.world.getChunk(x >> 4, z >> 4).getHeight(CraftHeightMap.toNMS(heightMap), x, z);
@@ -986,6 +1005,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -986,6 +1004,8 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override @Override
public void setBiome(int x, int y, int z, Holder<net.minecraft.world.level.biome.Biome> bb) { public void setBiome(int x, int y, int z, Holder<net.minecraft.world.level.biome.Biome> bb) {
BlockPos pos = new BlockPos(x, 0, z); BlockPos pos = new BlockPos(x, 0, z);
+ if (SparklyPaperParallelWorldTicking.enabled) // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, pos, "Cannot retrieve chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs) + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, pos, "Cannot retrieve chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
if (this.world.hasChunkAt(pos)) { if (this.world.hasChunkAt(pos)) {
net.minecraft.world.level.chunk.LevelChunk chunk = this.world.getChunkAt(pos); net.minecraft.world.level.chunk.LevelChunk chunk = this.world.getChunkAt(pos);
@@ -2328,6 +2349,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -2328,6 +2348,8 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override @Override
public void sendGameEvent(Entity sourceEntity, org.bukkit.GameEvent gameEvent, Vector position) { public void sendGameEvent(Entity sourceEntity, org.bukkit.GameEvent gameEvent, Vector position) {
+ if (SparklyPaperParallelWorldTicking.enabled) // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, position.getX(), position.getZ(), "Cannot send game event asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs) + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, position.getX(), position.getZ(), "Cannot send game event asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
getHandle().gameEvent(sourceEntity != null ? ((CraftEntity) sourceEntity).getHandle(): null, net.minecraft.core.registries.BuiltInRegistries.GAME_EVENT.get(org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(gameEvent.getKey())).orElseThrow(), org.bukkit.craftbukkit.util.CraftVector.toBlockPos(position)); getHandle().gameEvent(sourceEntity != null ? ((CraftEntity) sourceEntity).getHandle(): null, net.minecraft.core.registries.BuiltInRegistries.GAME_EVENT.get(org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(gameEvent.getKey())).orElseThrow(), org.bukkit.craftbukkit.util.CraftVector.toBlockPos(position));
} }
// Paper end // Paper end
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 973b297a22c0cc53f966582c67c3688f4b2205c7..747f20d080b602ab9a1c551c648bf54682e584e0 100644 index 973b297a22c0cc53f966582c67c3688f4b2205c7..61f9e88a7760b4bf23674ac8594dd31557768217 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -60,6 +60,7 @@ import org.bukkit.util.BlockVector; @@ -75,6 +75,11 @@ public class CraftBlock implements Block {
import org.bukkit.util.BoundingBox;
import org.bukkit.util.RayTraceResult;
import org.bukkit.util.Vector;
+import org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking;
public class CraftBlock implements Block {
private final net.minecraft.world.level.LevelAccessor world;
@@ -75,6 +76,11 @@ public class CraftBlock implements Block {
} }
public net.minecraft.world.level.block.state.BlockState getNMS() { public net.minecraft.world.level.block.state.BlockState getNMS() {
+ // Folia start - parallel world ticking + // SparklyPaper start - parallel world ticking
+ if (SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously"); + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
+ } + }
+ // Folia end - parallel world ticking + // SparklyPaper end - parallel world ticking
return this.world.getBlockState(this.position); return this.world.getBlockState(this.position);
} }
@@ -157,6 +163,11 @@ public class CraftBlock implements Block { @@ -157,6 +162,11 @@ public class CraftBlock implements Block {
} }
private void setData(final byte data, int flag) { private void setData(final byte data, int flag) {
+ // SparklyPaper start - parallel world ticking + // SparklyPaper start - parallel world ticking
+ if (SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously"); + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
+ } + }
+ // SparklyPaper end - parallel world ticking + // SparklyPaper end - parallel world ticking
this.world.setBlock(this.position, CraftMagicNumbers.getBlock(this.getType(), data), flag); this.world.setBlock(this.position, CraftMagicNumbers.getBlock(this.getType(), data), flag);
} }
@@ -198,6 +209,12 @@ public class CraftBlock implements Block { @@ -198,6 +208,12 @@ public class CraftBlock implements Block {
} }
public static boolean setTypeAndData(LevelAccessor world, BlockPos position, net.minecraft.world.level.block.state.BlockState old, net.minecraft.world.level.block.state.BlockState blockData, boolean applyPhysics) { public static boolean setTypeAndData(LevelAccessor world, BlockPos position, net.minecraft.world.level.block.state.BlockState old, net.minecraft.world.level.block.state.BlockState blockData, boolean applyPhysics) {
+ // SparklyPaper start - parallel world ticking + // SparklyPaper start - parallel world ticking
+ if (SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously"); + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
+ } + }
+ // SparklyPaper end - parallel world ticking + // SparklyPaper end - parallel world ticking
@@ -391,12 +364,12 @@ index 973b297a22c0cc53f966582c67c3688f4b2205c7..747f20d080b602ab9a1c551c648bf546
// SPIGOT-611: need to do this to prevent glitchiness. Easier to handle this here (like /setblock) than to fix weirdness in tile entity cleanup // SPIGOT-611: need to do this to prevent glitchiness. Easier to handle this here (like /setblock) than to fix weirdness in tile entity cleanup
if (old.hasBlockEntity() && blockData.getBlock() != old.getBlock()) { // SPIGOT-3725 remove old tile entity if block changes if (old.hasBlockEntity() && blockData.getBlock() != old.getBlock()) { // SPIGOT-3725 remove old tile entity if block changes
// SPIGOT-4612: faster - just clear tile // SPIGOT-4612: faster - just clear tile
@@ -343,18 +360,33 @@ public class CraftBlock implements Block { @@ -343,18 +359,33 @@ public class CraftBlock implements Block {
@Override @Override
public Biome getBiome() { public Biome getBiome() {
+ // SparklyPaper start - parallel world ticking + // SparklyPaper start - parallel world ticking
+ if (SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously"); + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
+ } + }
+ // SparklyPaper end - parallel world ticking + // SparklyPaper end - parallel world ticking
@@ -407,7 +380,7 @@ index 973b297a22c0cc53f966582c67c3688f4b2205c7..747f20d080b602ab9a1c551c648bf546
@Override @Override
public Biome getComputedBiome() { public Biome getComputedBiome() {
+ // SparklyPaper start - parallel world ticking + // SparklyPaper start - parallel world ticking
+ if (SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously"); + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
+ } + }
+ // SparklyPaper end - parallel world ticking + // SparklyPaper end - parallel world ticking
@@ -418,102 +391,102 @@ index 973b297a22c0cc53f966582c67c3688f4b2205c7..747f20d080b602ab9a1c551c648bf546
@Override @Override
public void setBiome(Biome bio) { public void setBiome(Biome bio) {
+ // SparklyPaper start - parallel world ticking + // SparklyPaper start - parallel world ticking
+ if (SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously"); + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
+ } + }
+ // SparklyPaper end - parallel world ticking + // SparklyPaper end - parallel world ticking
this.getWorld().setBiome(this.getX(), this.getY(), this.getZ(), bio); this.getWorld().setBiome(this.getX(), this.getY(), this.getZ(), bio);
} }
@@ -375,6 +407,11 @@ public class CraftBlock implements Block { @@ -375,6 +406,11 @@ public class CraftBlock implements Block {
@Override @Override
public boolean isBlockIndirectlyPowered() { public boolean isBlockIndirectlyPowered() {
+ // SparklyPaper start - parallel world ticking + // SparklyPaper start - parallel world ticking
+ if (SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously"); + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
+ } + }
+ // SparklyPaper end - parallel world ticking + // SparklyPaper end - parallel world ticking
return this.world.getMinecraftWorld().hasNeighborSignal(this.position); return this.world.getMinecraftWorld().hasNeighborSignal(this.position);
} }
@@ -414,6 +451,11 @@ public class CraftBlock implements Block { @@ -414,6 +450,11 @@ public class CraftBlock implements Block {
@Override @Override
public int getBlockPower(BlockFace face) { public int getBlockPower(BlockFace face) {
+ // SparklyPaper start - parallel world ticking + // SparklyPaper start - parallel world ticking
+ if (SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously"); + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
+ } + }
+ // SparklyPaper end - parallel world ticking + // SparklyPaper end - parallel world ticking
int power = 0; int power = 0;
net.minecraft.world.level.Level world = this.world.getMinecraftWorld(); net.minecraft.world.level.Level world = this.world.getMinecraftWorld();
int x = this.getX(); int x = this.getX();
@@ -484,6 +526,11 @@ public class CraftBlock implements Block { @@ -484,6 +525,11 @@ public class CraftBlock implements Block {
@Override @Override
public boolean breakNaturally() { public boolean breakNaturally() {
+ // SparklyPaper start - parallel world ticking + // SparklyPaper start - parallel world ticking
+ if (SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously"); + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
+ } + }
+ // SparklyPaper end - parallel world ticking + // SparklyPaper end - parallel world ticking
return this.breakNaturally(null); return this.breakNaturally(null);
} }
@@ -543,6 +590,11 @@ public class CraftBlock implements Block { @@ -543,6 +589,11 @@ public class CraftBlock implements Block {
@Override @Override
public boolean applyBoneMeal(BlockFace face) { public boolean applyBoneMeal(BlockFace face) {
+ // SparklyPaper start - parallel world ticking + // SparklyPaper start - parallel world ticking
+ if (SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously"); + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
+ } + }
+ // SparklyPaper end - parallel world ticking + // SparklyPaper end - parallel world ticking
Direction direction = CraftBlock.blockFaceToNotch(face); Direction direction = CraftBlock.blockFaceToNotch(face);
BlockFertilizeEvent event = null; BlockFertilizeEvent event = null;
ServerLevel world = this.getCraftWorld().getHandle(); ServerLevel world = this.getCraftWorld().getHandle();
@@ -554,8 +606,8 @@ public class CraftBlock implements Block { @@ -554,8 +605,8 @@ public class CraftBlock implements Block {
world.captureTreeGeneration = false; world.captureTreeGeneration = false;
if (world.capturedBlockStates.size() > 0) { if (world.capturedBlockStates.size() > 0) {
- TreeType treeType = SaplingBlock.treeType; - TreeType treeType = SaplingBlock.treeType;
- SaplingBlock.treeType = null; - SaplingBlock.treeType = null;
+ TreeType treeType = SaplingBlock.getTreeTypeRT(); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper parallel world ticking mod (collapse original behavior) + TreeType treeType = SaplingBlock.getTreeTypeRT(); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior)
+ SaplingBlock.setTreeTypeRT(null); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper parallel world ticking mod (collapse original behavior) + SaplingBlock.setTreeTypeRT(null); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior)
List<BlockState> blocks = new ArrayList<>(world.capturedBlockStates.values()); List<BlockState> blocks = new ArrayList<>(world.capturedBlockStates.values());
world.capturedBlockStates.clear(); world.capturedBlockStates.clear();
StructureGrowEvent structureEvent = null; StructureGrowEvent structureEvent = null;
@@ -644,6 +696,11 @@ public class CraftBlock implements Block { @@ -644,6 +695,11 @@ public class CraftBlock implements Block {
@Override @Override
public RayTraceResult rayTrace(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode) { public RayTraceResult rayTrace(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode) {
+ // SparklyPaper start - parallel world ticking + // SparklyPaper start - parallel world ticking
+ if (SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously"); + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
+ } + }
+ // SparklyPaper end - parallel world ticking + // SparklyPaper end - parallel world ticking
Preconditions.checkArgument(start != null, "Location start cannot be null"); Preconditions.checkArgument(start != null, "Location start cannot be null");
Preconditions.checkArgument(this.getWorld().equals(start.getWorld()), "Location start cannot be a different world"); Preconditions.checkArgument(this.getWorld().equals(start.getWorld()), "Location start cannot be a different world");
start.checkFinite(); start.checkFinite();
@@ -685,6 +742,11 @@ public class CraftBlock implements Block { @@ -685,6 +741,11 @@ public class CraftBlock implements Block {
@Override @Override
public boolean canPlace(BlockData data) { public boolean canPlace(BlockData data) {
+ // SparklyPaper start - parallel world ticking + // SparklyPaper start - parallel world ticking
+ if (SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously"); + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
+ } + }
+ // SparklyPaper end - parallel world ticking + // SparklyPaper end - parallel world ticking
Preconditions.checkArgument(data != null, "BlockData cannot be null"); Preconditions.checkArgument(data != null, "BlockData cannot be null");
net.minecraft.world.level.block.state.BlockState iblockdata = ((CraftBlockData) data).getState(); net.minecraft.world.level.block.state.BlockState iblockdata = ((CraftBlockData) data).getState();
net.minecraft.world.level.Level world = this.world.getMinecraftWorld(); net.minecraft.world.level.Level world = this.world.getMinecraftWorld();
@@ -719,6 +781,11 @@ public class CraftBlock implements Block { @@ -719,6 +780,11 @@ public class CraftBlock implements Block {
@Override @Override
public void tick() { public void tick() {
+ // SparklyPaper start - parallel world ticking + // SparklyPaper start - parallel world ticking
+ if (SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously"); + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
+ } + }
+ // SparklyPaper end - parallel world ticking + // SparklyPaper end - parallel world ticking
@@ -521,34 +494,19 @@ index 973b297a22c0cc53f966582c67c3688f4b2205c7..747f20d080b602ab9a1c551c648bf546
this.getNMS().tick(level, this.position, level.random); this.getNMS().tick(level, this.position, level.random);
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
index 768d3f93da2522d467183654260a8bd8653588b1..bad74104dcfde34ae0dec99adfe81e71132b7c28 100644 index 768d3f93da2522d467183654260a8bd8653588b1..58fdc0e7bb5d377c6dad1af6307d5d0d11b1ee45 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
@@ -11,12 +11,14 @@ import net.minecraft.network.protocol.game.ClientGamePacketListener; @@ -26,6 +26,27 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.LevelAccessor;
+import net.minecraft.world.level.block.DispenserBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.TileState;
import org.bukkit.craftbukkit.util.CraftLocation;
import org.bukkit.persistence.PersistentDataContainer;
+import org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -26,6 +28,26 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
private final T snapshot; private final T snapshot;
public boolean snapshotDisabled; // Paper public boolean snapshotDisabled; // Paper
public static boolean DISABLE_SNAPSHOT = false; // Paper public static boolean DISABLE_SNAPSHOT = false; // Paper
+ public static ThreadLocal<Boolean> DISABLE_SNAPSHOT_TL = ThreadLocal.withInitial(() -> Boolean.FALSE); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper parallel world ticking mod (distinguish name) + public static ThreadLocal<Boolean> DISABLE_SNAPSHOT_TL = ThreadLocal.withInitial(() -> Boolean.FALSE); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (distinguish name)
+ +
+ // Leaf - SparklyPaper parallel world ticking mod + // Leaf start - SparklyPaper - parallel world ticking mod
+ // refer to original field in case plugins attempt to modify it + // refer to original field in case plugins attempt to modify it
+ public static boolean getDisableSnapshotTL() { + public static boolean getDisableSnapshotTL() {
+ if (SparklyPaperParallelWorldTicking.enabled && DISABLE_SNAPSHOT_TL.get()) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && DISABLE_SNAPSHOT_TL.get())
+ return true; + return true;
+ synchronized (CraftBlockEntityState.class) { + synchronized (CraftBlockEntityState.class) {
+ return DISABLE_SNAPSHOT; + return DISABLE_SNAPSHOT;
@@ -557,44 +515,37 @@ index 768d3f93da2522d467183654260a8bd8653588b1..bad74104dcfde34ae0dec99adfe81e71
+ +
+ // update original field in case plugins attempt to access it + // update original field in case plugins attempt to access it
+ public static void setDisableSnapshotTL(boolean value) { + public static void setDisableSnapshotTL(boolean value) {
+ if (SparklyPaperParallelWorldTicking.enabled) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled)
+ DISABLE_SNAPSHOT_TL.set(value); + DISABLE_SNAPSHOT_TL.set(value);
+ synchronized (CraftBlockEntityState.class) { + synchronized (CraftBlockEntityState.class) {
+ DISABLE_SNAPSHOT = value; + DISABLE_SNAPSHOT = value;
+ } + }
+ } + }
+ // Leaf end - SparklyPaper - parallel world ticking mod
public CraftBlockEntityState(World world, T tileEntity) { public CraftBlockEntityState(World world, T tileEntity) {
super(world, tileEntity.getBlockPos(), tileEntity.getBlockState()); super(world, tileEntity.getBlockPos(), tileEntity.getBlockState());
@@ -34,8 +56,8 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft @@ -34,8 +55,8 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
try { // Paper - Show blockstate location if we failed to read it try { // Paper - Show blockstate location if we failed to read it
// Paper start // Paper start
- this.snapshotDisabled = DISABLE_SNAPSHOT; - this.snapshotDisabled = DISABLE_SNAPSHOT;
- if (DISABLE_SNAPSHOT) { - if (DISABLE_SNAPSHOT) {
+ this.snapshotDisabled = getDisableSnapshotTL(); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper parallel world ticking mod (collapse original behavior) + this.snapshotDisabled = getDisableSnapshotTL(); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior)
+ if (getDisableSnapshotTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper parallel world ticking mod (collapse original behavior) + if (getDisableSnapshotTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior)
this.snapshot = this.tileEntity; this.snapshot = this.tileEntity;
} else { } else {
this.snapshot = this.createSnapshot(tileEntity); this.snapshot = this.createSnapshot(tileEntity);
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
index fa63a6cfcfcc4eee4503a82d85333c139c8c8b2b..bc0f999f89fedebe58b6fa554c2abbacb65adbeb 100644 index fa63a6cfcfcc4eee4503a82d85333c139c8c8b2b..d106f65e4b745242484a195958fc559268a7dee0 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
@@ -21,6 +21,7 @@ import org.bukkit.material.Attachable; @@ -215,6 +215,12 @@ public class CraftBlockState implements BlockState {
import org.bukkit.material.MaterialData;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
+import org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking;
public class CraftBlockState implements BlockState {
@@ -215,6 +216,12 @@ public class CraftBlockState implements BlockState {
LevelAccessor access = this.getWorldHandle(); LevelAccessor access = this.getWorldHandle();
CraftBlock block = this.getBlock(); CraftBlock block = this.getBlock();
+ // SparklyPaper start - parallel world ticking + // SparklyPaper start - parallel world ticking
+ if (SparklyPaperParallelWorldTicking.enabled && access instanceof net.minecraft.server.level.ServerLevel serverWorld) { + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && access instanceof net.minecraft.server.level.ServerLevel serverWorld) {
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously"); + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
+ } + }
+ // SparklyPaper end - parallel world ticking + // SparklyPaper end - parallel world ticking
@@ -602,17 +553,17 @@ index fa63a6cfcfcc4eee4503a82d85333c139c8c8b2b..bc0f999f89fedebe58b6fa554c2abbac
if (block.getType() != this.getType()) { if (block.getType() != this.getType()) {
if (!force) { if (!force) {
return false; return false;
@@ -350,6 +357,8 @@ public class CraftBlockState implements BlockState { @@ -350,6 +356,8 @@ public class CraftBlockState implements BlockState {
@Override @Override
public java.util.Collection<org.bukkit.inventory.ItemStack> getDrops(org.bukkit.inventory.ItemStack item, org.bukkit.entity.Entity entity) { public java.util.Collection<org.bukkit.inventory.ItemStack> getDrops(org.bukkit.inventory.ItemStack item, org.bukkit.entity.Entity entity) {
+ if (SparklyPaperParallelWorldTicking.enabled) // Leaf - SparklyPaper parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) // Leaf - SparklyPaper - parallel world ticking mod (make configurable)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(world.getHandle(), position, "Cannot modify world asynchronously"); // SparklyPaper - parallel world ticking + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(world.getHandle(), position, "Cannot modify world asynchronously"); // SparklyPaper - parallel world ticking
this.requirePlaced(); this.requirePlaced();
net.minecraft.world.item.ItemStack nms = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(item); net.minecraft.world.item.ItemStack nms = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(item);
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
index 55572e799b5c8a74a546ac8febc14f80d5731c52..11a3970a9f3bee1d05327b8a5c5dde4f746929ac 100644 index 55572e799b5c8a74a546ac8febc14f80d5731c52..08a06c23c831a4de45b3e537228b837911019da8 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
@@ -249,8 +249,8 @@ public final class CraftBlockStates { @@ -249,8 +249,8 @@ public final class CraftBlockStates {
@@ -621,8 +572,8 @@ index 55572e799b5c8a74a546ac8febc14f80d5731c52..11a3970a9f3bee1d05327b8a5c5dde4f
// Paper start - block state snapshots // Paper start - block state snapshots
- boolean prev = CraftBlockEntityState.DISABLE_SNAPSHOT; - boolean prev = CraftBlockEntityState.DISABLE_SNAPSHOT;
- CraftBlockEntityState.DISABLE_SNAPSHOT = !useSnapshot; - CraftBlockEntityState.DISABLE_SNAPSHOT = !useSnapshot;
+ boolean prev = CraftBlockEntityState.getDisableSnapshotTL(); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper parallel world ticking mod (collapse original behavior) + boolean prev = CraftBlockEntityState.getDisableSnapshotTL(); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior)
+ CraftBlockEntityState.setDisableSnapshotTL(!useSnapshot); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper parallel world ticking mod (collapse original behavior) + CraftBlockEntityState.setDisableSnapshotTL(!useSnapshot); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior)
try { try {
// Paper end // Paper end
CraftBlockState blockState = CraftBlockStates.getBlockState(world, blockPosition, blockData, tileEntity); CraftBlockState blockState = CraftBlockStates.getBlockState(world, blockPosition, blockData, tileEntity);
@@ -631,33 +582,25 @@ index 55572e799b5c8a74a546ac8febc14f80d5731c52..11a3970a9f3bee1d05327b8a5c5dde4f
// Paper start // Paper start
} finally { } finally {
- CraftBlockEntityState.DISABLE_SNAPSHOT = prev; - CraftBlockEntityState.DISABLE_SNAPSHOT = prev;
+ CraftBlockEntityState.setDisableSnapshotTL(prev); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper parallel world ticking mod (collapse original behavior) + CraftBlockEntityState.setDisableSnapshotTL(prev); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior)
} }
// Paper end // Paper end
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index fbb4dd93c263c898731902b73dbd1c62df1eea4b..d19f87f1bbad8832db10d4d49186fe260728b40e 100644 index fbb4dd93c263c898731902b73dbd1c62df1eea4b..138662f3e57f9741a41701b5a5a65a859a31dfc8 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -254,6 +254,7 @@ import org.bukkit.inventory.meta.BookMeta; @@ -961,6 +961,28 @@ public class CraftEventFactory {
import org.bukkit.inventory.view.AnvilView;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
+import org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking;
public class CraftEventFactory {
@@ -961,6 +962,27 @@ public class CraftEventFactory {
} }
public static BlockPos sourceBlockOverride = null; // SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep. public static BlockPos sourceBlockOverride = null; // SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep.
+ public static final ThreadLocal<BlockPos> sourceBlockOverrideRT = new ThreadLocal<>(); // SparklyPaper - parallel world ticking (this is from Folia, fixes concurrency bugs with sculk catalysts) + public static final ThreadLocal<BlockPos> sourceBlockOverrideRT = new ThreadLocal<>(); // SparklyPaper - parallel world ticking (this is from Folia, fixes concurrency bugs with sculk catalysts)
+ +
+ // Leaf - SparklyPaper parallel world ticking mod + // Leaf start - SparklyPaper - parallel world ticking mod
+ // refer to original field in case plugins attempt to modify it + // refer to original field in case plugins attempt to modify it
+ public static BlockPos getSourceBlockOverrideRT() { + public static BlockPos getSourceBlockOverrideRT() {
+ BlockPos sourceBlockOverrideRTCopy; + BlockPos sourceBlockOverrideRTCopy;
+ if (SparklyPaperParallelWorldTicking.enabled && (sourceBlockOverrideRTCopy = sourceBlockOverrideRT.get()) != null) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && (sourceBlockOverrideRTCopy = sourceBlockOverrideRT.get()) != null)
+ return sourceBlockOverrideRTCopy; + return sourceBlockOverrideRTCopy;
+ synchronized (CraftEventFactory.class) { + synchronized (CraftEventFactory.class) {
+ return sourceBlockOverride; + return sourceBlockOverride;
@@ -666,12 +609,13 @@ index fbb4dd93c263c898731902b73dbd1c62df1eea4b..d19f87f1bbad8832db10d4d49186fe26
+ +
+ // update original field in case plugins attempt to access it + // update original field in case plugins attempt to access it
+ public static void setSourceBlockOverrideRT(BlockPos value) { + public static void setSourceBlockOverrideRT(BlockPos value) {
+ if (SparklyPaperParallelWorldTicking.enabled) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled)
+ sourceBlockOverrideRT.set(value); + sourceBlockOverrideRT.set(value);
+ synchronized (CraftEventFactory.class) { + synchronized (CraftEventFactory.class) {
+ sourceBlockOverride = value; + sourceBlockOverride = value;
+ } + }
+ } + }
+ // Leaf end - SparklyPaper - parallel world ticking mod
public static boolean handleBlockSpreadEvent(LevelAccessor world, BlockPos source, BlockPos target, net.minecraft.world.level.block.state.BlockState block, int flag) { public static boolean handleBlockSpreadEvent(LevelAccessor world, BlockPos source, BlockPos target, net.minecraft.world.level.block.state.BlockState block, int flag) {
// Suppress during worldgen // Suppress during worldgen
@@ -680,7 +624,7 @@ index fbb4dd93c263c898731902b73dbd1c62df1eea4b..d19f87f1bbad8832db10d4d49186fe26
state.setData(block); state.setData(block);
- BlockSpreadEvent event = new BlockSpreadEvent(state.getBlock(), CraftBlock.at(world, CraftEventFactory.sourceBlockOverride != null ? CraftEventFactory.sourceBlockOverride : source), state); - BlockSpreadEvent event = new BlockSpreadEvent(state.getBlock(), CraftBlock.at(world, CraftEventFactory.sourceBlockOverride != null ? CraftEventFactory.sourceBlockOverride : source), state);
+ BlockSpreadEvent event = new BlockSpreadEvent(state.getBlock(), CraftBlock.at(world, CraftEventFactory.getSourceBlockOverrideRT() != null ? CraftEventFactory.getSourceBlockOverrideRT() : source), state); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper parallel world ticking mod (collapse original behavior) + BlockSpreadEvent event = new BlockSpreadEvent(state.getBlock(), CraftBlock.at(world, CraftEventFactory.getSourceBlockOverrideRT() != null ? CraftEventFactory.getSourceBlockOverrideRT() : source), state); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior)
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (!event.isCancelled()) {
@@ -689,7 +633,7 @@ index fbb4dd93c263c898731902b73dbd1c62df1eea4b..d19f87f1bbad8832db10d4d49186fe26
org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), CraftVector.toBukkit(to)); org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), CraftVector.toBukkit(to));
- if (!net.minecraft.world.level.block.DispenserBlock.eventFired) { - if (!net.minecraft.world.level.block.DispenserBlock.eventFired) {
+ if (!net.minecraft.world.level.block.DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper parallel world ticking mod (collapse original behavior) + if (!net.minecraft.world.level.block.DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior)
if (!event.callEvent()) { if (!event.callEvent()) {
return itemStack; return itemStack;
} }

View File

@@ -1,21 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Taiyou06 <kaandindar21@gmail.com>
Date: Thu, 20 Mar 2025 00:16:49 +0100
Subject: [PATCH] Fix SparklyPaper - skip EntityScheduler's executeTick checks
if there isn't any tasks to be run
diff --git a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java
index bb56c56cdbd8a15803e85412b9c15b59a28e9e59..59becabc96366d97abbc3edf388bfaab1b1461da 100644
--- a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java
+++ b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java
@@ -190,4 +190,9 @@ public final class EntityScheduler {
}
}
}
+ public boolean hasTasks() {
+ synchronized (this.stateLock) {
+ return !this.currentlyExecuting.isEmpty() || !this.oneTimeDelayed.isEmpty();
+ }
+ }
}

View File

@@ -6,6 +6,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
public class SparklyPaperServerLevelTickExecutorThreadFactory implements ThreadFactory { public class SparklyPaperServerLevelTickExecutorThreadFactory implements ThreadFactory {
private final String worldName; private final String worldName;
public SparklyPaperServerLevelTickExecutorThreadFactory(final String worldName) { public SparklyPaperServerLevelTickExecutorThreadFactory(final String worldName) {

View File

@@ -10,7 +10,6 @@ public class AsyncChunkSend extends ConfigModules {
return EnumConfigCategory.ASYNC.getBaseKeyName() + ".async-chunk-send"; return EnumConfigCategory.ASYNC.getBaseKeyName() + ".async-chunk-send";
} }
@Experimental
public static boolean enabled = false; public static boolean enabled = false;
@Override @Override

View File

@@ -2,12 +2,15 @@ package org.dreeam.leaf.config.modules.async;
import org.dreeam.leaf.config.ConfigModules; import org.dreeam.leaf.config.ConfigModules;
import org.dreeam.leaf.config.EnumConfigCategory; import org.dreeam.leaf.config.EnumConfigCategory;
import org.dreeam.leaf.config.annotations.Experimental;
public class SparklyPaperParallelWorldTicking extends ConfigModules { public class SparklyPaperParallelWorldTicking extends ConfigModules {
public String getBasePath() { public String getBasePath() {
return EnumConfigCategory.ASYNC.getBaseKeyName() + ".parallel-world-tracking"; return EnumConfigCategory.ASYNC.getBaseKeyName() + ".parallel-world-tracking";
} }
@Experimental
public static boolean enabled = false; public static boolean enabled = false;
public static int threads = 8; public static int threads = 8;
public static boolean logContainerCreationStacktraces = false; public static boolean logContainerCreationStacktraces = false;