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
index 3446d5bb24fac345b65ac78927155f60fe437b2c..0f4bc6a5b87a72f521f6ca04cfe14147b4e35fe4 100644
index 52485a1bce522cf9a61c3e67673aafb1a5e1a82b..f2fcb836ca69bb0f49b79c92bf4e291f2a4448d6 100644
--- a/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

View File

@@ -70,10 +70,10 @@ index 6b2f6ab137ae37ff0db4827886614436b7ed5dcb..66a9fc729182476c4f601cdb32bcb109
/**
* The brand id for Pufferfish.
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
+++ 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() {
server.restart();
}
@@ -444,10 +444,10 @@ index ed8e11001c8d3c475dc851aedf6e6812a872dc54..c597c298795fb9893447bc822d941c17
+ // Purpur end - OfflinePlayer API
}
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
+++ 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
@@ -466,7 +466,7 @@ index 0f4bc6a5b87a72f521f6ca04cfe14147b4e35fe4..42bc72411462f3699a7a60f987eeca60
// Leaf start - Leaf config - API
@NotNull
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();
// Gale end - YAPFA - last tick time - API
@@ -1321,7 +1321,7 @@ index f1f97a85ec713c05c882d7588f4a3e4a017f4795..813f6cd253322538bdf96eb323dd23a7
+ // Purpur end
}
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
+++ b/src/main/java/org/bukkit/inventory/ItemStack.java
@@ -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)
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
+++ 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();
}
// Purpur end - Debug Marker API
@@ -26,10 +26,10 @@ index 0825a913b4f7d5e81d485df6415ab68a4e1530ce..f40e06c63a82dbbd6bbcadf2a71b7d28
+ // Leaves end - Photographer API
}
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
+++ 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();
// 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.
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
+++ b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
@@ -1,7 +1,7 @@
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;
@@ -13,18 +13,102 @@ import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities;
import net.minecraft.world.phys.AABB;
public class NearestLivingEntitySensor<T extends LivingEntity> extends Sensor<T> {
+
+ // Leaf start - Optimized entity sorting with buffer reuse
+ private static final int SMALL_ARRAY_THRESHOLD = 2;
+ private LivingEntity[] entityBuffer = new LivingEntity[0];
@@ -49,7 +41,7 @@ index b0c5e41fefc7c9adf1a61bd5b52861736657d37e..7f9550af4dce9c6442080c39d19e824f
- entitiesOfClass.sort(Comparator.comparingDouble(entity::distanceToSqr));
+
+ LivingEntity[] sorted = smartSort(entities, entity);
+ List<LivingEntity> sortedList = Arrays.asList(sorted);
+ List<LivingEntity> sortedList = java.util.Arrays.asList(sorted);
+
Brain<?> brain = entity.getBrain();
- brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, entitiesOfClass);
@@ -76,7 +68,7 @@ index b0c5e41fefc7c9adf1a61bd5b52861736657d37e..7f9550af4dce9c6442080c39d19e824f
+
+ 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) {

View File

@@ -1,15 +1,16 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Taiyou06 <kaandindar21@gmail.com>
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
index dd1c55e983bc1ddc9a77a0b825b78eba62c201ec..f7a3cdb3953a959fb258fcb0eeea81ea2c8b217a 100644
index f2d1025a13649c35991a662c267a7653e75d19a2..7739b4955dcb489c6bba9c9db65ba87025f7c669 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -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) {
try {
+ long i = Util.getNanos(); // SparklyPaper - track world's MSPT
@@ -21,51 +22,39 @@ index dd1c55e983bc1ddc9a77a0b825b78eba62c201ec..f7a3cdb3953a959fb258fcb0eeea81ea
+ serverLevel.tickTimes5s.add(this.tickCount, j);
+ serverLevel.tickTimes10s.add(this.tickCount, j);
+ serverLevel.tickTimes60s.add(this.tickCount, j);
+ // SparklyPaper end
+ // SparklyPaper end - track world's MSPT
} catch (Throwable levelTickingException) {
CrashReport crashReport = CrashReport.forThrowable(levelTickingException, "Exception ticking world");
serverLevel.fillReportDetails(crashReport);
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
+++ 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
+ // 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 tickTimes10s = new MinecraftServer.TickTimes(200);
+ public final MinecraftServer.TickTimes tickTimes60s = new MinecraftServer.TickTimes(1200);
+ // SparklyPaper end
+ // SparklyPaper end - track world's MSPT
+
public ServerLevel(
MinecraftServer server,
Executor dispatcher,
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
+++ b/org/purpurmc/purpur/task/TPSBarTask.java
@@ -7,6 +7,9 @@ import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
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 {
@@ -28,6 +28,44 @@ public class TPSBarTask extends BossBarTask {
@Override
void updateBossBar(BossBar bossbar, Player player) {
- bossbar.progress(getBossBarProgress());
- bossbar.color(getBossBarColor());
- bossbar.name(MiniMessage.miniMessage().deserialize(PurpurConfig.commandTPSBarTitle,
+ if (SparklyPaperParallelWorldTicking.enabled) {
+ // SparklyPaper start - track world's MSPT
+ if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) {
+ // 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
+ double worldMspt = calculateWorldMSPT(serverLevel);
@@ -100,23 +89,24 @@ index 8769993e7ca59da309087051a3cd38fc562c15d1..b05f30f973c771641cda031332d033f1
+ }
+ } else {
+ // Default behavior
+ bossbar.progress(getBossBarProgress());
+ bossbar.color(getBossBarColor());
+ bossbar.name(MiniMessage.miniMessage().deserialize(PurpurConfig.commandTPSBarTitle,
Placeholder.component("tps", getTPSColor()),
bossbar.progress(getBossBarProgress());
bossbar.color(getBossBarColor());
bossbar.name(MiniMessage.miniMessage().deserialize(PurpurConfig.commandTPSBarTitle,
@@ -35,6 +73,8 @@ public class TPSBarTask extends BossBarTask {
Placeholder.component("mspt", getMSPTColor()),
Placeholder.component("ping", getPingColor(player.getPing()))
- ));
+ ));
));
+ }
+ // SparklyPaper end - track world's MSPT
}
@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)));
}
+ 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 total = 0L;
+ int count = 0;
@@ -129,8 +119,10 @@ index 8769993e7ca59da309087051a3cd38fc562c15d1..b05f30f973c771641cda031332d033f1
+ }
+
+ if (count == 0) return 0.0;
+
+ return (double) total / (double) count * 1.0E-6D;
+ }
+ // SparklyPaper end - track world's MSPT
+
public enum FillMode {
TPS, MSPT, PING

View File

@@ -229,10 +229,10 @@ index f20c38c1ff978d00dc0c9810c050506deed44ebd..e58a40623c3a259c80d0f96686797445
player.getInventory().removeItem(ammo);
}
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
+++ 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;
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

View File

@@ -10,10 +10,10 @@ Leaf (After): ~628ms (-96%)
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
index 23446968f9b42f904da189fb6bc3a6fe15c01fe7..919ad58aef8f3c9705cb67f209e22760ec50ab1d 100644
index 47528dec6b1a2b36e71013a9372425a70cbc6a33..546fb78339c005ed71142cb3c894f816b8c72d08 100644
--- a/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 {
private TickingBlockEntity ticker;
private BlockPos cachedPos; // Leaf - Cache tile entity position
@@ -43,7 +43,7 @@ index 23446968f9b42f904da189fb6bc3a6fe15c01fe7..919ad58aef8f3c9705cb67f209e22760
}
@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
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).
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
+++ b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java
@@ -36,6 +36,7 @@ public final class EntityScheduler {
@@ -74,6 +74,19 @@ index c03608fec96b51e1867f43d8f42e5aefb1520e46..bb56c56cdbd8a15803e85412b9c15b59
if (this.tickCount == RETIRED_TICK_COUNT) {
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
index cc024874fbde9678bdddfdca7c25080869d66de2..edcd209798740f31cb302f36d7864a0d8ea1d561 100644
--- 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
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
index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..8d2694977f29b680d9daf83f2c8cc3502d3cb7dd 100644
index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..2fb65ce228da94eb7d9364ee0f94582300178f1d 100644
--- a/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;
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;
@@ -14,6 +14,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class TickThread extends Thread {
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() {
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) {
if (!isTickThread()) {
LOGGER.error("Thread failed main thread check: " + reason + ", context=" + getThreadContext(), new Throwable());
- throw new IllegalStateException(reason);
+ if (HARD_THROW)
+ throw new IllegalStateException(reason); // SparklyPaper - parallel world ticking
+ if (HARD_THROW) throw new IllegalStateException(reason); // SparklyPaper - parallel world ticking
}
}
@@ -38,90 +30,86 @@ index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..8d2694977f29b680d9daf83f2c8cc350
if (!isTickThreadFor(world, pos)) {
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 + " - " + 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());
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) {
if (!isTickThreadFor(world, pos, blockRadius)) {
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 + " - " + 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());
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) {
if (!isTickThreadFor(world, pos)) {
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 + " - " + 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());
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) {
if (!isTickThreadFor(world, chunkX, chunkZ)) {
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) + " - " + 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());
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) {
if (!isTickThreadFor(entity)) {
final String ex = "Thread failed main thread check: " +
- 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());
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) {
if (!isTickThreadFor(world, aabb)) {
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 + " - " + getTickThreadInformation(world.getServer());
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", aabb=" + aabb + " - " + getTickThreadInformation(world.getServer()); // SparklyPaper - parallel world ticking
LOGGER.error(ex, new Throwable());
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) {
if (!isTickThreadFor(world, blockX, blockZ)) {
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) + " - " + 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());
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
+ // 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) {
+ if (!isTickThreadFor(world)) {
+ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ world " + world.getWorld().getName() + " - " + getTickThreadInformation(world.getServer()), new Throwable());
+ if (HARD_THROW)
+ throw new IllegalStateException(reason);
+ 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) 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
+ public static void ensureOnlyTickThread(final String reason) {
+ boolean isTickThread = isTickThread();
+ boolean isServerLevelTickThread = isServerLevelTickThread();
+ if (!isTickThread || isServerLevelTickThread) {
+ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread ONLY tick thread check: " + reason, new Throwable());
+ if (HARD_THROW)
+ throw new IllegalStateException(reason);
+ if (HARD_THROW) 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.
+ public static void ensureTickThreadOrAsyncThread(final net.minecraft.server.level.ServerLevel world, final String reason) {
+ boolean isValidTickThread = isTickThreadFor(world);
@@ -129,8 +117,7 @@ index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..8d2694977f29b680d9daf83f2c8cc350
+ boolean isValid = isAsyncThread || isValidTickThread;
+ 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());
+ if (HARD_THROW)
+ throw new IllegalStateException(reason);
+ if (HARD_THROW) throw new IllegalStateException(reason);
+ }
+ }
+
@@ -159,70 +146,73 @@ index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..8d2694977f29b680d9daf83f2c8cc350
+ public static boolean isServerLevelTickThread() {
+ 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) */
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) {
- 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) {
- 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) {
- 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) {
- 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) {
- 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) {
- 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) {
- 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) {
- 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) {
- 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) {
- 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
+ // Because we only tick worlds in parallel (instead of regions), we can use this for our checks
+ public static boolean isTickThreadFor(final Level world) {
+ if (Thread.currentThread() instanceof ServerLevelTickThread serverLevelTickThread) {
+ return serverLevelTickThread.currentlyTickingServerLevel == world;
+ } else return isTickThread();
+ } else {
+ return isTickThread();
+ }
}
public static boolean isTickThreadFor(final Entity entity) {
@@ -231,10 +221,9 @@ index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..8d2694977f29b680d9daf83f2c8cc350
+ 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 ServerLevelTickThread(String name) {
+ super(name);
@@ -246,144 +235,128 @@ index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..8d2694977f29b680d9daf83f2c8cc350
+
+ 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
index 15673166e566b2a6d5093210d99b154e69fab0ad..3c80b73f969318ec12b4f39b50cf1e215b5ca23f 100644
index 15673166e566b2a6d5093210d99b154e69fab0ad..49abf1100271452e9c79c8643a25af3ce519773b 100644
--- a/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;
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 {
@@ -455,7 +455,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
}
private boolean unloadChunk0(int x, int z, boolean save) {
- org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot
+ // Leaf start - SparklyPaper parallel world ticking mod (make configurable)
+ if (SparklyPaperParallelWorldTicking.enabled)
+ // Leaf start - SparklyPaper - parallel world ticking mod (make configurable)
+ 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)
+ else
+ org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot
+ // Leaf end
+ // Leaf end - SparklyPaper - parallel world ticking mod (make configurable)
if (!this.isChunkLoaded(x, z)) {
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
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)
ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z));
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
public boolean loadChunk(int x, int z, boolean generate) {
- org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
+ // Leaf start - SparklyPaper parallel world ticking mod (make configurable)
+ if (SparklyPaperParallelWorldTicking.enabled)
+ // Leaf start - SparklyPaper - parallel world ticking mod (make configurable)
+ 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)
+ else
+ 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
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
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)
this.world.captureTreeGeneration = true;
this.world.captureBlockStates = true;
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) {
// 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)
net.minecraft.world.level.Level.ExplosionInteraction explosionType;
if (!breakBlocks) {
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
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)
warnUnsafeChunk("getting a faraway chunk", x >> 4, z >> 4); // Paper
// Transient load for this tick
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
public void setBiome(int x, int y, int z, Holder<net.minecraft.world.level.biome.Biome> bb) {
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)
if (this.world.hasChunkAt(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
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)
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
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
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -60,6 +60,7 @@ import org.bukkit.util.BlockVector;
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 {
@@ -75,6 +75,11 @@ public class CraftBlock implements Block {
}
public net.minecraft.world.level.block.state.BlockState getNMS() {
+ // Folia start - parallel world ticking
+ if (SparklyPaperParallelWorldTicking.enabled && world instanceof ServerLevel serverWorld) { // Leaf - SparklyPaper parallel world ticking mod (make configurable)
+ // SparklyPaper start - parallel world ticking
+ 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");
+ }
+ // Folia end - parallel world ticking
+ // SparklyPaper end - parallel world ticking
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) {
+ // 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");
+ }
+ // SparklyPaper end - parallel world ticking
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) {
+ // 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");
+ }
+ // 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
if (old.hasBlockEntity() && blockData.getBlock() != old.getBlock()) { // SPIGOT-3725 remove old tile entity if block changes
// 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
public Biome getBiome() {
+ // 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");
+ }
+ // SparklyPaper end - parallel world ticking
@@ -407,7 +380,7 @@ index 973b297a22c0cc53f966582c67c3688f4b2205c7..747f20d080b602ab9a1c551c648bf546
@Override
public Biome getComputedBiome() {
+ // 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");
+ }
+ // SparklyPaper end - parallel world ticking
@@ -418,102 +391,102 @@ index 973b297a22c0cc53f966582c67c3688f4b2205c7..747f20d080b602ab9a1c551c648bf546
@Override
public void setBiome(Biome bio) {
+ // 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");
+ }
+ // SparklyPaper end - parallel world ticking
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
public boolean isBlockIndirectlyPowered() {
+ // 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");
+ }
+ // SparklyPaper end - parallel world ticking
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
public int getBlockPower(BlockFace face) {
+ // 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");
+ }
+ // SparklyPaper end - parallel world ticking
int power = 0;
net.minecraft.world.level.Level world = this.world.getMinecraftWorld();
int x = this.getX();
@@ -484,6 +526,11 @@ public class CraftBlock implements Block {
@@ -484,6 +525,11 @@ public class CraftBlock implements Block {
@Override
public boolean breakNaturally() {
+ // 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");
+ }
+ // SparklyPaper end - parallel world ticking
return this.breakNaturally(null);
}
@@ -543,6 +590,11 @@ public class CraftBlock implements Block {
@@ -543,6 +589,11 @@ public class CraftBlock implements Block {
@Override
public boolean applyBoneMeal(BlockFace face) {
+ // 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");
+ }
+ // SparklyPaper end - parallel world ticking
Direction direction = CraftBlock.blockFaceToNotch(face);
BlockFertilizeEvent event = null;
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;
if (world.capturedBlockStates.size() > 0) {
- TreeType treeType = SaplingBlock.treeType;
- SaplingBlock.treeType = null;
+ 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)
+ 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)
List<BlockState> blocks = new ArrayList<>(world.capturedBlockStates.values());
world.capturedBlockStates.clear();
StructureGrowEvent structureEvent = null;
@@ -644,6 +696,11 @@ public class CraftBlock implements Block {
@@ -644,6 +695,11 @@ public class CraftBlock implements Block {
@Override
public RayTraceResult rayTrace(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode) {
+ // 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");
+ }
+ // SparklyPaper end - parallel world ticking
Preconditions.checkArgument(start != null, "Location start cannot be null");
Preconditions.checkArgument(this.getWorld().equals(start.getWorld()), "Location start cannot be a different world");
start.checkFinite();
@@ -685,6 +742,11 @@ public class CraftBlock implements Block {
@@ -685,6 +741,11 @@ public class CraftBlock implements Block {
@Override
public boolean canPlace(BlockData data) {
+ // 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");
+ }
+ // SparklyPaper end - parallel world ticking
Preconditions.checkArgument(data != null, "BlockData cannot be null");
net.minecraft.world.level.block.state.BlockState iblockdata = ((CraftBlockData) data).getState();
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
public void tick() {
+ // 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");
+ }
+ // SparklyPaper end - parallel world ticking
@@ -521,34 +494,19 @@ index 973b297a22c0cc53f966582c67c3688f4b2205c7..747f20d080b602ab9a1c551c648bf546
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
index 768d3f93da2522d467183654260a8bd8653588b1..bad74104dcfde34ae0dec99adfe81e71132b7c28 100644
index 768d3f93da2522d467183654260a8bd8653588b1..58fdc0e7bb5d377c6dad1af6307d5d0d11b1ee45 100644
--- a/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;
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
@@ -26,6 +26,27 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
private final T snapshot;
public boolean snapshotDisabled; // 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
+ 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;
+ synchronized (CraftBlockEntityState.class) {
+ return DISABLE_SNAPSHOT;
@@ -557,44 +515,37 @@ index 768d3f93da2522d467183654260a8bd8653588b1..bad74104dcfde34ae0dec99adfe81e71
+
+ // update original field in case plugins attempt to access it
+ public static void setDisableSnapshotTL(boolean value) {
+ if (SparklyPaperParallelWorldTicking.enabled)
+ if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled)
+ DISABLE_SNAPSHOT_TL.set(value);
+ synchronized (CraftBlockEntityState.class) {
+ DISABLE_SNAPSHOT = value;
+ }
+ }
+ // Leaf end - SparklyPaper - parallel world ticking mod
public CraftBlockEntityState(World world, T tileEntity) {
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
// Paper start
- this.snapshotDisabled = DISABLE_SNAPSHOT;
- if (DISABLE_SNAPSHOT) {
+ 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)
+ 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)
this.snapshot = this.tileEntity;
} else {
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
index fa63a6cfcfcc4eee4503a82d85333c139c8c8b2b..bc0f999f89fedebe58b6fa554c2abbacb65adbeb 100644
index fa63a6cfcfcc4eee4503a82d85333c139c8c8b2b..d106f65e4b745242484a195958fc559268a7dee0 100644
--- a/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;
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 {
@@ -215,6 +215,12 @@ public class CraftBlockState implements BlockState {
LevelAccessor access = this.getWorldHandle();
CraftBlock block = this.getBlock();
+ // 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");
+ }
+ // SparklyPaper end - parallel world ticking
@@ -602,17 +553,17 @@ index fa63a6cfcfcc4eee4503a82d85333c139c8c8b2b..bc0f999f89fedebe58b6fa554c2abbac
if (block.getType() != this.getType()) {
if (!force) {
return false;
@@ -350,6 +357,8 @@ public class CraftBlockState implements BlockState {
@@ -350,6 +356,8 @@ public class CraftBlockState implements BlockState {
@Override
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
this.requirePlaced();
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
index 55572e799b5c8a74a546ac8febc14f80d5731c52..11a3970a9f3bee1d05327b8a5c5dde4f746929ac 100644
index 55572e799b5c8a74a546ac8febc14f80d5731c52..08a06c23c831a4de45b3e537228b837911019da8 100644
--- a/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 {
@@ -621,8 +572,8 @@ index 55572e799b5c8a74a546ac8febc14f80d5731c52..11a3970a9f3bee1d05327b8a5c5dde4f
// Paper start - block state snapshots
- boolean prev = CraftBlockEntityState.DISABLE_SNAPSHOT;
- CraftBlockEntityState.DISABLE_SNAPSHOT = !useSnapshot;
+ 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)
+ 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)
try {
// Paper end
CraftBlockState blockState = CraftBlockStates.getBlockState(world, blockPosition, blockData, tileEntity);
@@ -631,33 +582,25 @@ index 55572e799b5c8a74a546ac8febc14f80d5731c52..11a3970a9f3bee1d05327b8a5c5dde4f
// Paper start
} finally {
- 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
}
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
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -254,6 +254,7 @@ import org.bukkit.inventory.meta.BookMeta;
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 {
@@ -961,6 +961,28 @@ 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 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
+ public static BlockPos getSourceBlockOverrideRT() {
+ BlockPos sourceBlockOverrideRTCopy;
+ if (SparklyPaperParallelWorldTicking.enabled && (sourceBlockOverrideRTCopy = sourceBlockOverrideRT.get()) != null)
+ if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && (sourceBlockOverrideRTCopy = sourceBlockOverrideRT.get()) != null)
+ return sourceBlockOverrideRTCopy;
+ synchronized (CraftEventFactory.class) {
+ return sourceBlockOverride;
@@ -666,12 +609,13 @@ index fbb4dd93c263c898731902b73dbd1c62df1eea4b..d19f87f1bbad8832db10d4d49186fe26
+
+ // update original field in case plugins attempt to access it
+ public static void setSourceBlockOverrideRT(BlockPos value) {
+ if (SparklyPaperParallelWorldTicking.enabled)
+ if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled)
+ sourceBlockOverrideRT.set(value);
+ synchronized (CraftEventFactory.class) {
+ 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) {
// Suppress during worldgen
@@ -680,7 +624,7 @@ index fbb4dd93c263c898731902b73dbd1c62df1eea4b..d19f87f1bbad8832db10d4d49186fe26
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.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);
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));
- 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()) {
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;
public class SparklyPaperServerLevelTickExecutorThreadFactory implements ThreadFactory {
private 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";
}
@Experimental
public static boolean enabled = false;
@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.EnumConfigCategory;
import org.dreeam.leaf.config.annotations.Experimental;
public class SparklyPaperParallelWorldTicking extends ConfigModules {
public String getBasePath() {
return EnumConfigCategory.ASYNC.getBaseKeyName() + ".parallel-world-tracking";
}
@Experimental
public static boolean enabled = false;
public static int threads = 8;
public static boolean logContainerCreationStacktraces = false;