diff --git a/leaf-archived-patches/unapplied/server/minecraft-patches/features/0134-SparklyPaper-Parallel-world-ticking.patch b/leaf-server/minecraft-patches/features/0224-SparklyPaper-Parallel-world-ticking.patch similarity index 69% rename from leaf-archived-patches/unapplied/server/minecraft-patches/features/0134-SparklyPaper-Parallel-world-ticking.patch rename to leaf-server/minecraft-patches/features/0224-SparklyPaper-Parallel-world-ticking.patch index d9544927..a7efddf1 100644 --- a/leaf-archived-patches/unapplied/server/minecraft-patches/features/0134-SparklyPaper-Parallel-world-ticking.patch +++ b/leaf-server/minecraft-patches/features/0224-SparklyPaper-Parallel-world-ticking.patch @@ -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 be820c6093dd2ae7642b9bee11edf65e3a8d7242..06ac3537f5655d048d770bb004243f207fad9faa 100644 +index ea4010df54dbd17cdae22d671ea1e4bd7b685b3e..8d53cb917e9f623a67aba066c6a21f278f1f0967 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -@@ -1031,7 +1031,7 @@ public final class ChunkHolderManager { +@@ -1116,7 +1116,7 @@ public final class ChunkHolderManager { if (changedFullStatus.isEmpty()) { return; } @@ -18,7 +18,7 @@ index be820c6093dd2ae7642b9bee11edf65e3a8d7242..06ac3537f5655d048d770bb004243f20 this.taskScheduler.scheduleChunkTask(() -> { final ArrayDeque pendingFullLoadUpdate = ChunkHolderManager.this.pendingFullLoadUpdate; for (int i = 0, len = changedFullStatus.size(); i < len; ++i) { -@@ -1057,7 +1057,12 @@ public final class ChunkHolderManager { +@@ -1142,7 +1142,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 be820c6093dd2ae7642b9bee11edf65e3a8d7242..06ac3537f5655d048d770bb004243f20 if (BLOCK_TICKET_UPDATES.get() == Boolean.TRUE) { throw new IllegalStateException("Cannot unload chunks recursively"); -@@ -1339,7 +1344,7 @@ public final class ChunkHolderManager { +@@ -1424,7 +1429,7 @@ public final class ChunkHolderManager { List changedFullStatus = null; @@ -41,242 +41,34 @@ index be820c6093dd2ae7642b9bee11edf65e3a8d7242..06ac3537f5655d048d770bb004243f20 boolean ret = false; final boolean canProcessFullUpdates = processFullUpdates & isTickThread; -diff --git a/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java b/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java -index 4a881636ba21fae9e50950bbba2b4321b71d35ab..9b01cc21a7e7411b8d112b5b7d7061e66c9bde06 100644 ---- a/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java -+++ b/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java -@@ -46,7 +46,7 @@ public class BoatDispenseItemBehavior extends DefaultDispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(singleItemStack); - - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d1, d2 + d4, d3)); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - serverLevel.getCraftServer().getPluginManager().callEvent(event); - } - -diff --git a/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java b/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java -index bd5bbc7e55c6bea77991fe5a3c0c2580313d16c5..e0f0834dd899d0ead0ad3995a9f457f9f33449e0 100644 ---- a/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java -+++ b/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java -@@ -78,7 +78,7 @@ public class DefaultDispenseItemBehavior implements DispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack); - - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block, craftItem.clone(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(itemEntity.getDeltaMovement())); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - level.getCraftServer().getPluginManager().callEvent(event); - } - diff --git a/net/minecraft/core/dispenser/DispenseItemBehavior.java b/net/minecraft/core/dispenser/DispenseItemBehavior.java -index f576449e8bc6fd92963cbe3954b0c853a02def3c..634a2a93569dc7e4bd2fe594cf611b278ef3a257 100644 +index 582e012222123e5001c34153f2ee1ab1d08935fd..c0bce2293d07ca58cc5bc9e036ab8dcac06c1566 100644 --- a/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -89,7 +89,7 @@ public interface DispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(singleItemStack); - - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - serverLevel.getCraftServer().getPluginManager().callEvent(event); - } - -@@ -147,7 +147,7 @@ public interface DispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(singleItemStack); - - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - serverLevel.getCraftServer().getPluginManager().callEvent(event); - } - -@@ -201,7 +201,7 @@ public interface DispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(singleItemStack); - - org.bukkit.event.block.BlockDispenseArmorEvent event = new org.bukkit.event.block.BlockDispenseArmorEvent(block, craftItem.clone(), entitiesOfClass.get(0).getBukkitLivingEntity()); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - world.getCraftServer().getPluginManager().callEvent(event); - } - -@@ -251,7 +251,7 @@ public interface DispenseItemBehavior { - org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(world, blockSource.pos()); - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(singleCopy); - org.bukkit.event.block.BlockDispenseArmorEvent event = new org.bukkit.event.block.BlockDispenseArmorEvent(block, craftItem.clone(), abstractChestedHorse.getBukkitLivingEntity()); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - world.getCraftServer().getPluginManager().callEvent(event); - } - -@@ -329,7 +329,7 @@ public interface DispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item.copyWithCount(1)); // Paper - single item in event - - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(x, y, z)); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - level.getCraftServer().getPluginManager().callEvent(event); - } - -@@ -389,7 +389,7 @@ public interface DispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item.copyWithCount(1)); // Paper - single item in event - - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(blockPos)); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - levelAccessor.getMinecraftWorld().getCraftServer().getPluginManager().callEvent(event); - } - -@@ -425,7 +425,7 @@ public interface DispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item); // Paper - ignore stack size on damageable items - - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - serverLevel.getCraftServer().getPluginManager().callEvent(event); - } - -@@ -482,7 +482,7 @@ public interface DispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item.copyWithCount(1)); // Paper - single item in event - - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - level.getCraftServer().getPluginManager().callEvent(event); - } - -@@ -510,8 +510,8 @@ public interface DispenseItemBehavior { +@@ -401,8 +401,8 @@ public interface DispenseItemBehavior { // CraftBukkit start level.captureTreeGeneration = false; - if (level.capturedBlockStates.size() > 0) { + if (!level.capturedBlockStates.isEmpty()) { - org.bukkit.TreeType treeType = net.minecraft.world.level.block.SaplingBlock.treeType; - net.minecraft.world.level.block.SaplingBlock.treeType = null; + org.bukkit.TreeType treeType = net.minecraft.world.level.block.SaplingBlock.getTreeTypeRT(); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) + net.minecraft.world.level.block.SaplingBlock.setTreeTypeRT(null); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) org.bukkit.Location location = org.bukkit.craftbukkit.util.CraftLocation.toBukkit(blockPos, level.getWorld()); - List blocks = new java.util.ArrayList<>(level.capturedBlockStates.values()); + List states = new java.util.ArrayList<>(level.capturedBlockStates.values()); level.capturedBlockStates.clear(); -@@ -548,7 +548,7 @@ public interface DispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(singleItemStack); - - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector((double) blockPos.getX() + 0.5D, (double) blockPos.getY(), (double) blockPos.getZ() + 0.5D)); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - level.getCraftServer().getPluginManager().callEvent(event); - } - -@@ -591,7 +591,7 @@ public interface DispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item.copyWithCount(1)); // Paper - single item in event - - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(blockPos)); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - level.getCraftServer().getPluginManager().callEvent(event); - } - -@@ -644,7 +644,7 @@ public interface DispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item.copyWithCount(1)); // Paper - single item in event - - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(blockPos)); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - level.getCraftServer().getPluginManager().callEvent(event); - } - -@@ -702,7 +702,7 @@ public interface DispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item.copyWithCount(1)); // Paper - only single item in event - - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(blockPos)); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - serverLevel.getCraftServer().getPluginManager().callEvent(event); - } - -@@ -783,7 +783,7 @@ public interface DispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item); // Paper - ignore stack size on damageable items - - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseArmorEvent(block, craftItem.clone(), entitiesOfClass.get(0).getBukkitLivingEntity()); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - serverLevel.getCraftServer().getPluginManager().callEvent(event); - } - -diff --git a/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java b/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java -index b91b2f5ea6a1da0477541dc65fdfbfa57b9af475..e8bf2884699be35330d5b72e2591629fe8318741 100644 ---- a/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java -+++ b/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java -@@ -39,7 +39,7 @@ public class EquipmentDispenseItemBehavior extends DefaultDispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack); - - org.bukkit.event.block.BlockDispenseArmorEvent event = new org.bukkit.event.block.BlockDispenseArmorEvent(block, craftItem.clone(), (org.bukkit.craftbukkit.entity.CraftLivingEntity) livingEntity.getBukkitEntity()); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - world.getCraftServer().getPluginManager().callEvent(event); - } - -diff --git a/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java b/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java -index 116395b6c00a0814922516707544a9ff26d68835..133ed3de05ee740836c83d6b49d7171e7fce155d 100644 ---- a/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java -+++ b/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java -@@ -62,7 +62,7 @@ public class MinecartDispenseItemBehavior extends DefaultDispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack1); - - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block2, craftItem.clone(), new org.bukkit.util.Vector(vec31.x, vec31.y, vec31.z)); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - serverLevel.getCraftServer().getPluginManager().callEvent(event); - } - -diff --git a/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java b/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java -index 449d9b72ff4650961daa9d1bd25940f3914a6b12..bdb4974f1eca8e585ce5f588ab898e4cf9e30625 100644 ---- a/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java -+++ b/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java -@@ -32,7 +32,7 @@ public class ProjectileDispenseBehavior extends DefaultDispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack1); - - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector((double) direction.getStepX(), (double) direction.getStepY(), (double) direction.getStepZ())); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - serverLevel.getCraftServer().getPluginManager().callEvent(event); - } - -diff --git a/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java -index 626e9feb6a6e7a2cbc7c63e30ba4fb6b923e85c7..1d8d492fdd040595615b8e8b7ce3910b160762b2 100644 ---- a/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java -+++ b/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java -@@ -25,7 +25,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior { - org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(serverLevel, blockSource.pos()); - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item); // Paper - ignore stack size on damageable items - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - serverLevel.getCraftServer().getPluginManager().callEvent(event); - } - -diff --git a/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java b/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java -index 5ab2c8333178335515e619b87ae420f948c83bd1..be3b2f023897a8823560ee059cb16ec91ffcb2d8 100644 ---- a/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java -+++ b/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java -@@ -27,7 +27,7 @@ public class ShulkerBoxDispenseBehavior extends OptionalDispenseItemBehavior { - org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item.copyWithCount(1)); // Paper - single item in event - - org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockPos.getX(), blockPos.getY(), blockPos.getZ())); -- if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.getEventFiredTL()) { // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - blockSource.level().getCraftServer().getPluginManager().callEvent(event); - } - diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index c50a301a0c2365c2052aefc6a23fcf6fa82e1b9d..7f791ff5bdf6c29c78f863d21af16270a74d8e7e 100644 +index bbd2b327c658b56a1fcf30c8b77cab987d688fcc..c9b8bc9592d5fce77750de89fa886db383d92a89 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -291,6 +291,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (concurrent because plugins may schedule tasks async) + public java.util.concurrent.Semaphore serverLevelTickingSemaphore = null; // SparklyPaper - parallel world ticking public static S spin(Function threadFunction) { - ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system -@@ -323,24 +324,36 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop atomicReference = new AtomicReference<>(); +@@ -321,24 +322,36 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop serverPlayer1.connection.suspendFlushing()); this.server.getScheduler().mainThreadHeartbeat(); // CraftBukkit -@@ -1743,28 +1774,50 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop, ServerLevel> oldLevels = this.levels; Map, ServerLevel> newLevels = Maps.newLinkedHashMap(oldLevels); newLevels.remove(level.dimension()); @@ -437,7 +229,7 @@ index c50a301a0c2365c2052aefc6a23fcf6fa82e1b9d..7f791ff5bdf6c29c78f863d21af16270 } // CraftBukkit end diff --git a/net/minecraft/server/PlayerAdvancements.java b/net/minecraft/server/PlayerAdvancements.java -index d2159a747fe42aa95cfc6bca0e55e3f4485847bb..abe7ffd48766c48fab091947f34db436b3c883d0 100644 +index 10ac7393d20a0857be2bfdd856dda448699b3eff..53d081aceaa602cdc77018b434edc6ff3a994f91 100644 --- a/net/minecraft/server/PlayerAdvancements.java +++ b/net/minecraft/server/PlayerAdvancements.java @@ -53,8 +53,11 @@ public class PlayerAdvancements { @@ -509,7 +301,7 @@ index d2159a747fe42aa95cfc6bca0e55e3f4485847bb..abe7ffd48766c48fab091947f34db436 @@ -271,7 +279,10 @@ public class PlayerAdvancements { } - public void flushDirty(ServerPlayer serverPlayer) { + public void flushDirty(ServerPlayer player, boolean showAdvancements) { - if (this.isFirstPacket || !this.rootsToUpdate.isEmpty() || !this.progressChanged.isEmpty()) { + // Leaf start - SparklyPaper - parallel world ticking + final boolean useConcurrent = org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled; @@ -545,7 +337,7 @@ index d2159a747fe42aa95cfc6bca0e55e3f4485847bb..abe7ffd48766c48fab091947f34db436 + } + // Leaf end - SparklyPaper - parallel world ticking if (!map.isEmpty() || !set.isEmpty() || !set1.isEmpty()) { - serverPlayer.connection.send(new ClientboundUpdateAdvancementsPacket(this.isFirstPacket, set, set1, map)); + player.connection.send(new ClientboundUpdateAdvancementsPacket(this.isFirstPacket, set, set1, map, showAdvancements)); } @@ -331,10 +350,13 @@ public class PlayerAdvancements { AdvancementHolder advancementHolder = node.holder(); @@ -564,13 +356,13 @@ index d2159a747fe42aa95cfc6bca0e55e3f4485847bb..abe7ffd48766c48fab091947f34db436 } else if (this.visible.remove(advancementHolder)) { idOutput.add(advancementHolder.id()); diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java -index d4048661575ebfaf128ba25da365843774364e0e..33dd16a26edd2974f04d9a868d3e58e8e3060032 100644 +index 54910c2e1d6e6bb556e536fda060bd09402e04e8..72e871b8c7fee9b5cbd567e03baee80ee4b9c82e 100644 --- a/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java -@@ -249,6 +249,12 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -198,6 +198,12 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface } org.purpurmc.purpur.PurpurConfig.registerCommands(); - */// Purpur end - Purpur config files // Purpur - Configurable void damage height and damage + // Purpur end - Purpur config files + // Leaf start - SparklyPaper - parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) { + serverLevelTickingSemaphore = new java.util.concurrent.Semaphore(org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.threads); // SparklyPaper - parallel world ticking @@ -580,11 +372,24 @@ index d4048661575ebfaf128ba25da365843774364e0e..33dd16a26edd2974f04d9a868d3e58e8 com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now // Gale start - Pufferfish - SIMD support +diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java +index 0f9d18dd29e210ad656da211a3cb1cb25cd4efb1..b3acfc7e00797ea16cc2c1793452f3ed97b9c61a 100644 +--- a/net/minecraft/server/level/ServerChunkCache.java ++++ b/net/minecraft/server/level/ServerChunkCache.java +@@ -175,7 +175,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + + // call mid-tick tasks for chunk system + if ((i & 7) == 0) { +- ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.level.getServer()).moonrise$executeMidTickTasks(); ++ //((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.level.getServer()).moonrise$executeMidTickTasks(); // SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks) + continue; + } + } diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index a66e5f6652d9633c856490de36d8d8fdf8a5298a..d6524d5c442555eaeb4d90f6a101262ee669f0d9 100644 +index 2ecb73fc7b6754ade93bf16b48c623e6b3a955a9..85bfc91ff163a2a564b7b610e27ff90e053787d0 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -182,7 +182,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -178,7 +178,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe private final MinecraftServer server; public final net.minecraft.world.level.storage.PrimaryLevelData serverLevelData; // CraftBukkit - type private int lastSpawnChunkRadius; @@ -593,29 +398,28 @@ index a66e5f6652d9633c856490de36d8d8fdf8a5298a..d6524d5c442555eaeb4d90f6a101262e // Paper - rewrite chunk system private final GameEventDispatcher gameEventDispatcher; public boolean noSave; -@@ -208,7 +208,9 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -204,6 +204,9 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe private double preciseTime; // Purpur - Configurable daylight cycle private boolean forceTime; // Purpur - Configurable daylight cycle private final RandomSequences randomSequences; -- + public java.util.concurrent.ExecutorService tickExecutor; // SparklyPaper - parallel world ticking + public final java.util.concurrent.ConcurrentLinkedQueue asyncReadRequestQueue = new java.util.concurrent.ConcurrentLinkedQueue<>(); // Leaf - SparklyPaper - parallel world ticking + private volatile boolean isShuttingDown = false; // Leaf - SparklyPaper - parallel world ticking - Shutdown handling for async reads + // CraftBukkit start public final LevelStorageSource.LevelStorageAccess levelStorageAccess; - public final UUID uuid; -@@ -703,8 +705,26 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -693,8 +696,26 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit this.preciseTime = this.serverLevelData.getDayTime(); // Purpur - Configurable daylight cycle this.realPlayers = Lists.newArrayList(); // Leaves - skip + this.tickExecutor = java.util.concurrent.Executors.newSingleThreadExecutor(new org.dreeam.leaf.async.world.SparklyPaperServerLevelTickExecutorThreadFactory(getWorld().getName())); // SparklyPaper - parallel world ticking -+ } -+ + } + + // Leaf start - SparklyPaper - parallel world ticking - Shutdown handling for async reads + public boolean isShuttingDown() { + return this.isShuttingDown; - } - ++ } ++ + public void prepareShutdown() { + this.isShuttingDown = true; + org.dreeam.leaf.async.world.WorldReadRequest req; @@ -631,7 +435,7 @@ index a66e5f6652d9633c856490de36d8d8fdf8a5298a..d6524d5c442555eaeb4d90f6a101262e // Paper start @Override public boolean hasChunk(int chunkX, int chunkZ) { -@@ -737,8 +757,112 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -727,8 +748,112 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public Player[] eligibleDespawnCheckingPlayerCache = new Player[0]; // Leaf - Cache eligible players for despawn checks @@ -718,10 +522,10 @@ index a66e5f6652d9633c856490de36d8d8fdf8a5298a..d6524d5c442555eaeb4d90f6a101262e + org.bukkit.FluidCollisionMode fluidCollisionMode = (org.bukkit.FluidCollisionMode) params[4]; + + org.bukkit.util.Vector dir = direction.clone().normalize().multiply(maxDistance); -+ Vec3 startPos = org.bukkit.craftbukkit.util.CraftLocation.toVec3D(start); ++ Vec3 startPos = org.bukkit.craftbukkit.util.CraftLocation.toVec3(start); + Vec3 endPos = startPos.add(dir.getX(), dir.getY(), dir.getZ()); + -+ return this.clip(new net.minecraft.world.level.ClipContext(startPos, endPos, net.minecraft.world.level.ClipContext.Block.OUTLINE, org.bukkit.craftbukkit.CraftFluidCollisionMode.toNMS(fluidCollisionMode), net.minecraft.world.phys.shapes.CollisionContext.empty()), pos); // Pass block pos ++ return this.clip(new net.minecraft.world.level.ClipContext(startPos, endPos, net.minecraft.world.level.ClipContext.Block.OUTLINE, org.bukkit.craftbukkit.CraftFluidCollisionMode.toFluid(fluidCollisionMode), net.minecraft.world.phys.shapes.CollisionContext.empty()), pos); // Pass block pos + } + case BLOCK_CAN_PLACE: { + pos = (BlockPos) params[0]; @@ -744,7 +548,7 @@ index a66e5f6652d9633c856490de36d8d8fdf8a5298a..d6524d5c442555eaeb4d90f6a101262e TickRateManager tickRateManager = this.tickRateManager(); boolean runsNormally = tickRateManager.runsNormally(); if (runsNormally) { -@@ -746,6 +870,14 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -736,6 +861,14 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.advanceWeatherCycle(); } @@ -759,7 +563,7 @@ index a66e5f6652d9633c856490de36d8d8fdf8a5298a..d6524d5c442555eaeb4d90f6a101262e int _int = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE); if (this.purpurConfig.playersSkipNight && this.sleepStatus.areEnoughSleeping(_int) && this.sleepStatus.areEnoughDeepSleeping(_int, this.players)) { // Purpur - Config for skipping night // Paper start - create time skip event - move up calculations -@@ -1313,9 +1445,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1309,9 +1442,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe fluidState.tick(this, pos, blockState); } // Paper start - rewrite chunk system @@ -774,7 +578,7 @@ index a66e5f6652d9633c856490de36d8d8fdf8a5298a..d6524d5c442555eaeb4d90f6a101262e // Paper end - rewrite chunk system } -@@ -1326,9 +1461,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1322,9 +1458,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe blockState.tick(this, pos, this.random); } // Paper start - rewrite chunk system @@ -789,19 +593,19 @@ index a66e5f6652d9633c856490de36d8d8fdf8a5298a..d6524d5c442555eaeb4d90f6a101262e // Paper end - rewrite chunk system } -@@ -1579,6 +1717,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1575,6 +1714,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } private void addPlayer(ServerPlayer player) { + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) // Leaf - SparklyPaper - parallel world ticking mod (make configurable / async is no longer safe; schedule on main) + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this, "Cannot add player off-main"); // SparklyPaper - parallel world ticking (additional concurrency issues logs) - Entity entity = this.getEntities().get(player.getUUID()); + Entity entity = this.getEntity(player.getUUID()); if (entity != null) { LOGGER.warn("Force-added player with duplicate UUID {}", player.getUUID()); -@@ -1591,7 +1731,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1587,7 +1728,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // CraftBukkit start - private boolean addEntity(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { + private boolean addEntity(Entity entity, @Nullable org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { - org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot + // Leaf start - SparklyPaper - parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) @@ -813,10 +617,10 @@ index a66e5f6652d9633c856490de36d8d8fdf8a5298a..d6524d5c442555eaeb4d90f6a101262e // 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 8362def0dc61496a087bd859052bd80ebba83185..09f517059aa47ca67329bc913243d4fdee09abe5 100644 +index ccd442b24693bc9269cc8ab3e44887d0ad3eadbd..ac7ac519ecc58a31c4b9efc24f054ec014851fb4 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -427,6 +427,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -456,6 +456,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc return this.viewDistanceHolder; } // Paper end - rewrite chunk system @@ -824,7 +628,7 @@ index 8362def0dc61496a087bd859052bd80ebba83185..09f517059aa47ca67329bc913243d4fd public ServerPlayer(MinecraftServer server, ServerLevel level, GameProfile gameProfile, ClientInformation clientInformation) { super(level, level.getSharedSpawnPos(), level.getSharedSpawnAngle(), gameProfile); -@@ -803,6 +804,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -749,6 +750,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc @Override public void tick() { @@ -832,7 +636,7 @@ index 8362def0dc61496a087bd859052bd80ebba83185..09f517059aa47ca67329bc913243d4fd // CraftBukkit start if (this.joining) { this.joining = false; -@@ -1448,6 +1450,8 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1398,6 +1400,8 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc teleportTransition.postTeleportTransition().onTransition(this); return this; } else { @@ -841,7 +645,7 @@ index 8362def0dc61496a087bd859052bd80ebba83185..09f517059aa47ca67329bc913243d4fd // CraftBukkit start /* this.isChangingDimension = true; -@@ -1819,6 +1823,12 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1748,6 +1752,12 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc return OptionalInt.empty(); } else { // CraftBukkit start @@ -854,7 +658,7 @@ index 8362def0dc61496a087bd859052bd80ebba83185..09f517059aa47ca67329bc913243d4fd this.containerMenu = abstractContainerMenu; // Moved up if (!this.isImmobile()) this.connection -@@ -1883,6 +1893,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1812,6 +1822,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc } @Override public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) { @@ -867,7 +671,7 @@ index 8362def0dc61496a087bd859052bd80ebba83185..09f517059aa47ca67329bc913243d4fd // Paper end - Inventory close reason this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId)); diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index b17c8a2f5294ac28cc05fb05c84a041b2c6c8721..3591de34443069f3f163f8d17df6372c3068611d 100644 +index 8b1652805a2ac9ebae9c99dd77e81c7a484a7abb..e4bccc642abe15b0ec4b1cf2634801065a27e11a 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java @@ -252,6 +252,8 @@ public abstract class PlayerList { @@ -880,9 +684,9 @@ index b17c8a2f5294ac28cc05fb05c84a041b2c6c8721..3591de34443069f3f163f8d17df6372c player.loginTime = System.currentTimeMillis(); // Paper - Replace OfflinePlayer#getLastPlayed GameProfile gameProfile = player.getGameProfile(); @@ -891,6 +893,15 @@ public abstract class PlayerList { - return this.respawn(player, keepInventory, reason, eventReason, null); } - public ServerPlayer respawn(ServerPlayer player, boolean keepInventory, Entity.RemovalReason reason, org.bukkit.event.player.PlayerRespawnEvent.RespawnReason eventReason, org.bukkit.Location location) { + + public ServerPlayer respawn(ServerPlayer player, boolean keepInventory, Entity.RemovalReason reason, @Nullable org.bukkit.event.player.PlayerRespawnEvent.RespawnReason eventReason, @Nullable org.bukkit.Location location) { + // Leaf start - SparklyPaper - parallel world ticking mod (make configurable) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) { + if (location != null) // Leaf - THIS CAN BE NULL; see PlayerList::respawn(ServerPlayer, boolean, Entity.RemovalReason, PlayerRespawnEvent.RespawnReason) @@ -904,10 +708,10 @@ index b17c8a2f5294ac28cc05fb05c84a041b2c6c8721..3591de34443069f3f163f8d17df6372c 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..334a47659ba75fade062bc79df3731d1e449114b 100644 +index 309a31215cb63452215fd880590cffd569aee208..b89923a0b30a294c393716b666ff3377f0a835dc 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -3370,15 +3370,40 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3317,15 +3317,40 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess if (this.portalProcess != null) { if (this.portalProcess.processPortalTeleportation(serverLevel, this, this.canUsePortal(false))) { this.setPortalCooldown(); @@ -955,7 +759,7 @@ index 9bc978ca290ca772b0367e89b69fe16b502b0cd2..334a47659ba75fade062bc79df3731d1 } else if (this.portalProcess.hasExpired()) { this.portalProcess = null; } -@@ -3908,6 +3933,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3890,6 +3915,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } private Entity teleportCrossDimension(ServerLevel level, TeleportTransition teleportTransition) { @@ -1078,28 +882,28 @@ index 3614551856c594f3c0cfee984fcf03fad672b007..f4577f908ca9f279b72d89e5b0822d34 }); entity.getBrain().eraseMemory(MemoryModuleType.POTENTIAL_JOB_SITE); diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java -index 0b4c4707139c9c72929799818ec1a1b25575d70e..acf8059017f4e45c307a113abed36c59b231d9a6 100644 +index ffc46d3ffe6d3a577fbad381f1f7d82d78e33d2a..63ce733ce78eb9bc630c497988949e18cbb56fe2 100644 --- a/net/minecraft/world/entity/npc/Villager.java +++ b/net/minecraft/world/entity/npc/Villager.java -@@ -806,13 +806,21 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - this.brain.getMemory(moduleType).ifPresent(globalPos -> { - ServerLevel level = server.getLevel(globalPos.dimension()); +@@ -795,13 +795,21 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + this.brain.getMemory(moduleType).ifPresent(pos -> { + ServerLevel level = server.getLevel(pos.dimension()); if (level != null) { - PoiManager poiManager = level.getPoiManager(); -- Optional> type = poiManager.getType(globalPos.pos()); +- Optional> type = poiManager.getType(pos.pos()); - BiPredicate> biPredicate = POI_MEMORIES.get(moduleType); - if (type.isPresent() && biPredicate.test(this, type.get())) { -- poiManager.release(globalPos.pos()); -- DebugPackets.sendPoiTicketCountPacket(level, globalPos.pos()); +- poiManager.release(pos.pos()); +- DebugPackets.sendPoiTicketCountPacket(level, pos.pos()); - } + // Leaf start - SparklyPaper - parallel world ticking mod (handling for releasing poi cross-dimension) + Runnable releasePoiTask = () -> { + PoiManager poiManager = level.getPoiManager(); -+ Optional> type = poiManager.getType(globalPos.pos()); ++ Optional> type = poiManager.getType(pos.pos()); + BiPredicate> biPredicate = POI_MEMORIES.get(moduleType); + if (type.isPresent() && biPredicate.test(this, type.get())) { -+ poiManager.release(globalPos.pos()); -+ DebugPackets.sendPoiTicketCountPacket(level, globalPos.pos()); ++ poiManager.release(pos.pos()); ++ DebugPackets.sendPoiTicketCountPacket(level, pos.pos()); + } + }; + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) @@ -1111,82 +915,34 @@ index 0b4c4707139c9c72929799818ec1a1b25575d70e..acf8059017f4e45c307a113abed36c59 }); } diff --git a/net/minecraft/world/entity/projectile/ThrownEnderpearl.java b/net/minecraft/world/entity/projectile/ThrownEnderpearl.java -index d212f57c8c0b2086f567fd30237b110203d9e8cb..ed4df82581b5411e54068ccc59ea85a78404fa2b 100644 +index 6575e8ef16f6011f7a799ba31531a2ebefee0c4d..a3ee65c9b7544b791f11c0c475ec9e0390be95a7 100644 --- a/net/minecraft/world/entity/projectile/ThrownEnderpearl.java +++ b/net/minecraft/world/entity/projectile/ThrownEnderpearl.java -@@ -126,40 +126,48 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { +@@ -122,8 +122,10 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { Vec3 vec3 = this.oldPosition(); if (owner instanceof ServerPlayer serverPlayer) { if (serverPlayer.connection.isAcceptingMessages()) { -- // CraftBukkit start -- ServerPlayer serverPlayer1 = serverPlayer.teleport(new TeleportTransition(serverLevel, vec3, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.ROTATION, Relative.DELTA), TeleportTransition.DO_NOTHING, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.ENDER_PEARL)); -- if (serverPlayer1 == null) { -- this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); -- return; -- } -- // CraftBukkit end -- if (this.random.nextFloat() < serverLevel.purpurConfig.enderPearlEndermiteChance && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) { // Purpur - Configurable Ender Pearl RNG -- Endermite endermite = EntityType.ENDERMITE.create(serverLevel, EntitySpawnReason.TRIGGERED); -- if (endermite != null) { -- endermite.setPlayerSpawned(true); // Purpur - Add back player spawned endermite API -- endermite.moveTo(owner.getX(), owner.getY(), owner.getZ(), owner.getYRot(), owner.getXRot()); -- serverLevel.addFreshEntity(endermite, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.ENDER_PEARL); + // Leaf start - SparklyPaper - parallel world ticking mod (handling for pearl teleportation cross-dimension) + java.util.function.Consumer teleportPlayerCrossDimensionTask = taskServerPlayer -> { -+ // CraftBukkit start -+ ServerPlayer serverPlayer1 = taskServerPlayer.teleport(new TeleportTransition(serverLevel, vec3, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.ROTATION, Relative.DELTA), TeleportTransition.DO_NOTHING, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.ENDER_PEARL)); -+ if (serverPlayer1 == null) { -+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); -+ return; -+ } -+ // CraftBukkit end -+ if (this.random.nextFloat() < serverLevel.purpurConfig.enderPearlEndermiteChance && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) { // Purpur - Configurable Ender Pearl RNG -+ Endermite endermite = EntityType.ENDERMITE.create(serverLevel, EntitySpawnReason.TRIGGERED); -+ if (endermite != null) { -+ endermite.setPlayerSpawned(true); // Purpur - Add back player spawned endermite API -+ endermite.moveTo(owner.getX(), owner.getY(), owner.getZ(), owner.getYRot(), owner.getXRot()); -+ serverLevel.addFreshEntity(endermite, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.ENDER_PEARL); -+ } - } -- } - -- if (this.isOnPortalCooldown()) { -- owner.setPortalCooldown(); -- } -+ if (this.isOnPortalCooldown()) { -+ owner.setPortalCooldown(); -+ } - -- // CraftBukkit start - moved up -- // ServerPlayer serverPlayer1 = serverPlayer.teleport( -- // new TeleportTransition( -- // serverLevel, vec3, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.ROTATION, Relative.DELTA), TeleportTransition.DO_NOTHING -- // ) -- // ); -- // CraftBukkit end - moved up -- if (serverPlayer1 != null) { -- serverPlayer1.resetFallDistance(); -- serverPlayer1.resetCurrentImpulseContext(); + // CraftBukkit start +- ServerPlayer serverPlayer1 = serverPlayer.teleport(new TeleportTransition(serverLevel, vec3, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.ROTATION, Relative.DELTA), TeleportTransition.DO_NOTHING, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.ENDER_PEARL)); ++ ServerPlayer serverPlayer1 = taskServerPlayer.teleport(new TeleportTransition(serverLevel, vec3, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.ROTATION, Relative.DELTA), TeleportTransition.DO_NOTHING, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.ENDER_PEARL)); + if (serverPlayer1 == null) { + this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); + return; +@@ -152,10 +154,17 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { + if (serverPlayer1 != null) { + serverPlayer1.resetFallDistance(); + serverPlayer1.resetCurrentImpulseContext(); - serverPlayer1.hurtServer(serverPlayer.serverLevel(), this.damageSources().enderPearl().eventEntityDamager(this), this.level().purpurConfig.enderPearlDamage); // CraftBukkit // Paper - fix DamageSource API // Purpur - Configurable Ender Pearl damage -- } -+ // CraftBukkit start - moved up -+ // ServerPlayer serverPlayer1 = serverPlayer.teleport( -+ // new TeleportTransition( -+ // serverLevel, vec3, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.ROTATION, Relative.DELTA), TeleportTransition.DO_NOTHING -+ // ) -+ // ); -+ // CraftBukkit end - moved up -+ if (serverPlayer1 != null) { -+ serverPlayer1.resetFallDistance(); -+ serverPlayer1.resetCurrentImpulseContext(); -+ serverPlayer1.hurtServer(taskServerPlayer.serverLevel(), this.damageSources().enderPearl().eventEntityDamager(this), this.level().purpurConfig.enderPearlDamage); // CraftBukkit // Paper - fix DamageSource API // Purpur - Configurable Ender Pearl damage -+ } ++ serverPlayer1.hurtServer(taskServerPlayer.serverLevel(), this.damageSources().enderPearl().eventEntityDamager(this), this.level().purpurConfig.enderPearlDamage); // CraftBukkit // Paper - fix DamageSource API // Purpur - Configurable Ender Pearl damage + } -- this.playSound(serverLevel, vec3); -+ this.playSound(serverLevel, vec3); + this.playSound(serverLevel, vec3); + }; + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) -+ serverPlayer.getBukkitEntity().taskScheduler.schedule(teleportPlayerCrossDimensionTask, entity -> {}, 0); ++ serverPlayer.getBukkitEntity().taskScheduler.schedule(teleportPlayerCrossDimensionTask, entity -> { ++ }, 0); + else + teleportPlayerCrossDimensionTask.accept(serverPlayer); + // Leaf end - SparklyPaper - parallel world ticking mod (handling for pearl teleportation cross-dimension) @@ -1194,11 +950,11 @@ index d212f57c8c0b2086f567fd30237b110203d9e8cb..ed4df82581b5411e54068ccc59ea85a7 } else { Entity entity = owner.teleport( diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java -index cee7daa4908efde754442bf7ef0932b94cf5ebca..ff2ff95ec9d94e2e31e8174196b384c37d56f38a 100644 +index c4721eb0efe34f5e313bc890b4e960144eca4fe1..9dd3187fd968ab95e9d55b4c8cc74e782cc0f241 100644 --- a/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/net/minecraft/world/inventory/AbstractContainerMenu.java -@@ -92,8 +92,14 @@ public abstract class AbstractContainerMenu { - } +@@ -96,8 +96,14 @@ public abstract class AbstractContainerMenu { + public void startOpen() {} // CraftBukkit end + public Throwable containerCreationStacktrace; // SparklyPaper - parallel world ticking (debugging) @@ -1213,10 +969,10 @@ index cee7daa4908efde754442bf7ef0932b94cf5ebca..ff2ff95ec9d94e2e31e8174196b384c3 this.containerId = containerId; } diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java -index fd7c1e800cbd4919a1a47f6c468c8776535bd028..ba369d605ae50906d11d32e6f1b7132b061a9835 100644 +index d1c8b4a2a32d49d90f2f2aa460915d319a781535..aed9baa4e0f01e8844a774ab8d0bc08acd3c5271 100644 --- a/net/minecraft/world/item/ItemStack.java +++ b/net/minecraft/world/item/ItemStack.java -@@ -412,8 +412,8 @@ public final class ItemStack implements DataComponentHolder, net.caffeinemc.mods +@@ -411,8 +411,8 @@ public final class ItemStack implements DataComponentHolder, net.caffeinemc.mods if (interactionResult.consumesAction() && serverLevel.captureTreeGeneration && !serverLevel.capturedBlockStates.isEmpty()) { serverLevel.captureTreeGeneration = false; org.bukkit.Location location = org.bukkit.craftbukkit.util.CraftLocation.toBukkit(clickedPos, serverLevel.getWorld()); @@ -1228,18 +984,18 @@ index fd7c1e800cbd4919a1a47f6c468c8776535bd028..ba369d605ae50906d11d32e6f1b7132b serverLevel.capturedBlockStates.clear(); org.bukkit.event.world.StructureGrowEvent structureEvent = null; diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 7d3163802640449b6bdaa93595518d7d0f62488b..4821ab14c6a7d5738f0fc93523aede5ea904aa84 100644 +index 22da84734462d09a55bc599db4374e1e4f4d6bd2..c8219508cf94da71143b8672661592c66b341782 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java -@@ -175,6 +175,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - - public final io.papermc.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray +@@ -164,6 +164,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl + } + // Gale end - Gale configuration public final org.purpurmc.purpur.PurpurWorldConfig purpurConfig; // Purpur - Purpur config files + public io.papermc.paper.redstone.RedstoneWireTurbo turbo = new io.papermc.paper.redstone.RedstoneWireTurbo((net.minecraft.world.level.block.RedStoneWireBlock) net.minecraft.world.level.block.Blocks.REDSTONE_WIRE); // SparklyPaper - parallel world ticking (moved to world) - public static BlockPos lastPhysicsProblem; // Spigot - private org.spigotmc.TickLimiter entityLimiter; - private org.spigotmc.TickLimiter tileLimiter; -@@ -1153,6 +1154,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + + public static @Nullable BlockPos lastPhysicsProblem; // Spigot + private int tileTickPosition; +@@ -1136,6 +1137,8 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl @Override public boolean setBlock(BlockPos pos, BlockState state, int flags, int recursionLeft) { @@ -1248,7 +1004,7 @@ index 7d3163802640449b6bdaa93595518d7d0f62488b..4821ab14c6a7d5738f0fc93523aede5e // CraftBukkit start - tree generation if (this.captureTreeGeneration) { // Paper start - Protect Bedrock and End Portal/Frames from being destroyed -@@ -1532,9 +1535,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1514,9 +1517,12 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl } else if (runsNormally && this.shouldTickBlocksAt(tickingBlockEntity.getPos())) { tickingBlockEntity.tick(); // Paper start - rewrite chunk system @@ -1263,7 +1019,7 @@ index 7d3163802640449b6bdaa93595518d7d0f62488b..4821ab14c6a7d5738f0fc93523aede5e // Paper end - rewrite chunk system } } -@@ -1555,7 +1561,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1537,7 +1543,8 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Gale - Airplane - remove lambda from ticking guard - diff on change ServerLevel#tick // Paper end - Prevent block entity and entity crashes } @@ -1273,7 +1029,7 @@ index 7d3163802640449b6bdaa93595518d7d0f62488b..4821ab14c6a7d5738f0fc93523aede5e } // Paper start - Option to prevent armor stands from doing entity lookups -@@ -1698,6 +1705,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1680,6 +1687,8 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl @Nullable public BlockEntity getBlockEntity(BlockPos pos, boolean validate) { @@ -1282,7 +1038,7 @@ index 7d3163802640449b6bdaa93595518d7d0f62488b..4821ab14c6a7d5738f0fc93523aede5e // Paper start - Perf: Optimize capturedTileEntities lookup net.minecraft.world.level.block.entity.BlockEntity blockEntity; if (!this.capturedTileEntities.isEmpty() && (blockEntity = this.capturedTileEntities.get(pos)) != null) { -@@ -1715,6 +1724,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1697,6 +1706,8 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl } public void setBlockEntity(BlockEntity blockEntity) { @@ -1291,7 +1047,7 @@ index 7d3163802640449b6bdaa93595518d7d0f62488b..4821ab14c6a7d5738f0fc93523aede5e BlockPos blockPos = blockEntity.getBlockPos(); if (!this.isOutsideBuildHeight(blockPos)) { // CraftBukkit start -@@ -1799,6 +1810,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1781,6 +1792,8 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl @Override public List getEntities(@Nullable Entity entity, AABB boundingBox, Predicate predicate) { @@ -1300,7 +1056,7 @@ index 7d3163802640449b6bdaa93595518d7d0f62488b..4821ab14c6a7d5738f0fc93523aede5e List list = Lists.newArrayList(); // Paper start - rewrite chunk system -@@ -2108,8 +2121,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -2099,8 +2112,15 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl public abstract RecipeAccess recipeAccess(); public BlockPos getBlockRandomPos(int x, int y, int z, int yMask) { @@ -1318,52 +1074,11 @@ index 7d3163802640449b6bdaa93595518d7d0f62488b..4821ab14c6a7d5738f0fc93523aede5e return new BlockPos(x + (i & 15), y + (i >> 16 & yMask), z + (i >> 8 & 15)); } -diff --git a/net/minecraft/world/level/block/DispenserBlock.java b/net/minecraft/world/level/block/DispenserBlock.java -index e0a4d41e5bcf144ea4c10d6f633c3a95ed2c5aec..fae9a880727207e2b5ecf553f22db650dac1b811 100644 ---- a/net/minecraft/world/level/block/DispenserBlock.java -+++ b/net/minecraft/world/level/block/DispenserBlock.java -@@ -51,6 +51,27 @@ public class DispenserBlock extends BaseEntityBlock { - public static final Map DISPENSER_REGISTRY = new IdentityHashMap<>(); - private static final int TRIGGER_DURATION = 4; - public static boolean eventFired = false; // CraftBukkit -+ public static ThreadLocal eventFiredTL = ThreadLocal.withInitial(() -> Boolean.FALSE); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (distinguish name) -+ -+ // Leaf start - SparklyPaper - parallel world ticking mod -+ // refer to original field in case plugins attempt to modify it -+ public static boolean getEventFiredTL() { -+ if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && eventFiredTL.get()) -+ return true; -+ synchronized (DispenserBlock.class) { -+ return eventFired; -+ } -+ } -+ -+ // update original field in case plugins attempt to access it -+ public static void setEventFiredTL(boolean value) { -+ if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) -+ eventFiredTL.set(value); -+ synchronized (DispenserBlock.class) { -+ eventFired = value; -+ } -+ } -+ // Leaf end - SparklyPaper - parallel world ticking mod - - @Override - public MapCodec codec() { -@@ -96,7 +117,7 @@ public class DispenserBlock extends BaseEntityBlock { - DispenseItemBehavior dispenseMethod = this.getDispenseMethod(level, item); - if (dispenseMethod != DispenseItemBehavior.NOOP) { - if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockPreDispenseEvent(level, pos, item, randomSlot)) return; // Paper - Add BlockPreDispenseEvent -- DispenserBlock.eventFired = false; // CraftBukkit - reset event status -+ DispenserBlock.setEventFiredTL(Boolean.FALSE); // CraftBukkit - reset event status // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) - dispenserBlockEntity.setItem(randomSlot, dispenseMethod.dispense(blockSource, item)); - } - } diff --git a/net/minecraft/world/level/block/FungusBlock.java b/net/minecraft/world/level/block/FungusBlock.java -index 85f0eac75784565c658c5178c544f969db3d6f54..690cb4f712d609e90fc2d4814f15c55145666701 100644 +index 9711efb088bd0da9168e9bcd0496bd7caddd2974..0a8599191bee283ff3a318174f4334e330d466dd 100644 --- a/net/minecraft/world/level/block/FungusBlock.java +++ b/net/minecraft/world/level/block/FungusBlock.java -@@ -76,9 +76,9 @@ public class FungusBlock extends BushBlock implements BonemealableBlock { +@@ -76,9 +76,9 @@ public class FungusBlock extends VegetationBlock implements BonemealableBlock { // CraftBukkit start .map((value) -> { if (this == Blocks.WARPED_FUNGUS) { @@ -1376,10 +1091,10 @@ index 85f0eac75784565c658c5178c544f969db3d6f54..690cb4f712d609e90fc2d4814f15c551 return value; }) diff --git a/net/minecraft/world/level/block/MushroomBlock.java b/net/minecraft/world/level/block/MushroomBlock.java -index 904369f4d7db41026183f2de7c96c2f0f4dc204d..afd952ddc8942818ec01d1c750413776b6537cc2 100644 +index d306f5f524dc64618df94c9783c2168dc561a5e3..2e0aec5327d92f89f38bbc393b3ba70597725445 100644 --- a/net/minecraft/world/level/block/MushroomBlock.java +++ b/net/minecraft/world/level/block/MushroomBlock.java -@@ -94,7 +94,7 @@ public class MushroomBlock extends BushBlock implements BonemealableBlock { +@@ -93,7 +93,7 @@ public class MushroomBlock extends VegetationBlock implements BonemealableBlock return false; } else { level.removeBlock(pos, false); @@ -1389,10 +1104,10 @@ index 904369f4d7db41026183f2de7c96c2f0f4dc204d..afd952ddc8942818ec01d1c750413776 return true; } else { diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java -index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..33a096ca7d175a714f874901d0152d0ecbc7f2a5 100644 +index 1943a6aad888647953e2d9dbbeedb0bd81c6f9df..3902c21a0a4f456a4e1b966a0301c15f8c20a298 100644 --- a/net/minecraft/world/level/block/RedStoneWireBlock.java +++ b/net/minecraft/world/level/block/RedStoneWireBlock.java -@@ -308,7 +308,12 @@ public class RedStoneWireBlock extends Block { +@@ -283,7 +283,12 @@ public class RedStoneWireBlock extends Block { if (orientation != null) { source = pos.relative(orientation.getFront().getOpposite()); } @@ -1406,7 +1121,7 @@ index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..33a096ca7d175a714f874901d0152d0e return; } updatePowerStrength(worldIn, pos, state, orientation, blockAdded); -@@ -336,7 +341,12 @@ public class RedStoneWireBlock extends Block { +@@ -311,7 +316,12 @@ public class RedStoneWireBlock extends Block { // [Space Walker] suppress shape updates and emit those manually to // bypass the new neighbor update stack. if (level.setBlock(pos, state, Block.UPDATE_KNOWN_SHAPE | Block.UPDATE_CLIENTS)) { @@ -1421,13 +1136,13 @@ index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..33a096ca7d175a714f874901d0152d0e } } diff --git a/net/minecraft/world/level/block/SaplingBlock.java b/net/minecraft/world/level/block/SaplingBlock.java -index e014f052e9b0f5ca6b28044e2389782b7d0e0cb8..5485e27b881ab0e4d6d00c088bae094d1232eec7 100644 +index a22cb810622e0ae97bc2a0d6390d026d9482b783..3e7478e959da3a0191de6c76b80cbb9b625b6898 100644 --- a/net/minecraft/world/level/block/SaplingBlock.java +++ b/net/minecraft/world/level/block/SaplingBlock.java -@@ -27,6 +27,28 @@ public class SaplingBlock extends BushBlock implements BonemealableBlock { - protected static final VoxelShape SHAPE = Block.box(2.0, 0.0, 2.0, 14.0, 12.0, 14.0); +@@ -26,6 +26,28 @@ public class SaplingBlock extends VegetationBlock implements BonemealableBlock { + private static final VoxelShape SHAPE = Block.column(12.0, 0.0, 12.0); protected final TreeGrower treeGrower; - public static org.bukkit.TreeType treeType; // CraftBukkit + public static @javax.annotation.Nullable org.bukkit.TreeType treeType; // CraftBukkit + public static final ThreadLocal treeTypeRT = new ThreadLocal<>(); // SparklyPaper - parallel world ticking (from Folia) + + // Leaf start - SparklyPaper - parallel world ticking mod @@ -1453,7 +1168,7 @@ index e014f052e9b0f5ca6b28044e2389782b7d0e0cb8..5485e27b881ab0e4d6d00c088bae094d @Override public MapCodec codec() { -@@ -63,14 +85,14 @@ public class SaplingBlock extends BushBlock implements BonemealableBlock { +@@ -62,14 +84,14 @@ public class SaplingBlock extends VegetationBlock implements BonemealableBlock { this.treeGrower.growTree(level, level.getChunkSource().getGenerator(), pos, state, random); level.captureTreeGeneration = false; if (!level.capturedBlockStates.isEmpty()) { @@ -1473,12 +1188,12 @@ index e014f052e9b0f5ca6b28044e2389782b7d0e0cb8..5485e27b881ab0e4d6d00c088bae094d } if (event == null || !event.isCancelled()) { diff --git a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java -index 26db603ed681a6c302596627d4dd5bf8a9bafc4e..7796c98ad7b9b3a0c97b177d34a3a2225409d147 100644 +index c63370fd458fb4f7190b79b1a8174fcc92d88f9c..5d3d3db955927647f5498eac0d67d3198b27f8cd 100644 --- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java -@@ -77,6 +77,12 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co - return canUnlock(player, code, displayName, null); +@@ -79,6 +79,12 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co } + public static boolean canUnlock(Player player, LockCode code, Component displayName, @Nullable BlockEntity blockEntity) { + // SparklyPaper - parallel world ticking (see: PARALLEL_NOTES.md - Opening an inventory after a world switch) + if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled && player instanceof net.minecraft.server.level.ServerPlayer serverPlayer && blockEntity != null && blockEntity.getLevel() != serverPlayer.serverLevel()) { // Leaf - SparklyPaper - parallel world ticking mod (make configurable) @@ -1490,7 +1205,7 @@ index 26db603ed681a6c302596627d4dd5bf8a9bafc4e..7796c98ad7b9b3a0c97b177d34a3a222 final org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(blockEntity.getLevel(), blockEntity.getBlockPos()); net.kyori.adventure.text.Component lockedMessage = net.kyori.adventure.text.Component.translatable("container.isLocked", io.papermc.paper.adventure.PaperAdventure.asAdventure(displayName)); diff --git a/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java b/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java -index 62038854696bd946f58e0e8d26da02415c34e4b1..2ef3c59196f5d75a97a08604c3bb47b670338d15 100644 +index 440d70811d96f97d3463c6aff131cbc5bd588254..a3178392325ca186f1c68143df7d1f499f6e762c 100644 --- a/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java +++ b/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java @@ -43,9 +43,9 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi @@ -1506,105 +1221,103 @@ index 62038854696bd946f58e0e8d26da02415c34e4b1..2ef3c59196f5d75a97a08604c3bb47b6 @Override diff --git a/net/minecraft/world/level/block/grower/TreeGrower.java b/net/minecraft/world/level/block/grower/TreeGrower.java -index cf7311c507de09a8f89934e430b2201e8bdffe51..e9936860323a23f989d554bcc5d483521e25415b 100644 +index d23f255de9208f42125fa358a9e8194c984fe4d3..c3acc0a875c0bf697b6b101051d80b3457431b92 100644 --- a/net/minecraft/world/level/block/grower/TreeGrower.java +++ b/net/minecraft/world/level/block/grower/TreeGrower.java -@@ -204,55 +204,59 @@ public final class TreeGrower { +@@ -203,55 +203,57 @@ public final class TreeGrower { + // CraftBukkit start - private void setTreeType(Holder> holder) { - ResourceKey> treeFeature = holder.unwrapKey().get(); -+ // SparklyPaper start - parallel world ticking -+ org.bukkit.TreeType treeType; - if (treeFeature == TreeFeatures.OAK || treeFeature == TreeFeatures.OAK_BEES_005) { + private void setTreeType(Holder> feature) { ++ org.bukkit.TreeType treeType; // SparklyPaper - parallel world ticking + if (feature.is(TreeFeatures.OAK) || feature.is(TreeFeatures.OAK_BEES_005)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.TREE; -+ treeType = org.bukkit.TreeType.TREE; - } else if (treeFeature == TreeFeatures.HUGE_RED_MUSHROOM) { ++ treeType = org.bukkit.TreeType.TREE; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.HUGE_RED_MUSHROOM)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.RED_MUSHROOM; -+ treeType = org.bukkit.TreeType.RED_MUSHROOM; - } else if (treeFeature == TreeFeatures.HUGE_BROWN_MUSHROOM) { ++ treeType = org.bukkit.TreeType.RED_MUSHROOM; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.HUGE_BROWN_MUSHROOM)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.BROWN_MUSHROOM; -+ treeType = org.bukkit.TreeType.BROWN_MUSHROOM; - } else if (treeFeature == TreeFeatures.JUNGLE_TREE) { ++ treeType = org.bukkit.TreeType.BROWN_MUSHROOM; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.JUNGLE_TREE)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.COCOA_TREE; -+ treeType = org.bukkit.TreeType.COCOA_TREE; - } else if (treeFeature == TreeFeatures.JUNGLE_TREE_NO_VINE) { ++ treeType = org.bukkit.TreeType.COCOA_TREE; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.JUNGLE_TREE_NO_VINE)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.SMALL_JUNGLE; -+ treeType = org.bukkit.TreeType.SMALL_JUNGLE; - } else if (treeFeature == TreeFeatures.PINE) { ++ treeType = org.bukkit.TreeType.SMALL_JUNGLE; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.PINE)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.TALL_REDWOOD; -+ treeType = org.bukkit.TreeType.TALL_REDWOOD; - } else if (treeFeature == TreeFeatures.SPRUCE) { ++ treeType = org.bukkit.TreeType.TALL_REDWOOD; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.SPRUCE)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.REDWOOD; -+ treeType = org.bukkit.TreeType.REDWOOD; - } else if (treeFeature == TreeFeatures.ACACIA) { ++ treeType = org.bukkit.TreeType.REDWOOD; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.ACACIA)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.ACACIA; -+ treeType = org.bukkit.TreeType.ACACIA; - } else if (treeFeature == TreeFeatures.BIRCH || treeFeature == TreeFeatures.BIRCH_BEES_005) { ++ treeType = org.bukkit.TreeType.ACACIA; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.BIRCH) || feature.is(TreeFeatures.BIRCH_BEES_005)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.BIRCH; -+ treeType = org.bukkit.TreeType.BIRCH; - } else if (treeFeature == TreeFeatures.SUPER_BIRCH_BEES_0002) { ++ treeType = org.bukkit.TreeType.BIRCH; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.SUPER_BIRCH_BEES_0002)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.TALL_BIRCH; -+ treeType = org.bukkit.TreeType.TALL_BIRCH; - } else if (treeFeature == TreeFeatures.SWAMP_OAK) { ++ treeType = org.bukkit.TreeType.TALL_BIRCH; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.SWAMP_OAK)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.SWAMP; -+ treeType = org.bukkit.TreeType.SWAMP; - } else if (treeFeature == TreeFeatures.FANCY_OAK || treeFeature == TreeFeatures.FANCY_OAK_BEES_005) { ++ treeType = org.bukkit.TreeType.SWAMP; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.FANCY_OAK) || feature.is(TreeFeatures.FANCY_OAK_BEES_005)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.BIG_TREE; -+ treeType = org.bukkit.TreeType.BIG_TREE; - } else if (treeFeature == TreeFeatures.JUNGLE_BUSH) { ++ treeType = org.bukkit.TreeType.BIG_TREE; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.JUNGLE_BUSH)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.JUNGLE_BUSH; -+ treeType = org.bukkit.TreeType.JUNGLE_BUSH; - } else if (treeFeature == TreeFeatures.DARK_OAK) { ++ treeType = org.bukkit.TreeType.JUNGLE_BUSH; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.DARK_OAK)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.DARK_OAK; -+ treeType = org.bukkit.TreeType.DARK_OAK; - } else if (treeFeature == TreeFeatures.MEGA_SPRUCE) { ++ treeType = org.bukkit.TreeType.DARK_OAK; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.MEGA_SPRUCE)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.MEGA_REDWOOD; -+ treeType = org.bukkit.TreeType.MEGA_REDWOOD; - } else if (treeFeature == TreeFeatures.MEGA_PINE) { ++ treeType = org.bukkit.TreeType.MEGA_REDWOOD; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.MEGA_PINE)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.MEGA_PINE; -+ treeType = org.bukkit.TreeType.MEGA_PINE; - } else if (treeFeature == TreeFeatures.MEGA_JUNGLE_TREE) { ++ treeType = org.bukkit.TreeType.MEGA_PINE; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.MEGA_JUNGLE_TREE)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.JUNGLE; -+ treeType = org.bukkit.TreeType.JUNGLE; - } else if (treeFeature == TreeFeatures.AZALEA_TREE) { ++ treeType = org.bukkit.TreeType.JUNGLE; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.AZALEA_TREE)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.AZALEA; -+ treeType = org.bukkit.TreeType.AZALEA; - } else if (treeFeature == TreeFeatures.MANGROVE) { ++ treeType = org.bukkit.TreeType.AZALEA; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.MANGROVE)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.MANGROVE; -+ treeType = org.bukkit.TreeType.MANGROVE; - } else if (treeFeature == TreeFeatures.TALL_MANGROVE) { ++ treeType = org.bukkit.TreeType.MANGROVE; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.TALL_MANGROVE)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.TALL_MANGROVE; -+ treeType = org.bukkit.TreeType.TALL_MANGROVE; - } else if (treeFeature == TreeFeatures.CHERRY || treeFeature == TreeFeatures.CHERRY_BEES_005) { ++ treeType = org.bukkit.TreeType.TALL_MANGROVE; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.CHERRY) || feature.is(TreeFeatures.CHERRY_BEES_005)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.CHERRY; -+ treeType = org.bukkit.TreeType.CHERRY; - } else if (treeFeature == TreeFeatures.PALE_OAK || treeFeature == TreeFeatures.PALE_OAK_BONEMEAL) { ++ treeType = org.bukkit.TreeType.CHERRY; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.PALE_OAK) || feature.is(TreeFeatures.PALE_OAK_BONEMEAL)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.PALE_OAK; -+ treeType = org.bukkit.TreeType.PALE_OAK; - } else if (treeFeature == TreeFeatures.PALE_OAK_CREAKING) { ++ treeType = org.bukkit.TreeType.PALE_OAK; // SparklyPaper - parallel world ticking + } else if (feature.is(TreeFeatures.PALE_OAK_CREAKING)) { - net.minecraft.world.level.block.SaplingBlock.treeType = org.bukkit.TreeType.PALE_OAK_CREAKING; -+ treeType = org.bukkit.TreeType.PALE_OAK_CREAKING; ++ treeType = org.bukkit.TreeType.PALE_OAK_CREAKING; // SparklyPaper - parallel world ticking } else { - throw new IllegalArgumentException("Unknown tree generator " + treeFeature); + throw new IllegalArgumentException("Unknown tree generator " + feature); } + net.minecraft.world.level.block.SaplingBlock.setTreeTypeRT(treeType); // SparklyPaper - parallel world ticking // Leaf - SparklyPaper - parallel world ticking mod (collapse original behavior) -+ // SparklyPaper end - parallel world ticking } // CraftBukkit end } diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index 238e015d4ff5fabb99e569118f253366d545d269..47528dec6b1a2b36e71013a9372425a70cbc6a33 100644 +index 5325989f46bd288c5a6f1362ec17d3354d55abfd..8d8d909c4b9496ae6f44ba34203ee40433d37f8c 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java -@@ -401,6 +401,8 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p - +@@ -399,6 +399,8 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p @Nullable - public BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving, boolean doPlace) { + @Override + public BlockState setBlockState(BlockPos pos, BlockState state, int flags) { + 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.level, pos, "Updating block asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs) - // CraftBukkit end int y = pos.getY(); LevelChunkSection section = this.getSection(this.getSectionIndex(y)); + boolean hasOnlyAir = section.hasOnlyAir(); diff --git a/net/minecraft/world/level/entity/EntityTickList.java b/net/minecraft/world/level/entity/EntityTickList.java index dec51066fc3f57b7bdc56195313c219f45a7fbee..359ead3bd32862206bccb4504ad5b4d027dba7a9 100644 --- a/net/minecraft/world/level/entity/EntityTickList.java @@ -1656,38 +1369,17 @@ index dec51066fc3f57b7bdc56195313c219f45a7fbee..359ead3bd32862206bccb4504ad5b4d0 // To ensure nothing weird happens with dimension travelling, do not iterate over new entries... // (by dfl iterator() is configured to not iterate over new entries) diff --git a/net/minecraft/world/level/saveddata/maps/MapIndex.java b/net/minecraft/world/level/saveddata/maps/MapIndex.java -index ffe604f8397a002800e6ecc2f878d0f6f1c98703..147cae56b4db456bbbe7cb2522568e007620df12 100644 +index 06025d79cc2297119b22224d777aca79f9d3d9c1..8e70deae0ff70d21e31f54410e3886be0280575c 100644 --- a/net/minecraft/world/level/saveddata/maps/MapIndex.java +++ b/net/minecraft/world/level/saveddata/maps/MapIndex.java -@@ -34,17 +34,25 @@ public class MapIndex extends SavedData { - - @Override - public CompoundTag save(CompoundTag tag, HolderLookup.Provider registries) { -- for (Entry entry : this.usedAuxIds.object2IntEntrySet()) { -- tag.putInt(entry.getKey(), entry.getIntValue()); -+ // SparklyPaper start - make map data thread-safe -+ synchronized (this.usedAuxIds) { -+ for (Entry entry : this.usedAuxIds.object2IntEntrySet()) { -+ tag.putInt(entry.getKey(), entry.getIntValue()); -+ } - } -+ // SparklyPaper end - make map data thread-safe - - return tag; +@@ -23,8 +23,10 @@ public class MapIndex extends SavedData { } - public MapId getFreeAuxValueForMap() { -- int i = this.usedAuxIds.getInt("map") + 1; -- this.usedAuxIds.put("map", i); -- this.setDirty(); -- return new MapId(i); -+ // SparklyPaper start - make map data thread-safe -+ synchronized (this.usedAuxIds) { -+ int i = this.usedAuxIds.getInt("map") + 1; -+ this.usedAuxIds.put("map", i); -+ this.setDirty(); -+ return new MapId(i); -+ } -+ // SparklyPaper end - make map data thread-safe + public MapId getNextMapId() { ++ synchronized (TYPE) { // SparklyPaper start - parallel world ticking + MapId mapId = new MapId(++this.lastMapId); + this.setDirty(); + return mapId; ++ } // SparklyPaper end - parallel world ticking } } diff --git a/leaf-archived-patches/unapplied/server/minecraft-patches/features/0135-SparklyPaper-Track-each-world-MSPT.patch b/leaf-server/minecraft-patches/features/0225-SparklyPaper-Track-each-world-MSPT.patch similarity index 94% rename from leaf-archived-patches/unapplied/server/minecraft-patches/features/0135-SparklyPaper-Track-each-world-MSPT.patch rename to leaf-server/minecraft-patches/features/0225-SparklyPaper-Track-each-world-MSPT.patch index f16beee9..276e4ba1 100644 --- a/leaf-archived-patches/unapplied/server/minecraft-patches/features/0135-SparklyPaper-Track-each-world-MSPT.patch +++ b/leaf-server/minecraft-patches/features/0225-SparklyPaper-Track-each-world-MSPT.patch @@ -6,10 +6,10 @@ 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 7f791ff5bdf6c29c78f863d21af16270a74d8e7e..1431a0fac3c8a846535c1bd2f60a1279d08f14ea 100644 +index c9b8bc9592d5fce77750de89fa886db383d92a89..1dc599e28682b59c8389ff2ada100b405bf97240 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -1699,7 +1699,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop, AutoCl +@@ -171,6 +171,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl public final Map explosionDensityCache = new java.util.HashMap<>(); // Paper - Optimize explosions public java.util.ArrayDeque redstoneUpdateInfos; // Paper - Faster redstone torch rapid clock removal; Move from Map in BlockRedstoneTorch to here public final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = org.dreeam.leaf.config.modules.opt.FastRNG.enabled ? new org.dreeam.leaf.util.math.random.FasterRandomSource(net.minecraft.world.level.levelgen.RandomSupport.generateUniqueSeed()) : new ca.spottedleaf.moonrise.common.util.SimpleThreadUnsafeRandom(net.minecraft.world.level.levelgen.RandomSupport.generateUniqueSeed()); // Gale - Pufferfish - move random tick random // Leaf - Faster random generator diff --git a/leaf-server/minecraft-patches/features/0225-Optimize-SetLookAndInteract-and-NearestVisibleLiving.patch b/leaf-server/minecraft-patches/features/0227-Optimize-SetLookAndInteract-and-NearestVisibleLiving.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0225-Optimize-SetLookAndInteract-and-NearestVisibleLiving.patch rename to leaf-server/minecraft-patches/features/0227-Optimize-SetLookAndInteract-and-NearestVisibleLiving.patch diff --git a/leaf-server/minecraft-patches/features/0226-Remove-streams-on-InsideBrownianWalk.patch b/leaf-server/minecraft-patches/features/0228-Remove-streams-on-InsideBrownianWalk.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0226-Remove-streams-on-InsideBrownianWalk.patch rename to leaf-server/minecraft-patches/features/0228-Remove-streams-on-InsideBrownianWalk.patch diff --git a/leaf-server/minecraft-patches/features/0227-Use-BFS-on-getSlopeDistance.patch b/leaf-server/minecraft-patches/features/0229-Use-BFS-on-getSlopeDistance.patch similarity index 98% rename from leaf-server/minecraft-patches/features/0227-Use-BFS-on-getSlopeDistance.patch rename to leaf-server/minecraft-patches/features/0229-Use-BFS-on-getSlopeDistance.patch index ddde4245..51b26527 100644 --- a/leaf-server/minecraft-patches/features/0227-Use-BFS-on-getSlopeDistance.patch +++ b/leaf-server/minecraft-patches/features/0229-Use-BFS-on-getSlopeDistance.patch @@ -9,10 +9,10 @@ Leaf: ~48ms (-36%) This should help drastically on the farms that use actively changing fluids. diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 2ecb73fc7b6754ade93bf16b48c623e6b3a955a9..4ecca1bf5ece7788f3de41d5ec58565b8a768251 100644 +index f4b9d0bcf305d99d39e530c3369faaec60bbc5a8..a311f81b7f34f2c988ebcd792ca87dfd7b175f96 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -1302,6 +1302,10 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1441,6 +1441,10 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.emptyTime = 0; } diff --git a/leaf-server/minecraft-patches/features/0228-Paper-PR-Throttle-failed-spawn-attempts.patch b/leaf-server/minecraft-patches/features/0230-Paper-PR-Throttle-failed-spawn-attempts.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0228-Paper-PR-Throttle-failed-spawn-attempts.patch rename to leaf-server/minecraft-patches/features/0230-Paper-PR-Throttle-failed-spawn-attempts.patch diff --git a/leaf-server/minecraft-patches/features/0229-Improve-BlockEntity-ticking-isRemoved-check.patch b/leaf-server/minecraft-patches/features/0231-Improve-BlockEntity-ticking-isRemoved-check.patch similarity index 91% rename from leaf-server/minecraft-patches/features/0229-Improve-BlockEntity-ticking-isRemoved-check.patch rename to leaf-server/minecraft-patches/features/0231-Improve-BlockEntity-ticking-isRemoved-check.patch index e8fc8329..dab2825c 100644 --- a/leaf-server/minecraft-patches/features/0229-Improve-BlockEntity-ticking-isRemoved-check.patch +++ b/leaf-server/minecraft-patches/features/0231-Improve-BlockEntity-ticking-isRemoved-check.patch @@ -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 5325989f46bd288c5a6f1362ec17d3354d55abfd..5ca0aa1fdaae3ba03a464e2c5bc061adc076b649 100644 +index 8d8d909c4b9496ae6f44ba34203ee40433d37f8c..e82e55ec400c5e338502ed7ce433372a88d4acff 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java -@@ -1014,15 +1014,29 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p +@@ -1016,15 +1016,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 5325989f46bd288c5a6f1362ec17d3354d55abfd..5ca0aa1fdaae3ba03a464e2c5bc061ad } @Override -@@ -1032,6 +1046,11 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p +@@ -1034,6 +1048,11 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p @Override public boolean isRemoved() { diff --git a/leaf-server/minecraft-patches/features/0230-Raytrace-AntiXray-SDK-integration.patch b/leaf-server/minecraft-patches/features/0232-Raytrace-AntiXray-SDK-integration.patch similarity index 94% rename from leaf-server/minecraft-patches/features/0230-Raytrace-AntiXray-SDK-integration.patch rename to leaf-server/minecraft-patches/features/0232-Raytrace-AntiXray-SDK-integration.patch index 10605cd9..c4648270 100644 --- a/leaf-server/minecraft-patches/features/0230-Raytrace-AntiXray-SDK-integration.patch +++ b/leaf-server/minecraft-patches/features/0232-Raytrace-AntiXray-SDK-integration.patch @@ -25,10 +25,10 @@ index 3a596650feb96123c5684bb5065e20c5b005c0b9..f7a05fd098ef7b303254cd410414d50d } diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 2f679f03360a2847ba3d98a6698b7c0210a0b67e..309dbb3b7a485ef5e13f893e53bbdbec1401422e 100644 +index 6278fe737a555f47625098828a03952cf9b859a7..4158bbe0740fe2971a9e857cb4cad08ee465576a 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java -@@ -1174,6 +1174,12 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl +@@ -1177,6 +1177,12 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl snapshot.setFlags(flags); // Paper - always set the flag of the most recent call to mitigate issues with multiple update at the same pos with different flags } BlockState blockState = chunkAt.setBlockState(pos, state, flags); diff --git a/leaf-server/minecraft-patches/features/0231-Optimize-addOrUpdateTransientModifier.patch b/leaf-server/minecraft-patches/features/0233-Optimize-addOrUpdateTransientModifier.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0231-Optimize-addOrUpdateTransientModifier.patch rename to leaf-server/minecraft-patches/features/0233-Optimize-addOrUpdateTransientModifier.patch diff --git a/leaf-server/minecraft-patches/features/0232-Optimize-ContextMap.create.patch b/leaf-server/minecraft-patches/features/0234-Optimize-ContextMap.create.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0232-Optimize-ContextMap.create.patch rename to leaf-server/minecraft-patches/features/0234-Optimize-ContextMap.create.patch diff --git a/leaf-server/minecraft-patches/features/0233-Micro-optimizations-for-random-tick.patch b/leaf-server/minecraft-patches/features/0235-Micro-optimizations-for-random-tick.patch similarity index 94% rename from leaf-server/minecraft-patches/features/0233-Micro-optimizations-for-random-tick.patch rename to leaf-server/minecraft-patches/features/0235-Micro-optimizations-for-random-tick.patch index c067bfc4..742d9423 100644 --- a/leaf-server/minecraft-patches/features/0233-Micro-optimizations-for-random-tick.patch +++ b/leaf-server/minecraft-patches/features/0235-Micro-optimizations-for-random-tick.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Micro optimizations for random tick diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 4ecca1bf5ece7788f3de41d5ec58565b8a768251..05173104db4c04823658930aa92645f6c2400109 100644 +index a311f81b7f34f2c988ebcd792ca87dfd7b175f96..4948557d2faef1dff664cd18df7af4564a0431ff 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -905,7 +905,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1044,7 +1044,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // Paper start - optimise random ticking private void optimiseRandomTick(final LevelChunk chunk, final int tickSpeed) { final LevelChunkSection[] sections = chunk.getSections(); @@ -17,7 +17,7 @@ index 4ecca1bf5ece7788f3de41d5ec58565b8a768251..05173104db4c04823658930aa92645f6 final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = this.simpleRandom; // Leaf - Faster random generator - upcasting final boolean doubleTickFluids = !ca.spottedleaf.moonrise.common.PlatformHooks.get().configFixMC224294(); -@@ -914,41 +914,41 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1053,41 +1053,41 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe final int offsetZ = cpos.z << 4; for (int sectionIndex = 0, sectionsLen = sections.length; sectionIndex < sectionsLen; sectionIndex++) { diff --git a/leaf-server/minecraft-patches/features/0234-Remove-streams-on-updateConnectedPlayersWithinRange.patch b/leaf-server/minecraft-patches/features/0236-Remove-streams-on-updateConnectedPlayersWithinRange.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0234-Remove-streams-on-updateConnectedPlayersWithinRange.patch rename to leaf-server/minecraft-patches/features/0236-Remove-streams-on-updateConnectedPlayersWithinRange.patch diff --git a/leaf-server/minecraft-patches/features/0235-Remove-streams-on-PlayerDetector.patch b/leaf-server/minecraft-patches/features/0237-Remove-streams-on-PlayerDetector.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0235-Remove-streams-on-PlayerDetector.patch rename to leaf-server/minecraft-patches/features/0237-Remove-streams-on-PlayerDetector.patch diff --git a/leaf-server/minecraft-patches/features/0236-Use-direct-iteration-on-Sensing.tick.patch b/leaf-server/minecraft-patches/features/0238-Use-direct-iteration-on-Sensing.tick.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0236-Use-direct-iteration-on-Sensing.tick.patch rename to leaf-server/minecraft-patches/features/0238-Use-direct-iteration-on-Sensing.tick.patch diff --git a/leaf-server/minecraft-patches/features/0237-Optimise-non-flush-packet-sending.patch b/leaf-server/minecraft-patches/features/0239-Optimise-non-flush-packet-sending.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0237-Optimise-non-flush-packet-sending.patch rename to leaf-server/minecraft-patches/features/0239-Optimise-non-flush-packet-sending.patch diff --git a/leaf-server/minecraft-patches/features/0238-Prevent-double-chunk-retrieving-in-entity-fluid-push.patch b/leaf-server/minecraft-patches/features/0240-Prevent-double-chunk-retrieving-in-entity-fluid-push.patch similarity index 91% rename from leaf-server/minecraft-patches/features/0238-Prevent-double-chunk-retrieving-in-entity-fluid-push.patch rename to leaf-server/minecraft-patches/features/0240-Prevent-double-chunk-retrieving-in-entity-fluid-push.patch index 0c1ce6a3..b973e023 100644 --- a/leaf-server/minecraft-patches/features/0238-Prevent-double-chunk-retrieving-in-entity-fluid-push.patch +++ b/leaf-server/minecraft-patches/features/0240-Prevent-double-chunk-retrieving-in-entity-fluid-push.patch @@ -11,10 +11,10 @@ As part of: Airplane (https://github.com/TECHNOVE/Airplane) Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html) diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 309a31215cb63452215fd880590cffd569aee208..1db32873588673900a8afa9767c3af12c7b6742a 100644 +index b89923a0b30a294c393716b666ff3377f0a835dc..cfd01993160bcc4a8a5b80c82df7c0c82b70f229 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -4579,10 +4579,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4606,10 +4606,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // Paper start - optimise collisions public boolean updateFluidHeightAndDoFluidPushing(final TagKey fluid, final double flowScale) { @@ -26,7 +26,7 @@ index 309a31215cb63452215fd880590cffd569aee208..1db32873588673900a8afa9767c3af12 final AABB boundingBox = this.getBoundingBox().deflate(1.0E-3); final Level world = this.level; -@@ -4618,7 +4615,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4645,7 +4642,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { diff --git a/leaf-server/minecraft-patches/features/0239-Null-handling-on-MultifaceSpreader.patch b/leaf-server/minecraft-patches/features/0241-Null-handling-on-MultifaceSpreader.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0239-Null-handling-on-MultifaceSpreader.patch rename to leaf-server/minecraft-patches/features/0241-Null-handling-on-MultifaceSpreader.patch diff --git a/leaf-server/minecraft-patches/features/0240-More-virtual-threads.patch b/leaf-server/minecraft-patches/features/0242-More-virtual-threads.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0240-More-virtual-threads.patch rename to leaf-server/minecraft-patches/features/0242-More-virtual-threads.patch diff --git a/leaf-server/minecraft-patches/features/0241-Async-target-finding.patch b/leaf-server/minecraft-patches/features/0243-Async-target-finding.patch similarity index 96% rename from leaf-server/minecraft-patches/features/0241-Async-target-finding.patch rename to leaf-server/minecraft-patches/features/0243-Async-target-finding.patch index a560d8ec..b5e01ba7 100644 --- a/leaf-server/minecraft-patches/features/0241-Async-target-finding.patch +++ b/leaf-server/minecraft-patches/features/0243-Async-target-finding.patch @@ -106,18 +106,18 @@ index 7b686d834e4eb36be5758b0e0a846a70d1e2294b..956d48fb7146b9eb2a5b5b4e23a83f60 final EntityCollectionBySection byType = this.entitiesByType.get(entity.getType()); byType.removeEntity(entity, sectionIndex); diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index bbd2b327c658b56a1fcf30c8b77cab987d688fcc..f8dba8be5774035744233c251c61abf572dd7d49 100644 +index 1dc599e28682b59c8389ff2ada100b405bf97240..c2c904565df5fb320b98307a4d451066286ad726 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -290,6 +290,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (concurrent because plugins may schedule tasks async) + public java.util.concurrent.Semaphore serverLevelTickingSemaphore = null; // SparklyPaper - parallel world ticking + @Nullable public org.dreeam.leaf.async.ai.AsyncGoalThread asyncGoalThread; // Leaf - Async target finding public static S spin(Function threadFunction) { AtomicReference atomicReference = new AtomicReference<>(); -@@ -1073,6 +1074,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop realPlayers; // Leaves - skip @@ -178,7 +177,7 @@ index 05173104db4c04823658930aa92645f6c2400109..e0fdf7205ff1dfab2c5cccd3d18c2b22 @Override public @Nullable LevelChunk getChunkIfLoaded(int x, int z) { -@@ -331,6 +341,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -334,6 +344,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks(); } @@ -191,10 +190,10 @@ index 05173104db4c04823658930aa92645f6c2400109..e0fdf7205ff1dfab2c5cccd3d18c2b22 @Override public final ChunkAccess moonrise$syncLoadNonFull(final int chunkX, final int chunkZ, final net.minecraft.world.level.chunk.status.ChunkStatus status) { return this.moonrise$getChunkTaskScheduler().syncLoadNonFull(chunkX, chunkZ, status); -@@ -693,6 +709,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit +@@ -703,6 +719,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.preciseTime = this.serverLevelData.getDayTime(); // Purpur - Configurable daylight cycle this.realPlayers = Lists.newArrayList(); // Leaves - skip + this.tickExecutor = java.util.concurrent.Executors.newSingleThreadExecutor(new org.dreeam.leaf.async.world.SparklyPaperServerLevelTickExecutorThreadFactory(getWorld().getName())); // SparklyPaper - parallel world ticking + // Leaf start - Async target finding + if (org.dreeam.leaf.config.modules.async.AsyncTargetFinding.enabled) { + this.asyncGoalExecutor = new org.dreeam.leaf.async.ai.AsyncGoalExecutor(server.asyncGoalThread, this); @@ -204,8 +203,8 @@ index 05173104db4c04823658930aa92645f6c2400109..e0fdf7205ff1dfab2c5cccd3d18c2b22 + // Leaf end - Async target finding } - // Paper start -@@ -837,12 +860,14 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + // Leaf start - SparklyPaper - parallel world ticking - Shutdown handling for async reads +@@ -976,12 +999,14 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } this.moonrise$midTickTasks(); // Paper - rewrite chunk system // Gale end - Airplane - remove lambda from ticking guard - copied from guardEntityTick @@ -220,16 +219,16 @@ index 05173104db4c04823658930aa92645f6c2400109..e0fdf7205ff1dfab2c5cccd3d18c2b22 } // Paper - rewrite chunk system } -@@ -1318,6 +1343,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - } +@@ -1460,6 +1485,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + // Leaf end - SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks) // Paper end - rewrite chunk system + this.leafMidTickTasks(); // Leaf - Async target finding } private void tickBlock(BlockPos pos, Block block) { -@@ -1331,6 +1357,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - } +@@ -1476,6 +1502,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + // Leaf end - SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks) // Paper end - rewrite chunk system + this.leafMidTickTasks(); // Leaf - Async target finding @@ -2047,25 +2046,27 @@ index e1717b5c854aa81fdd7b7e715d7c3498d9f86072..3627e7479b4deea28e268245410ec4cd static class StriderPathNavigation extends GroundPathNavigation { diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 309dbb3b7a485ef5e13f893e53bbdbec1401422e..1ef49db44e8dcfd944b600ef64dbcaee36546688 100644 +index 4158bbe0740fe2971a9e857cb4cad08ee465576a..e380cc68d0d88d983a1b7b1d9ef4ec8ef307761a 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java -@@ -1525,6 +1525,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl - ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)(Level)(Object)this).moonrise$midTickTasks(); +@@ -1531,6 +1531,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl } + // Leaf end - SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks) - do not bother with condition work / make configurable // Paper end - rewrite chunk system + ((ServerLevel) this).leafMidTickTasks(); // Leaf - Async target finding } } this.blockEntityTickers.removeMarkedEntries(); // SparklyPaper - optimize block entity removals -@@ -1788,7 +1789,11 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl +@@ -1799,9 +1800,11 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl @Override public List getEntities(@Nullable Entity entity, AABB boundingBox, Predicate predicate) { +- if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) // Leaf start - SparklyPaper - parallel world ticking mod (make configurable) +- ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel)this, boundingBox, "Cannot getEntities asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs) - List list = Lists.newArrayList(); + // Leaf start - Async target finding -+ // if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) // Leaf start - SparklyPaper - parallel world ticking mod (make configurable) -+ // ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel)this, boundingBox, "Cannot getEntities asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs) ++ //if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) // Leaf start - SparklyPaper - parallel world ticking mod (make configurable) ++ // ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel)this, boundingBox, "Cannot getEntities asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs) + //List list = Lists.newArrayList(); // Leaf - Async target finding - unused + // Leaf end - Async target finding diff --git a/leaf-server/minecraft-patches/features/0242-Optimize-ThreadedTicketLevelPropagator.patch b/leaf-server/minecraft-patches/features/0244-Optimize-ThreadedTicketLevelPropagator.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0242-Optimize-ThreadedTicketLevelPropagator.patch rename to leaf-server/minecraft-patches/features/0244-Optimize-ThreadedTicketLevelPropagator.patch diff --git a/leaf-server/minecraft-patches/features/0243-Optimise-MobEffectUtil-getDigSpeedAmplification.patch b/leaf-server/minecraft-patches/features/0245-Optimise-MobEffectUtil-getDigSpeedAmplification.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0243-Optimise-MobEffectUtil-getDigSpeedAmplification.patch rename to leaf-server/minecraft-patches/features/0245-Optimise-MobEffectUtil-getDigSpeedAmplification.patch diff --git a/leaf-server/minecraft-patches/features/0244-Optimise-chunkUnloads.patch b/leaf-server/minecraft-patches/features/0246-Optimise-chunkUnloads.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0244-Optimise-chunkUnloads.patch rename to leaf-server/minecraft-patches/features/0246-Optimise-chunkUnloads.patch diff --git a/leaf-server/minecraft-patches/features/0245-Optimize-BlockEntityType-isValid.patch b/leaf-server/minecraft-patches/features/0247-Optimize-BlockEntityType-isValid.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0245-Optimize-BlockEntityType-isValid.patch rename to leaf-server/minecraft-patches/features/0247-Optimize-BlockEntityType-isValid.patch diff --git a/leaf-server/minecraft-patches/features/0246-PaperPR-Add-ticket-on-player-join-to-avoid-chunk-loa.patch b/leaf-server/minecraft-patches/features/0248-PaperPR-Add-ticket-on-player-join-to-avoid-chunk-loa.patch similarity index 96% rename from leaf-server/minecraft-patches/features/0246-PaperPR-Add-ticket-on-player-join-to-avoid-chunk-loa.patch rename to leaf-server/minecraft-patches/features/0248-PaperPR-Add-ticket-on-player-join-to-avoid-chunk-loa.patch index 65d56ee1..0b9032aa 100644 --- a/leaf-server/minecraft-patches/features/0246-PaperPR-Add-ticket-on-player-join-to-avoid-chunk-loa.patch +++ b/leaf-server/minecraft-patches/features/0248-PaperPR-Add-ticket-on-player-join-to-avoid-chunk-loa.patch @@ -27,10 +27,10 @@ index 3a78e7512772fd3f7cf8f221e3a72474def14bea..ba52af914e9e231caa0ac50562e9a692 public static final int GENERATED_TICKET_LEVEL = ChunkHolderManager.FULL_LOADED_TICKET_LEVEL; public static final int LOADED_TICKET_LEVEL = ChunkTaskScheduler.getTicketLevel(ChunkStatus.EMPTY); diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index 8b1652805a2ac9ebae9c99dd77e81c7a484a7abb..608d4612ed15ec04492b0137ec61e157161d792f 100644 +index e4bccc642abe15b0ec4b1cf2634801065a27e11a..6a9aa085956ddd27e8910dd524ecb79caf9ae0ba 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -432,6 +432,13 @@ public abstract class PlayerList { +@@ -434,6 +434,13 @@ public abstract class PlayerList { // this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player))); // CraftBukkit - replaced with loop below // Paper start - Fire PlayerJoinEvent when Player is actually ready; correctly register player BEFORE PlayerJoinEvent, so the entity is valid and doesn't require tick delay hacks player.supressTrackerForLogin = true; diff --git a/leaf-server/minecraft-patches/features/0247-Sakura-Optimise-check-inside-blocks-and-traverse-blo.patch b/leaf-server/minecraft-patches/features/0249-Sakura-Optimise-check-inside-blocks-and-traverse-blo.patch similarity index 98% rename from leaf-server/minecraft-patches/features/0247-Sakura-Optimise-check-inside-blocks-and-traverse-blo.patch rename to leaf-server/minecraft-patches/features/0249-Sakura-Optimise-check-inside-blocks-and-traverse-blo.patch index 631f063d..9ffea2b4 100644 --- a/leaf-server/minecraft-patches/features/0247-Sakura-Optimise-check-inside-blocks-and-traverse-blo.patch +++ b/leaf-server/minecraft-patches/features/0249-Sakura-Optimise-check-inside-blocks-and-traverse-blo.patch @@ -6,7 +6,7 @@ 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 1db32873588673900a8afa9767c3af12c7b6742a..5d1027cb511be78b1e29d0e3bdc49cc9d6add346 100644 +index cfd01993160bcc4a8a5b80c82df7c0c82b70f229..f866fd8a7c37b94d24d6d1e41ed0a6106a82a4ac 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -1697,6 +1697,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/leaf-server/minecraft-patches/features/0248-Sakura-copy-EntityList-implementation-to-BasicEntity.patch b/leaf-server/minecraft-patches/features/0250-Sakura-copy-EntityList-implementation-to-BasicEntity.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0248-Sakura-copy-EntityList-implementation-to-BasicEntity.patch rename to leaf-server/minecraft-patches/features/0250-Sakura-copy-EntityList-implementation-to-BasicEntity.patch diff --git a/leaf-server/minecraft-patches/features/0249-Protocol-Core.patch b/leaf-server/minecraft-patches/features/0251-Protocol-Core.patch similarity index 90% rename from leaf-server/minecraft-patches/features/0249-Protocol-Core.patch rename to leaf-server/minecraft-patches/features/0251-Protocol-Core.patch index ae2a02fb..fb69fefd 100644 --- a/leaf-server/minecraft-patches/features/0249-Protocol-Core.patch +++ b/leaf-server/minecraft-patches/features/0251-Protocol-Core.patch @@ -22,10 +22,10 @@ index 56fd1ed7ccaf96e7eedea60fbdbf7f934939d563..d2f522ea6d0a209496848af073c9af1c } diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index f8dba8be5774035744233c251c61abf572dd7d49..2ca484a6c3e75fd392ca953737bb548ab10f2121 100644 +index c2c904565df5fb320b98307a4d451066286ad726..84b90f496e5ab59d43503301fe935627af123e3f 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -1771,6 +1771,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop mountedOrDismounted(List entities) { diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index ccd442b24693bc9269cc8ab3e44887d0ad3eadbd..aee177756afebd3f39917ae8a08bbbd0e2efe4df 100644 +index ac7ac519ecc58a31c4b9efc24f054ec014851fb4..59a61ac969e79966484a839b7d9ca0ac50e80994 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -803,6 +803,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -805,6 +805,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc } } // Purpur end - Ridables @@ -71,10 +71,10 @@ index 18f0d486c478087f404d8bb6cd840079e2c8d239..1a6f1c5f4cf13ee50bc8445845cbb973 final byte[] data = discardedPayload.data(); try { diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index 608d4612ed15ec04492b0137ec61e157161d792f..7802f33f4259e9df0b2e682dd2e6bb8f6f74f25b 100644 +index 6a9aa085956ddd27e8910dd524ecb79caf9ae0ba..e0f6b82d9836cb73f6fe631071bb1a0c5ec77eab 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -684,6 +684,7 @@ public abstract class PlayerList { +@@ -686,6 +686,7 @@ public abstract class PlayerList { } public @Nullable net.kyori.adventure.text.Component remove(ServerPlayer player, net.kyori.adventure.text.Component leaveMessage) { org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerLeave(player); // Leaves - protocol diff --git a/leaf-server/minecraft-patches/features/0250-Reduce-PlayerChunk-Updates.patch b/leaf-server/minecraft-patches/features/0252-Reduce-PlayerChunk-Updates.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0250-Reduce-PlayerChunk-Updates.patch rename to leaf-server/minecraft-patches/features/0252-Reduce-PlayerChunk-Updates.patch diff --git a/leaf-server/minecraft-patches/features/0251-Async-switch-connection-state.patch b/leaf-server/minecraft-patches/features/0253-Async-switch-connection-state.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0251-Async-switch-connection-state.patch rename to leaf-server/minecraft-patches/features/0253-Async-switch-connection-state.patch diff --git a/leaf-server/minecraft-patches/features/0252-Optimise-BlockEntities-tickersInLevel.patch b/leaf-server/minecraft-patches/features/0254-Optimise-BlockEntities-tickersInLevel.patch similarity index 91% rename from leaf-server/minecraft-patches/features/0252-Optimise-BlockEntities-tickersInLevel.patch rename to leaf-server/minecraft-patches/features/0254-Optimise-BlockEntities-tickersInLevel.patch index 8dbf75c3..bd977680 100644 --- a/leaf-server/minecraft-patches/features/0252-Optimise-BlockEntities-tickersInLevel.patch +++ b/leaf-server/minecraft-patches/features/0254-Optimise-BlockEntities-tickersInLevel.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Optimise BlockEntities tickersInLevel diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index 5ca0aa1fdaae3ba03a464e2c5bc061adc076b649..3e00ef33413764df933c85bb836d2cd327248edd 100644 +index e82e55ec400c5e338502ed7ce433372a88d4acff..155e9b807a61ab1212ee25cc79a386821596dedc 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java @@ -73,7 +73,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p diff --git a/leaf-server/minecraft-patches/features/0253-Pluto-Check-if-the-cactus-can-even-survive-being-pla.patch b/leaf-server/minecraft-patches/features/0255-Pluto-Check-if-the-cactus-can-even-survive-being-pla.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0253-Pluto-Check-if-the-cactus-can-even-survive-being-pla.patch rename to leaf-server/minecraft-patches/features/0255-Pluto-Check-if-the-cactus-can-even-survive-being-pla.patch diff --git a/leaf-server/minecraft-patches/features/0254-Flush-location-while-knockback.patch b/leaf-server/minecraft-patches/features/0256-Flush-location-while-knockback.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0254-Flush-location-while-knockback.patch rename to leaf-server/minecraft-patches/features/0256-Flush-location-while-knockback.patch diff --git a/leaf-server/minecraft-patches/features/0255-Only-tick-items-at-hand.patch b/leaf-server/minecraft-patches/features/0257-Only-tick-items-at-hand.patch similarity index 93% rename from leaf-server/minecraft-patches/features/0255-Only-tick-items-at-hand.patch rename to leaf-server/minecraft-patches/features/0257-Only-tick-items-at-hand.patch index ac15f030..97a02640 100644 --- a/leaf-server/minecraft-patches/features/0255-Only-tick-items-at-hand.patch +++ b/leaf-server/minecraft-patches/features/0257-Only-tick-items-at-hand.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Only tick items at hand diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index aee177756afebd3f39917ae8a08bbbd0e2efe4df..b4e5405a3b48cc18d2dac264c5bb7ff666ad2e22 100644 +index 59a61ac969e79966484a839b7d9ca0ac50e80994..82ac99c3c5b374482f3ff18f5d20bf888091e539 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -832,12 +832,19 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -834,12 +834,19 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc super.tick(); } diff --git a/leaf-server/minecraft-patches/features/0256-Smart-sort-items-in-NearestItemSensor.patch b/leaf-server/minecraft-patches/features/0258-Smart-sort-items-in-NearestItemSensor.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0256-Smart-sort-items-in-NearestItemSensor.patch rename to leaf-server/minecraft-patches/features/0258-Smart-sort-items-in-NearestItemSensor.patch diff --git a/leaf-server/minecraft-patches/features/0257-Optimise-player-movement-checks.patch b/leaf-server/minecraft-patches/features/0259-Optimise-player-movement-checks.patch similarity index 90% rename from leaf-server/minecraft-patches/features/0257-Optimise-player-movement-checks.patch rename to leaf-server/minecraft-patches/features/0259-Optimise-player-movement-checks.patch index 65883eb4..80ce2994 100644 --- a/leaf-server/minecraft-patches/features/0257-Optimise-player-movement-checks.patch +++ b/leaf-server/minecraft-patches/features/0259-Optimise-player-movement-checks.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Optimise player movement checks diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 5d1027cb511be78b1e29d0e3bdc49cc9d6add346..1b4aae603e965ae15d9b7e204a2ac5d31d045db0 100644 +index f866fd8a7c37b94d24d6d1e41ed0a6106a82a4ac..d09a32288398d3ffa0fa6e9c6fd06f953b33688f 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -1190,7 +1190,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/leaf-server/minecraft-patches/features/0258-Remove-streams-in-MobSensor.patch b/leaf-server/minecraft-patches/features/0260-Remove-streams-in-MobSensor.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0258-Remove-streams-in-MobSensor.patch rename to leaf-server/minecraft-patches/features/0260-Remove-streams-in-MobSensor.patch diff --git a/leaf-server/minecraft-patches/features/0259-Remove-streams-in-TemptingSensor.patch b/leaf-server/minecraft-patches/features/0261-Remove-streams-in-TemptingSensor.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0259-Remove-streams-in-TemptingSensor.patch rename to leaf-server/minecraft-patches/features/0261-Remove-streams-in-TemptingSensor.patch diff --git a/leaf-server/minecraft-patches/features/0260-Use-HashedList-on-WeightedList.patch b/leaf-server/minecraft-patches/features/0262-Use-HashedList-on-WeightedList.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0260-Use-HashedList-on-WeightedList.patch rename to leaf-server/minecraft-patches/features/0262-Use-HashedList-on-WeightedList.patch diff --git a/leaf-server/minecraft-patches/features/0261-Add-configurable-death-item-drop-knockback-settings.patch b/leaf-server/minecraft-patches/features/0263-Add-configurable-death-item-drop-knockback-settings.patch similarity index 94% rename from leaf-server/minecraft-patches/features/0261-Add-configurable-death-item-drop-knockback-settings.patch rename to leaf-server/minecraft-patches/features/0263-Add-configurable-death-item-drop-knockback-settings.patch index d98419dd..fd5f99d7 100644 --- a/leaf-server/minecraft-patches/features/0261-Add-configurable-death-item-drop-knockback-settings.patch +++ b/leaf-server/minecraft-patches/features/0263-Add-configurable-death-item-drop-knockback-settings.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add configurable death item drop knockback settings diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index b4e5405a3b48cc18d2dac264c5bb7ff666ad2e22..2a4fb4de12409166e9463eacafb13e37760a3a1b 100644 +index 82ac99c3c5b374482f3ff18f5d20bf888091e539..c9fbbbef8d006a90023c70419b5be7220602ee3b 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -1051,7 +1051,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1053,7 +1053,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc if (!keepInventory) { for (ItemStack item : this.getInventory().getContents()) { if (!item.isEmpty() && !EnchantmentHelper.has(item, net.minecraft.world.item.enchantment.EnchantmentEffectComponents.PREVENT_EQUIPMENT_DROP)) { diff --git a/leaf-server/minecraft-patches/features/0262-Optimize-getScaledTrackingDistance.patch b/leaf-server/minecraft-patches/features/0264-Optimize-getScaledTrackingDistance.patch similarity index 86% rename from leaf-server/minecraft-patches/features/0262-Optimize-getScaledTrackingDistance.patch rename to leaf-server/minecraft-patches/features/0264-Optimize-getScaledTrackingDistance.patch index c6fe72ac..a5597595 100644 --- a/leaf-server/minecraft-patches/features/0262-Optimize-getScaledTrackingDistance.patch +++ b/leaf-server/minecraft-patches/features/0264-Optimize-getScaledTrackingDistance.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Optimize getScaledTrackingDistance diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java -index 747eb54f84650a9a507398e3d5352e001b042490..595284787053a5fb7385e8493953c73a19fe7aee 100644 +index 41bdd0a3bb9c18f4eae3e2ca78c2946979da4f0b..8192031ab3d947bb67eb00eec0a95ea99dce47ad 100644 --- a/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java -@@ -780,7 +780,13 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -785,7 +785,13 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @Override public int getScaledTrackingDistance(int trackingDistance) { diff --git a/leaf-server/minecraft-patches/features/0263-Optimize-SynchedEntityData-packDirty.patch b/leaf-server/minecraft-patches/features/0265-Optimize-SynchedEntityData-packDirty.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0263-Optimize-SynchedEntityData-packDirty.patch rename to leaf-server/minecraft-patches/features/0265-Optimize-SynchedEntityData-packDirty.patch diff --git a/leaf-server/minecraft-patches/features/0264-Optimize-isEyeInFluid.patch b/leaf-server/minecraft-patches/features/0266-Optimize-isEyeInFluid.patch similarity index 97% rename from leaf-server/minecraft-patches/features/0264-Optimize-isEyeInFluid.patch rename to leaf-server/minecraft-patches/features/0266-Optimize-isEyeInFluid.patch index 9e99f5de..3ea7cb1f 100644 --- a/leaf-server/minecraft-patches/features/0264-Optimize-isEyeInFluid.patch +++ b/leaf-server/minecraft-patches/features/0266-Optimize-isEyeInFluid.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Optimize isEyeInFluid diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 1b4aae603e965ae15d9b7e204a2ac5d31d045db0..ffb23578d5d7a2a821427dae9bab343ec3c45036 100644 +index d09a32288398d3ffa0fa6e9c6fd06f953b33688f..c377aef03861f2d860a7c6273f634248a6963f01 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -269,6 +269,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/leaf-server/minecraft-patches/features/0265-Paw-optimization.patch b/leaf-server/minecraft-patches/features/0267-Paw-optimization.patch similarity index 95% rename from leaf-server/minecraft-patches/features/0265-Paw-optimization.patch rename to leaf-server/minecraft-patches/features/0267-Paw-optimization.patch index 8ae61256..589b1c74 100644 --- a/leaf-server/minecraft-patches/features/0265-Paw-optimization.patch +++ b/leaf-server/minecraft-patches/features/0267-Paw-optimization.patch @@ -77,7 +77,7 @@ index 4535858701b2bb232b9d2feb2af6551526232ddc..e65c62dbe4c1560ae153e4c4344e9194 - // Paper end - detailed watchdog information } diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java -index 0f9d18dd29e210ad656da211a3cb1cb25cd4efb1..d1c36cd17c83e7e0167046093c4a2b8427c8bae0 100644 +index b3acfc7e00797ea16cc2c1793452f3ed97b9c61a..17c1b05f520145b84e90fc359dca4523191f08cd 100644 --- a/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java @@ -622,8 +622,10 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @@ -94,10 +94,10 @@ index 0f9d18dd29e210ad656da211a3cb1cb25cd4efb1..d1c36cd17c83e7e0167046093c4a2b84 for (LevelChunk levelChunk : list) { diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index e0fdf7205ff1dfab2c5cccd3d18c2b22deda686a..9df599e94e17da12a880df2f40a2117c5ec2a569 100644 +index c0044f4013520fd617ec365012b10862571744f3..14d23006d3ec15bb3ec6f976bff6c0975662c69d 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -1373,13 +1373,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1518,13 +1518,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // Paper end - log detailed entity tick information public void tickNonPassenger(Entity entity) { @@ -111,7 +111,7 @@ index e0fdf7205ff1dfab2c5cccd3d18c2b22deda686a..9df599e94e17da12a880df2f40a2117c entity.setOldPosAndRot(); entity.tickCount++; entity.totalEntityAge++; // Paper - age-like counter for all entities -@@ -1392,13 +1386,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1537,13 +1531,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe for (Entity entity1 : entity.getPassengers()) { this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2 } @@ -126,7 +126,7 @@ index e0fdf7205ff1dfab2c5cccd3d18c2b22deda686a..9df599e94e17da12a880df2f40a2117c private void tickPassenger(Entity ridingEntity, Entity passengerEntity, final boolean isActive) { // Paper - EAR 2 diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index ffb23578d5d7a2a821427dae9bab343ec3c45036..95a15fa08a5bd2bb799a125e03844259038ef290 100644 +index c377aef03861f2d860a7c6273f634248a6963f01..192d65bdc9fc9ae96d460e9b0832c20a209d2b0d 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -1140,16 +1140,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -177,7 +177,7 @@ index ffb23578d5d7a2a821427dae9bab343ec3c45036..95a15fa08a5bd2bb799a125e03844259 } private void applyMovementEmissionAndPlaySound(Entity.MovementEmission movementEmission, Vec3 movement, BlockPos pos, BlockState state) { -@@ -4831,9 +4805,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4858,9 +4832,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public void setDeltaMovement(Vec3 deltaMovement) { @@ -187,7 +187,7 @@ index ffb23578d5d7a2a821427dae9bab343ec3c45036..95a15fa08a5bd2bb799a125e03844259 } public void addDeltaMovement(Vec3 addend) { -@@ -4941,9 +4913,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4968,9 +4940,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } // Paper end - Fix MC-4 if (this.position.x != x || this.position.y != y || this.position.z != z) { diff --git a/leaf-server/minecraft-patches/features/0266-Cache-block-path-type.patch b/leaf-server/minecraft-patches/features/0268-Cache-block-path-type.patch similarity index 97% rename from leaf-server/minecraft-patches/features/0266-Cache-block-path-type.patch rename to leaf-server/minecraft-patches/features/0268-Cache-block-path-type.patch index dda3b28e..1b81ee5a 100644 --- a/leaf-server/minecraft-patches/features/0266-Cache-block-path-type.patch +++ b/leaf-server/minecraft-patches/features/0268-Cache-block-path-type.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Cache block path type diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java -index 595284787053a5fb7385e8493953c73a19fe7aee..6dec45b376288638433f0d50e474f9713266d99c 100644 +index 8192031ab3d947bb67eb00eec0a95ea99dce47ad..6400f2b68a818e771b3b27724dede7f15562b2c0 100644 --- a/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java -@@ -360,6 +360,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -365,6 +365,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface } if (org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled) mobSpawnExecutor.start(); // Pufferfish diff --git a/leaf-server/minecraft-patches/features/0267-optimize-getEntityStatus.patch b/leaf-server/minecraft-patches/features/0269-optimize-getEntityStatus.patch similarity index 96% rename from leaf-server/minecraft-patches/features/0267-optimize-getEntityStatus.patch rename to leaf-server/minecraft-patches/features/0269-optimize-getEntityStatus.patch index 997bec81..182fd1ce 100644 --- a/leaf-server/minecraft-patches/features/0267-optimize-getEntityStatus.patch +++ b/leaf-server/minecraft-patches/features/0269-optimize-getEntityStatus.patch @@ -42,7 +42,7 @@ index 2d24d03bbdb5ee0d862cbfff2219f58afffafe12..11f4f2f3bc4c9f9f6a1f83b90f3de34c protected boolean addEntity(final Entity entity, final boolean fromDisk, final boolean event) { diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 95a15fa08a5bd2bb799a125e03844259038ef290..905ffdc8d9188c40dc86216c651e22dcbd14dc95 100644 +index 192d65bdc9fc9ae96d460e9b0832c20a209d2b0d..7961d8ff4fc13ca5274f6667181da5ce557ddc0f 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -370,6 +370,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/leaf-server/minecraft-patches/features/0268-Paper-Rewrite-dataconverter-system.patch b/leaf-server/minecraft-patches/features/0270-Paper-Rewrite-dataconverter-system.patch similarity index 99% rename from leaf-server/minecraft-patches/features/0268-Paper-Rewrite-dataconverter-system.patch rename to leaf-server/minecraft-patches/features/0270-Paper-Rewrite-dataconverter-system.patch index 120b807a..2ea6cf23 100644 --- a/leaf-server/minecraft-patches/features/0268-Paper-Rewrite-dataconverter-system.patch +++ b/leaf-server/minecraft-patches/features/0270-Paper-Rewrite-dataconverter-system.patch @@ -32327,10 +32327,10 @@ index 175647d57e59e838ea7b4680fbf22c161100c513..a7b772cfc89161414469cd7da374d6c7 return structureTemplate.save(new CompoundTag()); } diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 2ca484a6c3e75fd392ca953737bb548ab10f2121..1540b1a571c8f44c4163f4720a9279f87a8032c9 100644 +index 84b90f496e5ab59d43503301fe935627af123e3f..54e31a239d6563abe56435ee8de03e55548ead29 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -293,6 +293,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function threadFunction) { diff --git a/leaf-server/minecraft-patches/features/0269-Rail-Optimization-optimized-PoweredRailBlock-logic.patch b/leaf-server/minecraft-patches/features/0271-Rail-Optimization-optimized-PoweredRailBlock-logic.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0269-Rail-Optimization-optimized-PoweredRailBlock-logic.patch rename to leaf-server/minecraft-patches/features/0271-Rail-Optimization-optimized-PoweredRailBlock-logic.patch diff --git a/leaf-archived-patches/unapplied/server/paper-patches/features/0030-SparklyPaper-Parallel-world-ticking.patch b/leaf-server/paper-patches/features/0051-SparklyPaper-Parallel-world-ticking.patch similarity index 88% rename from leaf-archived-patches/unapplied/server/paper-patches/features/0030-SparklyPaper-Parallel-world-ticking.patch rename to leaf-server/paper-patches/features/0051-SparklyPaper-Parallel-world-ticking.patch index 32ce99bb..b2c7f2af 100644 --- a/leaf-archived-patches/unapplied/server/paper-patches/features/0030-SparklyPaper-Parallel-world-ticking.patch +++ b/leaf-server/paper-patches/features/0051-SparklyPaper-Parallel-world-ticking.patch @@ -6,7 +6,7 @@ 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..2fb65ce228da94eb7d9364ee0f94582300178f1d 100644 +index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..e1bf7dfdb3be8f92ef2cb86d7f15a613b4ccadff 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java @@ -14,6 +14,7 @@ import java.util.concurrent.atomic.AtomicInteger; @@ -17,75 +17,88 @@ index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..2fb65ce228da94eb7d9364ee0f945823 private static String getThreadContext() { return "thread=" + Thread.currentThread().getName(); -@@ -26,14 +27,14 @@ public class TickThread extends Thread { +@@ -26,6 +27,7 @@ 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) // SparklyPaper - parallel world ticking + throw new IllegalStateException(reason); } } - +@@ -33,8 +35,9 @@ public class TickThread extends Thread { public static void ensureTickThread(final Level world, final BlockPos pos, final String reason) { 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()); // SparklyPaper - parallel world ticking LOGGER.error(ex, new Throwable()); ++ if (HARD_THROW) // SparklyPaper - parallel world ticking throw new IllegalStateException(ex); } -@@ -42,7 +43,7 @@ public class TickThread extends Thread { + } +@@ -42,8 +45,9 @@ 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()); // SparklyPaper - parallel world ticking LOGGER.error(ex, new Throwable()); ++ if (HARD_THROW) // SparklyPaper - parallel world ticking throw new IllegalStateException(ex); } -@@ -51,7 +52,7 @@ public class TickThread extends Thread { + } +@@ -51,8 +55,9 @@ 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()); // SparklyPaper - parallel world ticking LOGGER.error(ex, new Throwable()); ++ if (HARD_THROW) // SparklyPaper - parallel world ticking throw new IllegalStateException(ex); } -@@ -60,7 +61,7 @@ public class TickThread extends Thread { + } +@@ -60,8 +65,9 @@ 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()); // SparklyPaper - parallel world ticking LOGGER.error(ex, new Throwable()); ++ if (HARD_THROW) // SparklyPaper - parallel world ticking throw new IllegalStateException(ex); } -@@ -69,7 +70,7 @@ public class TickThread extends Thread { + } +@@ -69,8 +75,9 @@ 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()); // SparklyPaper - parallel world ticking LOGGER.error(ex, new Throwable()); ++ if (HARD_THROW) // SparklyPaper - parallel world ticking throw new IllegalStateException(ex); } -@@ -78,7 +79,7 @@ public class TickThread extends Thread { + } +@@ -78,8 +85,9 @@ 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()); // SparklyPaper - parallel world ticking LOGGER.error(ex, new Throwable()); ++ if (HARD_THROW) // SparklyPaper - parallel world ticking throw new IllegalStateException(ex); } -@@ -87,12 +88,70 @@ public class TickThread extends Thread { + } +@@ -87,12 +95,71 @@ 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()); // SparklyPaper - parallel world ticking LOGGER.error(ex, new Throwable()); ++ if (HARD_THROW) // SparklyPaper - parallel world ticking throw new IllegalStateException(ex); } } @@ -151,7 +164,7 @@ index a4aa2615823d77920ff55b8aa0bcc27a54b8c3e1..2fb65ce228da94eb7d9364ee0f945823 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 +192,74 @@ public class TickThread extends Thread { +@@ -133,46 +200,74 @@ public class TickThread extends Thread { } public static boolean isTickThreadFor(final Level world, final BlockPos pos) { @@ -255,10 +268,10 @@ index 548fcd9646dee0c40b6ba9b3dafb9ca157dfe324..d7af94890bfccd6ff665d920cecfa1e5 } 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 af33cab59932f4ec135caf94dc5828930833daf6..caa92e48d031cb54950e6613a82f407d7ed2455a 100644 +index 0d2cfaef1413a343bc03829730453b03f903d5ce..bf87e5dcda7deb8f9c36a3f6b64285a97e48477f 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -455,7 +455,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -456,7 +456,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { } private boolean unloadChunk0(int x, int z, boolean save) { @@ -272,7 +285,7 @@ index af33cab59932f4ec135caf94dc5828930833daf6..caa92e48d031cb54950e6613a82f407d if (!this.isChunkLoaded(x, z)) { return true; } -@@ -472,6 +477,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -473,6 +478,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean refreshChunk(int x, int z) { @@ -281,7 +294,7 @@ index af33cab59932f4ec135caf94dc5828930833daf6..caa92e48d031cb54950e6613a82f407d ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z)); if (playerChunk == null) return false; -@@ -522,7 +529,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -523,7 +530,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean loadChunk(int x, int z, boolean generate) { @@ -295,7 +308,7 @@ index af33cab59932f4ec135caf94dc5828930833daf6..caa92e48d031cb54950e6613a82f407d 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 +762,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -751,6 +763,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) { @@ -304,7 +317,7 @@ index af33cab59932f4ec135caf94dc5828930833daf6..caa92e48d031cb54950e6613a82f407d this.world.captureTreeGeneration = true; this.world.captureBlockStates = true; boolean grownTree = this.generateTree(loc, type); -@@ -865,6 +879,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -866,6 +880,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 configurator) { // Paper end - expand explosion API @@ -313,7 +326,7 @@ index af33cab59932f4ec135caf94dc5828930833daf6..caa92e48d031cb54950e6613a82f407d net.minecraft.world.level.Level.ExplosionInteraction explosionType; if (!breakBlocks) { explosionType = net.minecraft.world.level.Level.ExplosionInteraction.NONE; // Don't break blocks -@@ -986,6 +1002,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -987,6 +1003,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setBiome(int x, int y, int z, Holder bb) { BlockPos pos = new BlockPos(x, 0, z); @@ -322,7 +335,7 @@ index af33cab59932f4ec135caf94dc5828930833daf6..caa92e48d031cb54950e6613a82f407d if (this.world.hasChunkAt(pos)) { net.minecraft.world.level.chunk.LevelChunk chunk = this.world.getChunkAt(pos); -@@ -2328,6 +2346,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2334,6 +2352,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void sendGameEvent(Entity sourceEntity, org.bukkit.GameEvent gameEvent, Vector position) { @@ -332,10 +345,10 @@ index af33cab59932f4ec135caf94dc5828930833daf6..caa92e48d031cb54950e6613a82f407d } // 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 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911c39f80c0 100644 +index b00a82816784ea2f6422ca98c1f11597105cc177..04c8902bcf8d19e59c57ac013a33b0a2fb1190da 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -@@ -74,13 +74,98 @@ public class CraftBlock implements Block { +@@ -74,12 +74,97 @@ public class CraftBlock implements Block { return new CraftBlock(world, position); } @@ -383,7 +396,7 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 + } catch (java.util.concurrent.CompletionException e) { + // Leaf start - SparklyPaper - parallel world ticking - Shutdown handling for async reads + if (e.getCause() instanceof IllegalStateException && e.getCause().getMessage() != null && e.getCause().getMessage().contains("shutting down")) { -+ org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "PWT: Async block read for " + methodName + " cancelled due to world shutdown: " + e.getCause().getMessage()); ++ org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "PWT: Async block read for " + methodName + " cancelled due to world shutdown: " + e.getCause().getMessage()); + } else { + org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "PWT: Async block read failed for " + methodName + " on tick thread.", e.getCause() != null ? e.getCause() : e); + } @@ -418,7 +431,6 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 + // Leaf end - SparklyPaper - parallel world ticking } - // Paper start public net.minecraft.world.level.material.FluidState getNMSFluid() { - return this.world.getFluidState(this.position); + // Leaf start - SparklyPaper - parallel world ticking @@ -434,42 +446,42 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 + } + // Leaf end - SparklyPaper - parallel world ticking } - // Paper end -@@ -144,10 +229,12 @@ public class CraftBlock implements Block { + public BlockPos getPosition() { +@@ -142,10 +227,12 @@ public class CraftBlock implements Block { return this.getWorld().getChunkAt(this); } + @Deprecated // Leaf - SparklyPaper - parallel world ticking - Magic value public void setData(final byte data) { - this.setData(data, 3); + this.setData(data, net.minecraft.world.level.block.Block.UPDATE_ALL); } + @Deprecated // Leaf - SparklyPaper - parallel world ticking - Magic value public void setData(final byte data, boolean applyPhysics) { if (applyPhysics) { - this.setData(data, 3); -@@ -157,12 +244,18 @@ public class CraftBlock implements Block { + this.setData(data, net.minecraft.world.level.block.Block.UPDATE_ALL); +@@ -155,12 +242,18 @@ public class CraftBlock implements Block { } - private void setData(final byte data, int flag) { + private void setData(final byte data, int flags) { + // 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), flag); + this.world.setBlock(this.position, CraftMagicNumbers.getBlock(this.getType(), data), flags); } @Override + @Deprecated // Leaf - SparklyPaper - parallel world ticking - Magic value public byte getData() { -- net.minecraft.world.level.block.state.BlockState blockData = this.world.getBlockState(this.position); -+ net.minecraft.world.level.block.state.BlockState blockData = this.getNMS(); // Leaf - SparklyPaper - parallel world ticking - return CraftMagicNumbers.toLegacyData(blockData); +- net.minecraft.world.level.block.state.BlockState state = this.world.getBlockState(this.position); ++ net.minecraft.world.level.block.state.BlockState state = this.getNMS(); // Leaf - SparklyPaper - parallel world ticking + return CraftMagicNumbers.toLegacyData(state); } -@@ -179,6 +272,7 @@ public class CraftBlock implements Block { +@@ -177,6 +270,7 @@ public class CraftBlock implements Block { @Override public void setType(Material type, boolean applyPhysics) { Preconditions.checkArgument(type != null, "Material cannot be null"); @@ -477,20 +489,19 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 this.setBlockData(type.createBlockData(), applyPhysics); } -@@ -198,6 +292,12 @@ public class CraftBlock implements Block { +@@ -196,6 +290,11 @@ public class CraftBlock implements Block { } - public static boolean setTypeAndData(LevelAccessor world, BlockPos position, net.minecraft.world.level.block.state.BlockState old, net.minecraft.world.level.block.state.BlockState blockData, boolean applyPhysics) { + public static boolean setBlockState(LevelAccessor world, BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState, 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, position, "Cannot modify world asynchronously"); ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, pos, "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 tile entity cleanup - if (old.hasBlockEntity() && blockData.getBlock() != old.getBlock()) { // SPIGOT-3725 remove old tile 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 block entity cleanup + if (oldState.hasBlockEntity() && newState.getBlock() != oldState.getBlock()) { // SPIGOT-3725 remove old block entity if block changes // SPIGOT-4612: faster - just clear tile -@@ -226,22 +326,62 @@ public class CraftBlock implements Block { +@@ -227,22 +326,62 @@ public class CraftBlock implements Block { @Override public Material getType() { @@ -557,12 +568,7 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 } public Block getFace(final BlockFace face) { -@@ -282,51 +422,37 @@ public class CraftBlock implements Block { - - @Override - public String toString() { -- return "CraftBlock{pos=" + this.position + ",type=" + this.getType() + ",data=" + this.getNMS() + ",fluid=" + this.world.getFluidState(this.position) + '}'; -+ return "CraftBlock{pos=" + this.position + ",type=" + this.getType() + ",data=" + this.getNMS() + ",fluid=" + this.getNMSFluid() + '}'; // Leaf - SparklyPaper - parallel world ticking +@@ -287,47 +426,32 @@ public class CraftBlock implements Block { } public static BlockFace notchToBlockFace(Direction notch) { @@ -594,7 +600,6 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 + case SOUTH -> BlockFace.SOUTH; + case WEST -> BlockFace.WEST; + case EAST -> BlockFace.EAST; -+ default -> BlockFace.SELF; + }; + // Leaf end - SparklyPaper - parallel world ticking - formatting } @@ -634,7 +639,7 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 } @Override -@@ -343,18 +469,65 @@ public class CraftBlock implements Block { +@@ -344,18 +468,65 @@ public class CraftBlock implements Block { @Override public Biome getBiome() { @@ -702,7 +707,7 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 this.getWorld().setBiome(this.getX(), this.getY(), this.getZ(), bio); } -@@ -370,12 +543,50 @@ public class CraftBlock implements Block { +@@ -371,12 +542,50 @@ public class CraftBlock implements Block { @Override public boolean isBlockPowered() { @@ -755,7 +760,7 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 } @Override -@@ -397,46 +608,102 @@ public class CraftBlock implements Block { +@@ -398,44 +607,103 @@ public class CraftBlock implements Block { @Override public boolean isBlockFacePowered(BlockFace face) { @@ -781,10 +786,6 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 @Override public boolean isBlockFaceIndirectlyPowered(BlockFace face) { - int power = this.world.getMinecraftWorld().getSignal(this.position, CraftBlock.blockFaceToNotch(face)); -- -- Block relative = this.getRelative(face); -- if (relative.getType() == Material.REDSTONE_WIRE) { -- return Math.max(power, relative.getData()) > 0; + // Leaf start - SparklyPaper - parallel world ticking + ServerLevel level = getServerLevel(); + String handlingMode = org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.asyncUnsafeReadHandling; @@ -805,9 +806,13 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 + return false; + } catch (Exception e) { + org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "PWT: Direct access failed for isBlockFaceIndirectlyPowered" + (level == null ? " (Not a ServerLevel)" : ""), e); + +- Block relative = this.getRelative(face); +- if (relative.getType() == Material.REDSTONE_WIRE) { +- return Math.max(power, relative.getData()) > 0; // todo remove legacy usage + return false; } -- + - return power > 0; + // Leaf end - SparklyPaper - parallel world ticking } @@ -829,24 +834,22 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 - return power > 0 ? power : (face == BlockFace.SELF ? this.isBlockIndirectlyPowered() : this.isBlockFaceIndirectlyPowered(face)) ? 15 : 0; - } - -- private static int getPower(int i, net.minecraft.world.level.block.state.BlockState iblockdata) { -- if (!iblockdata.is(Blocks.REDSTONE_WIRE)) { -- return i; +- private static int getPower(int power, net.minecraft.world.level.block.state.BlockState state) { +- if (!state.is(Blocks.REDSTONE_WIRE)) { +- return power; + ServerLevel level = getServerLevel(); + String handlingMode = org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.asyncUnsafeReadHandling; + + if (needsBuffering(level, handlingMode)) { + // Buffered path + return executeBufferedRead(level, org.dreeam.leaf.async.world.ReadOperationType.BLOCK_GET_BLOCK_POWER, new Object[]{this.position, face}, 0, "getBlockPower"); - } else { -- int j = iblockdata.getValue(RedStoneWireBlock.POWER); ++ } else { + // Strict/Disabled/Non-ServerLevel path + checkStrictMode(level, handlingMode, "getBlockPower"); + try { + // Requires Level for hasSignal and getBlockState + if (this.world instanceof net.minecraft.world.level.Level nmsLevel) { + int power = 0; -+ int x = this.getX(); int y = this.getY(); int z = this.getZ(); + BlockPos currentPos = this.position; // Use immutable position + + // Check neighbors using relative positions @@ -870,13 +873,13 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 + } + } + } - -- return j > i ? j : i; ++ + // Static helper, safe + public static int getPower(int currentMax, net.minecraft.world.level.block.state.BlockState neighborState) { + if (!neighborState.is(Blocks.REDSTONE_WIRE)) { + return currentMax; -+ } else { + } else { +- return Math.max(state.getValue(RedStoneWireBlock.POWER), power); + int neighborPower = neighborState.getValue(RedStoneWireBlock.POWER); + return Math.max(neighborPower, currentMax); } @@ -885,7 +888,7 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 @Override public int getBlockPower() { -@@ -479,105 +746,179 @@ public class CraftBlock implements Block { +@@ -478,106 +746,180 @@ public class CraftBlock implements Block { @Override public PistonMoveReaction getPistonMoveReaction() { @@ -939,20 +942,21 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 + } + + // Get NMS state safely - net.minecraft.world.level.block.state.BlockState iblockdata = this.getNMS(); - net.minecraft.world.level.block.Block block = iblockdata.getBlock(); ++ + net.minecraft.world.level.block.state.BlockState state = this.getNMS(); + net.minecraft.world.level.block.Block block = state.getBlock(); net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item); - boolean result = false; - -- // Modelled off EntityHuman#hasBlock -- if (block != Blocks.AIR && (item == null || !iblockdata.requiresCorrectToolForDrops() || nmsItem.isCorrectToolForDrops(iblockdata))) { -- net.minecraft.world.level.block.Block.dropResources(iblockdata, this.world.getMinecraftWorld(), this.position, this.world.getBlockEntity(this.position), null, nmsItem, false); // Paper - Properly handle xp dropping -- // Paper start - improve Block#breanNaturally +- // Modelled off Player#hasCorrectToolForDrops +- if (block != Blocks.AIR && (item == null || !state.requiresCorrectToolForDrops() || nmsItem.isCorrectToolForDrops(state))) { +- net.minecraft.world.level.block.Block.dropResources(state, this.world.getMinecraftWorld(), this.position, this.world.getBlockEntity(this.position), null, nmsItem, false); // Paper - Properly handle xp dropping +- // Paper start - improve Block#breakNaturally - if (triggerEffect) { -- if (iblockdata.getBlock() instanceof net.minecraft.world.level.block.BaseFireBlock) { +- if (state.getBlock() instanceof net.minecraft.world.level.block.BaseFireBlock) { - this.world.levelEvent(net.minecraft.world.level.block.LevelEvent.SOUND_EXTINGUISH_FIRE, this.position, 0); - } else { -- this.world.levelEvent(net.minecraft.world.level.block.LevelEvent.PARTICLES_DESTROY_BLOCK, this.position, net.minecraft.world.level.block.Block.getId(iblockdata)); +- this.world.levelEvent(net.minecraft.world.level.block.LevelEvent.PARTICLES_DESTROY_BLOCK, this.position, net.minecraft.world.level.block.Block.getId(state)); + boolean droppedItems = false; + + // Experience dropping requires ServerLevel @@ -960,73 +964,71 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 + + if (serverLevelForDrops != null) { // Only attempt drops/XP if we have a ServerLevel + // Check if block should drop items -+ if (!iblockdata.isAir() && (item == null || !iblockdata.requiresCorrectToolForDrops() || nmsItem.isCorrectToolForDrops(iblockdata))) { ++ if (!state.isAir() && (item == null || !state.requiresCorrectToolForDrops() || nmsItem.isCorrectToolForDrops(state))) { + // Drop items using ServerLevel -+ net.minecraft.world.level.block.Block.dropResources(iblockdata, serverLevelForDrops, this.position, this.world.getBlockEntity(this.position), null, nmsItem, false); ++ net.minecraft.world.level.block.Block.dropResources(state, serverLevelForDrops, this.position, this.world.getBlockEntity(this.position), null, nmsItem, false); + + // Trigger effect using LevelAccessor (safe) + if (triggerEffect) { -+ int eventId = (iblockdata.getBlock() instanceof net.minecraft.world.level.block.BaseFireBlock) ++ int eventId = (state.getBlock() instanceof net.minecraft.world.level.block.BaseFireBlock) + ? net.minecraft.world.level.block.LevelEvent.SOUND_EXTINGUISH_FIRE + : net.minecraft.world.level.block.LevelEvent.PARTICLES_DESTROY_BLOCK; + int eventData = (eventId == net.minecraft.world.level.block.LevelEvent.PARTICLES_DESTROY_BLOCK) -+ ? net.minecraft.world.level.block.Block.getId(iblockdata) : 0; ++ ? net.minecraft.world.level.block.Block.getId(state) : 0; + this.world.levelEvent(eventId, this.position, eventData); - } ++ } + // Drop experience using ServerLevel + if (dropExperience) { -+ int xp = block.getExpDrop(iblockdata, serverLevelForDrops, this.position, nmsItem, true); ++ int xp = block.getExpDrop(state, serverLevelForDrops, this.position, nmsItem, true); + if (xp > 0) { // Only pop if there's XP to drop + block.popExperience(serverLevelForDrops, this.position, xp); + } -+ } + } + droppedItems = true; + } + } else { + // Log if we couldn't drop XP because it wasn't a ServerLevel -+ if (dropExperience && !iblockdata.isAir()) { // Only warn if XP was requested and block wasn't air ++ if (dropExperience && !state.isAir()) { // Only warn if XP was requested and block wasn't air + org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "PWT: Cannot drop experience for breakNaturally: Not a ServerLevel."); + } + // Still trigger effects if requested and possible with LevelAccessor -+ if (triggerEffect && !iblockdata.isAir()) { -+ int eventId = (iblockdata.getBlock() instanceof net.minecraft.world.level.block.BaseFireBlock) ++ if (triggerEffect && !state.isAir()) { ++ int eventId = (state.getBlock() instanceof net.minecraft.world.level.block.BaseFireBlock) + ? net.minecraft.world.level.block.LevelEvent.SOUND_EXTINGUISH_FIRE + : net.minecraft.world.level.block.LevelEvent.PARTICLES_DESTROY_BLOCK; + int eventData = (eventId == net.minecraft.world.level.block.LevelEvent.PARTICLES_DESTROY_BLOCK) -+ ? net.minecraft.world.level.block.Block.getId(iblockdata) : 0; ++ ? net.minecraft.world.level.block.Block.getId(state) : 0; + this.world.levelEvent(eventId, this.position, eventData); } -- if (dropExperience) block.popExperience(this.world.getMinecraftWorld(), this.position, block.getExpDrop(iblockdata, this.world.getMinecraftWorld(), this.position, nmsItem, true)); +- if (dropExperience) block.popExperience(this.world.getMinecraftWorld(), this.position, block.getExpDrop(state, this.world.getMinecraftWorld(), this.position, nmsItem, true)); - // Paper end - result = true; } -- // SPIGOT-6778: Directly call setBlock instead of setTypeAndData, so that the tile entiy is not removed and custom remove logic is run. +- // SPIGOT-6778: Directly call setBlock instead of setBlockState, so that the block entity is not removed and custom remove logic is run. - // Paper start - improve breakNaturally + // Remove the block using LevelAccessor (safe) boolean destroyed = this.world.removeBlock(this.position, false); if (destroyed) { + // Call destroy hook using LevelAccessor (safe) - block.destroy(this.world, this.position, iblockdata); + block.destroy(this.world, this.position, state); } - if (result) { - // special cases -+ + // Special case handling - requires Level, check again + if (droppedItems && this.world instanceof net.minecraft.world.level.Level nmsLevelForSpecialCases) { if (block instanceof net.minecraft.world.level.block.IceBlock iceBlock) { - iceBlock.afterDestroy(this.world.getMinecraftWorld(), this.position, nmsItem); + iceBlock.afterDestroy(nmsLevelForSpecialCases, this.position, nmsItem); } else if (block instanceof net.minecraft.world.level.block.TurtleEggBlock turtleEggBlock) { -- turtleEggBlock.decreaseEggs(this.world.getMinecraftWorld(), this.position, iblockdata); -+ turtleEggBlock.decreaseEggs(nmsLevelForSpecialCases, this.position, iblockdata); +- turtleEggBlock.decreaseEggs(this.world.getMinecraftWorld(), this.position, state); ++ turtleEggBlock.decreaseEggs(nmsLevelForSpecialCases, this.position, state); } + } else if (droppedItems) { // Log if special cases couldn't run + org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "PWT: Cannot perform post-break special actions: Not a Level."); } - return destroyed && result; - // Paper end -+ + // Return true if the block was successfully destroyed AND items were dropped (or would have dropped if tool was right) + return destroyed && droppedItems; + // Leaf end - SparklyPaper - parallel world ticking - Write operation check @@ -1056,20 +1058,20 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 - UseOnContext context = new UseOnContext(world, null, InteractionHand.MAIN_HAND, Items.BONE_MEAL.getDefaultInstance(), new BlockHitResult(Vec3.ZERO, direction, this.getPosition(), false)); + UseOnContext context = new UseOnContext(level, null, InteractionHand.MAIN_HAND, Items.BONE_MEAL.getDefaultInstance(), new BlockHitResult(Vec3.ZERO, direction, this.getPosition(), false)); -- // SPIGOT-6895: Call StructureGrowEvent and BlockFertilizeEvent + // SPIGOT-6895: Call StructureGrowEvent and BlockFertilizeEvent - world.captureTreeGeneration = true; + level.captureTreeGeneration = true; InteractionResult result = BoneMealItem.applyBonemeal(context); - world.captureTreeGeneration = false; - -- if (world.capturedBlockStates.size() > 0) { +- if (!world.capturedBlockStates.isEmpty()) { - TreeType treeType = SaplingBlock.treeType; - SaplingBlock.treeType = null; -- List blocks = new ArrayList<>(world.capturedBlockStates.values()); +- List states = new ArrayList<>(world.capturedBlockStates.values()); - world.capturedBlockStates.clear(); + level.captureTreeGeneration = false; + -+ if (level.capturedBlockStates.size() > 0) { ++ if (level.capturedBlockStates.isEmpty()) { + TreeType treeType = SaplingBlock.getTreeTypeRT(); // Use thread-local getter + SaplingBlock.setTreeTypeRT(null); // Use thread-local setter + // Need Bukkit BlockState list for events @@ -1078,24 +1080,25 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 StructureGrowEvent structureEvent = null; if (treeType != null) { -- structureEvent = new StructureGrowEvent(this.getLocation(), treeType, true, null, blocks); +- structureEvent = new StructureGrowEvent(this.getLocation(), treeType, true, null, states); + structureEvent = new StructureGrowEvent(this.getLocation(), treeType, true, null, bukkitStates); Bukkit.getPluginManager().callEvent(structureEvent); } -- event = new BlockFertilizeEvent(CraftBlock.at(world, this.getPosition()), null, blocks); +- event = new BlockFertilizeEvent(CraftBlock.at(world, this.getPosition()), null, states); + event = new BlockFertilizeEvent(this, null, bukkitStates); // Use 'this' as the CraftBlock event.setCancelled(structureEvent != null && structureEvent.isCancelled()); Bukkit.getPluginManager().callEvent(event); if (!event.isCancelled()) { -- for (BlockState blockstate : blocks) { -- blockstate.update(true); -- world.checkCapturedTreeStateForObserverNotify(this.position, (org.bukkit.craftbukkit.block.CraftBlockState) blockstate); // Paper - notify observers even if grow failed -+ for (org.bukkit.block.BlockState blockstate : bukkitStates) { -+ blockstate.update(true); // This performs the actual block changes +- for (BlockState state : states) { ++ for (BlockState state : bukkitStates) { + CraftBlockState craftBlockState = (CraftBlockState) state; +- craftBlockState.place(craftBlockState.getFlags()); +- world.checkCapturedTreeStateForObserverNotify(this.position, craftBlockState); // Paper - notify observers even if grow failed ++ craftBlockState.place(craftBlockState.getFlags()); // This performs the actual block changes + // Notify observers using the captured state info -+ level.checkCapturedTreeStateForObserverNotify(this.position, (org.bukkit.craftbukkit.block.CraftBlockState) blockstate); ++ level.checkCapturedTreeStateForObserverNotify(this.position, craftBlockState); } } } @@ -1106,11 +1109,11 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 } @Override -@@ -592,31 +933,70 @@ public class CraftBlock implements Block { +@@ -592,31 +934,70 @@ public class CraftBlock implements Block { @Override public Collection getDrops(ItemStack item, Entity entity) { -- net.minecraft.world.level.block.state.BlockState iblockdata = this.getNMS(); +- net.minecraft.world.level.block.state.BlockState state = this.getNMS(); - net.minecraft.world.item.ItemStack nms = CraftItemStack.asNMSCopy(item); + // Leaf start - SparklyPaper - parallel world ticking - Write operation check + // Requires ServerLevel for Block.getDrops call @@ -1120,9 +1123,9 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 + return Collections.emptyList(); + } -- // Modelled off EntityHuman#hasBlock -- if (item == null || CraftBlockData.isPreferredTool(iblockdata, nms)) { -- return net.minecraft.world.level.block.Block.getDrops(iblockdata, (ServerLevel) this.world.getMinecraftWorld(), this.position, this.world.getBlockEntity(this.position), entity == null ? null : ((CraftEntity) entity).getHandle(), nms) +- // Modelled off Player#hasCorrectToolForDrops +- if (item == null || CraftBlockData.isPreferredTool(state, nms)) { +- return net.minecraft.world.level.block.Block.getDrops(state, this.world.getMinecraftWorld(), this.position, this.world.getBlockEntity(this.position), entity == null ? null : ((CraftEntity) entity).getHandle(), nms) - .stream().map(CraftItemStack::asBukkitCopy).collect(Collectors.toList()); - } else { + // Strict check if applicable @@ -1130,15 +1133,15 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 + checkStrictMode(level, handlingMode, "getDrops"); + + try { -+ net.minecraft.world.level.block.state.BlockState iblockdata = this.getNMS(); // Use safe getNMS ++ net.minecraft.world.level.block.state.BlockState state = this.getNMS(); // Use safe getNMS + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + net.minecraft.world.entity.Entity nmsEntity = (entity == null) ? null : ((CraftEntity) entity).getHandle(); + + // Check tool requirement -+ if (item == null || !iblockdata.requiresCorrectToolForDrops() || nmsItem.isCorrectToolForDrops(iblockdata)) { ++ if (item == null || !state.requiresCorrectToolForDrops() || nmsItem.isCorrectToolForDrops(state)) { + // Call NMS getDrops using the verified ServerLevel + List nmsDrops = net.minecraft.world.level.block.Block.getDrops( -+ iblockdata, level, this.position, this.world.getBlockEntity(this.position), nmsEntity, nmsItem ++ state, level, this.position, this.world.getBlockEntity(this.position), nmsEntity, nmsItem + ); + // Convert to Bukkit ItemStacks + return nmsDrops.stream().map(CraftItemStack::asBukkitCopy).collect(Collectors.toList()); @@ -1156,11 +1159,11 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 @Override public boolean isPreferredTool(ItemStack item) { + // Leaf - SparklyPaper - parallel world ticking - Uses safe getNMS() - net.minecraft.world.level.block.state.BlockState iblockdata = this.getNMS(); + net.minecraft.world.level.block.state.BlockState state = this.getNMS(); - net.minecraft.world.item.ItemStack nms = CraftItemStack.asNMSCopy(item); -- return CraftBlockData.isPreferredTool(iblockdata, nms); +- return CraftBlockData.isPreferredTool(state, nms); + net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item); -+ return iblockdata.requiresCorrectToolForDrops() && nmsItem.isCorrectToolForDrops(iblockdata); // Leaf - SparklyPaper - parallel world ticking - Delegate to helper which checks tool tags ++ return state.requiresCorrectToolForDrops() && nmsItem.isCorrectToolForDrops(state); // Leaf - SparklyPaper - parallel world ticking - Delegate to helper which checks tool tags } @Override @@ -1187,7 +1190,7 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 @Override public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { this.getCraftWorld().getBlockMetadata().setMetadata(this, metadataKey, newMetadataValue); -@@ -639,57 +1019,147 @@ public class CraftBlock implements Block { +@@ -639,57 +1020,148 @@ public class CraftBlock implements Block { @Override public boolean isPassable() { @@ -1229,7 +1232,7 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 - } - - Vector dir = direction.clone().normalize().multiply(maxDistance); -- Vec3 startPos = CraftLocation.toVec3D(start); +- Vec3 startPos = CraftLocation.toVec3(start); - Vec3 endPos = startPos.add(dir.getX(), dir.getY(), dir.getZ()); + if (maxDistance < 0.0D) return null; // Max distance must be non-negative + @@ -1244,27 +1247,27 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 + null, "rayTrace" + ); + // Convert NMS result (can be null) to Bukkit result -+ return CraftRayTraceResult.fromNMS(this.getWorld(), nmsHitResult); ++ return CraftRayTraceResult.convertFromInternal(this.world, nmsHitResult); + } else { + // Strict/Disabled/Non-ServerLevel path + checkStrictMode(level, handlingMode, "rayTrace"); + try { + // Calculate start and end points for the ray trace -+ Vec3 startPos = CraftLocation.toVec3D(start); ++ Vec3 startPos = CraftLocation.toVec3(start); + Vector dirNormalized = direction.clone().normalize(); // Normalize once + Vec3 endPos = startPos.add(dirNormalized.getX() * maxDistance, dirNormalized.getY() * maxDistance, dirNormalized.getZ() * maxDistance); + + // Perform the clip using LevelAccessor (safe) + // Pass the block's position as the context position for the clip function + HitResult nmsHitResult = this.world.clip( -+ new ClipContext(startPos, endPos, ClipContext.Block.OUTLINE, CraftFluidCollisionMode.toNMS(fluidCollisionMode), CollisionContext.empty()), ++ new ClipContext(startPos, endPos, ClipContext.Block.OUTLINE, CraftFluidCollisionMode.toFluid(fluidCollisionMode), CollisionContext.empty()), + this.position // Provide the block's position here + ); -- HitResult nmsHitResult = this.world.clip(new ClipContext(startPos, endPos, ClipContext.Block.OUTLINE, CraftFluidCollisionMode.toNMS(fluidCollisionMode), CollisionContext.empty()), this.position); -- return CraftRayTraceResult.fromNMS(this.getWorld(), nmsHitResult); +- HitResult hitResult = this.world.clip(new ClipContext(startPos, endPos, ClipContext.Block.OUTLINE, CraftFluidCollisionMode.toFluid(fluidCollisionMode), CollisionContext.empty()), this.position); +- return CraftRayTraceResult.convertFromInternal(this.world, hitResult); + // Convert NMS result to Bukkit result -+ return CraftRayTraceResult.fromNMS(this.getWorld(), nmsHitResult); ++ return CraftRayTraceResult.convertFromInternal(this.world, nmsHitResult); + } catch (Exception e) { + org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "PWT: Direct access failed for rayTrace" + (level == null ? " (Not a ServerLevel)" : ""), e); + return null; // Return null on error @@ -1303,7 +1306,7 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 + // Default to a full 1x1x1 box on error + return new BoundingBox(getX(), getY(), getZ(), getX() + 1, getY() + 1, getZ() + 1); } -- + - AABB aabb = shape.bounds(); - return new BoundingBox(this.getX() + aabb.minX, this.getY() + aabb.minY, this.getZ() + aabb.minZ, this.getX() + aabb.maxX, this.getY() + aabb.maxY, this.getZ() + aabb.maxZ); + // Leaf end - SparklyPaper - parallel world ticking @@ -1359,7 +1362,7 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 } @Override -@@ -700,7 +1170,10 @@ public class CraftBlock implements Block { +@@ -705,7 +1177,10 @@ public class CraftBlock implements Block { // Paper start @Override public com.destroystokyo.paper.block.BlockSoundGroup getSoundGroup() { @@ -1371,7 +1374,7 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 } @Override -@@ -713,26 +1186,76 @@ public class CraftBlock implements Block { +@@ -718,26 +1193,76 @@ public class CraftBlock implements Block { return this.getNMS().getBlock().getDescriptionId(); } @@ -1453,7 +1456,7 @@ index 811823a1a7e24a19a7e37eb4c08efdfa19e839ed..ac45c5cbe547705e3e341011740cf911 // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java -index 768d3f93da2522d467183654260a8bd8653588b1..5cef786fa2e5dfd3e7b79918bc73af02891b0bea 100644 +index 3422970353dcd886934b9ee906467769d39abbde..13c91223bbb4841cab0e491037a36113a33faf15 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 extends Craft @@ -1482,8 +1485,8 @@ index 768d3f93da2522d467183654260a8bd8653588b1..5cef786fa2e5dfd3e7b79918bc73af02 + } + // Leaf end - SparklyPaper - parallel world ticking mod - public CraftBlockEntityState(World world, T tileEntity) { - super(world, tileEntity.getBlockPos(), tileEntity.getBlockState()); + public CraftBlockEntityState(World world, T blockEntity) { + super(world, blockEntity.getBlockPos(), blockEntity.getBlockState()); @@ -34,8 +55,8 @@ public abstract class CraftBlockEntityState extends Craft try { // Paper - Show blockstate location if we failed to read it @@ -1492,14 +1495,14 @@ index 768d3f93da2522d467183654260a8bd8653588b1..5cef786fa2e5dfd3e7b79918bc73af02 - 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.tileEntity; + this.snapshot = this.blockEntity; } else { - this.snapshot = this.createSnapshot(tileEntity); + this.snapshot = this.createSnapshot(blockEntity); diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java -index fa63a6cfcfcc4eee4503a82d85333c139c8c8b2b..d106f65e4b745242484a195958fc559268a7dee0 100644 +index 196835bdf95ba0e149b2977e9ef41698971f501f..eb7e63d4549e672ff1206055d2d754395f189a4a 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java -@@ -215,6 +215,12 @@ public class CraftBlockState implements BlockState { +@@ -218,6 +218,12 @@ public class CraftBlockState implements BlockState { LevelAccessor access = this.getWorldHandle(); CraftBlock block = this.getBlock(); @@ -1512,7 +1515,7 @@ index fa63a6cfcfcc4eee4503a82d85333c139c8c8b2b..d106f65e4b745242484a195958fc5592 if (block.getType() != this.getType()) { if (!force) { return false; -@@ -350,6 +356,8 @@ public class CraftBlockState implements BlockState { +@@ -365,6 +371,8 @@ public class CraftBlockState implements BlockState { @Override public java.util.Collection getDrops(org.bukkit.inventory.ItemStack item, org.bukkit.entity.Entity entity) { @@ -1522,37 +1525,35 @@ index fa63a6cfcfcc4eee4503a82d85333c139c8c8b2b..d106f65e4b745242484a195958fc5592 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..08a06c23c831a4de45b3e537228b837911019da8 100644 +index 321280d7c9c3c828cbf2eb19d2fd196a1f84d4c3..cd8f771e08cee5d00c53a8e70f0fe37cf393cd52 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 { - net.minecraft.world.level.block.state.BlockState blockData = craftBlock.getNMS(); - BlockEntity tileEntity = craftBlock.getHandle().getBlockEntity(blockPosition); - // Paper start - block state snapshots +@@ -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); - 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 { - // Paper end - CraftBlockState blockState = CraftBlockStates.getBlockState(world, blockPosition, blockData, tileEntity); -@@ -258,7 +258,7 @@ public final class CraftBlockStates { - return blockState; - // Paper start + CraftBlockState blockState = CraftBlockStates.getBlockState(world, pos, state, blockEntity); + blockState.setWorldHandle(craftBlock.getHandle()); // Inject the block's generator access + return blockState; } 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 c2552c3706831f7012b5b449fa43c7d5990056a4..4e8a1d01a6c0afef92ae56cc4909af06d63e5268 100644 ---- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -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. +diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +index fec0f3b72c1808c5019e95760e3fef19c45e1be0..d0991574d3c8c826e31b4448bbe6a6c79c16c91d 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 { + } + + 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 final ThreadLocal sourceBlockOverrideRT = new ThreadLocal<>(); // SparklyPaper - parallel world ticking (this is from Folia, fixes concurrency bugs with sculk catalysts) + + // Leaf start - SparklyPaper - parallel world ticking mod @@ -1576,29 +1577,20 @@ index c2552c3706831f7012b5b449fa43c7d5990056a4..4e8a1d01a6c0afef92ae56cc4909af06 + } + // 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 -@@ -972,7 +994,10 @@ public class CraftEventFactory { - CraftBlockState state = CraftBlockStates.getBlockState(world, target, flag); - state.setData(block); + 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); -- BlockSpreadEvent event = new BlockSpreadEvent(state.getBlock(), CraftBlock.at(world, CraftEventFactory.sourceBlockOverride != null ? CraftEventFactory.sourceBlockOverride : source), state); +- BlockSpreadEvent event = new BlockSpreadEvent(snapshot.getBlock(), CraftBlock.at(world, CraftEventFactory.sourceBlockOverride != null ? CraftEventFactory.sourceBlockOverride : source), snapshot); + // Leaf start - SparklyPaper parallel world ticking mod (collapse original behavior) + final BlockPos sourceBlockOverrideRTSnap = getSourceBlockOverrideRT(); -+ BlockSpreadEvent event = new BlockSpreadEvent(state.getBlock(), CraftBlock.at(world, sourceBlockOverrideRTSnap != null ? sourceBlockOverrideRTSnap : source), state); // SparklyPaper - parallel world ticking ++ BlockSpreadEvent event = new BlockSpreadEvent(snapshot.getBlock(), CraftBlock.at(world, sourceBlockOverrideRTSnap != null ? sourceBlockOverrideRTSnap : source), snapshot); // SparklyPaper - parallel world ticking + // Leaf end - SparklyPaper parallel world ticking mod (collapse original behavior) - 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; - } + if (event.callEvent()) { + boolean result = snapshot.place(flags); + return !checkSetResult || result; 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 diff --git a/leaf-server/paper-patches/features/0051-Paper-PR-Throttle-failed-spawn-attempts.patch b/leaf-server/paper-patches/features/0052-Paper-PR-Throttle-failed-spawn-attempts.patch similarity index 100% rename from leaf-server/paper-patches/features/0051-Paper-PR-Throttle-failed-spawn-attempts.patch rename to leaf-server/paper-patches/features/0052-Paper-PR-Throttle-failed-spawn-attempts.patch diff --git a/leaf-server/paper-patches/features/0052-Async-playerdata-saving.patch b/leaf-server/paper-patches/features/0053-Async-playerdata-saving.patch similarity index 100% rename from leaf-server/paper-patches/features/0052-Async-playerdata-saving.patch rename to leaf-server/paper-patches/features/0053-Async-playerdata-saving.patch diff --git a/leaf-server/paper-patches/features/0053-Async-chunk-send.patch b/leaf-server/paper-patches/features/0054-Async-chunk-send.patch similarity index 100% rename from leaf-server/paper-patches/features/0053-Async-chunk-send.patch rename to leaf-server/paper-patches/features/0054-Async-chunk-send.patch diff --git a/leaf-server/paper-patches/features/0054-Optimise-player-movement-checks.patch b/leaf-server/paper-patches/features/0055-Optimise-player-movement-checks.patch similarity index 100% rename from leaf-server/paper-patches/features/0054-Optimise-player-movement-checks.patch rename to leaf-server/paper-patches/features/0055-Optimise-player-movement-checks.patch diff --git a/leaf-server/paper-patches/features/0055-Paw-optimization.patch b/leaf-server/paper-patches/features/0056-Paw-optimization.patch similarity index 100% rename from leaf-server/paper-patches/features/0055-Paw-optimization.patch rename to leaf-server/paper-patches/features/0056-Paw-optimization.patch diff --git a/leaf-server/paper-patches/features/0056-optimise-ReferenceList.patch b/leaf-server/paper-patches/features/0057-optimise-ReferenceList.patch similarity index 100% rename from leaf-server/paper-patches/features/0056-optimise-ReferenceList.patch rename to leaf-server/paper-patches/features/0057-optimise-ReferenceList.patch diff --git a/leaf-archived-patches/unapplied/src/main/java/org/dreeam/leaf/async/world/PWTEventScheduler.java b/leaf-server/src/main/java/org/dreeam/leaf/async/world/PWTEventScheduler.java similarity index 100% rename from leaf-archived-patches/unapplied/src/main/java/org/dreeam/leaf/async/world/PWTEventScheduler.java rename to leaf-server/src/main/java/org/dreeam/leaf/async/world/PWTEventScheduler.java diff --git a/leaf-archived-patches/unapplied/src/main/java/org/dreeam/leaf/async/world/ReadOperationType.java b/leaf-server/src/main/java/org/dreeam/leaf/async/world/ReadOperationType.java similarity index 100% rename from leaf-archived-patches/unapplied/src/main/java/org/dreeam/leaf/async/world/ReadOperationType.java rename to leaf-server/src/main/java/org/dreeam/leaf/async/world/ReadOperationType.java diff --git a/leaf-archived-patches/unapplied/src/main/java/org/dreeam/leaf/async/world/SparklyPaperServerLevelTickExecutorThreadFactory.java b/leaf-server/src/main/java/org/dreeam/leaf/async/world/SparklyPaperServerLevelTickExecutorThreadFactory.java similarity index 100% rename from leaf-archived-patches/unapplied/src/main/java/org/dreeam/leaf/async/world/SparklyPaperServerLevelTickExecutorThreadFactory.java rename to leaf-server/src/main/java/org/dreeam/leaf/async/world/SparklyPaperServerLevelTickExecutorThreadFactory.java diff --git a/leaf-archived-patches/unapplied/src/main/java/org/dreeam/leaf/async/world/WorldReadRequest.java b/leaf-server/src/main/java/org/dreeam/leaf/async/world/WorldReadRequest.java similarity index 100% rename from leaf-archived-patches/unapplied/src/main/java/org/dreeam/leaf/async/world/WorldReadRequest.java rename to leaf-server/src/main/java/org/dreeam/leaf/async/world/WorldReadRequest.java diff --git a/leaf-server/src/main/java/org/dreeam/leaf/command/LeafCommand.java b/leaf-server/src/main/java/org/dreeam/leaf/command/LeafCommand.java index 309e0acb..09ec7aeb 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/command/LeafCommand.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/command/LeafCommand.java @@ -5,7 +5,7 @@ import it.unimi.dsi.fastutil.Pair; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.minecraft.Util; -//import org.dreeam.leaf.command.subcommands.MSPTCommand; +import org.dreeam.leaf.command.subcommands.MSPTCommand; import org.dreeam.leaf.command.subcommands.ReloadCommand; import org.dreeam.leaf.command.subcommands.VersionCommand; import org.jetbrains.annotations.NotNull; @@ -38,13 +38,13 @@ public final class LeafCommand extends Command { // subcommand label -> subcommand private static final LeafSubcommand RELOAD_SUBCOMMAND = new ReloadCommand(); private static final LeafSubcommand VERSION_SUBCOMMAND = new VersionCommand(); - //private static final LeafSubcommand MSPT_SUBCOMMAND = new MSPTCommand(); + private static final LeafSubcommand MSPT_SUBCOMMAND = new MSPTCommand(); private static final Map SUBCOMMANDS = Util.make(() -> { final Map, LeafSubcommand> commands = new HashMap<>(); commands.put(Set.of(ReloadCommand.LITERAL_ARGUMENT), RELOAD_SUBCOMMAND); commands.put(Set.of(VersionCommand.LITERAL_ARGUMENT), VERSION_SUBCOMMAND); - //commands.put(Set.of(MSPTCommand.LITERAL_ARGUMENT), MSPT_SUBCOMMAND); + commands.put(Set.of(MSPTCommand.LITERAL_ARGUMENT), MSPT_SUBCOMMAND); return commands.entrySet().stream() .flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue()))) diff --git a/leaf-archived-patches/unapplied/src/main/java/org/dreeam/leaf/command/subcommands/MSPTCommand.java b/leaf-server/src/main/java/org/dreeam/leaf/command/subcommands/MSPTCommand.java similarity index 100% rename from leaf-archived-patches/unapplied/src/main/java/org/dreeam/leaf/command/subcommands/MSPTCommand.java rename to leaf-server/src/main/java/org/dreeam/leaf/command/subcommands/MSPTCommand.java