From 8ab1873995339daf39229b54b48f1c144dca00d5 Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Tue, 28 Oct 2025 16:41:19 +0300 Subject: [PATCH] update parallel world ticking, add api --- ...-SparklyPaper-Parallel-world-ticking.patch | 59 +++++ ...-SparklyPaper-Parallel-world-ticking.patch | 208 +++++++++--------- .../0051-Regionized-Chunk-Ticking.patch | 10 +- .../0060-Cleanup-dead-code-from-Paper.patch | 6 +- .../0067-Optimize-level-ticking.patch | 6 +- .../features/0068-Optimize-Moonrise.patch | 12 +- .../0071-lithium-sleeping_block_entity.patch | 12 +- ...-SparklyPaper-Parallel-world-ticking.patch | 106 ++++----- .../bxteam/divinemc/config/DivineConfig.java | 3 - 9 files changed, 226 insertions(+), 196 deletions(-) create mode 100644 divinemc-api/paper-patches/features/0010-SparklyPaper-Parallel-world-ticking.patch diff --git a/divinemc-api/paper-patches/features/0010-SparklyPaper-Parallel-world-ticking.patch b/divinemc-api/paper-patches/features/0010-SparklyPaper-Parallel-world-ticking.patch new file mode 100644 index 0000000..fabdee1 --- /dev/null +++ b/divinemc-api/paper-patches/features/0010-SparklyPaper-Parallel-world-ticking.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> +Date: Tue, 28 Oct 2025 16:26:54 +0300 +Subject: [PATCH] SparklyPaper: Parallel world ticking + +Original license: MIT +Original project (API): https://github.com/Biquaternions/Fish +Original project: https://github.com/SparklyPower/SparklyPaper + +This patch provides an API for performance monitoring plugins. + +diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java +index bf664ec7a3974abdb7fd3266b08803a02cb05929..d21f2c33480177f4892c906b80ffe89686ac663a 100644 +--- a/src/main/java/org/bukkit/Server.java ++++ b/src/main/java/org/bukkit/Server.java +@@ -2879,4 +2879,15 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi + */ + void clearBlockHighlights(); + // Purpur end - Debug Marker API ++ ++ // DivineMC start - Parallel world ticking ++ /** ++ * Returns whether the software has the Parallel World Ticking feature enabled ++ * ++ * @return If the Parallel World Ticking feature is enabled ++ */ ++ public default boolean isParallelWorldTickingEnabled() { ++ return false; ++ } ++ // DivineMC end - Parallel world ticking + } +diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java +index d320e8b621a8725d07579fbc3182df9b4822e3fb..6128b98305ee0c843df4bfef13fcb2f6a809d416 100644 +--- a/src/main/java/org/bukkit/World.java ++++ b/src/main/java/org/bukkit/World.java +@@ -4722,4 +4722,23 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient + } + } + } ++ ++ // DivineMC start - Parallel world ticking ++ /** ++ * Get a sample of the world last tick times (in nanos) ++ * ++ * @return A sample of the world last tick times (in nanos) ++ */ ++ public default long @NotNull [] getTickTimes() { ++ return new long[0]; ++ } ++ /** ++ * Get the world's average tick time (in millis) ++ * ++ * @return World's local average tick time (in millis) ++ */ ++ public default double getAverageTickTime () { ++ return 0.0; ++ } ++ // DivineMC end - Parallel world ticking + } diff --git a/divinemc-server/minecraft-patches/features/0048-SparklyPaper-Parallel-world-ticking.patch b/divinemc-server/minecraft-patches/features/0048-SparklyPaper-Parallel-world-ticking.patch index 1343711..e6f8ea0 100644 --- a/divinemc-server/minecraft-patches/features/0048-SparklyPaper-Parallel-world-ticking.patch +++ b/divinemc-server/minecraft-patches/features/0048-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/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -index 467065e3b40df17f38716499259b46663c174fd0..a95db39c5ca9f4de9afe64b1cbc75ca8e86b8521 100644 +index 467065e3b40df17f38716499259b46663c174fd0..18822bed7986348bbbed1712db7dac65884d39a9 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java @@ -1129,7 +1129,7 @@ public final class ChunkHolderManager { @@ -33,20 +33,37 @@ index 467065e3b40df17f38716499259b46663c174fd0..a95db39c5ca9f4de9afe64b1cbc75ca8 if (BLOCK_TICKET_UPDATES.get() == Boolean.TRUE) { throw new IllegalStateException("Cannot unload chunks recursively"); -@@ -1416,7 +1422,7 @@ public final class ChunkHolderManager { +@@ -1416,7 +1422,11 @@ public final class ChunkHolderManager { if (BLOCK_TICKET_UPDATES.get() == Boolean.TRUE) { throw new IllegalStateException("Cannot update ticket level while unloading chunks or updating entity manager"); } - final boolean isTickThread = TickThread.isTickThread(); -+ final boolean isTickThread = org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && TickThread.isTickThreadFor(world) || TickThread.isTickThread(); // DivineMC - Parallel world ticking ++ // DivineMC start - Parallel world ticking ++ final boolean isTickThread = org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking ++ ? TickThread.isTickThreadFor(world) ++ : TickThread.isTickThread(); ++ // DivineMC end - Parallel world ticking if (!PlatformHooks.get().allowAsyncTicketUpdates() && isTickThread) { TickThread.ensureTickThread("Cannot asynchronously process ticket updates"); +diff --git a/io/papermc/paper/entity/activation/ActivationRange.java b/io/papermc/paper/entity/activation/ActivationRange.java +index 226088405c019922085285ba5d04d7c131470c69..5d9089d98ed0daa8ee680123e50c3ce9abd2bca6 100644 +--- a/io/papermc/paper/entity/activation/ActivationRange.java ++++ b/io/papermc/paper/entity/activation/ActivationRange.java +@@ -120,7 +120,7 @@ public final class ActivationRange { + * + * @param world + */ +- public static void activateEntities(final Level world) { ++ public synchronized static void activateEntities(final Level world) { // DivineMC - Parallel world ticking + final int miscActivationRange = world.spigotConfig.miscActivationRange; + final int raiderActivationRange = world.spigotConfig.raiderActivationRange; + final int animalActivationRange = world.spigotConfig.animalActivationRange; diff --git a/io/papermc/paper/redstone/RedstoneWireTurbo.java b/io/papermc/paper/redstone/RedstoneWireTurbo.java -index ff747a1ecdf3c888bca0d69de4f85dcd810b6139..544c05c94b535174d97675ea3c21706dfe305438 100644 +index ff747a1ecdf3c888bca0d69de4f85dcd810b6139..4970243433e7de4ec2e452f25f8737cd57f2d263 100644 --- a/io/papermc/paper/redstone/RedstoneWireTurbo.java +++ b/io/papermc/paper/redstone/RedstoneWireTurbo.java -@@ -829,14 +829,9 @@ public final class RedstoneWireTurbo { +@@ -829,14 +829,21 @@ public final class RedstoneWireTurbo { j = getMaxCurrentStrength(upd, j); int l = 0; @@ -59,7 +76,19 @@ index ff747a1ecdf3c888bca0d69de4f85dcd810b6139..544c05c94b535174d97675ea3c21706d - final int k = worldIn.getBestNeighborSignal(upd.self); - wire.shouldSignal = true; + // DivineMC start - Parallel world ticking -+ final int k = wire.getBlockSignal(worldIn, upd.self); ++ final int k; ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { ++ k = wire.getBlockSignal(worldIn, upd.self); ++ } else { ++ wire.shouldSignal = false; ++ // Unfortunately, World.isBlockIndirectlyGettingPowered is complicated, ++ // and I'm not ready to try to replicate even more functionality from ++ // elsewhere in Minecraft into this accelerator. So sadly, we must ++ // suffer the performance hit of this very expensive call. If there ++ // is consistency to what this call returns, we may be able to cache it. ++ k = worldIn.getBestNeighborSignal(upd.self); ++ wire.shouldSignal = true; ++ } + // DivineMC end - Parallel world ticking // The variable 'k' holds the maximum redstone power value of any adjacent blocks. @@ -82,7 +111,7 @@ index 181fdb493f64442c659165c10e237ebc198fb6e2..43363235f3dc696973eee99548b1ae55 List states = new java.util.ArrayList<>(level.capturedBlockStates.values()); level.capturedBlockStates.clear(); diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 698460d2dc19a0bdf6cf2a528a702d6dbc625eb2..fd9ef48ac8b23e8b409c00d154dbea27b701e3bc 100644 +index 698460d2dc19a0bdf6cf2a528a702d6dbc625eb2..311aa4ea612c706032d8d3b7ec8fba5b7714a6db 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -289,6 +289,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop progress = new LinkedHashMap<>(); private final Set visible = new HashSet<>(); - private final Set progressChanged = new HashSet<>(); -+ private final Set progressChangedConcurrent = java.util.concurrent.ConcurrentHashMap.newKeySet(); // DivineMC - Parallel world ticking +- private final Set progressChanged = new HashSet<>(); ++ private final Set progressChanged = org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking ? java.util.concurrent.ConcurrentHashMap.newKeySet() : new HashSet<>(); // DivineMC - Parallel world ticking private final Set rootsToUpdate = new HashSet<>(); private ServerPlayer player; @Nullable -@@ -88,6 +89,7 @@ public class PlayerAdvancements { - this.visible.clear(); - this.rootsToUpdate.clear(); - this.progressChanged.clear(); -+ this.progressChangedConcurrent.clear(); // DivineMC - Parallel world ticking - this.isFirstPacket = true; - this.lastSelectedTab = null; - this.tree = manager.tree(); -@@ -178,10 +180,12 @@ public class PlayerAdvancements { - return false; - } - // Paper end - Add PlayerAdvancementCriterionGrantEvent -- this.unregisterListeners(advancement); -- this.progressChanged.add(advancement); -- flag = true; -- if (!isDone && orStartProgress.isDone()) { -+ // DivineMC start - Parallel world ticking -+ this.unregisterListeners(advancement); // Must unregister criteria listeners -+ (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking ? this.progressChangedConcurrent : this.progressChanged).add(advancement); -+ flag = true; // Mark progress changed -+ if (!isDone && orStartProgress.isDone()) { // If the advancement was just completed -+ // DivineMC end - Parallel world ticking - // Paper start - Add Adventure message to PlayerAdvancementDoneEvent - final net.kyori.adventure.text.Component message = advancement.value().display().flatMap(info -> { - return java.util.Optional.ofNullable( -@@ -215,8 +219,10 @@ public class PlayerAdvancements { - AdvancementProgress orStartProgress = this.getOrStartProgress(advancement); - boolean isDone = orStartProgress.isDone(); - if (orStartProgress.revokeProgress(criterionKey)) { -+ // DivineMC start - Parallel world ticking - this.registerListeners(advancement); -- this.progressChanged.add(advancement); -+ (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking ? this.progressChangedConcurrent : this.progressChanged).add(advancement); -+ // DivineMC end - Parallel world ticking - flag = true; - } - -@@ -266,7 +272,11 @@ public class PlayerAdvancements { +@@ -266,6 +266,7 @@ public class PlayerAdvancements { } public void flushDirty(ServerPlayer player, boolean showAdvancements) { -- if (this.isFirstPacket || !this.rootsToUpdate.isEmpty() || !this.progressChanged.isEmpty()) { -+ // DivineMC start - Parallel world ticking -+ final boolean useConcurrent = org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking; -+ final Set relevantProgressSet = useConcurrent ? this.progressChangedConcurrent : this.progressChanged; -+ if (this.isFirstPacket || !this.rootsToUpdate.isEmpty() || !relevantProgressSet.isEmpty()) { -+ // DivineMC end - Parallel world ticking ++ final boolean isConcurrent = org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking; // DivineMC - Parallel world ticking + if (this.isFirstPacket || !this.rootsToUpdate.isEmpty() || !this.progressChanged.isEmpty()) { Map map = new HashMap<>(); Set set = new java.util.TreeSet<>(java.util.Comparator.comparing(adv -> adv.id().toString())); // Paper - Changed from HashSet to TreeSet ordered alphabetically. - Set set1 = new HashSet<>(); -@@ -277,13 +287,23 @@ public class PlayerAdvancements { +@@ -277,13 +278,23 @@ public class PlayerAdvancements { this.rootsToUpdate.clear(); @@ -302,36 +290,27 @@ index 3836d60ce84fb26f30a609486a5755d3fd1c94f1..1aab02441e4dfa7703963855d77bb918 - if (this.visible.contains(advancementHolder)) { - map.put(advancementHolder.id(), this.progress.get(advancementHolder)); + // DivineMC start - Parallel world ticking -+ if (!relevantProgressSet.isEmpty()) { -+ Set toProcess = useConcurrent ? new HashSet<>(relevantProgressSet) : relevantProgressSet; ++ if (!this.progressChanged.isEmpty()) { ++ Set toProcess = isConcurrent ? new HashSet<>(this.progressChanged) : this.progressChanged; + + for (AdvancementHolder advancementHolder : toProcess) { + if (this.visible.contains(advancementHolder)) { + map.put(advancementHolder.id(), this.progress.get(advancementHolder)); + } -+ } -+ -+ if (useConcurrent) { -+ this.progressChangedConcurrent.removeAll(toProcess); + } +- } + +- this.progressChanged.clear(); ++ if (isConcurrent) { ++ this.progressChanged.removeAll(toProcess); + } else { + this.progressChanged.clear(); - } - } -- -- this.progressChanged.clear(); ++ } ++ } + // DivineMC end - Parallel world ticking if (!map.isEmpty() || !set.isEmpty() || !set1.isEmpty()) { player.connection.send(new ClientboundUpdateAdvancementsPacket(this.isFirstPacket, set, set1, map, showAdvancements)); } -@@ -328,7 +348,7 @@ public class PlayerAdvancements { - if (this.visible.add(advancementHolder)) { - advancementOutput.add(advancementHolder); - if (this.progress.containsKey(advancementHolder)) { -- this.progressChanged.add(advancementHolder); -+ (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking ? this.progressChangedConcurrent : this.progressChanged).add(advancementHolder); // DivineMC - Parallel world ticking - } - } - } else if (this.visible.remove(advancementHolder)) { diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java index c37851095cfe637a2768de0aa179efe66e9a4cde..1afd48654a421f0e0d4d5c2f27bdfe0b5f436bb8 100644 --- a/net/minecraft/server/dedicated/DedicatedServer.java @@ -370,7 +349,7 @@ index d8f0bd8173836796ecdd9771b637d24c7a807a79..e23f2004705fc299934a8b30e736ddf0 } } diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 0b1ea5c5248f0b54ba7b01d7bc89e1547ad2a89a..aa6d923d5e14aa0b2e920a7ae5c89dd151ad2c3c 100644 +index 0b1ea5c5248f0b54ba7b01d7bc89e1547ad2a89a..27a63526c4fde0a716eb9ac3f8f4d0fd84b550dc 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -186,7 +186,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -399,15 +378,34 @@ index 0b1ea5c5248f0b54ba7b01d7bc89e1547ad2a89a..aa6d923d5e14aa0b2e920a7ae5c89dd1 // Paper start - rewrite chunk system this.moonrise$setEntityLookup(new ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup((ServerLevel)(Object)this, ((ServerLevel)(Object)this).new EntityCallbacks())); this.chunkTaskScheduler = new ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler((ServerLevel)(Object)this); -@@ -722,6 +723,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -722,6 +723,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit this.preciseTime = this.serverLevelData.getDayTime(); // Purpur - Configurable daylight cycle this.ominousBanner = Objects.requireNonNullElse(this.registryAccess(), net.minecraft.core.RegistryAccess.EMPTY).lookup(Registries.BANNER_PATTERN).map(Raid::getOminousBannerInstance).orElse(null); // DivineMC - Optimize Raids -+ this.tickExecutor = java.util.concurrent.Executors.newSingleThreadExecutor(new org.bxteam.divinemc.async.world.ServerLevelTickThreadFactory(getWorld().getName())); // DivineMC - Parallel world ticking ++ // DivineMC start - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { ++ this.tickExecutor = java.util.concurrent.Executors.newSingleThreadExecutor(new org.bxteam.divinemc.async.world.ServerLevelTickThreadFactory(getWorld().getName())); ++ } else { ++ this.tickExecutor = null; ++ } ++ // DivineMC end - Parallel world ticking } // Paper start -@@ -1336,12 +1338,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -763,6 +771,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + this.advanceWeatherCycle(); + } + ++ // DivineMC start - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && (++this.tickedBlocksOrFluids & 7L) != 0L) { ++ this.moonrise$midTickTasks(); ++ } ++ // DivineMC end - Parallel world ticking ++ + 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 +@@ -1336,12 +1350,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (fluidState.is(fluid)) { fluidState.tick(this, pos, blockState); } @@ -425,7 +423,7 @@ index 0b1ea5c5248f0b54ba7b01d7bc89e1547ad2a89a..aa6d923d5e14aa0b2e920a7ae5c89dd1 } private void tickBlock(BlockPos pos, Block block) { -@@ -1349,12 +1351,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1349,12 +1363,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (blockState.is(block)) { blockState.tick(this, pos, this.random); } @@ -443,7 +441,7 @@ index 0b1ea5c5248f0b54ba7b01d7bc89e1547ad2a89a..aa6d923d5e14aa0b2e920a7ae5c89dd1 } // Paper start - log detailed entity tick information -@@ -1614,6 +1616,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1614,6 +1628,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } private void addPlayer(ServerPlayer player) { @@ -451,7 +449,7 @@ index 0b1ea5c5248f0b54ba7b01d7bc89e1547ad2a89a..aa6d923d5e14aa0b2e920a7ae5c89dd1 Entity entity = this.getEntity(player.getUUID()); if (entity != null) { LOGGER.warn("Force-added player with duplicate UUID {}", player.getUUID()); -@@ -1626,7 +1629,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1626,7 +1641,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // CraftBukkit start private boolean addEntity(Entity entity, @Nullable org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { @@ -915,7 +913,7 @@ index 9213d25928066ee6722f1a145ae37e99d6e62582..28f0b59500d67bdd92c97a7e138c9488 } else { Entity entity = owner.teleport( diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java -index c0b54e17d75150b1114a9d5895311995726bb88f..c88b0567d1b9377bfca4e4a62d8eb22daccd83a8 100644 +index c0b54e17d75150b1114a9d5895311995726bb88f..7d35e587508f24401a998de27f88ce9cef961b8a 100644 --- a/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/net/minecraft/world/inventory/AbstractContainerMenu.java @@ -96,8 +96,14 @@ public abstract class AbstractContainerMenu { @@ -926,7 +924,7 @@ index c0b54e17d75150b1114a9d5895311995726bb88f..c88b0567d1b9377bfca4e4a62d8eb22d protected AbstractContainerMenu(@Nullable MenuType menuType, int containerId) { + // DivineMC start - Parallel world ticking (debugging) -+ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.logContainerCreationStacktraces) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && org.bxteam.divinemc.config.DivineConfig.AsyncCategory.logContainerCreationStacktraces) { + this.containerCreationStacktrace = new Throwable(); + } + // DivineMC start - Parallel world ticking (debugging) @@ -951,18 +949,26 @@ index e4bcd4a3cbbc8942d52e5f3c7a4fb1572fdef91c..52a8a818a636e35b486b8aaf482cd688 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 79627c421088d439745164d7652a0cc1d93ced30..a8c2e02450caa52714bc3e064237d12fa56b4207 100644 +index 79627c421088d439745164d7652a0cc1d93ced30..1f00b7ddf6c470c8a32e418775fa40e90ec88dbe 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java -@@ -166,6 +166,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - - public final org.purpurmc.purpur.PurpurWorldConfig purpurConfig; // Purpur - Purpur config files - public final org.bxteam.divinemc.config.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 @Nullable BlockPos lastPhysicsProblem; // Spigot +@@ -170,6 +170,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl private int tileTickPosition; public final Map explosionDensityCache = new java.util.HashMap<>(); // Paper - Optimize explosions -@@ -1088,6 +1089,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + public java.util.ArrayDeque redstoneUpdateInfos; // Paper - Faster redstone torch rapid clock removal; Move from Map in BlockRedstoneTorch to here ++ public io.papermc.paper.redstone.RedstoneWireTurbo turbo; // DivineMC - Parallel world ticking (moved to world) + + // Purpur start - Add adjustable breeding cooldown to config + private com.google.common.cache.Cache playerBreedingCooldowns; +@@ -920,6 +921,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + this.damageSources = new DamageSources(registryAccess); + this.entityLookup = new ca.spottedleaf.moonrise.patches.chunk_system.level.entity.dfl.DefaultEntityLookup(this); // Paper - rewrite chunk system + this.chunkPacketBlockController = this.paperConfig().anticheat.antiXray.enabled ? new io.papermc.paper.antixray.ChunkPacketBlockControllerAntiXray(this, executor) : io.papermc.paper.antixray.ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray ++ this.turbo = org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking ? new io.papermc.paper.redstone.RedstoneWireTurbo((net.minecraft.world.level.block.RedStoneWireBlock) net.minecraft.world.level.block.Blocks.REDSTONE_WIRE) : null; // DivineMC - Parallel world ticking + } + + // Paper start - Cancel hit for vanished players +@@ -1088,6 +1090,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl @Override public boolean setBlock(BlockPos pos, BlockState state, int flags, int recursionLeft) { @@ -970,7 +976,7 @@ index 79627c421088d439745164d7652a0cc1d93ced30..a8c2e02450caa52714bc3e064237d12f // CraftBukkit start - tree generation if (this.captureTreeGeneration) { // Paper start - Protect Bedrock and End Portal/Frames from being destroyed -@@ -1471,11 +1473,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1471,11 +1474,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl this.blockEntityTickers.markAsRemoved(this.tileTickPosition); // DivineMC - optimize block entity removals - Fix MC-117075 } else if (runsNormally && this.shouldTickBlocksAt(tickingBlockEntity.getPos())) { tickingBlockEntity.tick(); @@ -987,7 +993,7 @@ index 79627c421088d439745164d7652a0cc1d93ced30..a8c2e02450caa52714bc3e064237d12f } } this.blockEntityTickers.removeMarkedEntries(); // DivineMC - optimize block entity removals - Fix MC-117075 -@@ -1495,7 +1498,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1495,7 +1499,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Paper end - Prevent block entity and entity crashes } @@ -1000,7 +1006,7 @@ index 79627c421088d439745164d7652a0cc1d93ced30..a8c2e02450caa52714bc3e064237d12f } // Paper start - Option to prevent armor stands from doing entity lookups -@@ -1637,6 +1644,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1637,6 +1645,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl @Nullable @Override public BlockEntity getBlockEntity(BlockPos pos) { @@ -1008,7 +1014,7 @@ index 79627c421088d439745164d7652a0cc1d93ced30..a8c2e02450caa52714bc3e064237d12f // Paper start - Perf: Optimize capturedTileEntities lookup net.minecraft.world.level.block.entity.BlockEntity blockEntity; if (!this.capturedTileEntities.isEmpty() && (blockEntity = this.capturedTileEntities.get(pos)) != null) { -@@ -1653,6 +1661,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1653,6 +1662,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl } public void setBlockEntity(BlockEntity blockEntity) { @@ -1016,7 +1022,7 @@ index 79627c421088d439745164d7652a0cc1d93ced30..a8c2e02450caa52714bc3e064237d12f BlockPos blockPos = blockEntity.getBlockPos(); if (!this.isOutsideBuildHeight(blockPos)) { // CraftBukkit start -@@ -1738,6 +1747,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1738,6 +1748,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl @Override public List getEntities(@Nullable Entity entity, AABB boundingBox, Predicate predicate) { @@ -1024,7 +1030,7 @@ index 79627c421088d439745164d7652a0cc1d93ced30..a8c2e02450caa52714bc3e064237d12f List list = Lists.newArrayList(); // Paper start - rewrite chunk system -@@ -2087,8 +2097,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -2087,8 +2098,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl public abstract RecipeAccess recipeAccess(); public BlockPos getBlockRandomPos(int x, int y, int z, int yMask) { diff --git a/divinemc-server/minecraft-patches/features/0051-Regionized-Chunk-Ticking.patch b/divinemc-server/minecraft-patches/features/0051-Regionized-Chunk-Ticking.patch index fb26577..f92d363 100644 --- a/divinemc-server/minecraft-patches/features/0051-Regionized-Chunk-Ticking.patch +++ b/divinemc-server/minecraft-patches/features/0051-Regionized-Chunk-Ticking.patch @@ -214,7 +214,7 @@ index e23f2004705fc299934a8b30e736ddf0a8eb2147..e8efa7b12746423de11b6970efe1651d private void tickSpawningChunk(LevelChunk chunk, long timeInhabited, List spawnCategories, NaturalSpawner.SpawnState spawnState) { ChunkPos pos = chunk.getPos(); diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 8bd2e419791f0dffbcbc43edd93178dead0c9620..86469253ecc2a142b70c2601cbc50fe9ffbfedea 100644 +index ca9883277c0f036c94e861f7917ca42facd3c47b..8c98c2593eec14a8a378041e94cf52b8fbfedc30 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -197,7 +197,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -277,7 +277,7 @@ index 8bd2e419791f0dffbcbc43edd93178dead0c9620..86469253ecc2a142b70c2601cbc50fe9 this.chunkSource.getGeneratorState().ensureStructuresGenerated(); this.portalForcer = new PortalForcer(this); this.updateSkyBrightness(); -@@ -834,6 +852,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -846,6 +864,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.dragonFight.tick(); } @@ -291,7 +291,7 @@ index 8bd2e419791f0dffbcbc43edd93178dead0c9620..86469253ecc2a142b70c2601cbc50fe9 io.papermc.paper.entity.activation.ActivationRange.activateEntities(this); // Paper - EAR this.entityTickList .forEach( -@@ -1862,22 +1887,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1874,22 +1899,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (Shapes.joinIsNotEmpty(collisionShape, collisionShape1, BooleanOp.NOT_SAME)) { List list = new ObjectArrayList<>(); @@ -323,7 +323,7 @@ index 8bd2e419791f0dffbcbc43edd93178dead0c9620..86469253ecc2a142b70c2601cbc50fe9 try { this.isUpdatingNavigations = true; diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index a8c2e02450caa52714bc3e064237d12fa56b4207..ebe34866e79397ac4c6a6bba97c99f5354adbe64 100644 +index 1f00b7ddf6c470c8a32e418775fa40e90ec88dbe..5e6306c5322d46c051aea02525d49ae9ed76b85f 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -112,7 +112,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl @@ -344,7 +344,7 @@ index a8c2e02450caa52714bc3e064237d12fa56b4207..ebe34866e79397ac4c6a6bba97c99f53 public Map capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper - Retain block place order when capturing blockstates @Nullable public List captureDrops; -@@ -1457,10 +1457,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1458,10 +1458,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl public void tickBlockEntities() { this.tickingBlockEntities = true; diff --git a/divinemc-server/minecraft-patches/features/0060-Cleanup-dead-code-from-Paper.patch b/divinemc-server/minecraft-patches/features/0060-Cleanup-dead-code-from-Paper.patch index e008383..a181635 100644 --- a/divinemc-server/minecraft-patches/features/0060-Cleanup-dead-code-from-Paper.patch +++ b/divinemc-server/minecraft-patches/features/0060-Cleanup-dead-code-from-Paper.patch @@ -70,10 +70,10 @@ index 98b101fde04fbf5507f021bb8d8e6bed334de5b6..e76530da9641acc482aa0f030c4dc267 } } diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 86469253ecc2a142b70c2601cbc50fe9ffbfedea..66eddcb27d9d3e8af7a5911225397aef10ba48e4 100644 +index 8c98c2593eec14a8a378041e94cf52b8fbfedc30..4788686f0bd8ab67700bf3687560ff4a26a8e493 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -1403,13 +1403,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1415,13 +1415,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // Paper end - log detailed entity tick information public void tickNonPassenger(Entity entity) { @@ -87,7 +87,7 @@ index 86469253ecc2a142b70c2601cbc50fe9ffbfedea..66eddcb27d9d3e8af7a5911225397aef entity.setOldPosAndRot(); entity.tickCount++; entity.totalEntityAge++; // Paper - age-like counter for all entities -@@ -1422,13 +1416,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1434,13 +1428,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe for (Entity entity1 : entity.getPassengers()) { this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2 } diff --git a/divinemc-server/minecraft-patches/features/0067-Optimize-level-ticking.patch b/divinemc-server/minecraft-patches/features/0067-Optimize-level-ticking.patch index c596e4f..e8832dc 100644 --- a/divinemc-server/minecraft-patches/features/0067-Optimize-level-ticking.patch +++ b/divinemc-server/minecraft-patches/features/0067-Optimize-level-ticking.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Optimize level ticking diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 66eddcb27d9d3e8af7a5911225397aef10ba48e4..16b5e2959526cd9f394991730fd179496719ecc4 100644 +index 4788686f0bd8ab67700bf3687560ff4a26a8e493..ba496e78740218a176d8e3117a21cbfc5173cfef 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -962,9 +962,10 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -974,9 +974,10 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // Paper start - optimise random ticking private final ca.spottedleaf.moonrise.common.util.SimpleThreadUnsafeRandom simpleRandom = new ca.spottedleaf.moonrise.common.util.SimpleThreadUnsafeRandom(net.minecraft.world.level.levelgen.RandomSupport.generateUniqueSeed()); @@ -20,7 +20,7 @@ index 66eddcb27d9d3e8af7a5911225397aef10ba48e4..16b5e2959526cd9f394991730fd17949 final ca.spottedleaf.moonrise.common.util.SimpleThreadUnsafeRandom simpleRandom = this.simpleRandom; final boolean doubleTickFluids = !ca.spottedleaf.moonrise.common.PlatformHooks.get().configFixMC224294(); -@@ -973,42 +974,38 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -985,42 +986,38 @@ 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/divinemc-server/minecraft-patches/features/0068-Optimize-Moonrise.patch b/divinemc-server/minecraft-patches/features/0068-Optimize-Moonrise.patch index e6fb566..f154f23 100644 --- a/divinemc-server/minecraft-patches/features/0068-Optimize-Moonrise.patch +++ b/divinemc-server/minecraft-patches/features/0068-Optimize-Moonrise.patch @@ -68,7 +68,7 @@ index 2d24d03bbdb5ee0d862cbfff2219f58afffafe12..b4c55b8fee8dbab278e096580702a052 protected boolean addEntity(final Entity entity, final boolean fromDisk, final boolean event) { diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -index a95db39c5ca9f4de9afe64b1cbc75ca8e86b8521..7cca448dedb167f177c1fa3ba8d13077955a2a5b 100644 +index 18822bed7986348bbbed1712db7dac65884d39a9..906c0019cae2529962d1221939ce276f2c28dae9 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java @@ -75,37 +75,49 @@ public final class ChunkHolderManager { @@ -283,7 +283,7 @@ index a95db39c5ca9f4de9afe64b1cbc75ca8e86b8521..7cca448dedb167f177c1fa3ba8d13077 public enum TicketOperationType { ADD, REMOVE, ADD_IF_REMOVED, ADD_AND_REMOVE } -@@ -1466,8 +1503,10 @@ public final class ChunkHolderManager { +@@ -1470,8 +1507,10 @@ public final class ChunkHolderManager { // only call on tick thread private void processOffThreadFullUpdates() { @@ -296,7 +296,7 @@ index a95db39c5ca9f4de9afe64b1cbc75ca8e86b8521..7cca448dedb167f177c1fa3ba8d13077 NewChunkHolder toUpdate; while ((toUpdate = offThreadPendingFullLoadUpdate.poll()) != null) { -@@ -1479,7 +1518,7 @@ public final class ChunkHolderManager { +@@ -1483,7 +1522,7 @@ public final class ChunkHolderManager { private boolean processPendingFullUpdate() { this.processOffThreadFullUpdates(); @@ -466,7 +466,7 @@ index e8efa7b12746423de11b6970efe1651db2509511..a90086ae56118720cb49b674e031bc9d } diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 16b5e2959526cd9f394991730fd179496719ecc4..973b98d8a074b4461723fc695523b240365244dd 100644 +index ba496e78740218a176d8e3117a21cbfc5173cfef..14790f65b00ede0c063c567f524674270ca58b5c 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -186,6 +186,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -485,7 +485,7 @@ index 16b5e2959526cd9f394991730fd179496719ecc4..973b98d8a074b4461723fc695523b240 this.entityDataController = new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.EntityDataController( new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.EntityDataController.EntityRegionFileStorage( new RegionStorageInfo(levelStorageAccess.getLevelId(), dimension, "entities"), -@@ -900,8 +902,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -912,8 +914,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public boolean shouldTickBlocksAt(long chunkPos) { // Paper start - rewrite chunk system @@ -495,7 +495,7 @@ index 16b5e2959526cd9f394991730fd179496719ecc4..973b98d8a074b4461723fc695523b240 // Paper end - rewrite chunk system } -@@ -2656,16 +2657,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2668,16 +2669,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public boolean isPositionTickingWithEntitiesLoaded(long chunkPos) { // Paper start - rewrite chunk system diff --git a/divinemc-server/minecraft-patches/features/0071-lithium-sleeping_block_entity.patch b/divinemc-server/minecraft-patches/features/0071-lithium-sleeping_block_entity.patch index cc404ba..c44fe37 100644 --- a/divinemc-server/minecraft-patches/features/0071-lithium-sleeping_block_entity.patch +++ b/divinemc-server/minecraft-patches/features/0071-lithium-sleeping_block_entity.patch @@ -71,10 +71,10 @@ index 2b8d394dc30d459127289a1afeee0780003f4c79..2fd2712550a9b8ac79974f113ebcea5d } } diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 973b98d8a074b4461723fc695523b240365244dd..1a669ebe6e6cc777d1c15b20c396f8c8d894e136 100644 +index 14790f65b00ede0c063c567f524674270ca58b5c..f0ad8c869e22c7c10e59e88effd4b0ebffb3f62c 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -2508,6 +2508,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2520,6 +2520,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe for (TickingBlockEntity tickingBlockEntity : this.blockEntityTickers) { BlockPos pos = tickingBlockEntity.getPos(); @@ -264,7 +264,7 @@ index 0f9bfcd1eab023c1772e9fafcda85d110904bd1c..a54dbf14af2abcf0307c1c43fb82cfd6 + // DivineMC end - lithium: sleeping_block_entity } diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java -index c88b0567d1b9377bfca4e4a62d8eb22daccd83a8..487c8812f921ecc7b00ecac7deee5ac76954aa40 100644 +index 7d35e587508f24401a998de27f88ce9cef961b8a..343bfbb8b122b5c1d6fd8de736a8ad7ed5367cd6 100644 --- a/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/net/minecraft/world/inventory/AbstractContainerMenu.java @@ -901,6 +901,12 @@ public abstract class AbstractContainerMenu { @@ -417,10 +417,10 @@ index 52a8a818a636e35b486b8aaf482cd68849a0bbcd..7706bf3cdd8017eb0591a4002489835b + // DivineMC end - lithium: sleeping_block_entity } diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 604b4670f59e0c3ed5c287e8a0c573560826ed78..2f031b9119f7b520d736223ab8a7d96d79b17d52 100644 +index b799bcd450da148a941289a23bd3758cc75245d2..2c06a6dd8d6164818777753f6572e1f07043abae 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java -@@ -1475,7 +1475,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1476,7 +1476,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl // Spigot end if (tickingBlockEntity.isRemoved()) { this.blockEntityTickers.markAsRemoved(this.tileTickPosition); // DivineMC - optimize block entity removals - Fix MC-117075 @@ -429,7 +429,7 @@ index 604b4670f59e0c3ed5c287e8a0c573560826ed78..2f031b9119f7b520d736223ab8a7d96d tickingBlockEntity.tick(); // DivineMC start - Parallel world ticking ++tickedEntities; -@@ -2195,4 +2195,25 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -2196,4 +2196,25 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl return getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END; } // Purpur end - Add allow water in end world option diff --git a/divinemc-server/paper-patches/features/0016-SparklyPaper-Parallel-world-ticking.patch b/divinemc-server/paper-patches/features/0016-SparklyPaper-Parallel-world-ticking.patch index 2b96f5d..abadc6e 100644 --- a/divinemc-server/paper-patches/features/0016-SparklyPaper-Parallel-world-ticking.patch +++ b/divinemc-server/paper-patches/features/0016-SparklyPaper-Parallel-world-ticking.patch @@ -222,33 +222,24 @@ index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..73475f21a65395ab3f888d04d4860acd } + // DivineMC end - Parallel world ticking } -diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java -index ab499a7eaccdc1578ec64f90f54f79b0da3c0e96..6bcb8069de18e8a0f4ee9d5c71b6bdd1afe640dd 100644 ---- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java -+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java -@@ -28,6 +28,7 @@ import java.util.logging.Level; - class PaperEventManager { - - private final Server server; -+ private final org.purpurmc.purpur.util.MinecraftInternalPlugin minecraftInternalPlugin = new org.purpurmc.purpur.util.MinecraftInternalPlugin(); // DivineMC - Parallel world ticking - - public PaperEventManager(Server server) { - this.server = server; -@@ -40,6 +41,12 @@ class PaperEventManager { - if (listeners.length == 0) return; - // DivineMC end - Skip event if no listeners - if (event.isAsynchronous() && this.server.isPrimaryThread()) { -+ // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && org.bxteam.divinemc.config.DivineConfig.AsyncCategory.pwtCompatabilityMode) { -+ org.bukkit.Bukkit.getAsyncScheduler().runNow(minecraftInternalPlugin, task -> event.callEvent()); -+ return; -+ } -+ // DivineMC end - Parallel world ticking - throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously."); - } else if (!event.isAsynchronous() && !this.server.isPrimaryThread() && !this.server.isStopping()) { - // DivineMC start - Multithreaded Tracker +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index 560f7192b45399947e9a805d80c36a65aa0a53eb..8889864e988e0df590a1dcf407428f0de35f4d03 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -3067,4 +3067,11 @@ public final class CraftServer implements Server { + return getServer().lagging; + } + // Purpur end - Lagging threshold ++ ++ // DivineMC start - Parallel world ticking ++ @Override ++ public boolean isParallelWorldTickingEnabled() { ++ return org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking; ++ } ++ // DivineMC end - Parallel world ticking + } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 89df0225f6544e226afe57b3dd19eadcb5631111..738b9000dfc72016707a2f985b9612b9f9dba7f2 100644 +index 89df0225f6544e226afe57b3dd19eadcb5631111..8480004bcefee0a5d190dcf7136df18f13bb7db2 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -462,7 +462,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -329,6 +320,22 @@ index 89df0225f6544e226afe57b3dd19eadcb5631111..738b9000dfc72016707a2f985b9612b9 getHandle().gameEvent(sourceEntity != null ? ((CraftEntity) sourceEntity).getHandle(): null, net.minecraft.core.registries.BuiltInRegistries.GAME_EVENT.get(org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(gameEvent.getKey())).orElseThrow(), org.bukkit.craftbukkit.util.CraftVector.toBlockPos(position)); } // Paper end +@@ -2112,4 +2130,15 @@ public class CraftWorld extends CraftRegionAccessor implements World { + return POINTERS_SUPPLIER.view(this); + } + // Paper end ++ ++ // DivineMC start - Parallel world ticking ++ @Override ++ public long @NotNull [] getTickTimes() { ++ return this.world.tickTimes5s.getTimes(); ++ } ++ @Override ++ public double getAverageTickTime() { ++ return this.world.tickTimes5s.getAverage(); ++ } ++ // DivineMC end - Parallel world ticking + } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java index 52b3362259ed1ba2ce5379230b2c3b06b0ff6249..1d8c9f94198b558a6b4cdc5d4981b6b4e946903b 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -592,45 +599,11 @@ index 03418a9d7cca79a6fa682b64f9d901a4af3e1d58..f0af6319089b477c5d63aec521aee4cc } } -diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java -index e4e2e42d0ca25df7fe9f2dd4275610e45fcb2c84..93bf7beab3b00973a19e51d48a9dfb26dd0a254c 100644 ---- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java -+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java -@@ -19,11 +19,28 @@ class CraftAsyncTask extends CraftTask { - - @Override - public boolean isSync() { -- return false; -+ return org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && org.bxteam.divinemc.config.DivineConfig.AsyncCategory.pwtCompatabilityMode; // DivineMC - Parallel world ticking - } - - @Override - public void run() { -+ // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && org.bxteam.divinemc.config.DivineConfig.AsyncCategory.pwtCompatabilityMode) { -+ try { -+ super.run(); -+ } catch (final Throwable t) { -+ this.getOwner().getLogger().log( -+ Level.WARNING, -+ String.format( -+ "Plugin %s generated an exception while executing task %s (sync mode)", -+ this.getOwner().getDescription().getFullName(), -+ this.getTaskId()), -+ t); -+ } -+ return; -+ } -+ // DivineMC end - Parallel world ticking -+ - final Thread thread = Thread.currentThread(); - // Paper start - name threads according to running plugin - final String nameBefore = thread.getName(); diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java -index 0e5b10153821fda6056791e1c216d05a9ac8e5bc..85699885e6be932758978eec5d2b8ff22944c7c3 100644 +index 0e5b10153821fda6056791e1c216d05a9ac8e5bc..89e12d30d0815d93842b59642178b4558ee9aae3 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java +++ b/src/main/java/org/spigotmc/WatchdogThread.java -@@ -112,6 +112,23 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre +@@ -112,6 +112,18 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre WatchdogThread.dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(MinecraftServer.getServer().serverThread.threadId(), Integer.MAX_VALUE), logger); logger.log(Level.SEVERE, "------------------------------"); @@ -638,13 +611,8 @@ index 0e5b10153821fda6056791e1c216d05a9ac8e5bc..85699885e6be932758978eec5d2b8ff2 + if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { + logger.log(Level.SEVERE, "Parallel world ticking thread dump"); + for (Thread thread : org.apache.commons.lang3.ThreadUtils.getAllThreads()) { -+ if (MinecraftServer.getServer().serverThread == thread || thread instanceof WatchdogThread) { -+ continue; -+ } -+ if (thread instanceof ca.spottedleaf.moonrise.common.util.TickThread tickThread) { -+ if (tickThread instanceof ServerLevelTickThread tickThread1) { -+ WatchdogThread.dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(tickThread1.threadId(), Integer.MAX_VALUE), logger); -+ } ++ if (thread instanceof ServerLevelTickThread tickThread) { ++ WatchdogThread.dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(tickThread.threadId(), Integer.MAX_VALUE), logger); + } + } + logger.log(Level.SEVERE, "------------------------------"); diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java b/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java index 0beced7..ffaaadd 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java @@ -191,7 +191,6 @@ public class DivineConfig { public static int parallelThreadCount = 4; public static boolean logContainerCreationStacktraces = false; public static boolean disableHardThrow = false; - public static boolean pwtCompatabilityMode = false; public static boolean usePerWorldTpsBar = true; public static boolean showTPSOfServerInsteadOfWorld = true; @@ -241,8 +240,6 @@ public class DivineConfig { logContainerCreationStacktraces = getBoolean(ConfigCategory.ASYNC.key("parallel-world-ticking.log-container-creation-stacktraces"), logContainerCreationStacktraces); disableHardThrow = getBoolean(ConfigCategory.ASYNC.key("parallel-world-ticking.disable-hard-throw"), disableHardThrow, "Disables annoying 'not on main thread' throws. But, THIS IS NOT RECOMMENDED because you SHOULD FIX THE ISSUES THEMSELVES instead of RISKING DATA CORRUPTION! If you lose something, take the blame on yourself."); - pwtCompatabilityMode = getBoolean(ConfigCategory.ASYNC.key("parallel-world-ticking.compatability-mode"), pwtCompatabilityMode, - "Enables compatibility mode for plugins that are not compatible with Parallel World Ticking. This makes all async tasks run synchronously."); usePerWorldTpsBar = getBoolean(ConfigCategory.ASYNC.key("parallel-world-ticking.use-per-world-tps-bar"), usePerWorldTpsBar, "Enables per-world TPS bar, which shows the TPS of the world the player is currently in. TPS bar can be turned on/off with /tpsbar command."); showTPSOfServerInsteadOfWorld = getBoolean(ConfigCategory.ASYNC.key("parallel-world-ticking.show-tps-of-server-instead-of-world"), showTPSOfServerInsteadOfWorld,