9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2026-01-06 15:51:31 +00:00

Update changes from ver/1.21.4 branch

This commit is contained in:
Dreeam
2025-05-02 22:45:26 -04:00
84 changed files with 6041 additions and 1028 deletions

View File

@@ -6,10 +6,10 @@ Subject: [PATCH] SparklyPaper: Parallel world ticking
Original project: https://github.com/SparklyPower/SparklyPaper
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
index d6a30d6735d24f24a8108b6a5d15725587bb662a..39517966935265bc4533d4ce414d2df72df5a614 100644
index be820c6093dd2ae7642b9bee11edf65e3a8d7242..06ac3537f5655d048d770bb004243f207fad9faa 100644
--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
@@ -1050,7 +1050,7 @@ public final class ChunkHolderManager {
@@ -1031,7 +1031,7 @@ public final class ChunkHolderManager {
if (changedFullStatus.isEmpty()) {
return;
}
@@ -18,7 +18,7 @@ index d6a30d6735d24f24a8108b6a5d15725587bb662a..39517966935265bc4533d4ce414d2df7
this.taskScheduler.scheduleChunkTask(() -> {
final ArrayDeque<NewChunkHolder> pendingFullLoadUpdate = ChunkHolderManager.this.pendingFullLoadUpdate;
for (int i = 0, len = changedFullStatus.size(); i < len; ++i) {
@@ -1076,7 +1076,12 @@ public final class ChunkHolderManager {
@@ -1057,7 +1057,12 @@ public final class ChunkHolderManager {
// note: never call while inside the chunk system, this will absolutely break everything
public void processUnloads() {
@@ -32,7 +32,7 @@ index d6a30d6735d24f24a8108b6a5d15725587bb662a..39517966935265bc4533d4ce414d2df7
if (BLOCK_TICKET_UPDATES.get() == Boolean.TRUE) {
throw new IllegalStateException("Cannot unload chunks recursively");
@@ -1358,7 +1363,7 @@ public final class ChunkHolderManager {
@@ -1339,7 +1344,7 @@ public final class ChunkHolderManager {
List<NewChunkHolder> changedFullStatus = null;
@@ -650,7 +650,7 @@ index ae5d3de44fb710b48fdabf04f5e706df1f9889b7..31abf2da10bc9b4b7825ed4b3d4e9da5
// Paper start - extra debug info
if (entity.valid) {
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index e2b15968e89a532ec21c786f41b7f9322fd65a04..915498dcb08a678256e6cc1659642d6126851365 100644
index fefaab58da149b082a4d1e3bed9ec84ae8488d45..9100da3fe4e478cea7198cb4e028fcefccb3eb3c 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -434,6 +434,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -669,7 +669,7 @@ index e2b15968e89a532ec21c786f41b7f9322fd65a04..915498dcb08a678256e6cc1659642d61
// CraftBukkit start
if (this.joining) {
this.joining = false;
@@ -1454,6 +1456,8 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -1455,6 +1457,8 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
teleportTransition.postTeleportTransition().onTransition(this);
return this;
} else {
@@ -678,7 +678,7 @@ index e2b15968e89a532ec21c786f41b7f9322fd65a04..915498dcb08a678256e6cc1659642d61
// CraftBukkit start
/*
this.isChangingDimension = true;
@@ -1825,6 +1829,12 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -1826,6 +1830,12 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
return OptionalInt.empty();
} else {
// CraftBukkit start
@@ -691,7 +691,7 @@ index e2b15968e89a532ec21c786f41b7f9322fd65a04..915498dcb08a678256e6cc1659642d61
this.containerMenu = abstractContainerMenu; // Moved up
if (!this.isImmobile())
this.connection
@@ -1889,6 +1899,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -1890,6 +1900,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
}
@Override
public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
@@ -743,10 +743,10 @@ index b17c8a2f5294ac28cc05fb05c84a041b2c6c8721..0b8b4658dbbad1bacc13e97b4fc0cdce
serverPlayer.connection = player.connection;
serverPlayer.restoreFrom(player, keepInventory);
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 9bc978ca290ca772b0367e89b69fe16b502b0cd2..17ff57db6f90b3f4facef691ad4347e67a9f5836 100644
index 9bc978ca290ca772b0367e89b69fe16b502b0cd2..334a47659ba75fade062bc79df3731d1e449114b 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -3370,15 +3370,33 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -3370,15 +3370,40 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
if (this.portalProcess != null) {
if (this.portalProcess.processPortalTeleportation(serverLevel, this, this.canUsePortal(false))) {
this.setPortalCooldown();
@@ -760,6 +760,11 @@ index 9bc978ca290ca772b0367e89b69fe16b502b0cd2..17ff57db6f90b3f4facef691ad4347e6
+ // TCRF SparklyPaper (Pathothingi) start - parallel world ticking
+ java.util.function.Consumer<Entity> portalEntityTask = entity -> {
+ assert entity.portalProcess != null;
+ // Fix NPE when portalProcess becomes null before task execution
+ // Portal process was likely nulled out (e.g., expired) between scheduling and execution.
+ if (entity.portalProcess == null) {
+ return;
+ }
+
+ if (entity.portalProcess.isParallelCancelledByPlugin()) {
+ entity.portalProcess = null;
@@ -775,8 +780,10 @@ index 9bc978ca290ca772b0367e89b69fe16b502b0cd2..17ff57db6f90b3f4facef691ad4347e6
+ entity.teleport(portalDestination);
+ }
+ }
+ if (this.portalProcess != null)
+ // Add another null check here just in case teleport() somehow nulled it (defensive)
+ if (entity.portalProcess != null) {
+ entity.portalProcess.confirmParallelAsHandled();
+ }
+ };
+ if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) {
+ this.portalProcess.setParallelAsScheduled();
@@ -787,7 +794,7 @@ index 9bc978ca290ca772b0367e89b69fe16b502b0cd2..17ff57db6f90b3f4facef691ad4347e6
} else if (this.portalProcess.hasExpired()) {
this.portalProcess = null;
}
@@ -3908,6 +3926,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -3908,6 +3933,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
private Entity teleportCrossDimension(ServerLevel level, TeleportTransition teleportTransition) {

View File

@@ -0,0 +1,69 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samsuik <kfian294ma4@gmail.com>
Date: Thu, 1 May 2025 22:38:48 +0200
Subject: [PATCH] Sakura: Optimise-check-inside-blocks-and-traverse-blocks
Dreeam TODO: refactor checkinsideblcoks
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 4221e5322fa3a3ff6ab53946aa71d54144d2c4b2..4474639b0411236e208c542973084864365c544c 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -1670,6 +1670,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
private void checkInsideBlocks(List<Entity.Movement> movements, Set<BlockState> blocksInside) {
if (this.isAffectedByBlocks()) {
LongSet set = this.visitedBlocks;
+ // Sakura start - optimise check inside blocks
+ int lastChunkX = Integer.MIN_VALUE;
+ int lastChunkZ = Integer.MIN_VALUE;
+ net.minecraft.world.level.chunk.ChunkAccess chunk = null;
+ // Sakura end - optimise check inside blocks
for (Entity.Movement movement : movements) {
Vec3 vec3 = movement.from();
@@ -1681,7 +1686,19 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return;
}
- BlockState blockState = this.level().getBlockState(blockPos);
+ // Sakura start - optimise check inside blocks
+ final int chunkX = blockPos.getX() >> 4;
+ final int chunkZ = blockPos.getZ() >> 4;
+ if (chunk == null || chunkX != lastChunkX || chunkZ != lastChunkZ) {
+ chunk = this.level.getChunkIfLoadedImmediately(chunkX, chunkZ);
+ if (chunk == null) {
+ continue;
+ }
+ lastChunkX = chunkX;
+ lastChunkZ = chunkZ;
+ }
+ final BlockState blockState = chunk.getBlockState(blockPos);
+ // Sakura end - optimise check inside blocks
if (!blockState.isAir() && set.add(blockPos.asLong())) {
try {
VoxelShape entityInsideCollisionShape = blockState.getEntityInsideCollisionShape(this.level(), blockPos);
diff --git a/net/minecraft/world/level/BlockGetter.java b/net/minecraft/world/level/BlockGetter.java
index 91865d7e78e15cc643a65de03045b90a52d6ec2a..03f82e60528738e89f195cfc59094f53156f5370 100644
--- a/net/minecraft/world/level/BlockGetter.java
+++ b/net/minecraft/world/level/BlockGetter.java
@@ -214,10 +214,18 @@ public interface BlockGetter extends LevelHeightAccessor {
static Iterable<BlockPos> boxTraverseBlocks(Vec3 oldPosition, Vec3 position, AABB boundingBox) {
Vec3 vec3 = position.subtract(oldPosition);
- Iterable<BlockPos> iterable = BlockPos.betweenClosed(boundingBox);
+ // Sakura start - optimise check inside blocks
if (vec3.lengthSqr() < Mth.square(0.99999F)) {
- return iterable;
+ return org.dreeam.leaf.util.map.BlockPosIterator.iterable(boundingBox);
} else {
+ final boolean xZero = vec3.x() == 0.0;
+ final boolean yZero = vec3.y() == 0.0;
+ final boolean zZero = vec3.z() == 0.0;
+ if (xZero && yZero || yZero && zZero || xZero && zZero) {
+ return org.dreeam.leaf.util.map.BlockPosIterator.traverseArea(vec3, boundingBox);
+ }
+ Iterable<BlockPos> iterable = BlockPos.betweenClosed(boundingBox);
+ // Sakura end - optimise check inside blocks
Set<BlockPos> set = new ObjectLinkedOpenHashSet<>();
Vec3 minPosition = boundingBox.getMinPosition();
Vec3 vec31 = minPosition.subtract(vec3);

View File

@@ -238,24 +238,16 @@ index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..2fb65ce228da94eb7d9364ee0f945823
+ // SparklyPaper end - parallel world ticking
}
diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
index 196fddeab452e7bc89ef6758635e1d07074e7416..55a2ffa0fff6ef66b9bd5069300c09e9e3535c0d 100644
index 548fcd9646dee0c40b6ba9b3dafb9ca157dfe324..d7af94890bfccd6ff665d920cecfa1e5be626aa4 100644
--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
@@ -28,6 +28,7 @@ import java.util.logging.Level;
class PaperEventManager {
private final Server server;
+ private final org.purpurmc.purpur.util.MinecraftInternalPlugin minecraftInternalPlugin = new org.purpurmc.purpur.util.MinecraftInternalPlugin(); // Leaf - Parallel world ticking
public PaperEventManager(Server server) {
this.server = server;
@@ -40,6 +41,12 @@ class PaperEventManager {
@@ -40,6 +40,12 @@ class PaperEventManager {
if (listeners.length == 0) return;
// Leaf end - Skip event if no listeners
if (event.isAsynchronous() && this.server.isPrimaryThread()) {
+ // Leaf start - Parallel world ticking
+ if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.runAsyncTasksSync) {
+ org.bukkit.Bukkit.getAsyncScheduler().runNow(minecraftInternalPlugin, task -> event.callEvent());
+ org.dreeam.leaf.async.world.PWTEventScheduler.getScheduler().scheduleTask(event::callEvent);
+ return;
+ }
+ // Leaf end - Parallel world ticking
@@ -263,10 +255,10 @@ index 196fddeab452e7bc89ef6758635e1d07074e7416..55a2ffa0fff6ef66b9bd5069300c09e9
} else if (!event.isAsynchronous() && !this.server.isPrimaryThread() && !this.server.isStopping()) {
// Leaf start - Multithreaded tracker
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 6bcece7ceb5be047371faf7ab85b3688ed3e045b..96faa72abe918e7ab3f1dec44072a5fee27b6476 100644
index af33cab59932f4ec135caf94dc5828930833daf6..92463ddc6fdcf542ce4a6d2a5059d4a9f7a6085a 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -456,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) {
@@ -280,7 +272,7 @@ index 6bcece7ceb5be047371faf7ab85b3688ed3e045b..96faa72abe918e7ab3f1dec44072a5fe
if (!this.isChunkLoaded(x, z)) {
return true;
}
@@ -473,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) {
@@ -289,7 +281,7 @@ index 6bcece7ceb5be047371faf7ab85b3688ed3e045b..96faa72abe918e7ab3f1dec44072a5fe
ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z));
if (playerChunk == null) return false;
@@ -523,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) {
@@ -303,7 +295,7 @@ index 6bcece7ceb5be047371faf7ab85b3688ed3e045b..96faa72abe918e7ab3f1dec44072a5fe
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
@@ -751,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) {
@@ -312,7 +304,7 @@ index 6bcece7ceb5be047371faf7ab85b3688ed3e045b..96faa72abe918e7ab3f1dec44072a5fe
this.world.captureTreeGeneration = true;
this.world.captureBlockStates = true;
boolean grownTree = this.generateTree(loc, type);
@@ -866,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
@@ -321,7 +313,7 @@ index 6bcece7ceb5be047371faf7ab85b3688ed3e045b..96faa72abe918e7ab3f1dec44072a5fe
net.minecraft.world.level.Level.ExplosionInteraction explosionType;
if (!breakBlocks) {
explosionType = net.minecraft.world.level.Level.ExplosionInteraction.NONE; // Don't break blocks
@@ -957,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) {
@@ -330,7 +322,7 @@ index 6bcece7ceb5be047371faf7ab85b3688ed3e045b..96faa72abe918e7ab3f1dec44072a5fe
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);
@@ -987,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);
@@ -339,7 +331,7 @@ index 6bcece7ceb5be047371faf7ab85b3688ed3e045b..96faa72abe918e7ab3f1dec44072a5fe
if (this.world.hasChunkAt(pos)) {
net.minecraft.world.level.chunk.LevelChunk chunk = this.world.getChunkAt(pos);
@@ -2329,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) {
@@ -349,7 +341,7 @@ index 6bcece7ceb5be047371faf7ab85b3688ed3e045b..96faa72abe918e7ab3f1dec44072a5fe
}
// 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 5f04b2dcff7c0e967647bde9dfa0f35f59e8524c..8fa769f1f18d05b6f037c84175dcb56bead15b24 100644
index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..b94efcab12d41fa8745e5bb55cfa6481d8262e74 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -75,6 +75,11 @@ public class CraftBlock implements Block {
@@ -364,31 +356,32 @@ index 5f04b2dcff7c0e967647bde9dfa0f35f59e8524c..8fa769f1f18d05b6f037c84175dcb56b
return this.world.getBlockState(this.position);
}
@@ -155,6 +160,11 @@ public class CraftBlock implements Block {
@@ -157,6 +162,11 @@ public class CraftBlock implements Block {
}
private void setData(final byte data, int flags) {
private void setData(final byte data, int flag) {
+ // 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 modify world asynchronously");
+ }
+ // SparklyPaper end - parallel world ticking
this.world.setBlock(this.position, CraftMagicNumbers.getBlock(this.getType(), data), flags);
this.world.setBlock(this.position, CraftMagicNumbers.getBlock(this.getType(), data), flag);
}
@@ -196,6 +206,11 @@ public class CraftBlock implements Block {
@@ -198,6 +208,12 @@ public class CraftBlock implements Block {
}
public static boolean setBlockState(LevelAccessor world, BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState, 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
+ 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, pos, "Cannot modify world asynchronously");
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
+ }
+ // SparklyPaper end - parallel world ticking
// SPIGOT-611: need to do this to prevent glitchiness. Easier to handle this here (like /setblock) than to fix weirdness in block entity cleanup
if (oldState.hasBlockEntity() && newState.getBlock() != oldState.getBlock()) { // SPIGOT-3725 remove old block entity if block changes
+
// 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
@@ -344,18 +359,33 @@ public class CraftBlock implements Block {
@@ -343,18 +359,33 @@ public class CraftBlock implements Block {
@Override
public Biome getBiome() {
@@ -422,7 +415,7 @@ index 5f04b2dcff7c0e967647bde9dfa0f35f59e8524c..8fa769f1f18d05b6f037c84175dcb56b
this.getWorld().setBiome(this.getX(), this.getY(), this.getZ(), bio);
}
@@ -376,6 +406,11 @@ public class CraftBlock implements Block {
@@ -375,6 +406,11 @@ public class CraftBlock implements Block {
@Override
public boolean isBlockIndirectlyPowered() {
@@ -434,7 +427,7 @@ index 5f04b2dcff7c0e967647bde9dfa0f35f59e8524c..8fa769f1f18d05b6f037c84175dcb56b
return this.world.getMinecraftWorld().hasNeighborSignal(this.position);
}
@@ -415,6 +450,11 @@ public class CraftBlock implements Block {
@@ -414,6 +450,11 @@ public class CraftBlock implements Block {
@Override
public int getBlockPower(BlockFace face) {
@@ -446,7 +439,7 @@ index 5f04b2dcff7c0e967647bde9dfa0f35f59e8524c..8fa769f1f18d05b6f037c84175dcb56b
int power = 0;
net.minecraft.world.level.Level world = this.world.getMinecraftWorld();
int x = this.getX();
@@ -483,6 +523,11 @@ public class CraftBlock implements Block {
@@ -484,6 +525,11 @@ public class CraftBlock implements Block {
@Override
public boolean breakNaturally() {
@@ -458,7 +451,7 @@ index 5f04b2dcff7c0e967647bde9dfa0f35f59e8524c..8fa769f1f18d05b6f037c84175dcb56b
return this.breakNaturally(null);
}
@@ -542,6 +587,11 @@ public class CraftBlock implements Block {
@@ -543,6 +589,11 @@ public class CraftBlock implements Block {
@Override
public boolean applyBoneMeal(BlockFace face) {
@@ -470,18 +463,18 @@ index 5f04b2dcff7c0e967647bde9dfa0f35f59e8524c..8fa769f1f18d05b6f037c84175dcb56b
Direction direction = CraftBlock.blockFaceToNotch(face);
BlockFertilizeEvent event = null;
ServerLevel world = this.getCraftWorld().getHandle();
@@ -553,8 +603,8 @@ public class CraftBlock implements Block {
@@ -554,8 +605,8 @@ public class CraftBlock implements Block {
world.captureTreeGeneration = false;
if (!world.capturedBlockStates.isEmpty()) {
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)
List<BlockState> states = new ArrayList<>(world.capturedBlockStates.values());
List<BlockState> blocks = new ArrayList<>(world.capturedBlockStates.values());
world.capturedBlockStates.clear();
StructureGrowEvent structureEvent = null;
@@ -644,6 +694,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) {
@@ -493,7 +486,7 @@ index 5f04b2dcff7c0e967647bde9dfa0f35f59e8524c..8fa769f1f18d05b6f037c84175dcb56b
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 +740,11 @@ public class CraftBlock implements Block {
@@ -685,6 +741,11 @@ public class CraftBlock implements Block {
@Override
public boolean canPlace(BlockData data) {
@@ -505,7 +498,7 @@ index 5f04b2dcff7c0e967647bde9dfa0f35f59e8524c..8fa769f1f18d05b6f037c84175dcb56b
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 +779,11 @@ public class CraftBlock implements Block {
@@ -719,6 +780,11 @@ public class CraftBlock implements Block {
@Override
public void tick() {
@@ -518,7 +511,7 @@ index 5f04b2dcff7c0e967647bde9dfa0f35f59e8524c..8fa769f1f18d05b6f037c84175dcb56b
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 3422970353dcd886934b9ee906467769d39abbde..13c91223bbb4841cab0e491037a36113a33faf15 100644
index 768d3f93da2522d467183654260a8bd8653588b1..5cef786fa2e5dfd3e7b79918bc73af02891b0bea 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
@@ -26,6 +26,27 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
@@ -547,8 +540,8 @@ index 3422970353dcd886934b9ee906467769d39abbde..13c91223bbb4841cab0e491037a36113
+ }
+ // Leaf end - SparklyPaper - parallel world ticking mod
public CraftBlockEntityState(World world, T blockEntity) {
super(world, blockEntity.getBlockPos(), blockEntity.getBlockState());
public CraftBlockEntityState(World world, T tileEntity) {
super(world, tileEntity.getBlockPos(), tileEntity.getBlockState());
@@ -34,8 +55,8 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
try { // Paper - Show blockstate location if we failed to read it
@@ -557,14 +550,14 @@ index 3422970353dcd886934b9ee906467769d39abbde..13c91223bbb4841cab0e491037a36113
- if (DISABLE_SNAPSHOT) {
+ this.snapshotDisabled = getDisableSnapshotTL(); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior)
+ if (this.snapshotDisabled) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior)
this.snapshot = this.blockEntity;
this.snapshot = this.tileEntity;
} else {
this.snapshot = this.createSnapshot(blockEntity);
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 c0a7659776a9f0fb82bb8563acbf3286b318fe03..69fc25b20cc84a2cd89cb0927aceba05df405e2a 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
@@ -217,6 +217,12 @@ public class CraftBlockState implements BlockState {
@@ -215,6 +215,12 @@ public class CraftBlockState implements BlockState {
LevelAccessor access = this.getWorldHandle();
CraftBlock block = this.getBlock();
@@ -577,7 +570,7 @@ index c0a7659776a9f0fb82bb8563acbf3286b318fe03..69fc25b20cc84a2cd89cb0927aceba05
if (block.getType() != this.getType()) {
if (!force) {
return false;
@@ -365,6 +371,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) {
@@ -587,35 +580,37 @@ index c0a7659776a9f0fb82bb8563acbf3286b318fe03..69fc25b20cc84a2cd89cb0927aceba05
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 321280d7c9c3c828cbf2eb19d2fd196a1f84d4c3..cd8f771e08cee5d00c53a8e70f0fe37cf393cd52 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
@@ -195,14 +195,14 @@ public final class CraftBlockStates {
BlockPos pos = craftBlock.getPosition();
net.minecraft.world.level.block.state.BlockState state = craftBlock.getNMS();
BlockEntity blockEntity = craftBlock.getHandle().getBlockEntity(pos);
@@ -249,8 +249,8 @@ public final class CraftBlockStates {
net.minecraft.world.level.block.state.BlockState blockData = craftBlock.getNMS();
BlockEntity tileEntity = craftBlock.getHandle().getBlockEntity(blockPosition);
// 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)
try {
CraftBlockState blockState = CraftBlockStates.getBlockState(world, pos, state, blockEntity);
blockState.setWorldHandle(craftBlock.getHandle()); // Inject the block's generator access
return blockState;
// Paper end
CraftBlockState blockState = CraftBlockStates.getBlockState(world, blockPosition, blockData, tileEntity);
@@ -258,7 +258,7 @@ public final class CraftBlockStates {
return blockState;
// Paper start
} finally {
- CraftBlockEntityState.DISABLE_SNAPSHOT = prev;
+ 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 ebb07b9b9f6bef9195978c8ecdd5f4ef3ee198bc..3848011363056d700110564c6af8e4c3bd54ac6c 100644
index c2552c3706831f7012b5b449fa43c7d5990056a4..4e8a1d01a6c0afef92ae56cc4909af06d63e5268 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -818,6 +818,28 @@ 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 BlockPos 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)
+
+ // Leaf start - SparklyPaper - parallel world ticking mod
@@ -639,20 +634,29 @@ index ebb07b9b9f6bef9195978c8ecdd5f4ef3ee198bc..3848011363056d700110564c6af8e4c3
+ }
+ // Leaf end - SparklyPaper - parallel world ticking mod
public static boolean handleBlockSpreadEvent(LevelAccessor world, BlockPos source, BlockPos target, net.minecraft.world.level.block.state.BlockState state, int flags) {
return handleBlockSpreadEvent(world, source, target, state, flags, false);
@@ -833,7 +855,10 @@ public class CraftEventFactory {
CraftBlockState snapshot = CraftBlockStates.getBlockState(world, target);
snapshot.setData(state);
public static boolean handleBlockSpreadEvent(LevelAccessor world, BlockPos source, BlockPos target, net.minecraft.world.level.block.state.BlockState block, int flag) {
// Suppress during worldgen
@@ -972,7 +994,10 @@ public class CraftEventFactory {
CraftBlockState state = CraftBlockStates.getBlockState(world, target, flag);
state.setData(block);
- BlockSpreadEvent event = new BlockSpreadEvent(snapshot.getBlock(), CraftBlock.at(world, CraftEventFactory.sourceBlockOverride != null ? CraftEventFactory.sourceBlockOverride : source), snapshot);
- BlockSpreadEvent event = new BlockSpreadEvent(state.getBlock(), CraftBlock.at(world, CraftEventFactory.sourceBlockOverride != null ? CraftEventFactory.sourceBlockOverride : source), state);
+ // Leaf start - SparklyPaper parallel world ticking mod (collapse original behavior)
+ final BlockPos sourceBlockOverrideRTSnap = getSourceBlockOverrideRT();
+ BlockSpreadEvent event = new BlockSpreadEvent(snapshot.getBlock(), CraftBlock.at(world, sourceBlockOverrideRTSnap != null ? sourceBlockOverrideRTSnap : source), snapshot); // SparklyPaper - parallel world ticking
+ BlockSpreadEvent event = new BlockSpreadEvent(state.getBlock(), CraftBlock.at(world, sourceBlockOverrideRTSnap != null ? sourceBlockOverrideRTSnap : source), state); // SparklyPaper - parallel world ticking
+ // Leaf end - SparklyPaper parallel world ticking mod (collapse original behavior)
if (event.callEvent()) {
boolean result = snapshot.place(flags);
return !checkSetResult || result;
Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
@@ -2265,7 +2290,7 @@ public class CraftEventFactory {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemStack.copyWithCount(1));
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 (!event.callEvent()) {
return itemStack;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java
index e4e2e42d0ca25df7fe9f2dd4275610e45fcb2c84..e7c6b2ab5f2c68f3319ccd52785c8d3488a2eef7 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java

View File

@@ -0,0 +1,37 @@
package org.dreeam.leaf.async.world;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class PWTEventScheduler {
private static volatile PWTEventScheduler instance;
private final ExecutorService executor;
private PWTEventScheduler() {
this.executor = Executors.newCachedThreadPool(
new ThreadFactoryBuilder()
.setNameFormat("Leaf PWT Event Scheduler Thread - %d")
.setDaemon(true)
.setPriority(Thread.NORM_PRIORITY - 2)
.build()
);
}
public static PWTEventScheduler getScheduler() {
if (instance == null) {
synchronized (PWTEventScheduler.class) {
if (instance == null) {
instance = new PWTEventScheduler();
}
}
}
return instance;
}
public void scheduleTask(Runnable task) {
this.executor.execute(task);
}
}

View File

@@ -144,6 +144,10 @@ public class LinearRegionFile implements IRegionFile {
}
private synchronized void save() throws IOException {
if (MinecraftServer.getServer().hasStopped()) {
// Save only once on shutdown
if (!closed) return;
}
long timestamp = getTimestamp();
short chunkCount = 0;
@@ -217,7 +221,7 @@ public class LinearRegionFile implements IRegionFile {
LOGGER.error("Chunk write IOException {} {}", e, this.path);
}
if ((System.nanoTime() - this.lastFlushed) >= TimeUnit.NANOSECONDS.toSeconds(RegionFormatConfig.linearFlushFrequency)) {
if (TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - this.lastFlushed) >= (RegionFormatConfig.linearFlushFrequency)) {
this.flushWrapper();
}
}