From 86763bcff405a3abca6dc71823efcf108df85b59 Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Wed, 9 Jul 2025 03:03:03 +0300 Subject: [PATCH] another patch applies --- .../0061-Use-switch-for-VarInt-write.patch | 68 ++ .../features/0062-Optimize-Fluids.patch | 0 .../0063-Optimize-Structure-Generation.patch | 16 +- .../0064-Implement-NoChatReports.patch | 4 +- .../features/0065-Lag-compensation.patch | 18 +- .../features/0066-Virtual-Threads.patch | 4 +- .../features/0067-Async-Chunk-Sending.patch | 6 +- ...-Command-block-parse-results-caching.patch | 2 +- .../0069-Player-ProfileResult-caching.patch | 0 .../features/0070-Implement-Secure-Seed.patch | 12 +- .../0071-Dynamic-Activation-of-Brain.patch | 10 +- .../0072-Petal-Async-Pathfinding.patch | 18 +- .../0073-Petal-Multithreaded-Tracker.patch | 40 +- ...074-Pufferfish-Optimize-mob-spawning.patch | 109 +-- .../features/0015-Implement-Secure-Seed.patch | 2 +- .../0016-Petal-Multithreaded-Tracker.patch | 18 +- ...017-Pufferfish-Optimize-mob-spawning.patch | 59 ++ .../pufferfish/util/IterableWrapper.java | 13 + .../minecraft/0008-Misc-Optimizations.patch | 741 ------------------ ...08-Configurable-thread-pool-priority.patch | 18 - .../server/paper/0009-Virtual-Threads.patch | 59 -- 21 files changed, 257 insertions(+), 960 deletions(-) create mode 100644 divinemc-server/minecraft-patches/features/0061-Use-switch-for-VarInt-write.patch rename patches/work/server/minecraft/0009-Optimize-Fluids.patch => divinemc-server/minecraft-patches/features/0062-Optimize-Fluids.patch (100%) rename patches/work/server/minecraft/0025-Optimize-Structure-Generation.patch => divinemc-server/minecraft-patches/features/0063-Optimize-Structure-Generation.patch (97%) rename patches/work/server/minecraft/0013-Implement-NoChatReports.patch => divinemc-server/minecraft-patches/features/0064-Implement-NoChatReports.patch (99%) rename patches/work/server/minecraft/0012-Lag-compensation.patch => divinemc-server/minecraft-patches/features/0065-Lag-compensation.patch (95%) rename patches/work/server/minecraft/0024-Virtual-Threads.patch => divinemc-server/minecraft-patches/features/0066-Virtual-Threads.patch (98%) rename patches/work/server/minecraft/0027-Async-Chunk-Sending.patch => divinemc-server/minecraft-patches/features/0067-Async-Chunk-Sending.patch (95%) rename patches/work/server/minecraft/0032-Command-block-parse-results-caching.patch => divinemc-server/minecraft-patches/features/0068-Command-block-parse-results-caching.patch (98%) rename patches/work/server/minecraft/0040-Player-ProfileResult-caching.patch => divinemc-server/minecraft-patches/features/0069-Player-ProfileResult-caching.patch (100%) rename patches/work/server/minecraft/0004-Implement-Secure-Seed.patch => divinemc-server/minecraft-patches/features/0070-Implement-Secure-Seed.patch (98%) rename patches/work/server/minecraft/0037-Dynamic-Activation-of-Brain.patch => divinemc-server/minecraft-patches/features/0071-Dynamic-Activation-of-Brain.patch (98%) rename patches/work/server/minecraft/0005-Async-Pathfinding.patch => divinemc-server/minecraft-patches/features/0072-Petal-Async-Pathfinding.patch (98%) rename patches/work/server/minecraft/0007-Multithreaded-Tracker.patch => divinemc-server/minecraft-patches/features/0073-Petal-Multithreaded-Tracker.patch (95%) rename patches/work/server/minecraft/0041-Async-mob-spawning.patch => divinemc-server/minecraft-patches/features/0074-Pufferfish-Optimize-mob-spawning.patch (66%) rename patches/work/server/paper/0005-Implement-Secure-Seed.patch => divinemc-server/paper-patches/features/0015-Implement-Secure-Seed.patch (96%) rename patches/work/server/paper/0010-Multithreaded-Tracker.patch => divinemc-server/paper-patches/features/0016-Petal-Multithreaded-Tracker.patch (85%) create mode 100644 divinemc-server/paper-patches/features/0017-Pufferfish-Optimize-mob-spawning.patch create mode 100644 divinemc-server/src/main/java/gg/pufferfish/pufferfish/util/IterableWrapper.java delete mode 100644 patches/work/server/minecraft/0008-Misc-Optimizations.patch delete mode 100644 patches/work/server/paper/0008-Configurable-thread-pool-priority.patch delete mode 100644 patches/work/server/paper/0009-Virtual-Threads.patch diff --git a/divinemc-server/minecraft-patches/features/0061-Use-switch-for-VarInt-write.patch b/divinemc-server/minecraft-patches/features/0061-Use-switch-for-VarInt-write.patch new file mode 100644 index 0000000..6421a49 --- /dev/null +++ b/divinemc-server/minecraft-patches/features/0061-Use-switch-for-VarInt-write.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> +Date: Wed, 9 Jul 2025 02:08:35 +0300 +Subject: [PATCH] Use switch for VarInt#write + + +diff --git a/net/minecraft/network/VarInt.java b/net/minecraft/network/VarInt.java +index 4897ff4648083ebe737ae5b32bae344af27357e4..dddabc57f5415077b905cb59c5b47db1a621807f 100644 +--- a/net/minecraft/network/VarInt.java ++++ b/net/minecraft/network/VarInt.java +@@ -51,21 +51,46 @@ public class VarInt { + } + + public static ByteBuf write(ByteBuf buffer, int value) { +- // Paper start - Optimize VarInts +- // Peel the one and two byte count cases explicitly as they are the most common VarInt sizes +- // that the proxy will write, to improve inlining. +- if ((value & (0xFFFFFFFF << 7)) == 0) { +- buffer.writeByte(value); +- } else if ((value & (0xFFFFFFFF << 14)) == 0) { +- int w = (value & 0x7F | 0x80) << 8 | (value >>> 7); +- buffer.writeShort(w); +- } else { +- writeOld(buffer, value); ++ // DivineMC start - Use switch for VarInt#write ++ int bytesNeeded = getByteSize(value); ++ ++ switch (bytesNeeded) { ++ case 1: ++ buffer.writeByte(value); ++ break; ++ case 2: ++ int w2 = ((value & 0x7F) << 8) | (value >>> 7) | 0x00008000; ++ buffer.writeShort(w2); ++ break; ++ case 3: ++ int w3 = (value & 0x7F) << 16 ++ | (value & 0x3F80) << 1 ++ | (value >>> 14) ++ | 0x00808000; ++ buffer.writeMedium(w3); ++ break; ++ case 4: ++ int w4 = (value & 0x7F) << 24 ++ | ((value & 0x3F80) << 9) ++ | (value & 0x1FC000) >> 6 ++ | (value >>> 21) ++ | 0x80808000; ++ buffer.writeInt(w4); ++ break; ++ case 5: ++ int w5 = (value & 0x7F) << 24 ++ | (value & 0x3F80) << 9 ++ | (value & 0x1FC000) >> 6 ++ | ((value >>> 21) & 0x7F) ++ | 0x80808080; ++ buffer.writeInt(w5); ++ buffer.writeByte(value >>> 28); ++ break; + } ++ // DivineMC end - Use switch for VarInt#write + return buffer; + } + public static ByteBuf writeOld(ByteBuf buffer, int value) { +- // Paper end - Optimize VarInts + while ((value & -128) != 0) { + buffer.writeByte(value & 127 | 128); + value >>>= 7; diff --git a/patches/work/server/minecraft/0009-Optimize-Fluids.patch b/divinemc-server/minecraft-patches/features/0062-Optimize-Fluids.patch similarity index 100% rename from patches/work/server/minecraft/0009-Optimize-Fluids.patch rename to divinemc-server/minecraft-patches/features/0062-Optimize-Fluids.patch diff --git a/patches/work/server/minecraft/0025-Optimize-Structure-Generation.patch b/divinemc-server/minecraft-patches/features/0063-Optimize-Structure-Generation.patch similarity index 97% rename from patches/work/server/minecraft/0025-Optimize-Structure-Generation.patch rename to divinemc-server/minecraft-patches/features/0063-Optimize-Structure-Generation.patch index 813d35a..ee3655c 100644 --- a/patches/work/server/minecraft/0025-Optimize-Structure-Generation.patch +++ b/divinemc-server/minecraft-patches/features/0063-Optimize-Structure-Generation.patch @@ -3,9 +3,11 @@ From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Tue, 4 Feb 2025 19:52:24 +0300 Subject: [PATCH] Optimize Structure Generation +Original project: https://github.com/TelepathicGrunt/StructureLayoutOptimizer +Original license: MIT diff --git a/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java b/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java -index 86a54586112b84b7c2026a4cbdad99cdf1c6ef81..e4ca880b5d16ae30676ec25c39c3d5b5f6cb3c24 100644 +index 1cfa0fcd28685736fcdce4aef817e4d4cc4061cb..cd3b24a760053dcd650a1a263b3c0093a0cbb175 100644 --- a/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java +++ b/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java @@ -4,6 +4,8 @@ import com.google.common.collect.Lists; @@ -17,7 +19,7 @@ index 86a54586112b84b7c2026a4cbdad99cdf1c6ef81..e4ca880b5d16ae30676ec25c39c3d5b5 import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Holder; -@@ -292,6 +294,108 @@ public class JigsawPlacement { +@@ -288,6 +290,108 @@ public class JigsawPlacement { this.random = random; } @@ -126,7 +128,7 @@ index 86a54586112b84b7c2026a4cbdad99cdf1c6ef81..e4ca880b5d16ae30676ec25c39c3d5b5 void tryPlacingChildren( PoolElementStructurePiece piece, MutableObject free, -@@ -349,9 +453,9 @@ public class JigsawPlacement { +@@ -345,9 +449,9 @@ public class JigsawPlacement { mutableObject1 = free; } @@ -138,7 +140,7 @@ index 86a54586112b84b7c2026a4cbdad99cdf1c6ef81..e4ca880b5d16ae30676ec25c39c3d5b5 } list.addAll(fallback.value().getShuffledTemplates(this.random)); -@@ -362,10 +466,14 @@ public class JigsawPlacement { +@@ -358,10 +462,14 @@ public class JigsawPlacement { break; } @@ -155,7 +157,7 @@ index 86a54586112b84b7c2026a4cbdad99cdf1c6ef81..e4ca880b5d16ae30676ec25c39c3d5b5 BoundingBox boundingBox1 = structurePoolElement.getBoundingBox(this.structureTemplateManager, BlockPos.ZERO, rotation1); int i2; if (useExpansionHack && boundingBox1.getYSpan() <= 16) { -@@ -398,7 +506,7 @@ public class JigsawPlacement { +@@ -394,7 +502,7 @@ public class JigsawPlacement { } for (StructureTemplate.JigsawBlockInfo jigsawBlockInfo1 : shuffledJigsawBlocks) { @@ -164,7 +166,7 @@ index 86a54586112b84b7c2026a4cbdad99cdf1c6ef81..e4ca880b5d16ae30676ec25c39c3d5b5 BlockPos blockPos2 = jigsawBlockInfo1.info().pos(); BlockPos blockPos3 = blockPos1.subtract(blockPos2); BoundingBox boundingBox2 = structurePoolElement.getBoundingBox(this.structureTemplateManager, blockPos3, rotation1); -@@ -427,9 +535,26 @@ public class JigsawPlacement { +@@ -423,9 +531,26 @@ public class JigsawPlacement { boundingBox3.encapsulate(new BlockPos(boundingBox3.minX(), boundingBox3.minY() + max, boundingBox3.minZ())); } @@ -231,7 +233,7 @@ index 5c081a5b3d10f713e4e82fe1a43758f553fe50e0..85e84603a19964f05d9d5e62eb096ca7 + // DivineMC end - Optimize Structure Generation } diff --git a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java -index 5a05536e474bec574aa637f86bfc51f566d76ebf..e0f4500099c582653a81e6679be859e3d669bb88 100644 +index f21e612a35d6ac4482dbf5d14e506959659e371a..c02c3b1fddd513cb477cbb7400c30a9ad57f80a6 100644 --- a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java +++ b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java @@ -255,6 +255,12 @@ public class StructureTemplate { diff --git a/patches/work/server/minecraft/0013-Implement-NoChatReports.patch b/divinemc-server/minecraft-patches/features/0064-Implement-NoChatReports.patch similarity index 99% rename from patches/work/server/minecraft/0013-Implement-NoChatReports.patch rename to divinemc-server/minecraft-patches/features/0064-Implement-NoChatReports.patch index 2be2edc..8b8f786 100644 --- a/patches/work/server/minecraft/0013-Implement-NoChatReports.patch +++ b/divinemc-server/minecraft-patches/features/0064-Implement-NoChatReports.patch @@ -287,7 +287,7 @@ index 667ef5b2ab50eeb0491f7fe0bc8913ec29a4603a..a7c4fad2b1cb0cbac742a18d37d688bb if (packet == null || this.processedDisconnect) { // Spigot return; diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index 8a67672f1175769ac213099331453fbae59442fa..5ebbb4e37469beef11bdfd1531b0d10f3d01c826 100644 +index fb1b9f75cffeb15875e6690a0e030f8a4fd8b276..6713eb83b36f115e72fa5999c413e59e4f634f9f 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java @@ -276,7 +276,7 @@ public abstract class PlayerList { @@ -299,7 +299,7 @@ index 8a67672f1175769ac213099331453fbae59442fa..5ebbb4e37469beef11bdfd1531b0d10f ) ); player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit -@@ -1318,6 +1318,7 @@ public abstract class PlayerList { +@@ -1332,6 +1332,7 @@ public abstract class PlayerList { } public boolean verifyChatTrusted(PlayerChatMessage message) { diff --git a/patches/work/server/minecraft/0012-Lag-compensation.patch b/divinemc-server/minecraft-patches/features/0065-Lag-compensation.patch similarity index 95% rename from patches/work/server/minecraft/0012-Lag-compensation.patch rename to divinemc-server/minecraft-patches/features/0065-Lag-compensation.patch index 38d2a80..4805345 100644 --- a/patches/work/server/minecraft/0012-Lag-compensation.patch +++ b/divinemc-server/minecraft-patches/features/0065-Lag-compensation.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Lag compensation diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index abfecaf4467092f7baa02e0f5bbfd23d087f2aa3..77a693f42d90b5d17bf56d86b1676247c1ad505d 100644 +index 7a3775185d5c80f43456a595f22a9ebf19760bd6..23144971acc04bbeacd719dafe2363d1618153b9 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -288,6 +288,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Date: Tue, 28 Jan 2025 01:04:55 +0300 -Subject: [PATCH] Async Pathfinding +Subject: [PATCH] Petal: Async Pathfinding Original code by Bloom-host, licensed under GPL v3 You can find the original code on https://github.com/Bloom-host/Petal @@ -393,7 +393,7 @@ index 86fccf3617a32f3791b03d8067e2eaf6b8d8bebb..2c26d30a7373c6ac8ead22894b63a8d6 } diff --git a/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/net/minecraft/world/entity/ai/navigation/PathNavigation.java -index c8e4ccb96a0f162c780066cf4f61b970b49b7703..0b5f1f1e24c8c0468875d709c6b81798882600a0 100644 +index 24dd92449f70144c79f25bf24942ebd666655ed2..8d243cac4a0ba0536bd65c39bf3483d056e00116 100644 --- a/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/net/minecraft/world/entity/ai/navigation/PathNavigation.java @@ -167,6 +167,10 @@ public abstract class PathNavigation { @@ -579,10 +579,10 @@ index ca5651f15552f91fba650747d28a75c00fa11442..c5883758d11e91f96b4139b3bd8586a8 } } diff --git a/net/minecraft/world/entity/animal/frog/Frog.java b/net/minecraft/world/entity/animal/frog/Frog.java -index c6e4966d3e4fdb7c91577fc1693fb66930b4f3dc..81f0e444ccb6962d675e3a097341683d504d0889 100644 +index 85963b74a533beb7883ea417ceb3c21d834aebe0..1c9f3f0b2a344c026532c89c0db377ab8183c912 100644 --- a/net/minecraft/world/entity/animal/frog/Frog.java +++ b/net/minecraft/world/entity/animal/frog/Frog.java -@@ -483,6 +483,17 @@ public class Frog extends Animal { +@@ -488,6 +488,17 @@ public class Frog extends Animal { super(mob, level); } @@ -600,7 +600,7 @@ index c6e4966d3e4fdb7c91577fc1693fb66930b4f3dc..81f0e444ccb6962d675e3a097341683d @Override public boolean canCutCorner(PathType pathType) { return pathType != PathType.WATER_BORDER && super.canCutCorner(pathType); -@@ -491,6 +502,11 @@ public class Frog extends Animal { +@@ -496,6 +507,11 @@ public class Frog extends Animal { @Override protected PathFinder createPathFinder(int maxVisitedNodes) { this.nodeEvaluator = new Frog.FrogNodeEvaluator(true); @@ -613,10 +613,10 @@ index c6e4966d3e4fdb7c91577fc1693fb66930b4f3dc..81f0e444ccb6962d675e3a097341683d } } diff --git a/net/minecraft/world/entity/monster/Drowned.java b/net/minecraft/world/entity/monster/Drowned.java -index 2e6d0f035a01277aa28bbe912d5df8dc4cf04547..edcb20935f58e78fa4ef2c11a7dcc6a7857341c2 100644 +index 2a13332ebabf2e63a8f51a5d794fab3d66c7a1db..d4e7fc0a5bda4f44bcfed3d1adae7cdaf815784b 100644 --- a/net/minecraft/world/entity/monster/Drowned.java +++ b/net/minecraft/world/entity/monster/Drowned.java -@@ -308,7 +308,7 @@ public class Drowned extends Zombie implements RangedAttackMob { +@@ -309,7 +309,7 @@ public class Drowned extends Zombie implements RangedAttackMob { protected boolean closeToNextPos() { Path path = this.getNavigation().getPath(); @@ -656,10 +656,10 @@ index fe31c4a45afd61be8b74efe9d0858ccd0aced075..859c41c3c81b3d3ac05eebdc83c959d1 } diff --git a/net/minecraft/world/entity/monster/warden/Warden.java b/net/minecraft/world/entity/monster/warden/Warden.java -index 021aa51da04bea01b0e827390ce1690af7092b8f..0440cbbc0d6657f32dc37a1dbbe9ee78f8e229cf 100644 +index 7bfc597655cc55c46b65c9726a6e9de9f3f5afc8..4944b6d389c65511eed75d580779f912b8ff076d 100644 --- a/net/minecraft/world/entity/monster/warden/Warden.java +++ b/net/minecraft/world/entity/monster/warden/Warden.java -@@ -574,6 +574,16 @@ public class Warden extends Monster implements VibrationSystem { +@@ -579,6 +579,16 @@ public class Warden extends Monster implements VibrationSystem { @Override protected PathFinder createPathFinder(int maxVisitedNodes) { this.nodeEvaluator = new WalkNodeEvaluator(); diff --git a/patches/work/server/minecraft/0007-Multithreaded-Tracker.patch b/divinemc-server/minecraft-patches/features/0073-Petal-Multithreaded-Tracker.patch similarity index 95% rename from patches/work/server/minecraft/0007-Multithreaded-Tracker.patch rename to divinemc-server/minecraft-patches/features/0073-Petal-Multithreaded-Tracker.patch index 9c949a8..28aa428 100644 --- a/patches/work/server/minecraft/0007-Multithreaded-Tracker.patch +++ b/divinemc-server/minecraft-patches/features/0073-Petal-Multithreaded-Tracker.patch @@ -1,8 +1,18 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Tue, 28 Jan 2025 01:18:49 +0300 -Subject: [PATCH] Multithreaded Tracker +Subject: [PATCH] Petal: Multithreaded Tracker +Original project: https://github.com/Bloom-host/Petal +Original license: GPL v3 + +Patch description: + +We made much of tracking logic asynchronously, and fixed visible issue +for the case of some NPC plugins which using real entity type, e.g. Citizens. + +But it is still recommending to use those packet based, virtual entity +based NPC plugins, e.g. ZNPC Plus, Adyeshach, Fancy NPC, etc. diff --git a/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java index 1b8193587814225c2ef2c5d9e667436eb50ff6c5..93272808d94e81d31af728ebe85df9a2bc7aedab 100644 @@ -27,10 +37,10 @@ index 1b8193587814225c2ef2c5d9e667436eb50ff6c5..93272808d94e81d31af728ebe85df9a2 { for (int i = 0; i < this.directByChunk.length; ++i) { diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -index bdc1200ef5317fdaf58973bf580b0a672aee800f..dc2b3ccf7810731c0e2c90e5a476c1c8203a1fb7 100644 +index 053da602eb08b5a8b7a316e56f76a99e86149483..d1adef3f61acdbbc246f7ca3614b7e8aa7d25284 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -@@ -344,7 +344,11 @@ public final class RegionizedPlayerChunkLoader { +@@ -347,7 +347,11 @@ public final class RegionizedPlayerChunkLoader { private boolean canGenerateChunks = true; private final ArrayDeque> delayedTicketOps = new ArrayDeque<>(); @@ -56,7 +66,7 @@ index 9c0c99b936b4a82ebfe924866e53ec71f7bbe9ad..01ed1e3572e9c2ccfd19df117cda0d5c .add( new ClientboundUpdateAttributesPacket.AttributeSnapshot( diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java -index edda52a8430386238be4963e8ea2406f0c2d4df3..2c5104b9ae1d2ea902eeac5a1c9d49bc1af67c43 100644 +index c0d996fb99f053863ce623889add3feb70d7137d..a3290eb416ecb377d240bf334aef4e2b5e3bbefc 100644 --- a/net/minecraft/server/level/ChunkMap.java +++ b/net/minecraft/server/level/ChunkMap.java @@ -255,9 +255,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -346,7 +356,7 @@ index f106373ef3ac4a8685c2939c9e8361688a285913..b844b6dd89bc53b74c0d1bdbf4657c11 public boolean visible = true; diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java -index e96d4dee14c05f2fa329bfb1588ec795d4e3d730..917029d96afb5843276f4fa4ee37292327aea626 100644 +index 0868189fee30d40dfb82ae39592a65b510e96b54..39e28ad0cbb4617a80d7f197723233d4bdc1eed5 100644 --- a/net/minecraft/server/level/ServerEntity.java +++ b/net/minecraft/server/level/ServerEntity.java @@ -134,7 +134,7 @@ public class ServerEntity { @@ -358,7 +368,7 @@ index e96d4dee14c05f2fa329bfb1588ec795d4e3d730..917029d96afb5843276f4fa4ee372923 final ServerPlayer serverPlayer = connection.getPlayer(); // Paper savedData.tickCarriedBy(serverPlayer, item); Packet updatePacket = savedData.getUpdatePacket(mapId, serverPlayer); -@@ -424,8 +424,6 @@ public class ServerEntity { +@@ -428,8 +428,6 @@ public class ServerEntity { // CraftBukkit end this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), attributesToSync)); } @@ -368,10 +378,10 @@ index e96d4dee14c05f2fa329bfb1588ec795d4e3d730..917029d96afb5843276f4fa4ee372923 } diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 9dcb9e5ecc31fcc3fc7547a47ec98d2689698769..2560799fe6ec006916a2bc9915355a358ab6c8bb 100644 +index 78bf3365b426e7090182af84630111d410a2460e..3c1795eb56900cd80cfec38bd1d922d566463ecb 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -2504,7 +2504,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2517,7 +2517,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public LevelEntityGetter getEntities() { @@ -379,7 +389,7 @@ index 9dcb9e5ecc31fcc3fc7547a47ec98d2689698769..2560799fe6ec006916a2bc9915355a35 return this.moonrise$getEntityLookup(); // Paper - rewrite chunk system } -@@ -2771,7 +2770,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2784,7 +2783,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } map.carriedByPlayers.remove(player); @@ -389,10 +399,10 @@ index 9dcb9e5ecc31fcc3fc7547a47ec98d2689698769..2560799fe6ec006916a2bc9915355a35 } } diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index f36e042b36b94a0de2524d01ed44558900ba2a99..649b01c00ec01eea1514676e424d88acbfa26184 100644 +index b6f67c4359e718db8eb9240a22e71fd0b1bc6d05..bc738535f67d789e9d240b245e9247e026b3c751 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1931,7 +1931,6 @@ public class ServerGamePacketListenerImpl +@@ -1934,7 +1934,6 @@ public class ServerGamePacketListenerImpl } public void internalTeleport(PositionMoveRotation posMoveRotation, Set relatives) { @@ -401,10 +411,10 @@ index f36e042b36b94a0de2524d01ed44558900ba2a99..649b01c00ec01eea1514676e424d88ac if (this.player.isRemoved()) { LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName()); diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index d382a9760c0379f3d1c3bc65303d1de250858343..f5a036cfde9ced6ed8f0e548db3b69b1a46a0d2d 100644 +index a6a7af2393c15f92683f05500bd4f45b1b1f4853..6ac8209ec468ec4f65f75b383478eee0b537fabf 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -1335,13 +1335,13 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin +@@ -1353,13 +1353,13 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin } private void refreshDirtyAttributes() { @@ -638,10 +648,10 @@ index 325ec57df2885f5e81b8a6b61e3a9fed9484b30f..1796f0a6f647c94b0943a6003a130779 @Override diff --git a/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java -index 7bbeed6c998c91e68376d3f17a510d68e3cd0b27..de7b3a8a7c841360310a88005da02a0733b46714 100644 +index ebb0b7e5047efa65e8b6986f12dd5a7d6c0e9613..a77665abefdf653e65393cc6908506a5812b5596 100644 --- a/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java +++ b/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java -@@ -211,6 +211,7 @@ public class MapItemSavedData extends SavedData { +@@ -212,6 +212,7 @@ public class MapItemSavedData extends SavedData { for (int i = 0; i < this.carriedBy.size(); i++) { MapItemSavedData.HoldingPlayer holdingPlayer1 = this.carriedBy.get(i); diff --git a/patches/work/server/minecraft/0041-Async-mob-spawning.patch b/divinemc-server/minecraft-patches/features/0074-Pufferfish-Optimize-mob-spawning.patch similarity index 66% rename from patches/work/server/minecraft/0041-Async-mob-spawning.patch rename to divinemc-server/minecraft-patches/features/0074-Pufferfish-Optimize-mob-spawning.patch index a7210ac..5f053df 100644 --- a/patches/work/server/minecraft/0041-Async-mob-spawning.patch +++ b/divinemc-server/minecraft-patches/features/0074-Pufferfish-Optimize-mob-spawning.patch @@ -1,11 +1,15 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Wed, 19 Mar 2025 23:24:32 +0300 -Subject: [PATCH] Async mob spawning +Subject: [PATCH] Pufferfish: Optimize mob spawning +Original license: GPL v3 +Original project: https://github.com/pufferfish-gg/Pufferfish + +This patch reduces the main-thread impact of mob spawning by moving spawning work to other threads diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 1a36a7c071c9f203d32f524008cf031fb1a4d6a6..c067f46935753794b49f29358262273fcd15d707 100644 +index 7dbefd83d164a7d97a56b02862fef3b2f17d5aab..2f4be37e1ef4ea550bd6acd2c4647e5a7ed77648 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -289,6 +289,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function threadFunction) { ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java -index 6de832e7aec630914e70fb0f11223907ab28298c..7205fc8d3b17863c262d4c4c3cb956c852468c6f 100644 +index 75c8ce32e68f92e20201e9c243f46f2be716eac8..a76f7ce474cc1d6ff918737e845666a7529bd4a3 100644 --- a/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java @@ -182,6 +182,10 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @@ -31,7 +35,7 @@ index 6de832e7aec630914e70fb0f11223907ab28298c..7205fc8d3b17863c262d4c4c3cb956c8 public ServerChunkCache( ServerLevel level, -@@ -505,6 +509,32 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -506,6 +510,47 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon this.broadcastChangedChunks(); } @@ -42,20 +46,35 @@ index 6de832e7aec630914e70fb0f11223907ab28298c..7205fc8d3b17863c262d4c4c3cb956c8 + for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) { + player.mobCounts[ii] = 0; + -+ int newBackoff = Math.max(0, player.mobBackoffCounts[ii] - 1); // DivineMC - Async mob spawning ++ int newBackoff = Math.max(0, player.mobBackoffCounts[ii] - 1); + player.mobBackoffCounts[ii] = newBackoff; + } + } ++ + if (firstRunSpawnCounts) { + firstRunSpawnCounts = false; + spawnCountsReady.set(true); + } ++ + if (spawnCountsReady.getAndSet(false)) { -+ MinecraftServer.getServer().mobSpawnExecutor.submit(() -> { ++ net.minecraft.server.MinecraftServer.getServer().mobSpawnExecutor.submit(() -> { + int mapped = distanceManager.getNaturalSpawnChunkCount(); ++ ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet.Iterator objectiterator = level.entityTickList.entities.iterator(ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet.ITERATOR_FLAG_SEE_ADDITIONS); ++ + try { -+ lastSpawnState = NaturalSpawner.createState(mapped, new java.util.ArrayList<>(level.entityTickList.entities), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap), true); -+ } finally { } ++ gg.pufferfish.pufferfish.util.IterableWrapper wrappedIterator = new gg.pufferfish.pufferfish.util.IterableWrapper<>(objectiterator); ++ LocalMobCapCalculator mobCapCalculator = !level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(chunkMap) : null; ++ ++ lastSpawnState = NaturalSpawner.createState( ++ mapped, ++ wrappedIterator, ++ ServerChunkCache.this::getFullChunk, ++ mobCapCalculator, ++ level.paperConfig().entities.spawning.perPlayerMobSpawns ++ ); ++ } finally { ++ objectiterator.finishedIterating(); ++ } + spawnCountsReady.set(true); + }); + } @@ -64,7 +83,7 @@ index 6de832e7aec630914e70fb0f11223907ab28298c..7205fc8d3b17863c262d4c4c3cb956c8 } private void broadcastChangedChunks() { -@@ -522,27 +552,31 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -523,27 +568,31 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon int naturalSpawnChunkCount = this.distanceManager.getNaturalSpawnChunkCount(); // Paper start - Optional per player mob spawns NaturalSpawner.SpawnState spawnState; @@ -110,7 +129,7 @@ index 6de832e7aec630914e70fb0f11223907ab28298c..7205fc8d3b17863c262d4c4c3cb956c8 boolean _boolean = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit int _int = this.level.getGameRules().getInt(GameRules.RULE_RANDOMTICKING); List filteredSpawningCategories; -@@ -556,7 +590,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -557,7 +606,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon } // Paper end - PlayerNaturallySpawnCreaturesEvent boolean flag = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && this.level.getLevelData().getGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit @@ -119,7 +138,7 @@ index 6de832e7aec630914e70fb0f11223907ab28298c..7205fc8d3b17863c262d4c4c3cb956c8 } else { filteredSpawningCategories = List.of(); } -@@ -573,7 +607,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -572,7 +621,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon // Paper end - chunk tick iteration optimisation for (LevelChunk levelChunk : list) { @@ -128,7 +147,7 @@ index 6de832e7aec630914e70fb0f11223907ab28298c..7205fc8d3b17863c262d4c4c3cb956c8 } } finally { list.clear(); -@@ -592,11 +626,11 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -591,11 +640,11 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon this.level.tickThunder(chunk); } @@ -144,69 +163,3 @@ index 6de832e7aec630914e70fb0f11223907ab28298c..7205fc8d3b17863c262d4c4c3cb956c8 } private void getFullChunk(long chunkPos, Consumer fullChunkGetter) { -diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java -index 68a074a1eb11b158af773a2c44aa49d5d8462080..a5f6f50ad1e276a908347d9c21527fb583734538 100644 ---- a/net/minecraft/world/level/NaturalSpawner.java -+++ b/net/minecraft/world/level/NaturalSpawner.java -@@ -149,7 +149,18 @@ public final class NaturalSpawner { - return list; - } - -+ private static int maxCapPerPlayer = -1; // DivineMC - Async mob spawning -+ - public static void spawnForChunk(ServerLevel level, LevelChunk chunk, NaturalSpawner.SpawnState spawnState, List categories) { -+ // DivineMC start - Async mob spawning -+ if (maxCapPerPlayer < 0) { -+ maxCapPerPlayer = 0; -+ for (final MobCategory value : MobCategory.values()) { -+ maxCapPerPlayer += value.getMaxInstancesPerChunk(); -+ } -+ } -+ // DivineMC end - Async mob spawning -+ - for (MobCategory mobCategory : categories) { - // Paper start - Optional per player mob spawns - final boolean canSpawn; -@@ -680,6 +691,13 @@ public final class NaturalSpawner { - } - - boolean canSpawnForCategoryLocal(MobCategory category, ChunkPos chunkPos) { -+ // DivineMC start - Async mob spawning -+ if (this.localMobCapCalculator == null) { -+ LOGGER.warn("Local mob cap calculator was null! Report to DivineMC!"); -+ return false; -+ } -+ // DivineMC end - Async mob spawning -+ - return this.localMobCapCalculator.canSpawn(category, chunkPos); - } - } -diff --git a/net/minecraft/world/level/entity/EntityTickList.java b/net/minecraft/world/level/entity/EntityTickList.java -index c89701d7bdc9b889038d3c52f2232fb17624b113..9e75320e51886e0f93c23683d8614128f44a613e 100644 ---- a/net/minecraft/world/level/entity/EntityTickList.java -+++ b/net/minecraft/world/level/entity/EntityTickList.java -@@ -9,7 +9,7 @@ import javax.annotation.Nullable; - 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 - - private void ensureActiveIsNotIterated() { - // Paper - rewrite chunk system -@@ -33,13 +33,13 @@ public class EntityTickList { - // 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) -- final ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet.Iterator iterator = this.entities.iterator(); -+ final java.util.Iterator iterator = this.entities.iterator(); // DivineMC - Async mob spawning - try { - while (iterator.hasNext()) { - entity.accept(iterator.next()); - } - } finally { -- iterator.finishedIterating(); -+ //iterator.finishedIterating(); // DivineMC - Async mob spawning - } - // Paper end - rewrite chunk system - } diff --git a/patches/work/server/paper/0005-Implement-Secure-Seed.patch b/divinemc-server/paper-patches/features/0015-Implement-Secure-Seed.patch similarity index 96% rename from patches/work/server/paper/0005-Implement-Secure-Seed.patch rename to divinemc-server/paper-patches/features/0015-Implement-Secure-Seed.patch index f0d7b21..88d4cbc 100644 --- a/patches/work/server/paper/0005-Implement-Secure-Seed.patch +++ b/divinemc-server/paper-patches/features/0015-Implement-Secure-Seed.patch @@ -25,7 +25,7 @@ index 400e632208d133a3f49fc7f14bceb48a1026769b..a1c7ba0fdb505d09407cca94e890dedd @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 8014666a5145c46d7ecd40b2175f0990e699db47..b161209bb1111fd2ae7a3b601c8303cbdfab0ea7 100644 +index 414fdc6ca7a2979124a7fbf529bff60f993c005a..19430a22687e6bf2887222ecdda2fdda9539c0f8 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1352,7 +1352,11 @@ public final class CraftServer implements Server { diff --git a/patches/work/server/paper/0010-Multithreaded-Tracker.patch b/divinemc-server/paper-patches/features/0016-Petal-Multithreaded-Tracker.patch similarity index 85% rename from patches/work/server/paper/0010-Multithreaded-Tracker.patch rename to divinemc-server/paper-patches/features/0016-Petal-Multithreaded-Tracker.patch index e667eaf..b78e3ec 100644 --- a/patches/work/server/paper/0010-Multithreaded-Tracker.patch +++ b/divinemc-server/paper-patches/features/0016-Petal-Multithreaded-Tracker.patch @@ -1,8 +1,18 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Sat, 1 Mar 2025 23:06:52 +0300 -Subject: [PATCH] Multithreaded Tracker +Subject: [PATCH] Petal: Multithreaded Tracker +Original project: https://github.com/Bloom-host/Petal +Original license: GPL v3 + +Patch description: + +We made much of tracking logic asynchronously, and fixed visible issue +for the case of some NPC plugins which using real entity type, e.g. Citizens. + +But it is still recommending to use those packet based, virtual entity +based NPC plugins, e.g. ZNPC Plus, Adyeshach, Fancy NPC, etc. 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 d7398b1ecf2660c29fb7d106b48fe02d3736603e..ab499a7eaccdc1578ec64f90f54f79b0da3c0e96 100644 @@ -22,10 +32,10 @@ index d7398b1ecf2660c29fb7d106b48fe02d3736603e..ab499a7eaccdc1578ec64f90f54f79b0 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index acd3b4f8b3e9c40253bacb3d16017fb7102c071c..fda15b81d2405179261fa6fa76c3ec8f7ad6eaf5 100644 +index 4913ac7d0426025689c8aee3790d87f7ac0131fd..d4d3aeae964d9a64805ddc5862e46fff5dd7d98a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2942,7 +2942,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player, PluginMessa +@@ -2953,7 +2953,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player, PluginMessa Iterator iterator = collection.iterator(); while (iterator.hasNext()) { AttributeInstance genericInstance = iterator.next(); @@ -35,7 +45,7 @@ index acd3b4f8b3e9c40253bacb3d16017fb7102c071c..fda15b81d2405179261fa6fa76c3ec8f break; } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index a162440a583801671787163d998d6b9546ef7e61..214bc24aa301f99c911a129676bc7d7d50df7236 100644 +index d10ee84ed2f6b1c81667b968984f3ebf5c39e445..83c6cf3cb062c8a6508728822e37d52a543415a3 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -1808,6 +1808,26 @@ public class CraftEventFactory { diff --git a/divinemc-server/paper-patches/features/0017-Pufferfish-Optimize-mob-spawning.patch b/divinemc-server/paper-patches/features/0017-Pufferfish-Optimize-mob-spawning.patch new file mode 100644 index 0000000..6ae2fe5 --- /dev/null +++ b/divinemc-server/paper-patches/features/0017-Pufferfish-Optimize-mob-spawning.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> +Date: Wed, 9 Jul 2025 03:01:38 +0300 +Subject: [PATCH] Pufferfish: Optimize mob spawning + +Original license: GPL v3 +Original project: https://github.com/pufferfish-gg/Pufferfish + +This patch reduces the main-thread impact of mob spawning by moving spawning work to other threads + +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java +index ece6db7b9a0dfd535141c0c756947c4898140503..41a725e9926767fbbf2a3e3558f850f0d57c5945 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java +@@ -19,7 +19,7 @@ public final class IteratorSafeOrderedReferenceSet { + + private final double maxFragFactor; + +- private int iteratorCount; ++ private final java.util.concurrent.atomic.AtomicInteger iteratorCount = new java.util.concurrent.atomic.AtomicInteger(); // DivineMC - Pufferfish: Optimize mob spawning + + public IteratorSafeOrderedReferenceSet() { + this(Object.class); +@@ -99,7 +99,7 @@ public final class IteratorSafeOrderedReferenceSet { + } + + public int createRawIterator() { +- ++this.iteratorCount; ++ this.iteratorCount.incrementAndGet(); // DivineMC - Pufferfish: Optimize mob spawning + if (this.indexMap.isEmpty()) { + return Integer.MAX_VALUE; + } else { +@@ -120,7 +120,7 @@ public final class IteratorSafeOrderedReferenceSet { + } + + public void finishRawIterator() { +- if (--this.iteratorCount == 0) { ++ if (this.iteratorCount.decrementAndGet() == 0) { // DivineMC - Pufferfish: Optimize mob spawning + if (this.getFragFactor() >= this.maxFragFactor) { + this.defrag(); + } +@@ -137,7 +137,7 @@ public final class IteratorSafeOrderedReferenceSet { + throw new IllegalStateException(); + } + this.listElements[index] = null; +- if (this.iteratorCount == 0 && this.getFragFactor() >= this.maxFragFactor) { ++ if (this.iteratorCount.get() == 0 && this.getFragFactor() >= this.maxFragFactor) { // DivineMC - Pufferfish: Optimize mob spawning + this.defrag(); + } + //this.check(); +@@ -235,7 +235,7 @@ public final class IteratorSafeOrderedReferenceSet { + } + + public IteratorSafeOrderedReferenceSet.Iterator iterator(final int flags) { +- ++this.iteratorCount; ++ this.iteratorCount.incrementAndGet(); // DivineMC - Pufferfish: Optimize mob spawning + return new BaseIterator<>(this, true, (flags & ITERATOR_FLAG_SEE_ADDITIONS) != 0 ? Integer.MAX_VALUE : this.listSize); + } + diff --git a/divinemc-server/src/main/java/gg/pufferfish/pufferfish/util/IterableWrapper.java b/divinemc-server/src/main/java/gg/pufferfish/pufferfish/util/IterableWrapper.java new file mode 100644 index 0000000..08e75cd --- /dev/null +++ b/divinemc-server/src/main/java/gg/pufferfish/pufferfish/util/IterableWrapper.java @@ -0,0 +1,13 @@ +package gg.pufferfish.pufferfish.util; + +import java.util.Iterator; + +import org.jetbrains.annotations.NotNull; + +public record IterableWrapper(Iterator iterator) implements Iterable { + @NotNull + @Override + public Iterator iterator() { + return iterator; + } +} diff --git a/patches/work/server/minecraft/0008-Misc-Optimizations.patch b/patches/work/server/minecraft/0008-Misc-Optimizations.patch deleted file mode 100644 index 44ea716..0000000 --- a/patches/work/server/minecraft/0008-Misc-Optimizations.patch +++ /dev/null @@ -1,741 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> -Date: Fri, 31 Jan 2025 21:50:46 +0300 -Subject: [PATCH] Misc Optimizations - - -diff --git a/com/mojang/math/Transformation.java b/com/mojang/math/Transformation.java -index 5fb382be4d86328690c49f2a5a0c3ec698a38e21..f333d9028f315e7912dd335c8158abd525c27ecd 100644 ---- a/com/mojang/math/Transformation.java -+++ b/com/mojang/math/Transformation.java -@@ -52,6 +52,7 @@ public final class Transformation { - } else { - this.matrix = matrix; - } -+ ensureDecomposed(); // DivineMC - Math Optimizations - } - - public Transformation(@Nullable Vector3f translation, @Nullable Quaternionf leftRotation, @Nullable Vector3f scale, @Nullable Quaternionf rightRotation) { -@@ -61,6 +62,7 @@ public final class Transformation { - this.scale = scale != null ? scale : new Vector3f(1.0F, 1.0F, 1.0F); - this.rightRotation = rightRotation != null ? rightRotation : new Quaternionf(); - this.decomposed = true; -+ ensureDecomposed(); // DivineMC - Math Optimizations - } - - public static Transformation identity() { -diff --git a/net/minecraft/core/MappedRegistry.java b/net/minecraft/core/MappedRegistry.java -index 4715a60760c2c9079313db9016000bfb5c65e070..fce8f1caca81f47f704bc0237147e9999cc5732c 100644 ---- a/net/minecraft/core/MappedRegistry.java -+++ b/net/minecraft/core/MappedRegistry.java -@@ -33,10 +33,12 @@ public class MappedRegistry implements WritableRegistry { - private final ResourceKey> key; - private final ObjectList> byId = new ObjectArrayList<>(256); - private final Reference2IntMap toId = Util.make(new Reference2IntOpenHashMap<>(2048), map -> map.defaultReturnValue(-1)); // Paper - Perf: Use bigger expected size to reduce collisions -- private final Map> byLocation = new HashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions -- private final Map, Holder.Reference> byKey = new HashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions -- private final Map> byValue = new IdentityHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions -- private final Map, RegistrationInfo> registrationInfos = new IdentityHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions -+ // DivineMC start - Some optimizations -+ private final Map> byLocation = new java.util.concurrent.ConcurrentHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions -+ private final Map, Holder.Reference> byKey = new java.util.concurrent.ConcurrentHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions -+ private final Map> byValue = Collections.synchronizedMap(new IdentityHashMap<>(2048)); // Paper - Perf: Use bigger expected size to reduce collisions -+ private final Map, RegistrationInfo> registrationInfos = Collections.synchronizedMap(new IdentityHashMap<>(2048)); // Paper - Perf: Use bigger expected size to reduce collisions -+ // DivineMC end - Some optimizations - private Lifecycle registryLifecycle; - private final Map, HolderSet.Named> frozenTags = new IdentityHashMap<>(); - MappedRegistry.TagSet allTags = MappedRegistry.TagSet.unbound(); -diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java -index e72eda830644851656fae3118c513d7bd701be45..cdacbfa64bda461d4f24c2a85db9feae7766b597 100644 ---- a/net/minecraft/network/Connection.java -+++ b/net/minecraft/network/Connection.java -@@ -601,13 +601,7 @@ public class Connection extends SimpleChannelInboundHandler> { - if (!(this.packetListener instanceof net.minecraft.server.network.ServerLoginPacketListenerImpl loginPacketListener) - || loginPacketListener.state != net.minecraft.server.network.ServerLoginPacketListenerImpl.State.VERIFYING - || Connection.joinAttemptsThisTick++ < MAX_PER_TICK) { -- // Paper start - detailed watchdog information -- net.minecraft.network.protocol.PacketUtils.packetProcessing.push(this.packetListener); -- try { - tickablePacketListener.tick(); -- } finally { -- net.minecraft.network.protocol.PacketUtils.packetProcessing.pop(); -- } // Paper end - detailed watchdog information - } // Paper end - Buffer joins to world - } - -diff --git a/net/minecraft/network/VarInt.java b/net/minecraft/network/VarInt.java -index 4897ff4648083ebe737ae5b32bae344af27357e4..0d103821d7220daa5cc0d5d3231e794fca0ca055 100644 ---- a/net/minecraft/network/VarInt.java -+++ b/net/minecraft/network/VarInt.java -@@ -52,16 +52,43 @@ public class VarInt { - - public static ByteBuf write(ByteBuf buffer, int value) { - // Paper start - Optimize VarInts -- // Peel the one and two byte count cases explicitly as they are the most common VarInt sizes -- // that the proxy will write, to improve inlining. -- if ((value & (0xFFFFFFFF << 7)) == 0) { -- buffer.writeByte(value); -- } else if ((value & (0xFFFFFFFF << 14)) == 0) { -- int w = (value & 0x7F | 0x80) << 8 | (value >>> 7); -- buffer.writeShort(w); -- } else { -- writeOld(buffer, value); -+ // DivineMC start - Misc optimizations -+ int bytesNeeded = getByteSize(value); -+ -+ switch (bytesNeeded) { -+ case 1: -+ buffer.writeByte(value); -+ break; -+ case 2: -+ int w2 = ((value & 0x7F) << 8) | (value >>> 7) | 0x00008000; -+ buffer.writeShort(w2); -+ break; -+ case 3: -+ int w3 = (value & 0x7F) << 16 -+ | (value & 0x3F80) << 1 -+ | (value >>> 14) -+ | 0x00808000; -+ buffer.writeMedium(w3); -+ break; -+ case 4: -+ int w4 = (value & 0x7F) << 24 -+ | ((value & 0x3F80) << 9) -+ | (value & 0x1FC000) >> 6 -+ | (value >>> 21) -+ | 0x80808000; -+ buffer.writeInt(w4); -+ break; -+ case 5: -+ int w5 = (value & 0x7F) << 24 -+ | (value & 0x3F80) << 9 -+ | (value & 0x1FC000) >> 6 -+ | ((value >>> 21) & 0x7F) -+ | 0x80808080; -+ buffer.writeInt(w5); -+ buffer.writeByte(value >>> 28); -+ break; - } -+ // DivineMC end - Slightly optimized VarInt#write - return buffer; - } - public static ByteBuf writeOld(ByteBuf buffer, int value) { -diff --git a/net/minecraft/network/protocol/PacketUtils.java b/net/minecraft/network/protocol/PacketUtils.java -index 4535858701b2bb232b9d2feb2af6551526232ddc..e65c62dbe4c1560ae153e4c4344e9194c783a2f4 100644 ---- a/net/minecraft/network/protocol/PacketUtils.java -+++ b/net/minecraft/network/protocol/PacketUtils.java -@@ -21,8 +21,6 @@ public class PacketUtils { - public static void ensureRunningOnSameThread(Packet packet, T processor, BlockableEventLoop executor) throws RunningOnDifferentThreadException { - if (!executor.isSameThread()) { - executor.executeIfPossible(() -> { -- packetProcessing.push(processor); // Paper - detailed watchdog information -- try { // Paper - detailed watchdog information - if (processor instanceof net.minecraft.server.network.ServerCommonPacketListenerImpl serverCommonPacketListener && serverCommonPacketListener.processedDisconnect) return; // Paper - Don't handle sync packets for kicked players - if (processor.shouldHandleMessage(packet)) { - try { -@@ -37,12 +35,6 @@ public class PacketUtils { - } else { - LOGGER.debug("Ignoring packet due to disconnection: {}", packet); - } -- // Paper start - detailed watchdog information -- } finally { -- totalMainThreadPacketsProcessed.getAndIncrement(); -- packetProcessing.pop(); -- } -- // Paper end - detailed watchdog information - }); - throw RunningOnDifferentThreadException.RUNNING_ON_DIFFERENT_THREAD; - } -@@ -69,22 +61,4 @@ public class PacketUtils { - - packetListener.fillCrashReport(crashReport); - } -- -- // Paper start - detailed watchdog information -- public static final java.util.concurrent.ConcurrentLinkedDeque packetProcessing = new java.util.concurrent.ConcurrentLinkedDeque<>(); -- static final java.util.concurrent.atomic.AtomicLong totalMainThreadPacketsProcessed = new java.util.concurrent.atomic.AtomicLong(); -- -- public static long getTotalProcessedPackets() { -- return totalMainThreadPacketsProcessed.get(); -- } -- -- public static java.util.List getCurrentPacketProcessors() { -- java.util.List listeners = new java.util.ArrayList<>(4); -- for (PacketListener listener : packetProcessing) { -- listeners.add(listener); -- } -- -- return listeners; -- } -- // Paper end - detailed watchdog information - } -diff --git a/net/minecraft/server/level/ChunkTrackingView.java b/net/minecraft/server/level/ChunkTrackingView.java -index bee90335677f7d8b01589ce5cfd81a40fd422886..a5e488d14fd2016ee188b114d0e681562b5b09cc 100644 ---- a/net/minecraft/server/level/ChunkTrackingView.java -+++ b/net/minecraft/server/level/ChunkTrackingView.java -@@ -73,12 +73,12 @@ public interface ChunkTrackingView { - } - - static boolean isWithinDistance(int centerX, int centerZ, int viewDistance, int x, int z, boolean includeOuterChunksAdjacentToViewBorder) { -- int i = includeOuterChunksAdjacentToViewBorder ? 2 : 1; -- long l = Math.max(0, Math.abs(x - centerX) - i); -- long l1 = Math.max(0, Math.abs(z - centerZ) - i); -- long l2 = l * l + l1 * l1; -- int i1 = viewDistance * viewDistance; -- return l2 < i1; -+ // DivineMC start - Some optimizations -+ int actualViewDistance = viewDistance + (includeOuterChunksAdjacentToViewBorder ? 1 : 0); -+ int xDistance = Math.abs(centerX - x); -+ int zDistance = Math.abs(centerZ - z); -+ return xDistance <= actualViewDistance && zDistance <= actualViewDistance; -+ // DivineMC end - Some optimizations - } - - public record Positioned(ChunkPos center, int viewDistance) implements ChunkTrackingView { -diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java -index 75c8ce32e68f92e20201e9c243f46f2be716eac8..879d6eb8e72b63bc95d8028cbc2f6e93e516ab1d 100644 ---- a/net/minecraft/server/level/ServerChunkCache.java -+++ b/net/minecraft/server/level/ServerChunkCache.java -@@ -567,8 +567,10 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - try { - this.chunkMap.collectSpawningChunks(list); - // Paper start - chunk tick iteration optimisation -- this.shuffleRandom.setSeed(this.level.random.nextLong()); -- if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) Util.shuffle(list, this.shuffleRandom); // Paper - Optional per player mob spawns; do not need this when per-player is enabled -+ if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { -+ this.shuffleRandom.setSeed(this.level.random.nextLong()); // DivineMC - Misc Optimizations -+ Util.shuffle(list, this.shuffleRandom); // Paper - Optional per player mob spawns; do not need this when per-player is enabled -+ } - // Paper end - chunk tick iteration optimisation - - for (LevelChunk levelChunk : list) { -diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 2560799fe6ec006916a2bc9915355a358ab6c8bb..740f6324eeb4021bc45d27d6145ff71282c761c2 100644 ---- a/net/minecraft/server/level/ServerLevel.java -+++ b/net/minecraft/server/level/ServerLevel.java -@@ -1321,13 +1321,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - // Paper end - log detailed entity tick information - - public void tickNonPassenger(Entity entity) { -- // Paper start - log detailed entity tick information - ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot tick an entity off-main"); -- try { -- if (currentlyTickingEntity.get() == null) { -- currentlyTickingEntity.lazySet(entity); -- } -- // Paper end - log detailed entity tick information - entity.setOldPosAndRot(); - entity.tickCount++; - entity.totalEntityAge++; // Paper - age-like counter for all entities -@@ -1340,13 +1334,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - for (Entity entity1 : entity.getPassengers()) { - this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2 - } -- // Paper start - log detailed entity tick information -- } finally { -- if (currentlyTickingEntity.get() == entity) { -- currentlyTickingEntity.lazySet(null); -- } -- } -- // Paper end - log detailed entity tick information - } - - private void tickPassenger(Entity ridingEntity, Entity passengerEntity, final boolean isActive) { // Paper - EAR 2 -diff --git a/net/minecraft/util/ClassInstanceMultiMap.java b/net/minecraft/util/ClassInstanceMultiMap.java -index 2a708ae0d5bb209650b525e3c56051f8b5655074..4c7670224f0c90c1d0d833ff0b3d908846133b4a 100644 ---- a/net/minecraft/util/ClassInstanceMultiMap.java -+++ b/net/minecraft/util/ClassInstanceMultiMap.java -@@ -14,9 +14,9 @@ import java.util.Map.Entry; - import net.minecraft.Util; - - public class ClassInstanceMultiMap extends AbstractCollection { -- private final Map, List> byClass = Maps.newHashMap(); -+ private final Map, List> byClass = new it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap<>(); // DivineMC - Misc Optimizations - private final Class baseClass; -- private final List allInstances = Lists.newArrayList(); -+ private final List allInstances = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); // DivineMC - Misc Optimizations - - public ClassInstanceMultiMap(Class baseClass) { - this.baseClass = baseClass; -@@ -56,13 +56,27 @@ public class ClassInstanceMultiMap extends AbstractCollection { - } - - public Collection find(Class type) { -+ // DivineMC start - Some optimizations -+ List cached = this.byClass.get(type); -+ if (cached != null) return (Collection) cached; -+ - if (!this.baseClass.isAssignableFrom(type)) { - throw new IllegalArgumentException("Don't know how to search for " + type); - } else { -- List list = this.byClass -- .computeIfAbsent(type, clazz -> this.allInstances.stream().filter(clazz::isInstance).collect(Util.toMutableList())); -- return (Collection)Collections.unmodifiableCollection(list); -+ List list = this.byClass.computeIfAbsent(type, -+ typeClass -> { -+ it.unimi.dsi.fastutil.objects.ObjectArrayList ts = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(this.allInstances.size()); -+ for (Object _allElement : ((it.unimi.dsi.fastutil.objects.ObjectArrayList) this.allInstances).elements()) { -+ if (typeClass.isInstance(_allElement)) { -+ ts.add((T) _allElement); -+ } -+ } -+ return ts; -+ } -+ ); -+ return (Collection) list; - } -+ // DivineMC end - Some optimizations - } - - @Override -diff --git a/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java b/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java -index f28fbf81a417a678726d3f77b3999054676d522e..7ff32b1f93b31fafd13f4e0857d14d85ef1f28c7 100644 ---- a/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java -+++ b/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java -@@ -52,23 +52,23 @@ public class CrudeIncrementalIntIdentityHashBiMap implements IdMap, ca.spo - - @Nullable - @Override -- public K byId(int value) { -+ public synchronized K byId(int value) { // DivineMC - Misc Optimizations - return value >= 0 && value < this.byId.length ? this.byId[value] : null; - } - -- private int getValue(int key) { -+ private synchronized int getValue(int key) { // DivineMC - Misc Optimizations - return key == -1 ? -1 : this.values[key]; - } - -- public boolean contains(K value) { -+ public synchronized boolean contains(K value) { // DivineMC - Misc Optimizations - return this.getId(value) != -1; - } - -- public boolean contains(int value) { -+ public synchronized boolean contains(int value) { // DivineMC - Misc Optimizations - return this.byId(value) != null; - } - -- public int add(K object) { -+ public synchronized int add(K object) { // DivineMC - Misc Optimizations - int i = this.nextId(); - this.addMapping(object, i); - return i; -@@ -106,7 +106,7 @@ public class CrudeIncrementalIntIdentityHashBiMap implements IdMap, ca.spo - // Paper end - optimise palette reads - } - -- public void addMapping(K object, int intKey) { -+ public synchronized void addMapping(K object, int intKey) { // DivineMC - Misc Optimizations - int max = Math.max(intKey, this.size + 1); - if (max >= this.keys.length * 0.8F) { - int i = this.keys.length << 1; -@@ -173,11 +173,11 @@ public class CrudeIncrementalIntIdentityHashBiMap implements IdMap, ca.spo - } - - @Override -- public Iterator iterator() { -+ public synchronized Iterator iterator() { // DivineMC - Misc Optimizations - return Iterators.filter(Iterators.forArray(this.byId), Predicates.notNull()); - } - -- public void clear() { -+ public synchronized void clear() { // DivineMC - Misc Optimizations - Arrays.fill(this.keys, null); - Arrays.fill(this.byId, null); - this.nextId = 0; -diff --git a/net/minecraft/util/Mth.java b/net/minecraft/util/Mth.java -index e2602c6d817794616eb05a471077447804b835a1..d5a9fd918621708c5bcbf56e33513a6765122d1c 100644 ---- a/net/minecraft/util/Mth.java -+++ b/net/minecraft/util/Mth.java -@@ -46,11 +46,11 @@ public class Mth { - private static final double[] COS_TAB = new double[257]; - - public static float sin(float value) { -- return SIN[(int)(value * 10430.378F) & 65535]; -+ return net.caffeinemc.mods.lithium.common.util.math.CompactSineLUT.sin(value); // DivineMC - Math Optimizations - } - - public static float cos(float value) { -- return SIN[(int)(value * 10430.378F + 16384.0F) & 65535]; -+ return net.caffeinemc.mods.lithium.common.util.math.CompactSineLUT.cos(value); // DivineMC - Math Optimizations - } - - public static float sqrt(float value) { -@@ -58,18 +58,15 @@ public class Mth { - } - - public static int floor(float value) { -- int i = (int)value; -- return value < i ? i - 1 : i; -+ return (int) Math.floor(value); // DivineMC - Math Optimizations - } - - public static int floor(double value) { -- int i = (int)value; -- return value < i ? i - 1 : i; -+ return (int) Math.floor(value); // DivineMC - Math Optimizations - } - - public static long lfloor(double value) { -- long l = (long)value; -- return value < l ? l - 1L : l; -+ return (long) Math.floor(value); // DivineMC - Math Optimizations - } - - public static float abs(float value) { -@@ -81,13 +78,11 @@ public class Mth { - } - - public static int ceil(float value) { -- int i = (int)value; -- return value > i ? i + 1 : i; -+ return (int) Math.ceil(value); // DivineMC - Math Optimizations - } - - public static int ceil(double value) { -- int i = (int)value; -- return value > i ? i + 1 : i; -+ return (int) Math.ceil(value); // DivineMC - Math Optimizations - } - - public static int clamp(int value, int min, int max) { -@@ -123,15 +118,7 @@ public class Mth { - } - - public static double absMax(double x, double y) { -- if (x < 0.0) { -- x = -x; -- } -- -- if (y < 0.0) { -- y = -y; -- } -- -- return Math.max(x, y); -+ return Math.max(Math.abs(x), Math.abs(y)); // DivineMC - Math Optimizations - } - - public static int floorDiv(int dividend, int divisor) { -@@ -162,14 +149,26 @@ public class Mth { - return Math.floorMod(x, y); - } - -- public static float positiveModulo(float numerator, float denominator) { -+ public static float positiveModuloForAnyDenominator(float numerator, float denominator) { // DivineMC - Math Optimizations - return (numerator % denominator + denominator) % denominator; - } - -- public static double positiveModulo(double numerator, double denominator) { -+ public static double positiveModuloForAnyDenominator(double numerator, double denominator) { // DivineMC - Math Optimizations - return (numerator % denominator + denominator) % denominator; - } - -+ // DivineMC start - Math Optimizations -+ public static float positiveModuloForPositiveIntegerDenominator(float numerator, float denominator) { -+ var modulo = numerator % denominator; -+ return modulo < 0 ? modulo + denominator : modulo; -+ } -+ -+ public static double positiveModuloForPositiveIntegerDenominator(double numerator, double denominator) { -+ var modulo = numerator % denominator; -+ return modulo < 0 ? modulo + denominator : modulo; -+ } -+ // DivineMC end - Math Optimizations -+ - public static boolean isMultipleOf(int number, int multiple) { - return number % multiple == 0; - } -diff --git a/net/minecraft/util/RandomSource.java b/net/minecraft/util/RandomSource.java -index 8516d47b0ba79d91638837199e7ae0fb6cb44a79..71444431b10582f5917c1795275ccdadd2364c3c 100644 ---- a/net/minecraft/util/RandomSource.java -+++ b/net/minecraft/util/RandomSource.java -@@ -12,7 +12,7 @@ public interface RandomSource { - double GAUSSIAN_SPREAD_FACTOR = 2.297; - - static RandomSource create() { -- return create(RandomSupport.generateUniqueSeed()); -+ return createThreadSafe(); // DivineMC - Misc Optimizations - } - - @Deprecated -@@ -21,7 +21,7 @@ public interface RandomSource { - } - - static RandomSource create(long seed) { -- return new LegacyRandomSource(seed); -+ return new ThreadSafeLegacyRandomSource(seed); // DivineMC - Misc Optimizations - } - - static RandomSource createNewThreadLocalInstance() { -diff --git a/net/minecraft/util/debugchart/DebugSampleSubscriptionTracker.java b/net/minecraft/util/debugchart/DebugSampleSubscriptionTracker.java -index a18240418a19a95147341a634527d774f3d5bb92..66f74ad2a194a6676574da2932cf4677f9383ecd 100644 ---- a/net/minecraft/util/debugchart/DebugSampleSubscriptionTracker.java -+++ b/net/minecraft/util/debugchart/DebugSampleSubscriptionTracker.java -@@ -14,7 +14,7 @@ public class DebugSampleSubscriptionTracker { - public static final int STOP_SENDING_AFTER_MS = 10000; - private final PlayerList playerList; - private final Map> subscriptions; -- private final Queue subscriptionRequestQueue = new LinkedList<>(); -+ private final java.util.List subscriptionRequestQueue = java.util.Collections.synchronizedList(new LinkedList<>()); // DivineMC - Misc Optimizations - - public DebugSampleSubscriptionTracker(PlayerList playerList) { - this.playerList = playerList; -diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index f8b37b4ce54afd61a72e9d18ac323540431c655d..0f28bc38d8dcb1b68ee7ae05c0c95ca86865c8ba 100644 ---- a/net/minecraft/world/entity/Entity.java -+++ b/net/minecraft/world/entity/Entity.java -@@ -155,7 +155,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - } - - // Paper start - Share random for entities to make them more random -- public static RandomSource SHARED_RANDOM = new RandomRandomSource(); -+ public static RandomSource SHARED_RANDOM = new net.minecraft.world.level.levelgen.ThreadSafeLegacyRandomSource(net.minecraft.world.level.levelgen.RandomSupport.generateUniqueSeed()); // DivineMC - Misc Optimizations - // Paper start - replace random - private static final class RandomRandomSource extends ca.spottedleaf.moonrise.common.util.ThreadUnsafeRandom { - public RandomRandomSource() { -@@ -1108,28 +1108,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - return this.onGround; - } - -- // Paper start - detailed watchdog information -- public final Object posLock = new Object(); // Paper - log detailed entity tick information -- -- @Nullable -- private Vec3 moveVector; -- private double moveStartX; -- private double moveStartY; -- private double moveStartZ; -- // Paper end - detailed watchdog information -- - public void move(MoverType type, Vec3 movement) { - final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity -- // Paper start - detailed watchdog information - ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot move an entity off-main"); -- synchronized (this.posLock) { -- this.moveStartX = this.getX(); -- this.moveStartY = this.getY(); -- this.moveStartZ = this.getZ(); -- this.moveVector = movement; -- } -- try { -- // Paper end - detailed watchdog information - if (this.noPhysics) { - this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z); - } else { -@@ -1244,13 +1225,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - this.setDeltaMovement(this.getDeltaMovement().multiply(blockSpeedFactor, 1.0, blockSpeedFactor)); - } - } -- // Paper start - detailed watchdog information -- } finally { -- synchronized (this.posLock) { // Paper -- this.moveVector = null; -- } // Paper -- } -- // Paper end - detailed watchdog information - } - - private void applyMovementEmissionAndPlaySound(Entity.MovementEmission movementEmission, Vec3 movement, BlockPos pos, BlockState state) { -@@ -4922,9 +4896,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - } - - public void setDeltaMovement(Vec3 deltaMovement) { -- synchronized (this.posLock) { // Paper - detailed watchdog information - this.deltaMovement = deltaMovement; -- } // Paper - detailed watchdog information - } - - public void addDeltaMovement(Vec3 addend) { -@@ -5022,9 +4994,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - } - // Paper end - Block invalid positions and bounding box - if (this.position.x != x || this.position.y != y || this.position.z != z) { -- synchronized (this.posLock) { // Paper - detailed watchdog information - this.position = new Vec3(x, y, z); -- } // Paper - detailed watchdog information - int floor = Mth.floor(x); - int floor1 = Mth.floor(y); - int floor2 = Mth.floor(z); -diff --git a/net/minecraft/world/entity/ExperienceOrb.java b/net/minecraft/world/entity/ExperienceOrb.java -index c8354d46ed909090f7c15f396863bf7d73afcefa..382ef2dad5e995bc01f6492218b8c8f7a930d6ac 100644 ---- a/net/minecraft/world/entity/ExperienceOrb.java -+++ b/net/minecraft/world/entity/ExperienceOrb.java -@@ -195,6 +195,7 @@ public class ExperienceOrb extends Entity { - if (this.age >= 6000) { - this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause - } -+ if (this.count == 0) this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // DivineMC - discard when count is 0 - } - } - -diff --git a/net/minecraft/world/level/GameRules.java b/net/minecraft/world/level/GameRules.java -index d510503a8ad272255aeba20a916642828023fd19..2d9bf302b779602d733187c6f86e52467f0dc540 100644 ---- a/net/minecraft/world/level/GameRules.java -+++ b/net/minecraft/world/level/GameRules.java -@@ -288,7 +288,7 @@ public class GameRules { - } - - private GameRules(Map, GameRules.Value> rules, FeatureFlagSet enabledFeatures) { -- this.rules = rules; -+ this.rules = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(rules); // DivineMC - lithium: collections.gamerules - this.enabledFeatures = enabledFeatures; - - // Paper start - Perf: Use array for gamerule storage -diff --git a/net/minecraft/world/level/LocalMobCapCalculator.java b/net/minecraft/world/level/LocalMobCapCalculator.java -index 9641219c190261dea0db5f95f040a705ba0a3ff9..a3fccdeb2c076e12b611683da55d45e00a166417 100644 ---- a/net/minecraft/world/level/LocalMobCapCalculator.java -+++ b/net/minecraft/world/level/LocalMobCapCalculator.java -@@ -13,16 +13,24 @@ import net.minecraft.world.entity.MobCategory; - - public class LocalMobCapCalculator { - private final Long2ObjectMap> playersNearChunk = new Long2ObjectOpenHashMap<>(); -- private final Map playerMobCounts = Maps.newHashMap(); -+ private final Map playerMobCounts = Maps.newConcurrentMap(); // DivineMC - Misc Optimizations - private final ChunkMap chunkMap; - - public LocalMobCapCalculator(ChunkMap chunkMap) { - this.chunkMap = chunkMap; - } - -- private List getPlayersNear(ChunkPos pos) { -- return this.playersNearChunk.computeIfAbsent(pos.toLong(), key -> this.chunkMap.getPlayersCloseForSpawning(pos)); -+ // DivineMC start - Some optimizations -+ private synchronized @org.jetbrains.annotations.NotNull List getPlayersNear(ChunkPos pos) { -+ List retVal = this.playersNearChunk.get(pos.toLong()); -+ if (retVal == null) { -+ List newVal = this.chunkMap.getPlayersCloseForSpawning(pos); -+ this.playersNearChunk.put(pos.toLong(), newVal); -+ return newVal; -+ } -+ return retVal; - } -+ // DivineMC end - Some optimizations - - public void addMob(ChunkPos pos, MobCategory category) { - for (ServerPlayer serverPlayer : this.getPlayersNear(pos)) { -@@ -42,14 +50,14 @@ public class LocalMobCapCalculator { - } - - static class MobCounts { -- private final Object2IntMap counts = new Object2IntOpenHashMap<>(MobCategory.values().length); -+ private final int[] spawnGroupDensities = new int[MobCategory.values().length]; // DivineMC - Misc Optimizations - - public void add(MobCategory category) { -- this.counts.computeInt(category, (key, value) -> value == null ? 1 : value + 1); -+ this.spawnGroupDensities[category.ordinal()] ++; // DivineMC - Misc Optimizations - } - - public boolean canSpawn(MobCategory category) { -- return this.counts.getOrDefault(category, 0) < category.getMaxInstancesPerChunk(); -+ return this.spawnGroupDensities[category.ordinal()] < category.getMaxInstancesPerChunk(); // DivineMC - Misc Optimizations - } - } - } -diff --git a/net/minecraft/world/level/levelgen/blending/Blender.java b/net/minecraft/world/level/levelgen/blending/Blender.java -index 01e5b29d6e9a5c53c0e23b61ed0c1d7be1a0fe08..d80df05e40f3941ade5ed320e12f8dcf47e6b247 100644 ---- a/net/minecraft/world/level/levelgen/blending/Blender.java -+++ b/net/minecraft/world/level/levelgen/blending/Blender.java -@@ -144,7 +144,7 @@ public class Blender { - private static double heightToOffset(double height) { - double d = 1.0; - double d1 = height + 0.5; -- double d2 = Mth.positiveModulo(d1, 8.0); -+ double d2 = Mth.positiveModuloForPositiveIntegerDenominator(d1, 8.0); // DivineMC - Math optimizations - return 1.0 * (32.0 * (d1 - 128.0) - 3.0 * (d1 - 120.0) * d2 + 3.0 * d2 * d2) / (128.0 * (32.0 - 3.0 * d2)); - } - -diff --git a/net/minecraft/world/level/levelgen/feature/OreFeature.java b/net/minecraft/world/level/levelgen/feature/OreFeature.java -index c7b46efd4f08067e2c9c5c8b0e8b71a94a79823d..c7252c636fcea34a866dcc4862b60cef31071666 100644 ---- a/net/minecraft/world/level/levelgen/feature/OreFeature.java -+++ b/net/minecraft/world/level/levelgen/feature/OreFeature.java -@@ -69,7 +69,7 @@ public class OreFeature extends Feature { - int height - ) { - int i = 0; -- BitSet bitSet = new BitSet(width * height * width); -+ BitSet bitSet = org.bxteam.divinemc.util.cache.CachedOrNewBitsGetter.getCachedOrNewBitSet(width * height * width); // DivineMC - Misc Optimizations - BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); - int i1 = config.size; - double[] doubles = new double[i1 * 4]; -diff --git a/net/minecraft/world/level/storage/DimensionDataStorage.java b/net/minecraft/world/level/storage/DimensionDataStorage.java -index 1ff0b19a077333ad9da9cab7f5a891eeaa2109a9..b82be2c9576b7d41d104b0c44237a01e678811d5 100644 ---- a/net/minecraft/world/level/storage/DimensionDataStorage.java -+++ b/net/minecraft/world/level/storage/DimensionDataStorage.java -@@ -39,7 +39,7 @@ import org.slf4j.Logger; - public class DimensionDataStorage implements AutoCloseable { - private static final Logger LOGGER = LogUtils.getLogger(); - private final SavedData.Context context; -- public final Map, Optional> cache = new HashMap<>(); -+ public final Map, Optional> cache = new java.util.concurrent.ConcurrentHashMap<>(); // DivineMC - Misc Optimizations - private final DataFixer fixerUpper; - private final HolderLookup.Provider registries; - private final Path dataFolder; -diff --git a/net/minecraft/world/phys/AABB.java b/net/minecraft/world/phys/AABB.java -index e53398996bbb278c6e06024d8ca945b364a44c10..f60c1ab58a2e9adfb01e9bd430b92cd1902e5dbe 100644 ---- a/net/minecraft/world/phys/AABB.java -+++ b/net/minecraft/world/phys/AABB.java -@@ -190,13 +190,15 @@ public class AABB { - } - - public AABB intersect(AABB other) { -- double max = Math.max(this.minX, other.minX); -- double max1 = Math.max(this.minY, other.minY); -- double max2 = Math.max(this.minZ, other.minZ); -- double min = Math.min(this.maxX, other.maxX); -- double min1 = Math.min(this.maxY, other.maxY); -- double min2 = Math.min(this.maxZ, other.maxZ); -- return new AABB(max, max1, max2, min, min1, min2); -+ // DivineMC start - Math Optimizations -+ return new AABB( -+ this.minX > other.minX ? this.minX : other.minX, -+ this.minY > other.minY ? this.minY : other.minY, -+ this.minZ > other.minZ ? this.minZ : other.minZ, -+ this.maxX < other.maxX ? this.maxX : other.maxX, -+ this.maxY < other.maxY ? this.maxY : other.maxY, -+ this.maxZ < other.maxZ ? this.maxZ : other.maxZ -+ ); - } - - public AABB minmax(AABB other) { -@@ -228,16 +230,37 @@ public class AABB { - } - - public boolean intersects(AABB other) { -- return this.intersects(other.minX, other.minY, other.minZ, other.maxX, other.maxY, other.maxZ); -+ // DivineMC start - Math Optimizations -+ return this.minX < other.maxX && -+ this.maxX > other.minX && -+ this.minY < other.maxY && -+ this.maxY > other.minY && -+ this.minZ < other.maxZ && -+ this.maxZ > other.minZ; -+ // DivineMC end - Math Optimizations - } - - public boolean intersects(double x1, double y1, double z1, double x2, double y2, double z2) { -- return this.minX < x2 && this.maxX > x1 && this.minY < y2 && this.maxY > y1 && this.minZ < z2 && this.maxZ > z1; -+ // DivineMC start - Math Optimizations -+ return this.minX < x2 && -+ this.maxX > x1 && -+ this.minY < y2 && -+ this.maxY > y1 && -+ this.minZ < z2 && -+ this.maxZ > z1; -+ // DivineMC end - Math Optimizations - } - - public boolean intersects(Vec3 min, Vec3 max) { - return this.intersects( -- Math.min(min.x, max.x), Math.min(min.y, max.y), Math.min(min.z, max.z), Math.max(min.x, max.x), Math.max(min.y, max.y), Math.max(min.z, max.z) -+ // DivineMC start - Math Optimizations -+ min.x < max.x ? min.x : max.x, -+ min.y < max.y ? min.y : max.y, -+ min.z < max.z ? min.z : max.z, -+ min.x > max.x ? min.x : max.x, -+ min.y > max.y ? min.y : max.y, -+ min.z > max.z ? min.z : max.z -+ // DivineMC end - Math Optimizations - ); - } - diff --git a/patches/work/server/paper/0008-Configurable-thread-pool-priority.patch b/patches/work/server/paper/0008-Configurable-thread-pool-priority.patch deleted file mode 100644 index 213ae7e..0000000 --- a/patches/work/server/paper/0008-Configurable-thread-pool-priority.patch +++ /dev/null @@ -1,18 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> -Date: Sun, 23 Feb 2025 00:43:23 +0300 -Subject: [PATCH] Configurable thread pool priority - - -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java -index 03e7344661b6aea258918bd388dc0e4e6fb5bc96..098b50751d805f03cad5e94e8ed04a20697a51cc 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java -@@ -75,6 +75,7 @@ public final class MoonriseCommon { - LOGGER.error("Uncaught exception in thread {}", thread.getName(), throwable); - } - }); -+ thread.setPriority(DivineConfig.PerformanceCategory.threadPoolPriority); // DivineMC - Configurable thread pool priority - } - } - ); diff --git a/patches/work/server/paper/0009-Virtual-Threads.patch b/patches/work/server/paper/0009-Virtual-Threads.patch deleted file mode 100644 index 80f48f8..0000000 --- a/patches/work/server/paper/0009-Virtual-Threads.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> -Date: Mon, 24 Feb 2025 19:36:33 +0300 -Subject: [PATCH] Virtual Threads - - -diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java -index 8492a06883e2ff597bbbdaa74fe5e5cdd0a0a1b1..862e49f510720f3546c339f5c4cf1945303dd8c9 100644 ---- a/src/main/java/io/papermc/paper/util/MCUtil.java -+++ b/src/main/java/io/papermc/paper/util/MCUtil.java -@@ -37,7 +37,7 @@ public final class MCUtil { - run.run(); - } - }; -- public static final ExecutorService ASYNC_EXECUTOR = Executors.newFixedThreadPool(2, new ThreadFactoryBuilder() -+ public static final ExecutorService ASYNC_EXECUTOR = org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.virtualThreadsEnabled && org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.virtualAsyncExecutor ? Executors.newVirtualThreadPerTaskExecutor() : Executors.newFixedThreadPool(2, new ThreadFactoryBuilder() // DivineMC - Virtual Threads - .setNameFormat("Paper Async Task Handler Thread - %1$d") - .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(MinecraftServer.LOGGER)) - .build() -diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java -index 0ca279fb71d39c81b1f608e0ee9ba3e498d55fa3..8f82c034de320af7b65bad1602ebb561dd844e59 100644 ---- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java -+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java -@@ -31,14 +31,18 @@ import java.util.ArrayList; - import java.util.Iterator; - import java.util.List; - import java.util.concurrent.Executor; -+import java.util.concurrent.ExecutorService; - import java.util.concurrent.Executors; - import java.util.concurrent.SynchronousQueue; - import java.util.concurrent.ThreadPoolExecutor; - import java.util.concurrent.TimeUnit; - - public class CraftAsyncScheduler extends CraftScheduler { -- -- private final ThreadPoolExecutor executor = new ThreadPoolExecutor( -+ // DivineMC start - Virtual Threads -+ private final ExecutorService executor = org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.virtualThreadsEnabled && org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.virtualBukkitScheduler -+ ? Executors.newVirtualThreadPerTaskExecutor() -+ : new ThreadPoolExecutor( -+ // DivineMC end - Virtual Threads - 4, Integer.MAX_VALUE,30L, TimeUnit.SECONDS, new SynchronousQueue<>(), - new ThreadFactoryBuilder().setNameFormat("Craft Scheduler Thread - %1$d").build()); - private final Executor management = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder() -@@ -47,8 +51,12 @@ public class CraftAsyncScheduler extends CraftScheduler { - - CraftAsyncScheduler() { - super(true); -- executor.allowCoreThreadTimeOut(true); -- executor.prestartAllCoreThreads(); -+ // DivineMC start - Virtual Threads -+ if (!org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.virtualThreadsEnabled && !org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.virtualBukkitScheduler) { -+ ((ThreadPoolExecutor) executor).allowCoreThreadTimeOut(true); -+ ((ThreadPoolExecutor) executor).prestartAllCoreThreads(); -+ } -+ // DivineMC end - Virtual Threads - } - - @Override