diff --git a/divinemc-server/minecraft-patches/features/0010-Optimize-Fluids.patch b/divinemc-server/minecraft-patches/features/0010-Optimize-Fluids.patch index f9ac231..04ece05 100644 --- a/divinemc-server/minecraft-patches/features/0010-Optimize-Fluids.patch +++ b/divinemc-server/minecraft-patches/features/0010-Optimize-Fluids.patch @@ -17,7 +17,7 @@ index ae609e0603a78423c4c89b7efb9c41ab8fe7aa52..5c143e3227371c701f36362e24bd3c1f } // CraftBukkit end diff --git a/net/minecraft/world/level/material/FlowingFluid.java b/net/minecraft/world/level/material/FlowingFluid.java -index 1b06e44a267d2d4af844997ac0c557f30aaf9b15..fa4570dbeba4acad4da6442faebed2401fafe59d 100644 +index 1b06e44a267d2d4af844997ac0c557f30aaf9b15..abf1866c26330fc3ec61a4457a7c6966cf0f38a7 100644 --- a/net/minecraft/world/level/material/FlowingFluid.java +++ b/net/minecraft/world/level/material/FlowingFluid.java @@ -199,6 +199,7 @@ public abstract class FlowingFluid extends Fluid { @@ -41,7 +41,7 @@ index 1b06e44a267d2d4af844997ac0c557f30aaf9b15..fa4570dbeba4acad4da6442faebed240 + BlockPos blockPos = pos.relative(direction.getOpposite()); + if (level.getFluidState(blockPos).is(net.minecraft.tags.FluidTags.WATER)) { + Block block = level.getFluidState(pos).isSource() ? Blocks.OBSIDIAN : Blocks.COBBLESTONE; -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, pos, block.defaultBlockState())) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, pos, block.defaultBlockState(), 3)) { + this.fizz(level, pos); + level.setBlock(pos, block.defaultBlockState(), 3); + } @@ -49,7 +49,7 @@ index 1b06e44a267d2d4af844997ac0c557f30aaf9b15..fa4570dbeba4acad4da6442faebed240 + } + + if (isSoulSoil && level.getBlockState(blockPos).is(Blocks.BLUE_ICE)) { -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, pos, Blocks.BASALT.defaultBlockState())) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, pos, Blocks.BASALT.defaultBlockState(), 3)) { + this.fizz(level, pos); + } + return false; diff --git a/patches/unapplied/server/0008-Parallel-world-ticking.patch b/divinemc-server/minecraft-patches/features/0043-Parallel-world-ticking.patch similarity index 65% rename from patches/unapplied/server/0008-Parallel-world-ticking.patch rename to divinemc-server/minecraft-patches/features/0043-Parallel-world-ticking.patch index 7d2a317..d12e573 100644 --- a/patches/unapplied/server/0008-Parallel-world-ticking.patch +++ b/divinemc-server/minecraft-patches/features/0043-Parallel-world-ticking.patch @@ -5,19 +5,19 @@ Subject: [PATCH] Parallel world ticking diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -index b5817aa8f537593f6d9fc6b612c82ccccb250ac7..5683395e09a65b1b39748df5152fffef630ac083 100644 +index 60705955e231d47c60f5a0a5e869988aed8774fc..3106d183cc9fdb08b445838c7724799fbba55f7a 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 { +@@ -1129,7 +1129,7 @@ public final class ChunkHolderManager { if (changedFullStatus.isEmpty()) { return; } - if (!TickThread.isTickThread()) { + if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && !TickThread.isTickThreadFor(world)) { // DivineMC - Parallel world ticking this.taskScheduler.scheduleChunkTask(() -> { - final ArrayDeque pendingFullLoadUpdate = ChunkHolderManager.this.pendingFullLoadUpdate; + final java.util.Deque pendingFullLoadUpdate = ChunkHolderManager.this.getData().pendingFullLoadUpdate; // DivineMC - Chunk System optimization for (int i = 0, len = changedFullStatus.size(); i < len; ++i) { -@@ -1057,7 +1057,13 @@ public final class ChunkHolderManager { +@@ -1155,7 +1155,13 @@ 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 b5817aa8f537593f6d9fc6b612c82ccccb250ac7..5683395e09a65b1b39748df5152fffef if (BLOCK_TICKET_UPDATES.get() == Boolean.TRUE) { throw new IllegalStateException("Cannot unload chunks recursively"); -@@ -1339,7 +1345,7 @@ public final class ChunkHolderManager { +@@ -1458,7 +1464,7 @@ public final class ChunkHolderManager { List changedFullStatus = null; @@ -41,112 +41,14 @@ index b5817aa8f537593f6d9fc6b612c82ccccb250ac7..5683395e09a65b1b39748df5152fffef 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..ebcd52da2228893f7a2d96f61e71906f8d2783ba 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()) { // DivineMC - Parallel world ticking - serverLevel.getCraftServer().getPluginManager().callEvent(event); - } - -diff --git a/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java b/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java -index bd5bbc7e55c6bea77991fe5a3c0c2580313d16c5..b822dd53138c9cde3e7248afb7589ca32a1b178a 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()) { // DivineMC - Parallel world ticking - level.getCraftServer().getPluginManager().callEvent(event); - } - diff --git a/net/minecraft/core/dispenser/DispenseItemBehavior.java b/net/minecraft/core/dispenser/DispenseItemBehavior.java -index f576449e8bc6fd92963cbe3954b0c853a02def3c..075987ec1eabb7385918049c54d7210ff2b38847 100644 +index ac27ff24f018d8798921c5152e679ceed1e88d8d..ec7d1353b19e55b00c558df8981323efb9b88bdf 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()) { // DivineMC - Parallel world ticking - 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()) { // DivineMC - Parallel world ticking - 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()) { // DivineMC - Parallel world ticking - 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()) { // DivineMC - Parallel world ticking - 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()) { // DivineMC - Parallel world ticking - 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()) { // DivineMC - Parallel world ticking - 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()) { // DivineMC - Parallel world ticking - 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()) { // DivineMC - Parallel world ticking - level.getCraftServer().getPluginManager().callEvent(event); - } - -@@ -510,8 +510,10 @@ public interface DispenseItemBehavior { +@@ -401,8 +401,10 @@ 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; + // DivineMC start - Parallel world ticking @@ -154,131 +56,21 @@ index f576449e8bc6fd92963cbe3954b0c853a02def3c..075987ec1eabb7385918049c54d7210f + net.minecraft.world.level.block.SaplingBlock.setTreeTypeTL(null); + // DivineMC end - Parallel world ticking 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 +550,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()) { // DivineMC - Parallel world ticking - level.getCraftServer().getPluginManager().callEvent(event); - } - -@@ -591,7 +593,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()) { // DivineMC - Parallel world ticking - level.getCraftServer().getPluginManager().callEvent(event); - } - -@@ -644,7 +646,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()) { // DivineMC - Parallel world ticking - level.getCraftServer().getPluginManager().callEvent(event); - } - -@@ -702,7 +704,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()) { // DivineMC - Parallel world ticking - serverLevel.getCraftServer().getPluginManager().callEvent(event); - } - -@@ -783,7 +785,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()) { // DivineMC - Parallel world ticking - serverLevel.getCraftServer().getPluginManager().callEvent(event); - } - -diff --git a/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java b/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java -index b91b2f5ea6a1da0477541dc65fdfbfa57b9af475..136c52cab0097fb68e8d12f653f1dab934de9bde 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()) { // DivineMC - Parallel world ticking - world.getCraftServer().getPluginManager().callEvent(event); - } - -diff --git a/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java b/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java -index 116395b6c00a0814922516707544a9ff26d68835..11d4da87aa80aa338d5f3048285079777bae7d3d 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()) { // DivineMC - Parallel world ticking - serverLevel.getCraftServer().getPluginManager().callEvent(event); - } - -diff --git a/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java b/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java -index 449d9b72ff4650961daa9d1bd25940f3914a6b12..ce12d4729d100be7dffaf4bdfc1c999d68c07bac 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()) { // DivineMC - Parallel world ticking - serverLevel.getCraftServer().getPluginManager().callEvent(event); - } - -diff --git a/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java -index 626e9feb6a6e7a2cbc7c63e30ba4fb6b923e85c7..81b37cf681ff0220263628b390910d9597662a3a 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()) { // DivineMC - Parallel world ticking - serverLevel.getCraftServer().getPluginManager().callEvent(event); - } - -diff --git a/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java b/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java -index 5ab2c8333178335515e619b87ae420f948c83bd1..e3034132c9119956e15a6a0342173d70e44ad669 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()) { // DivineMC - Parallel world ticking - blockSource.level().getCraftServer().getPluginManager().callEvent(event); - } - diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 4cb26cb312802ffc00426293014ed3994793a391..5a726da8535aa939f043829a3c60fdd9d4ed154a 100644 +index 172c69d577e53354fd4f37702d395e8f61754336..ef2cf6d9ca57266bb0466ca1aa5d2066349f9954 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -288,6 +288,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // DivineMC - Skip EntityScheduler's executeTick checks if there isn't any tasks to be run + public org.bxteam.divinemc.util.AsyncProcessor mobSpawnExecutor = new org.bxteam.divinemc.util.AsyncProcessor("mob_spawning"); // DivineMC - Async mob spawning + public java.util.concurrent.Semaphore serverLevelTickingSemaphore = null; // DivineMC - Parallel world ticking public static S spin(Function threadFunction) { - ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system -@@ -320,24 +321,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 -@@ -1714,28 +1739,43 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop, ServerLevel> oldLevels = this.levels; Map, ServerLevel> newLevels = Maps.newLinkedHashMap(oldLevels); newLevels.remove(level.dimension()); @@ -418,36 +210,37 @@ index 4cb26cb312802ffc00426293014ed3994793a391..5a726da8535aa939f043829a3c60fdd9 } // CraftBukkit end diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java -index 0d889730641fd88d4da0c9116226a4dae385e846..f7a061ad623fa909389c60c1d5b4be840f99e2bf 100644 +index 25460607359b7f172842657f2693ce3bf6151750..5287bf52df85ebe32334f90a0d66e9befa34c36b 100644 --- a/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java -@@ -243,6 +243,12 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface - io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command - this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark - com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics +@@ -204,6 +204,13 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface + // DivineMC end - Configuration + com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now + + // DivineMC start - Parallel world ticking + if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { + serverLevelTickingSemaphore = new java.util.concurrent.Semaphore(org.bxteam.divinemc.DivineConfig.parallelThreadCount); + DedicatedServer.LOGGER.info("Using {} permits for Parallel world ticking", serverLevelTickingSemaphore.availablePermits()); + } + // DivineMC end - Parallel world ticking - /*// Purpur start - Purpur config files // Purpur - Configurable void damage height and damage - try { - org.purpurmc.purpur.PurpurConfig.init((java.io.File) options.valueOf("purpur-settings")); ++ + this.setPvpAllowed(properties.pvp); + this.setFlightAllowed(properties.allowFlight); + this.setMotd(properties.motd); diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index ba5ca5213fafd60b2257409f334a7c6b28fe918a..52ba052fc1ff2a35786570c282a7de4e9dff99f5 100644 +index 27ff3ae4400de969c95eb337cfd88f8137c77d3b..857439f7b59549cff75e318fdf9c1effe83c7e17 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 - private final MinecraftServer server; +@@ -179,7 +179,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public final net.minecraft.world.level.storage.PrimaryLevelData serverLevelData; // CraftBukkit - type + public final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager.LevelHolderData chunkHolderData; // DivineMC - Chunk System optimization private int lastSpawnChunkRadius; - final EntityTickList entityTickList = new EntityTickList(); + final EntityTickList entityTickList = new EntityTickList(this); // DivineMC - Parallel world ticking // Paper - rewrite chunk system private final GameEventDispatcher gameEventDispatcher; public boolean noSave; -@@ -208,6 +208,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -205,6 +205,7 @@ 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; @@ -455,15 +248,15 @@ index ba5ca5213fafd60b2257409f334a7c6b28fe918a..52ba052fc1ff2a35786570c282a7de4e // CraftBukkit start public final LevelStorageSource.LevelStorageAccess levelStorageAccess; -@@ -700,6 +701,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -695,6 +696,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.chunkDataController = new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.ChunkDataController((ServerLevel)(Object)this, this.chunkTaskScheduler); // Paper end - rewrite chunk system this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit + this.tickExecutor = java.util.concurrent.Executors.newSingleThreadExecutor(new org.bxteam.divinemc.server.ServerLevelTickExecutorThreadFactory(getWorld().getName())); // DivineMC - Parallel world ticking this.preciseTime = this.serverLevelData.getDayTime(); // Purpur - Configurable daylight cycle - } - -@@ -1281,12 +1283,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + this.chunkSystemPriorities = new org.bxteam.divinemc.server.chunk.PriorityHandler(this); // DivineMC - Chunk System optimizations + this.ominousBanner = Objects.requireNonNullElse(this.registryAccess(), net.minecraft.core.RegistryAccess.EMPTY).lookup(Registries.BANNER_PATTERN).map(Raid::getOminousBannerInstance).orElse(null); // DivineMC - Optimize Raids +@@ -1293,12 +1295,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (fluidState.is(fluid)) { fluidState.tick(this, pos, blockState); } @@ -481,7 +274,7 @@ index ba5ca5213fafd60b2257409f334a7c6b28fe918a..52ba052fc1ff2a35786570c282a7de4e } private void tickBlock(BlockPos pos, Block block) { -@@ -1294,12 +1296,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1306,12 +1308,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (blockState.is(block)) { blockState.tick(this, pos, this.random); } @@ -499,18 +292,18 @@ index ba5ca5213fafd60b2257409f334a7c6b28fe918a..52ba052fc1ff2a35786570c282a7de4e } // Paper start - log detailed entity tick information -@@ -1548,6 +1550,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1560,6 +1562,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } private void addPlayer(ServerPlayer player) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this, "Cannot add player off-main"); // DivineMC - Parallel world ticking (additional concurrency issues logs) - Entity entity = this.getEntities().get(player.getUUID()); ++ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this, "Cannot add player off-main"); // DivineMC - Parallel world ticking + Entity entity = this.getEntity(player.getUUID()); if (entity != null) { LOGGER.warn("Force-added player with duplicate UUID {}", player.getUUID()); -@@ -1560,7 +1563,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1572,7 +1575,13 @@ 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 + // DivineMC start - Parallel world ticking + if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { @@ -523,10 +316,10 @@ index ba5ca5213fafd60b2257409f334a7c6b28fe918a..52ba052fc1ff2a35786570c282a7de4e // 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 21d41b477cc0e8d2476d1e3141bdf23d0c06f3e0..195d9dc696a9a7da0bb041612b73c0bbacf2919e 100644 +index 30c6bdbcd2e33e384f4d6b67e03e7a0acad2a464..fa95080ef6cca7d0b67f4b885fc62a0c3126a41d 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -432,6 +432,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -460,6 +460,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc return this.viewDistanceHolder; } // Paper end - rewrite chunk system @@ -534,7 +327,7 @@ index 21d41b477cc0e8d2476d1e3141bdf23d0c06f3e0..195d9dc696a9a7da0bb041612b73c0bb public ServerPlayer(MinecraftServer server, ServerLevel level, GameProfile gameProfile, ClientInformation clientInformation) { super(level, level.getSharedSpawnPos(), level.getSharedSpawnAngle(), gameProfile); -@@ -808,6 +809,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -753,6 +754,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc @Override public void tick() { @@ -542,7 +335,7 @@ index 21d41b477cc0e8d2476d1e3141bdf23d0c06f3e0..195d9dc696a9a7da0bb041612b73c0bb // CraftBukkit start if (this.joining) { this.joining = false; -@@ -1453,6 +1455,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1397,6 +1399,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc return this; } else { // CraftBukkit start @@ -550,7 +343,7 @@ index 21d41b477cc0e8d2476d1e3141bdf23d0c06f3e0..195d9dc696a9a7da0bb041612b73c0bb /* this.isChangingDimension = true; LevelData levelData = level.getLevelData(); -@@ -1815,6 +1818,12 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1738,6 +1741,12 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc return OptionalInt.empty(); } else { // CraftBukkit start @@ -563,7 +356,7 @@ index 21d41b477cc0e8d2476d1e3141bdf23d0c06f3e0..195d9dc696a9a7da0bb041612b73c0bb this.containerMenu = abstractContainerMenu; // Moved up if (!this.isImmobile()) this.connection -@@ -1879,6 +1888,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1802,6 +1811,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc } @Override public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) { @@ -576,7 +369,7 @@ index 21d41b477cc0e8d2476d1e3141bdf23d0c06f3e0..195d9dc696a9a7da0bb041612b73c0bb // 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 6f66c5a93383b2897425e117c32add9a34054add..5ff0ce34cfacb745748d3dc627127842ac1df9fa 100644 +index 338df3c49e19b7ff3f54ecf93a980d4573b142d7..0b8301ea5e90565e673e38e51f7ed3c8c3552a50 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java @@ -150,6 +150,7 @@ public abstract class PlayerList { @@ -587,22 +380,22 @@ index 6f66c5a93383b2897425e117c32add9a34054add..5ff0ce34cfacb745748d3dc627127842 player.isRealPlayer = true; // Paper player.loginTime = System.currentTimeMillis(); // Paper - Replace OfflinePlayer#getLastPlayed GameProfile gameProfile = player.getGameProfile(); -@@ -716,6 +717,14 @@ public abstract class PlayerList { - return this.respawn(player, keepInventory, reason, eventReason, null); +@@ -715,6 +716,14 @@ public abstract class PlayerList { } - public ServerPlayer respawn(ServerPlayer player, boolean keepInventory, Entity.RemovalReason reason, org.bukkit.event.player.PlayerRespawnEvent.RespawnReason eventReason, org.bukkit.Location location) { -+ // DivineMC start - Parallel world ticking (additional concurrency issues logs) + + public ServerPlayer respawn(ServerPlayer player, boolean keepInventory, Entity.RemovalReason reason, @Nullable org.bukkit.event.player.PlayerRespawnEvent.RespawnReason eventReason, @Nullable org.bukkit.Location location) { ++ // DivineMC start - Parallel world ticking + if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { + if (location != null) + ca.spottedleaf.moonrise.common.util.TickThread.ensureOnlyTickThread("Cannot respawn player off-main, from world " + player.serverLevel().getWorld().getName() + " to world " + location.getWorld().getName()); + else + ca.spottedleaf.moonrise.common.util.TickThread.ensureOnlyTickThread("Cannot respawn player off-main, respawning in world " + player.serverLevel().getWorld().getName()); + } -+ // DivineMC end - Parallel world ticking (additional concurrency issues logs) ++ // DivineMC end - Parallel world ticking this.players.remove(player); this.playersByName.remove(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot player.serverLevel().removePlayerImmediately(player, reason); -@@ -725,6 +734,7 @@ public abstract class PlayerList { +@@ -724,6 +733,7 @@ public abstract class PlayerList { ServerPlayer serverPlayer = player; Level fromWorld = player.level(); player.wonGame = false; @@ -611,10 +404,10 @@ index 6f66c5a93383b2897425e117c32add9a34054add..5ff0ce34cfacb745748d3dc627127842 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 4c4bed85db28d92ca55593a19ac23616619e4bd1..7e29f1f1972f2fb4f9a779653467bc85ce37c7bc 100644 +index b98010d6d3d369c680ccc8f15da9574e4f6a139c..7326796c98761db2d00cf9a7e92bbc82bc6510fe 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -3314,14 +3314,34 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3248,14 +3248,34 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess if (this.portalProcess != null) { if (this.portalProcess.processPortalTeleportation(serverLevel, this, this.canUsePortal(false))) { this.setPortalCooldown(); @@ -655,7 +448,7 @@ index 4c4bed85db28d92ca55593a19ac23616619e4bd1..7e29f1f1972f2fb4f9a779653467bc85 } else if (this.portalProcess.hasExpired()) { this.portalProcess = null; } -@@ -3851,6 +3871,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3820,6 +3840,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } private Entity teleportCrossDimension(ServerLevel level, TeleportTransition teleportTransition) { @@ -664,7 +457,7 @@ index 4c4bed85db28d92ca55593a19ac23616619e4bd1..7e29f1f1972f2fb4f9a779653467bc85 List list = new ArrayList<>(passengers.size()); this.ejectPassengers(); diff --git a/net/minecraft/world/entity/PortalProcessor.java b/net/minecraft/world/entity/PortalProcessor.java -index 88b07fbb96b20124777889830afa480673629d43..be357d9e3c5327ceec12c31830551a564c8cea1b 100644 +index d2661ea79536010414f77256332f214d19106dd9..f77da420bc88df6ec304086fc1eba0690fe278b1 100644 --- a/net/minecraft/world/entity/PortalProcessor.java +++ b/net/minecraft/world/entity/PortalProcessor.java @@ -11,6 +11,7 @@ public class PortalProcessor { @@ -683,7 +476,7 @@ index 88b07fbb96b20124777889830afa480673629d43..be357d9e3c5327ceec12c31830551a56 if (!this.insidePortalThisTick) { this.decayTick(); return false; -@@ -42,7 +44,7 @@ public class PortalProcessor { +@@ -52,7 +54,7 @@ public class PortalProcessor { } public boolean hasExpired() { @@ -692,7 +485,7 @@ index 88b07fbb96b20124777889830afa480673629d43..be357d9e3c5327ceec12c31830551a56 } public BlockPos getEntryPosition() { -@@ -68,4 +70,30 @@ public class PortalProcessor { +@@ -78,4 +80,30 @@ public class PortalProcessor { public boolean isSamePortal(Portal portal) { return this.portal == portal; } @@ -756,27 +549,27 @@ index 3614551856c594f3c0cfee984fcf03fad672b007..6add256046e392d8eb797e3fa9d1cbe7 }); 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 fec90e482c8935dfca609bbf90e67f86a1586221..4ee1791f293ba3abdbfe69824b85566fd9a36586 100644 +index abf7308a41e7c28e1d9fd82d5f86022a80159bff..b68dfb81974e8cc8537c1f42add6a9c6e57fe40d 100644 --- a/net/minecraft/world/entity/npc/Villager.java +++ b/net/minecraft/world/entity/npc/Villager.java -@@ -803,13 +803,24 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - this.brain.getMemory(moduleType).ifPresent(globalPos -> { - ServerLevel level = server.getLevel(globalPos.dimension()); +@@ -795,13 +795,24 @@ 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()); + // DivineMC start - Parallel world ticking + 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()); + } + }; + @@ -791,10 +584,10 @@ index fec90e482c8935dfca609bbf90e67f86a1586221..4ee1791f293ba3abdbfe69824b85566f }); } diff --git a/net/minecraft/world/entity/projectile/ThrownEnderpearl.java b/net/minecraft/world/entity/projectile/ThrownEnderpearl.java -index d212f57c8c0b2086f567fd30237b110203d9e8cb..d59bdab65c034bab443ea9448930fdff85a85392 100644 +index 6575e8ef16f6011f7a799ba31531a2ebefee0c4d..407f00af5aac495eb116e4cf8a05fcc66c7331b1 100644 --- a/net/minecraft/world/entity/projectile/ThrownEnderpearl.java +++ b/net/minecraft/world/entity/projectile/ThrownEnderpearl.java -@@ -126,40 +126,50 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { +@@ -122,40 +122,50 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { Vec3 vec3 = this.oldPosition(); if (owner instanceof ServerPlayer serverPlayer) { if (serverPlayer.connection.isAcceptingMessages()) { @@ -809,7 +602,7 @@ index d212f57c8c0b2086f567fd30237b110203d9e8cb..d59bdab65c034bab443ea9448930fdff - 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()); +- endermite.snapTo(owner.getX(), owner.getY(), owner.getZ(), owner.getYRot(), owner.getXRot()); - serverLevel.addFreshEntity(endermite, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.ENDER_PEARL); + // DivineMC start - Parallel world ticking + java.util.function.Consumer teleportPlayerCrossDimensionTask = taskServerPlayer -> { @@ -824,7 +617,7 @@ index d212f57c8c0b2086f567fd30237b110203d9e8cb..d59bdab65c034bab443ea9448930fdff + 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()); ++ endermite.snapTo(owner.getX(), owner.getY(), owner.getZ(), owner.getYRot(), owner.getXRot()); + serverLevel.addFreshEntity(endermite, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.ENDER_PEARL); + } } @@ -876,11 +669,11 @@ index d212f57c8c0b2086f567fd30237b110203d9e8cb..d59bdab65c034bab443ea9448930fdff } else { Entity entity = owner.teleport( diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java -index e6419715fab462b12790ecb175ce1e1a1fceed8f..b03068bb94c785db51da660361ce28b9f4b45898 100644 +index 8e97a20306652cdfc757b7102a07c58ce0e339e3..8b691f9b0283cf1847c40a57892395763751aad3 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; // DivineMC - Parallel world ticking @@ -895,10 +688,10 @@ index e6419715fab462b12790ecb175ce1e1a1fceed8f..b03068bb94c785db51da660361ce28b9 this.containerId = containerId; } diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java -index 264b713e8b7c3d5f7d8e1facc90a60349f2cf414..596abdcda01e412d995d150ca9d056a5278ea691 100644 +index f1b61e98e07d1d89f9af225f99085d8a3fee878c..ac2c8d38fc6d75d23d0f3c5c49ec141b30403e4e 100644 --- a/net/minecraft/world/item/ItemStack.java +++ b/net/minecraft/world/item/ItemStack.java -@@ -407,8 +407,10 @@ public final class ItemStack implements DataComponentHolder { +@@ -406,8 +406,10 @@ public final class ItemStack implements DataComponentHolder { if (interactionResult.consumesAction() && serverLevel.captureTreeGeneration && !serverLevel.capturedBlockStates.isEmpty()) { serverLevel.captureTreeGeneration = false; org.bukkit.Location location = org.bukkit.craftbukkit.util.CraftLocation.toBukkit(clickedPos, serverLevel.getWorld()); @@ -912,18 +705,18 @@ index 264b713e8b7c3d5f7d8e1facc90a60349f2cf414..596abdcda01e412d995d150ca9d056a5 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 0c58919e8242317ba276e103b81d07006c41deca..788e83078e9e430b84bf5dc9df877eb7ef46543b 100644 +index 4eedfc61c7e682a44858703b462eecad17a48904..c01463194470624ecd84209100fdbdc851028fb7 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java -@@ -170,6 +170,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - public final io.papermc.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray +@@ -160,6 +160,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl + public final org.purpurmc.purpur.PurpurWorldConfig purpurConfig; // Purpur - Purpur config files public final org.bxteam.divinemc.DivineWorldConfig divineConfig; // DivineMC - Configuration + 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); // DivineMC - Parallel world ticking (moved to world) - public static BlockPos lastPhysicsProblem; // Spigot - private org.spigotmc.TickLimiter entityLimiter; - private org.spigotmc.TickLimiter tileLimiter; -@@ -1149,6 +1150,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + public static @Nullable BlockPos lastPhysicsProblem; // Spigot + private int tileTickPosition; + public final Map explosionDensityCache = new java.util.HashMap<>(); // Paper - Optimize explosions +@@ -1134,6 +1135,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl @Override public boolean setBlock(BlockPos pos, BlockState state, int flags, int recursionLeft) { @@ -931,8 +724,8 @@ index 0c58919e8242317ba276e103b81d07006c41deca..788e83078e9e430b84bf5dc9df877eb7 // CraftBukkit start - tree generation if (this.captureTreeGeneration) { // Paper start - Protect Bedrock and End Portal/Frames from being destroyed -@@ -1529,11 +1531,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - toRemove.add(tickingBlockEntity); // Paper - Fix MC-117075; use removeAll +@@ -1511,11 +1513,12 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl + this.blockEntityTickers.markAsRemoved(this.tileTickPosition); // DivineMC - optimize block entity removals - Fix MC-117075 } else if (runsNormally && this.shouldTickBlocksAt(tickingBlockEntity.getPos())) { tickingBlockEntity.tick(); - // Paper start - rewrite chunk system @@ -947,8 +740,8 @@ index 0c58919e8242317ba276e103b81d07006c41deca..788e83078e9e430b84bf5dc9df877eb7 + // DivineMC end - Parallel world ticking } } - this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 -@@ -1553,7 +1556,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + this.blockEntityTickers.removeMarkedEntries(); // DivineMC - optimize block entity removals - Fix MC-117075 +@@ -1535,7 +1538,11 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Paper end - Prevent block entity and entity crashes } @@ -961,7 +754,7 @@ index 0c58919e8242317ba276e103b81d07006c41deca..788e83078e9e430b84bf5dc9df877eb7 } // Paper start - Option to prevent armor stands from doing entity lookups -@@ -1696,6 +1703,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1678,6 +1685,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl @Nullable public BlockEntity getBlockEntity(BlockPos pos, boolean validate) { @@ -969,7 +762,7 @@ index 0c58919e8242317ba276e103b81d07006c41deca..788e83078e9e430b84bf5dc9df877eb7 // Paper start - Perf: Optimize capturedTileEntities lookup net.minecraft.world.level.block.entity.BlockEntity blockEntity; if (!this.capturedTileEntities.isEmpty() && (blockEntity = this.capturedTileEntities.get(pos)) != null) { -@@ -1713,6 +1721,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1695,6 +1703,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl } public void setBlockEntity(BlockEntity blockEntity) { @@ -977,7 +770,7 @@ index 0c58919e8242317ba276e103b81d07006c41deca..788e83078e9e430b84bf5dc9df877eb7 BlockPos blockPos = blockEntity.getBlockPos(); if (!this.isOutsideBuildHeight(blockPos)) { // CraftBukkit start -@@ -1797,6 +1806,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1779,6 +1788,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl @Override public List getEntities(@Nullable Entity entity, AABB boundingBox, Predicate predicate) { @@ -985,7 +778,7 @@ index 0c58919e8242317ba276e103b81d07006c41deca..788e83078e9e430b84bf5dc9df877eb7 List list = Lists.newArrayList(); // Paper start - rewrite chunk system -@@ -2106,8 +2116,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -2097,8 +2107,15 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl public abstract RecipeAccess recipeAccess(); public BlockPos getBlockRandomPos(int x, int y, int z, int yMask) { @@ -1003,50 +796,11 @@ index 0c58919e8242317ba276e103b81d07006c41deca..788e83078e9e430b84bf5dc9df877eb7 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..12ead3dc17828558b2e6b67a5f306a5948f7b2cf 100644 ---- a/net/minecraft/world/level/block/DispenserBlock.java -+++ b/net/minecraft/world/level/block/DispenserBlock.java -@@ -51,6 +51,25 @@ 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 -+ // DivineMC start - Parallel world ticking -+ public static ThreadLocal eventFiredTL = ThreadLocal.withInitial(() -> Boolean.FALSE); -+ -+ public static boolean getEventFiredTL() { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && eventFiredTL.get()) return true; -+ -+ synchronized (DispenserBlock.class) { -+ return eventFired; -+ } -+ } -+ -+ public static void setEventFiredTL(boolean value) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) eventFiredTL.set(value); -+ -+ synchronized (DispenserBlock.class) { -+ eventFired = value; -+ } -+ } -+ // DivineMC end - Parallel world ticking - - @Override - public MapCodec codec() { -@@ -96,7 +115,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 // DivineMC - Parallel world ticking - 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..fc900a7c382f825110c561070155c1f6451557ed 100644 +index 9711efb088bd0da9168e9bcd0496bd7caddd2974..ea310d53f728aaf5de3284b372ed393e4225a52f 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) { @@ -1059,10 +813,10 @@ index 85f0eac75784565c658c5178c544f969db3d6f54..fc900a7c382f825110c561070155c1f6 return value; }) diff --git a/net/minecraft/world/level/block/MushroomBlock.java b/net/minecraft/world/level/block/MushroomBlock.java -index 904369f4d7db41026183f2de7c96c2f0f4dc204d..371334bc3a1ea505b3293f13542aef4cf8f2a2d2 100644 +index d306f5f524dc64618df94c9783c2168dc561a5e3..6a0c4dc2ff5e3d82e811db63dc9da7b93e6f2cc9 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); @@ -1072,10 +826,10 @@ index 904369f4d7db41026183f2de7c96c2f0f4dc204d..371334bc3a1ea505b3293f13542aef4c return true; } else { diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java -index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..4293c5f11a17500353b63cad399727ece1461c5e 100644 +index 1943a6aad888647953e2d9dbbeedb0bd81c6f9df..9b564348b24444c4cf717907bc92b8ea7cf40ffe 100644 --- a/net/minecraft/world/level/block/RedStoneWireBlock.java +++ b/net/minecraft/world/level/block/RedStoneWireBlock.java -@@ -308,7 +308,13 @@ public class RedStoneWireBlock extends Block { +@@ -283,7 +283,13 @@ public class RedStoneWireBlock extends Block { if (orientation != null) { source = pos.relative(orientation.getFront().getOpposite()); } @@ -1090,7 +844,7 @@ index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..4293c5f11a17500353b63cad399727ec return; } updatePowerStrength(worldIn, pos, state, orientation, blockAdded); -@@ -336,7 +342,13 @@ public class RedStoneWireBlock extends Block { +@@ -311,7 +317,13 @@ 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)) { @@ -1106,13 +860,13 @@ index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..4293c5f11a17500353b63cad399727ec } } diff --git a/net/minecraft/world/level/block/SaplingBlock.java b/net/minecraft/world/level/block/SaplingBlock.java -index e014f052e9b0f5ca6b28044e2389782b7d0e0cb8..4ad0e278a348407beed1ec4381bfeacf4de32a0d 100644 +index a22cb810622e0ae97bc2a0d6390d026d9482b783..8ccc1dafdd035477ecbfcbed4cf9a9c503820ce3 100644 --- a/net/minecraft/world/level/block/SaplingBlock.java +++ b/net/minecraft/world/level/block/SaplingBlock.java -@@ -27,6 +27,26 @@ 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,26 @@ 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 + // DivineMC start - Parallel world ticking + public static final ThreadLocal treeTypeTL = new ThreadLocal<>(); + @@ -1136,7 +890,7 @@ index e014f052e9b0f5ca6b28044e2389782b7d0e0cb8..4ad0e278a348407beed1ec4381bfeacf @Override public MapCodec codec() { -@@ -63,14 +83,16 @@ public class SaplingBlock extends BushBlock implements BonemealableBlock { +@@ -62,14 +82,16 @@ public class SaplingBlock extends VegetationBlock implements BonemealableBlock { this.treeGrower.growTree(level, level.getChunkSource().getGenerator(), pos, state, random); level.captureTreeGeneration = false; if (!level.capturedBlockStates.isEmpty()) { @@ -1158,12 +912,12 @@ index e014f052e9b0f5ca6b28044e2389782b7d0e0cb8..4ad0e278a348407beed1ec4381bfeacf } 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..20e8155c0c5f4bd60344c1bbd15f7555ad9ef554 100644 +index c63370fd458fb4f7190b79b1a8174fcc92d88f9c..6af22d8c1a244b7540cad18c6c9da8f939d8d81a 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) { + // DivineMC start - Parallel world ticking + if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && player instanceof net.minecraft.server.level.ServerPlayer serverPlayer && blockEntity != null && blockEntity.getLevel() != serverPlayer.serverLevel()) { @@ -1175,102 +929,100 @@ index 26db603ed681a6c302596627d4dd5bf8a9bafc4e..20e8155c0c5f4bd60344c1bbd15f7555 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 1638eccef431fb68775af624110f1968f0c6dabd..491ac8be8fdaa573fe1b3a234a14110d89b43345 100644 +index 2627583ab12d886b1fba0b1d1e599f942926b499..2caa770411c542a70fe50267ce4cffb22fc94b97 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 +@@ -43,9 +43,7 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi // Paper end - Fix NPE in SculkBloomEvent world access public static void serverTick(Level level, BlockPos pos, BlockState state, SculkCatalystBlockEntity sculkCatalyst) { - org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverride = sculkCatalyst.getBlockPos(); // CraftBukkit - SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep. -+ org.bukkit.craftbukkit.event.CraftEventFactory.setSourceBlockOverrideTL(pos); // DivineMC - Parallel world ticking // CraftBukkit - SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep. sculkCatalyst.catalystListener.getSculkSpreader().updateCursors(level, pos, level.getRandom(), true); - org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverride = null; // CraftBukkit -+ org.bukkit.craftbukkit.event.CraftEventFactory.setSourceBlockOverrideTL(null); // DivineMC - Parallel world ticking // CraftBukkit } @Override diff --git a/net/minecraft/world/level/block/grower/TreeGrower.java b/net/minecraft/world/level/block/grower/TreeGrower.java -index cf7311c507de09a8f89934e430b2201e8bdffe51..e76cb020471f28c29f1b24addb5cd101ddc9630f 100644 +index d23f255de9208f42125fa358a9e8194c984fe4d3..92e9bc9ba577474ca1108b8d0615739502ca5e57 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,59 @@ public final class TreeGrower { + // CraftBukkit start - private void setTreeType(Holder> holder) { - ResourceKey> treeFeature = holder.unwrapKey().get(); + private void setTreeType(Holder> feature) { + // DivineMC start - Parallel world ticking + org.bukkit.TreeType treeType; - if (treeFeature == TreeFeatures.OAK || treeFeature == TreeFeatures.OAK_BEES_005) { + 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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) { + } 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; } else { - throw new IllegalArgumentException("Unknown tree generator " + treeFeature); + throw new IllegalArgumentException("Unknown tree generator " + feature); } + net.minecraft.world.level.block.SaplingBlock.setTreeTypeTL(treeType); + // DivineMC end - Parallel world ticking @@ -1278,25 +1030,25 @@ index cf7311c507de09a8f89934e430b2201e8bdffe51..e76cb020471f28c29f1b24addb5cd101 // CraftBukkit end } diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index e3d71604c161373ef44164606602290af1bd1cb0..b245f594ff91e2d29c83f56b9ed5165f37387e7e 100644 +index d2eed7a0cf0c2c9dbcfb272cf89194f11d37151c..b5d74a13e6311732b9cb67f23844e64de31d9cac 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java -@@ -365,6 +365,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p - +@@ -363,6 +363,7 @@ 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.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.level, pos, "Updating block asynchronously"); // DivineMC - Parallel world ticking - // 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 c89701d7bdc9b889038d3c52f2232fb17624b113..018a04674897cfcec0e8de5cb2ab06243a994ae3 100644 +index 9e75320e51886e0f93c23683d8614128f44a613e..86c7e5a469fbd276ebbf5aee1b72531d444d6359 100644 --- a/net/minecraft/world/level/entity/EntityTickList.java +++ b/net/minecraft/world/level/entity/EntityTickList.java @@ -10,17 +10,26 @@ import net.minecraft.world.entity.Entity; public class EntityTickList { - public final ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet entities = new ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet<>(); // Paper - rewrite chunk system + public final java.util.concurrent.ConcurrentLinkedQueue entities = new java.util.concurrent.ConcurrentLinkedQueue<>(); // Paper - rewrite chunk system // DivineMC - Async mob spawning + // DivineMC start - Parallel world ticking + private final net.minecraft.server.level.ServerLevel serverLevel; + @@ -1310,13 +1062,13 @@ index c89701d7bdc9b889038d3c52f2232fb17624b113..018a04674897cfcec0e8de5cb2ab0624 } public void add(Entity entity) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(entity, "Asynchronous entity ticklist addition"); // Paper // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(entity, "Asynchronous entity ticklist addition"); // DivineMC - Parallel world ticking this.ensureActiveIsNotIterated(); this.entities.add(entity); // Paper - rewrite chunk system } public void remove(Entity entity) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(entity, "Asynchronous entity ticklist removal"); // Paper // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(entity, "Asynchronous entity ticklist removal"); // DivineMC - Parallel world ticking this.ensureActiveIsNotIterated(); this.entities.remove(entity); // Paper - rewrite chunk system } @@ -1328,39 +1080,3 @@ index c89701d7bdc9b889038d3c52f2232fb17624b113..018a04674897cfcec0e8de5cb2ab0624 // Paper start - rewrite chunk system // 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..8f6436d2e87e7e11d98dcf20f4a62a4b3c7f6d92 100644 ---- a/net/minecraft/world/level/saveddata/maps/MapIndex.java -+++ b/net/minecraft/world/level/saveddata/maps/MapIndex.java -@@ -34,17 +34,24 @@ 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()); -+ // DivineMC start - make map data thread-safe -+ synchronized (this.usedAuxIds) { -+ for (Entry entry : this.usedAuxIds.object2IntEntrySet()) { -+ tag.putInt(entry.getKey(), entry.getIntValue()); -+ } - } -- -+ // DivineMC end - make map data thread-safe - return tag; - } - - public MapId getFreeAuxValueForMap() { -- int i = this.usedAuxIds.getInt("map") + 1; -- this.usedAuxIds.put("map", i); -- this.setDirty(); -- return new MapId(i); -+ // DivineMC 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); -+ } -+ // DivineMC end - make map data thread-safe - } - } diff --git a/patches/unapplied/server/0017-MSPT-Tracking-for-each-world.patch b/divinemc-server/minecraft-patches/features/0044-MSPT-Tracking-for-each-world.patch similarity index 86% rename from patches/unapplied/server/0017-MSPT-Tracking-for-each-world.patch rename to divinemc-server/minecraft-patches/features/0044-MSPT-Tracking-for-each-world.patch index a9a4bf9..9347b1d 100644 --- a/patches/unapplied/server/0017-MSPT-Tracking-for-each-world.patch +++ b/divinemc-server/minecraft-patches/features/0044-MSPT-Tracking-for-each-world.patch @@ -5,10 +5,10 @@ Subject: [PATCH] MSPT Tracking for each world diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 11b89a625b942f5f2f882c54dbfc08c16e983425..fc9de137ed1681afd1ef51391cf8f30fd4c61c4b 100644 +index ef2cf6d9ca57266bb0466ca1aa5d2066349f9954..c4ae883af4337e04d0944c603f298ee1576cb3d2 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -1684,7 +1684,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop configurator) { // Paper end - expand explosion API @@ -304,7 +304,7 @@ index bc2522968205d0c701a2fa23f29565a500881492..312018206729b623a7c854af1c11a2d0 net.minecraft.world.level.Level.ExplosionInteraction explosionType; if (!breakBlocks) { explosionType = net.minecraft.world.level.Level.ExplosionInteraction.NONE; // Don't break blocks -@@ -955,6 +970,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -956,6 +971,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public int getHighestBlockYAt(int x, int z, org.bukkit.HeightMap heightMap) { @@ -312,7 +312,7 @@ index bc2522968205d0c701a2fa23f29565a500881492..312018206729b623a7c854af1c11a2d0 warnUnsafeChunk("getting a faraway chunk", x >> 4, z >> 4); // Paper // Transient load for this tick return this.world.getChunk(x >> 4, z >> 4).getHeight(CraftHeightMap.toNMS(heightMap), x, z); -@@ -985,6 +1001,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -986,6 +1002,7 @@ 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); @@ -320,7 +320,7 @@ index bc2522968205d0c701a2fa23f29565a500881492..312018206729b623a7c854af1c11a2d0 if (this.world.hasChunkAt(pos)) { net.minecraft.world.level.chunk.LevelChunk chunk = this.world.getChunkAt(pos); -@@ -2288,6 +2305,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2294,6 +2311,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void sendGameEvent(Entity sourceEntity, org.bukkit.GameEvent gameEvent, Vector position) { @@ -329,7 +329,7 @@ index bc2522968205d0c701a2fa23f29565a500881492..312018206729b623a7c854af1c11a2d0 } // 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 5cb69d0b822e11a99a96aef4f59986d083b079f4..0e47184336f63123211e24a966908a16aa27d6c6 100644 +index e9ca19c8668d3028f9453f478b1853baa24b47b4..01dd87b5bb0695ea6a1ba386a759e281488d7bdd 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -75,6 +75,11 @@ public class CraftBlock implements Block { @@ -344,31 +344,31 @@ index 5cb69d0b822e11a99a96aef4f59986d083b079f4..0e47184336f63123211e24a966908a16 return this.world.getBlockState(this.position); } -@@ -157,6 +162,11 @@ public class CraftBlock implements Block { +@@ -155,6 +160,11 @@ public class CraftBlock implements Block { } - private void setData(final byte data, int flag) { + private void setData(final byte data, int flags) { + // DivineMC start - Parallel world ticking + if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously"); + } + // DivineMC 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); } -@@ -198,6 +208,11 @@ public class CraftBlock implements Block { +@@ -196,6 +206,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) { + // DivineMC start - Parallel world ticking + if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { -+ 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"); + } + // DivineMC 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 -@@ -343,18 +358,33 @@ public class CraftBlock implements Block { +@@ -344,18 +359,33 @@ public class CraftBlock implements Block { @Override public Biome getBiome() { @@ -402,7 +402,7 @@ index 5cb69d0b822e11a99a96aef4f59986d083b079f4..0e47184336f63123211e24a966908a16 this.getWorld().setBiome(this.getX(), this.getY(), this.getZ(), bio); } -@@ -402,6 +432,11 @@ public class CraftBlock implements Block { +@@ -403,6 +433,11 @@ public class CraftBlock implements Block { @Override public boolean isBlockFaceIndirectlyPowered(BlockFace face) { @@ -414,7 +414,7 @@ index 5cb69d0b822e11a99a96aef4f59986d083b079f4..0e47184336f63123211e24a966908a16 int power = this.world.getMinecraftWorld().getSignal(this.position, CraftBlock.blockFaceToNotch(face)); Block relative = this.getRelative(face); -@@ -414,6 +449,11 @@ public class CraftBlock implements Block { +@@ -415,6 +450,11 @@ public class CraftBlock implements Block { @Override public int getBlockPower(BlockFace face) { @@ -426,7 +426,7 @@ index 5cb69d0b822e11a99a96aef4f59986d083b079f4..0e47184336f63123211e24a966908a16 int power = 0; net.minecraft.world.level.Level world = this.world.getMinecraftWorld(); int x = this.getX(); -@@ -484,6 +524,11 @@ public class CraftBlock implements Block { +@@ -483,6 +523,11 @@ public class CraftBlock implements Block { @Override public boolean breakNaturally() { @@ -438,7 +438,7 @@ index 5cb69d0b822e11a99a96aef4f59986d083b079f4..0e47184336f63123211e24a966908a16 return this.breakNaturally(null); } -@@ -543,6 +588,11 @@ public class CraftBlock implements Block { +@@ -542,6 +587,11 @@ public class CraftBlock implements Block { @Override public boolean applyBoneMeal(BlockFace face) { @@ -450,17 +450,17 @@ index 5cb69d0b822e11a99a96aef4f59986d083b079f4..0e47184336f63123211e24a966908a16 Direction direction = CraftBlock.blockFaceToNotch(face); BlockFertilizeEvent event = null; ServerLevel world = this.getCraftWorld().getHandle(); -@@ -554,8 +604,10 @@ public class CraftBlock implements Block { +@@ -553,8 +603,10 @@ public class CraftBlock implements Block { world.captureTreeGeneration = false; - if (world.capturedBlockStates.size() > 0) { + if (!world.capturedBlockStates.isEmpty()) { - TreeType treeType = SaplingBlock.treeType; - SaplingBlock.treeType = null; + // DivineMC start - Parallel world ticking + TreeType treeType = SaplingBlock.getTreeTypeTL(); + SaplingBlock.setTreeTypeTL(null); + // DivineMC end - Parallel world ticking - List blocks = new ArrayList<>(world.capturedBlockStates.values()); + List states = new ArrayList<>(world.capturedBlockStates.values()); world.capturedBlockStates.clear(); StructureGrowEvent structureEvent = null; @@ -644,6 +696,11 @@ public class CraftBlock implements Block { @@ -500,7 +500,7 @@ index 5cb69d0b822e11a99a96aef4f59986d083b079f4..0e47184336f63123211e24a966908a16 this.getNMS().tick(level, this.position, level.random); } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java -index 768d3f93da2522d467183654260a8bd8653588b1..dd3c9e214a59d20c2b5e8556951687e2aba2d116 100644 +index 3422970353dcd886934b9ee906467769d39abbde..cb60c1b09f06872c07d05b04b7bacc5921fea78d 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java @@ -26,6 +26,25 @@ public abstract class CraftBlockEntityState extends Craft @@ -527,8 +527,8 @@ index 768d3f93da2522d467183654260a8bd8653588b1..dd3c9e214a59d20c2b5e8556951687e2 + } + // DivineMC end - Parallel world ticking - 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 +53,10 @@ public abstract class CraftBlockEntityState extends Craft try { // Paper - Show blockstate location if we failed to read it @@ -539,14 +539,14 @@ index 768d3f93da2522d467183654260a8bd8653588b1..dd3c9e214a59d20c2b5e8556951687e2 + this.snapshotDisabled = getDisableSnapshotTL(); + if (snapshotDisabled) { + // DivineMC end - Parallel world ticking - 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..cddb460892f1756faa4b58ae53406058acd9803d 100644 +index c0a7659776a9f0fb82bb8563acbf3286b318fe03..d4ffcf6a96a66f4482af440d1b89aa8ccdd0fd9b 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 { +@@ -217,6 +217,12 @@ public class CraftBlockState implements BlockState { LevelAccessor access = this.getWorldHandle(); CraftBlock block = this.getBlock(); @@ -559,7 +559,7 @@ index fa63a6cfcfcc4eee4503a82d85333c139c8c8b2b..cddb460892f1756faa4b58ae53406058 if (block.getType() != this.getType()) { if (!force) { return false; -@@ -350,6 +356,7 @@ public class CraftBlockState implements BlockState { +@@ -365,6 +371,7 @@ public class CraftBlockState implements BlockState { @Override public java.util.Collection getDrops(org.bukkit.inventory.ItemStack item, org.bukkit.entity.Entity entity) { @@ -568,13 +568,13 @@ index fa63a6cfcfcc4eee4503a82d85333c139c8c8b2b..cddb460892f1756faa4b58ae53406058 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 56453454cbd4b9e9270fc833f8ab38d5fa7a3763..c3cc5012cf460f57495d8867f198007676bae5bf 100644 +index 2338e7c115037430cefae26a571ded71f77983c4..6d5af7f72158e9e4abbfb6ae650833a66ea7a934 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java -@@ -249,8 +249,10 @@ 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,16 @@ 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; + // DivineMC start - Parallel world ticking @@ -582,69 +582,15 @@ index 56453454cbd4b9e9270fc833f8ab38d5fa7a3763..c3cc5012cf460f57495d8867f1980076 + CraftBlockEntityState.setDisableSnapshotTL(!useSnapshot); + // DivineMC end - Parallel world ticking try { - // Paper end - CraftBlockState blockState = CraftBlockStates.getBlockState(world, blockPosition, blockData, tileEntity); -@@ -258,7 +260,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); // DivineMC - Parallel world ticking } - // 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 4df143dfa4c01dc70e496ec8dc44fdde00ab40c6..59ee059f8d2d96b5e5ae507f209d267da24c9fa1 100644 ---- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -961,6 +961,26 @@ 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. -+ // DivineMC start - Parallel world ticking -+ public static final ThreadLocal sourceBlockOverrideTL = new ThreadLocal<>(); -+ -+ public static BlockPos getSourceBlockOverrideTL() { -+ BlockPos sourceBlockOverrideRTCopy; -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && (sourceBlockOverrideRTCopy = sourceBlockOverrideTL.get()) != null) return sourceBlockOverrideRTCopy; -+ -+ synchronized (CraftEventFactory.class) { -+ return sourceBlockOverride; -+ } -+ } -+ -+ public static void setSourceBlockOverrideTL(BlockPos value) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) sourceBlockOverrideTL.set(value); -+ -+ synchronized (CraftEventFactory.class) { -+ sourceBlockOverride = value; -+ } -+ } -+ // DivineMC end - Parallel world ticking - - 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 +992,10 @@ public class CraftEventFactory { - CraftBlockState state = CraftBlockStates.getBlockState(world, target, flag); - state.setData(block); - -- BlockSpreadEvent event = new BlockSpreadEvent(state.getBlock(), CraftBlock.at(world, CraftEventFactory.sourceBlockOverride != null ? CraftEventFactory.sourceBlockOverride : source), state); -+ // DivineMC start - Parallel world ticking -+ final BlockPos sourceBlockOverrideRTSnap = getSourceBlockOverrideTL(); -+ BlockSpreadEvent event = new BlockSpreadEvent(state.getBlock(), CraftBlock.at(world, sourceBlockOverrideRTSnap != null ? sourceBlockOverrideRTSnap : source), state); -+ // DivineMC end - Parallel world ticking - Bukkit.getPluginManager().callEvent(event); - - if (!event.isCancelled()) { -@@ -2245,7 +2268,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()) { // DivineMC - Parallel world ticking - if (!event.callEvent()) { - return itemStack; - } diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java index e4e2e42d0ca25df7fe9f2dd4275610e45fcb2c84..8d0816dcc4159b62e5bbb03e3897b255feb961e6 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/util/structure/GeneralUtils.java b/divinemc-server/src/main/java/org/bxteam/divinemc/util/structure/GeneralUtils.java index 3298792..f88d834 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/util/structure/GeneralUtils.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/util/structure/GeneralUtils.java @@ -45,7 +45,7 @@ public final class GeneralUtils { for (StructureTemplate.JigsawBlockInfo structureBlockInfo : list) { int key = 0; if (structureBlockInfo.info().nbt() != null) { - key = getIntMicroOptimised(structureBlockInfo.info().nbt(), "selection_priority"); + key = structureBlockInfo.info().nbt().getIntOr("selection_priority", 0); } buckets.computeIfAbsent(key, k -> new ArrayList<>()).add(structureBlockInfo); @@ -73,12 +73,8 @@ public final class GeneralUtils { } } - public static int getIntMicroOptimised(@NotNull CompoundTag tag, String key) { - return tag.get(key) instanceof NumericTag numericTag ? numericTag.getAsInt() : 0; - } - public static @NotNull String getStringMicroOptimised(@NotNull CompoundTag tag, String key) { - return tag.get(key) instanceof StringTag stringTag ? stringTag.getAsString() : ""; + return tag.get(key) instanceof StringTag stringTag ? stringTag.value() : ""; } public static void copyAll(@NotNull List src, List dest) {