diff --git a/divinemc-server/minecraft-patches/features/0002-Configuration.patch b/divinemc-server/minecraft-patches/features/0002-Configuration.patch index 0ab87e9..0a1035c 100644 --- a/divinemc-server/minecraft-patches/features/0002-Configuration.patch +++ b/divinemc-server/minecraft-patches/features/0002-Configuration.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Configuration diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java -index debea77d5777b90c6b17b225e27e6b3c72370175..1a8c125a58f7363dbff4f11f5e34537ca1fbd605 100644 +index debea77d5777b90c6b17b225e27e6b3c72370175..f5761420749110ca8811533c3fb5d80c8b025c67 100644 --- a/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java @@ -193,6 +193,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -14,7 +14,7 @@ index debea77d5777b90c6b17b225e27e6b3c72370175..1a8c125a58f7363dbff4f11f5e34537c // Purpur end - Purpur config files + // DivineMC start - Configuration + try { -+ org.bxteam.divinemc.DivineConfig.init((java.io.File) options.valueOf("divinemc-settings")); ++ org.bxteam.divinemc.config.DivineConfig.init((java.io.File) options.valueOf("divinemc-settings")); + } catch (Exception e) { + DedicatedServer.LOGGER.error("Unable to load DivineMC configuration", e); + return false; @@ -25,14 +25,14 @@ index debea77d5777b90c6b17b225e27e6b3c72370175..1a8c125a58f7363dbff4f11f5e34537c // DivineMC start - Pufferfish SIMD diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 801c4e8e01590beeb3633275f58d436d87ad746e..269011e6ba70c9da42f2bc7c902fed5ab6994042 100644 +index 801c4e8e01590beeb3633275f58d436d87ad746e..5ffaae02967dbc079619d35c2b8e3f7763b75d38 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -161,6 +161,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl // Paper end - add paper world config public final org.purpurmc.purpur.PurpurWorldConfig purpurConfig; // Purpur - Purpur config files -+ public final org.bxteam.divinemc.DivineWorldConfig divineConfig; // DivineMC - Configuration ++ public final org.bxteam.divinemc.config.DivineWorldConfig divineConfig; // DivineMC - Configuration public static @Nullable BlockPos lastPhysicsProblem; // Spigot private int tileTickPosition; public final Map explosionDensityCache = new java.util.HashMap<>(); // Paper - Optimize explosions @@ -42,7 +42,7 @@ index 801c4e8e01590beeb3633275f58d436d87ad746e..269011e6ba70c9da42f2bc7c902fed5a this.purpurConfig = new org.purpurmc.purpur.PurpurWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName(), environment); // Purpur - Purpur config files + // DivineMC start - Configuration + try { -+ this.divineConfig = new org.bxteam.divinemc.DivineWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName(), environment); ++ this.divineConfig = new org.bxteam.divinemc.config.DivineWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName(), environment); + } catch (java.io.IOException e) { + net.minecraft.server.MinecraftServer.LOGGER.error("Failed to load DivineMC configuration for world '{}'", ((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName(), e); + throw new RuntimeException(e); diff --git a/divinemc-server/minecraft-patches/features/0004-Implement-Secure-Seed.patch b/divinemc-server/minecraft-patches/features/0004-Implement-Secure-Seed.patch index fc0d04a..7d2daee 100644 --- a/divinemc-server/minecraft-patches/features/0004-Implement-Secure-Seed.patch +++ b/divinemc-server/minecraft-patches/features/0004-Implement-Secure-Seed.patch @@ -7,7 +7,7 @@ Original license: GPLv3 Original project: https://github.com/plasmoapp/matter diff --git a/net/minecraft/server/commands/SeedCommand.java b/net/minecraft/server/commands/SeedCommand.java -index a65affc41a4fc299bc2281f0f53f2e075633899d..7284c984f9309d4a862fe6f89df993c9a6a9efa6 100644 +index a65affc41a4fc299bc2281f0f53f2e075633899d..552b9e7973c7c22100fbdfe9821f162ea032c975 100644 --- a/net/minecraft/server/commands/SeedCommand.java +++ b/net/minecraft/server/commands/SeedCommand.java @@ -12,6 +12,17 @@ public class SeedCommand { @@ -16,7 +16,7 @@ index a65affc41a4fc299bc2281f0f53f2e075633899d..7284c984f9309d4a862fe6f89df993c9 context.getSource().sendSuccess(() -> Component.translatable("commands.seed.success", component), false); + + // DivineMC start - Implement Secure Seed -+ if (org.bxteam.divinemc.DivineConfig.enableSecureSeed) { ++ if (org.bxteam.divinemc.config.DivineConfig.MiscCategory.enableSecureSeed) { + su.plo.matter.Globals.setupGlobals(context.getSource().getLevel()); + String seedStr = su.plo.matter.Globals.seedToString(su.plo.matter.Globals.worldSeed); + Component featureSeedComponent = ComponentUtils.copyOnClickText(seedStr); @@ -29,7 +29,7 @@ index a65affc41a4fc299bc2281f0f53f2e075633899d..7284c984f9309d4a862fe6f89df993c9 })); } diff --git a/net/minecraft/server/dedicated/DedicatedServerProperties.java b/net/minecraft/server/dedicated/DedicatedServerProperties.java -index 5748658abf0b90812005ae9d426df92daf5532f0..8b4b91be368b4195326eeb1c714d713a95f28d76 100644 +index 5748658abf0b90812005ae9d426df92daf5532f0..8849a04b10517ff2de12a9df212ac90ff4882401 100644 --- a/net/minecraft/server/dedicated/DedicatedServerProperties.java +++ b/net/minecraft/server/dedicated/DedicatedServerProperties.java @@ -114,7 +114,17 @@ public class DedicatedServerProperties extends Settings list = this.featuresPerStep.get(); - WorldgenRandom worldgenRandom = new WorldgenRandom(new XoroshiroRandomSource(RandomSupport.generateUniqueSeed())); + // DivineMC start - Implement Secure Seed -+ WorldgenRandom worldgenRandom = org.bxteam.divinemc.DivineConfig.enableSecureSeed ++ WorldgenRandom worldgenRandom = org.bxteam.divinemc.config.DivineConfig.MiscCategory.enableSecureSeed + ? new su.plo.matter.WorldgenCryptoRandom(blockPos.getX(), blockPos.getZ(), su.plo.matter.Globals.Salt.UNDEFINED, 0) + : new WorldgenRandom(new XoroshiroRandomSource(RandomSupport.generateUniqueSeed())); + // DivineMC end - Implement Secure Seed @@ -150,7 +150,7 @@ index 857aa6e29b57a0a8eea4d7c14971b9dde59bb0d0..fdf9318b96d7ac7f707777bb63a5d36a - worldgenRandom.setLargeFeatureSeed(structureState.getLevelSeed(), pos.x, pos.z); + // DivineMC start - Implement Secure Seed + WorldgenRandom worldgenRandom; -+ if (org.bxteam.divinemc.DivineConfig.enableSecureSeed) { ++ if (org.bxteam.divinemc.config.DivineConfig.MiscCategory.enableSecureSeed) { + worldgenRandom = new su.plo.matter.WorldgenCryptoRandom( + pos.x, pos.z, su.plo.matter.Globals.Salt.GENERATE_FEATURE, 0 + ); @@ -164,7 +164,7 @@ index 857aa6e29b57a0a8eea4d7c14971b9dde59bb0d0..fdf9318b96d7ac7f707777bb63a5d36a for (StructureSet.StructureSelectionEntry structureSelectionEntry1 : list1) { diff --git a/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java b/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java -index 619b98e42e254c0c260c171a26a2472ddf59b885..a3093ef1b47544f2eb02d366040526697dafc8db 100644 +index 619b98e42e254c0c260c171a26a2472ddf59b885..7c110c3ab9b659fb26afddbe3541eb4e45503e4a 100644 --- a/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java +++ b/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java @@ -205,14 +205,21 @@ public class ChunkGeneratorStructureState { @@ -180,11 +180,11 @@ index 619b98e42e254c0c260c171a26a2472ddf59b885..a3093ef1b47544f2eb02d36604052669 - randomSource.setSeed(this.concentricRingsSeed); - } // Paper - Add missing structure set seed configs + // DivineMC start - Implement Secure Seed -+ RandomSource randomSource = org.bxteam.divinemc.DivineConfig.enableSecureSeed ++ RandomSource randomSource = org.bxteam.divinemc.config.DivineConfig.MiscCategory.enableSecureSeed + ? new su.plo.matter.WorldgenCryptoRandom(0, 0, su.plo.matter.Globals.Salt.STRONGHOLDS, 0) + : RandomSource.create(); + -+ if (!org.bxteam.divinemc.DivineConfig.enableSecureSeed) { ++ if (!org.bxteam.divinemc.config.DivineConfig.MiscCategory.enableSecureSeed) { + // Paper start - Add missing structure set seed configs + if (this.conf.strongholdSeed != null && structureSet.is(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS)) { + randomSource.setSeed(this.conf.strongholdSeed); @@ -210,7 +210,7 @@ index b8348976e80578d9eff64eea68c04c603fed49ad..9494e559113798fe451a6d0226be3ae0 ProfiledDuration profiledDuration = JvmProfiler.INSTANCE .onChunkGenerate(chunk.getPos(), worldGenContext.level().dimension(), this.targetStatus.getName()); diff --git a/net/minecraft/world/level/levelgen/WorldOptions.java b/net/minecraft/world/level/levelgen/WorldOptions.java -index c92508741439a8d0d833ea02d0104416adb83c92..630f6c409db349819fc5fd19a3d78fadb4cfb6d6 100644 +index c92508741439a8d0d833ea02d0104416adb83c92..c4afe1cc270e6d7b4ffeada75da8265b46afd694 100644 --- a/net/minecraft/world/level/levelgen/WorldOptions.java +++ b/net/minecraft/world/level/levelgen/WorldOptions.java @@ -9,17 +9,28 @@ import net.minecraft.util.RandomSource; @@ -218,7 +218,7 @@ index c92508741439a8d0d833ea02d0104416adb83c92..630f6c409db349819fc5fd19a3d78fad public class WorldOptions { + // DivineMC start - Implement Secure Seed -+ private static final boolean isSecureSeedEnabled = org.bxteam.divinemc.DivineConfig.enableSecureSeed; ++ private static final boolean isSecureSeedEnabled = org.bxteam.divinemc.config.DivineConfig.MiscCategory.enableSecureSeed; public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( - instance -> instance.group( + instance -> isSecureSeedEnabled @@ -328,7 +328,7 @@ index c92508741439a8d0d833ea02d0104416adb83c92..630f6c409db349819fc5fd19a3d78fad public static OptionalLong parseSeed(String seed) { seed = seed.trim(); diff --git a/net/minecraft/world/level/levelgen/feature/GeodeFeature.java b/net/minecraft/world/level/levelgen/feature/GeodeFeature.java -index 4e72eb49dbf4c70ae7556ba6eb210fcd5ef36aaa..44cefaac4806008ce59b43f5b95ce17ee3ad39e5 100644 +index 4e72eb49dbf4c70ae7556ba6eb210fcd5ef36aaa..00e20c8c76ff8d902c3ea85ed96dfa3649c8e301 100644 --- a/net/minecraft/world/level/levelgen/feature/GeodeFeature.java +++ b/net/minecraft/world/level/levelgen/feature/GeodeFeature.java @@ -41,7 +41,11 @@ public class GeodeFeature extends Feature { @@ -337,7 +337,7 @@ index 4e72eb49dbf4c70ae7556ba6eb210fcd5ef36aaa..44cefaac4806008ce59b43f5b95ce17e int i2 = geodeConfiguration.distributionPoints.sample(randomSource); - WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(worldGenLevel.getSeed())); + // DivineMC start - Implement Secure Seed -+ WorldgenRandom worldgenRandom = org.bxteam.divinemc.DivineConfig.enableSecureSeed ++ WorldgenRandom worldgenRandom = org.bxteam.divinemc.config.DivineConfig.MiscCategory.enableSecureSeed + ? new su.plo.matter.WorldgenCryptoRandom(0, 0, su.plo.matter.Globals.Salt.GEODE_FEATURE, 0) + : new WorldgenRandom(new LegacyRandomSource(worldGenLevel.getSeed())); + // DivineMC end - Implement Secure Seed @@ -345,7 +345,7 @@ index 4e72eb49dbf4c70ae7556ba6eb210fcd5ef36aaa..44cefaac4806008ce59b43f5b95ce17e List list1 = Lists.newLinkedList(); double d = (double)i2 / geodeConfiguration.outerWallDistance.getMaxValue(); diff --git a/net/minecraft/world/level/levelgen/structure/Structure.java b/net/minecraft/world/level/levelgen/structure/Structure.java -index 8328e864c72b7a358d6bb1f33459b8c4df2ecb1a..7c35949c9a2f102e9da246fd5bf81d9e14eb36ca 100644 +index 8328e864c72b7a358d6bb1f33459b8c4df2ecb1a..95881be2b7a5d16df22e8842acaba037b91a7009 100644 --- a/net/minecraft/world/level/levelgen/structure/Structure.java +++ b/net/minecraft/world/level/levelgen/structure/Structure.java @@ -249,6 +249,14 @@ public abstract class Structure { @@ -353,7 +353,7 @@ index 8328e864c72b7a358d6bb1f33459b8c4df2ecb1a..7c35949c9a2f102e9da246fd5bf81d9e private static WorldgenRandom makeRandom(long seed, ChunkPos chunkPos) { + // DivineMC start - Implement Secure Seed -+ if (org.bxteam.divinemc.DivineConfig.enableSecureSeed) { ++ if (org.bxteam.divinemc.config.DivineConfig.MiscCategory.enableSecureSeed) { + return new su.plo.matter.WorldgenCryptoRandom( + chunkPos.x, chunkPos.z, su.plo.matter.Globals.Salt.GENERATE_FEATURE, seed + ); @@ -364,7 +364,7 @@ index 8328e864c72b7a358d6bb1f33459b8c4df2ecb1a..7c35949c9a2f102e9da246fd5bf81d9e worldgenRandom.setLargeFeatureSeed(seed, chunkPos.x, chunkPos.z); return worldgenRandom; diff --git a/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java b/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java -index ee0d9dddb36b6879fa113299e24f1aa3b2b151cc..f01d96895ab348971fb31b614026fb3d106e9a3e 100644 +index ee0d9dddb36b6879fa113299e24f1aa3b2b151cc..3af3bf800215ef78b98a4866df572f3ba263055d 100644 --- a/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java +++ b/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java @@ -67,8 +67,17 @@ public class RandomSpreadStructurePlacement extends StructurePlacement { @@ -375,7 +375,7 @@ index ee0d9dddb36b6879fa113299e24f1aa3b2b151cc..f01d96895ab348971fb31b614026fb3d - worldgenRandom.setLargeFeatureWithSalt(seed, i, i1, this.salt()); + // DivineMC start - Implement Secure Seed + WorldgenRandom worldgenRandom; -+ if (org.bxteam.divinemc.DivineConfig.enableSecureSeed) { ++ if (org.bxteam.divinemc.config.DivineConfig.MiscCategory.enableSecureSeed) { + worldgenRandom = new su.plo.matter.WorldgenCryptoRandom( + i, i1, su.plo.matter.Globals.Salt.POTENTIONAL_FEATURE, this.salt + ); @@ -388,7 +388,7 @@ index ee0d9dddb36b6879fa113299e24f1aa3b2b151cc..f01d96895ab348971fb31b614026fb3d int i3 = this.spreadType.evaluate(worldgenRandom, i2); int i4 = this.spreadType.evaluate(worldgenRandom, i2); diff --git a/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java b/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java -index 1f939b325ec5291b3c4aabc4735c863f9436a6f8..4ed6a3d6103ce48797950c7363ea0854227e62e8 100644 +index 1f939b325ec5291b3c4aabc4735c863f9436a6f8..0a544577922bef471d2f07544ad45ce2186d92d1 100644 --- a/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java +++ b/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java @@ -119,8 +119,17 @@ public abstract class StructurePlacement { @@ -399,7 +399,7 @@ index 1f939b325ec5291b3c4aabc4735c863f9436a6f8..4ed6a3d6103ce48797950c7363ea0854 - worldgenRandom.setLargeFeatureWithSalt(levelSeed, regionX, regionZ, salt); + // DivineMC start - Implement Secure Seed + WorldgenRandom worldgenRandom; -+ if (org.bxteam.divinemc.DivineConfig.enableSecureSeed) { ++ if (org.bxteam.divinemc.config.DivineConfig.MiscCategory.enableSecureSeed) { + worldgenRandom = new su.plo.matter.WorldgenCryptoRandom( + regionX, regionZ, su.plo.matter.Globals.Salt.UNDEFINED, salt + ); @@ -412,7 +412,7 @@ index 1f939b325ec5291b3c4aabc4735c863f9436a6f8..4ed6a3d6103ce48797950c7363ea0854 } diff --git a/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java b/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java -index 1cfa0fcd28685736fcdce4aef817e4d4cc4061cb..e275dc8395e556e8a9412b121034e91553fbaea4 100644 +index 1cfa0fcd28685736fcdce4aef817e4d4cc4061cb..86a54586112b84b7c2026a4cbdad99cdf1c6ef81 100644 --- a/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java +++ b/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java @@ -64,7 +64,11 @@ public class JigsawPlacement { @@ -421,7 +421,7 @@ index 1cfa0fcd28685736fcdce4aef817e4d4cc4061cb..e275dc8395e556e8a9412b121034e915 LevelHeightAccessor levelHeightAccessor = context.heightAccessor(); - WorldgenRandom worldgenRandom = context.random(); + // DivineMC start - Implement Secure Seed -+ WorldgenRandom worldgenRandom = org.bxteam.divinemc.DivineConfig.enableSecureSeed ++ WorldgenRandom worldgenRandom = org.bxteam.divinemc.config.DivineConfig.MiscCategory.enableSecureSeed + ? new su.plo.matter.WorldgenCryptoRandom(context.chunkPos().x, context.chunkPos().z, su.plo.matter.Globals.Salt.JIGSAW_PLACEMENT, 0) + : context.random(); + // DivineMC end - Implement Secure Seed diff --git a/divinemc-server/minecraft-patches/features/0005-Async-Pathfinding.patch b/divinemc-server/minecraft-patches/features/0005-Async-Pathfinding.patch index afaebb5..4c3810a 100644 --- a/divinemc-server/minecraft-patches/features/0005-Async-Pathfinding.patch +++ b/divinemc-server/minecraft-patches/features/0005-Async-Pathfinding.patch @@ -9,7 +9,7 @@ You can find the original code on https://github.com/Bloom-host/Petal Makes most pathfinding-related work happen asynchronously diff --git a/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/net/minecraft/world/entity/ai/behavior/AcquirePoi.java -index 67cbf9f5760fae5db6f31e64095cd1b6be6ade8e..7ad36864d700f3012a3791bf3814465e5e9deffa 100644 +index 67cbf9f5760fae5db6f31e64095cd1b6be6ade8e..327a0414c8723420ffe34597464c1772768e8fa3 100644 --- a/net/minecraft/world/entity/ai/behavior/AcquirePoi.java +++ b/net/minecraft/world/entity/ai/behavior/AcquirePoi.java @@ -94,21 +94,18 @@ public class AcquirePoi { @@ -26,7 +26,7 @@ index 67cbf9f5760fae5db6f31e64095cd1b6be6ade8e..7ad36864d700f3012a3791bf3814465e - map.clear(); - DebugPackets.sendPoiTicketCountPacket(level, target); + // DivineMC start - Async path processing -+ if (org.bxteam.divinemc.DivineConfig.asyncPathfinding) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding) { + Path possiblePath = findPathToPois(mob, set); + + org.bxteam.divinemc.entity.pathfinding.AsyncPathProcessor.awaitProcessing(possiblePath, path -> { @@ -79,7 +79,7 @@ index 67cbf9f5760fae5db6f31e64095cd1b6be6ade8e..7ad36864d700f3012a3791bf3814465e public static Path findPathToPois(Mob mob, Set, BlockPos>> poiPositions) { if (poiPositions.isEmpty()) { diff --git a/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java b/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java -index 621ba76784f2b92790eca62be4d0688834335ab6..3f676309af0d5529413fa047a7f3cac99260b9ad 100644 +index 621ba76784f2b92790eca62be4d0688834335ab6..92d8899ff7d42ecc987a7bf2035cc72484ea9e82 100644 --- a/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java +++ b/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java @@ -21,6 +21,7 @@ public class MoveToTargetSink extends Behavior { @@ -95,10 +95,10 @@ index 621ba76784f2b92790eca62be4d0688834335ab6..3f676309af0d5529413fa047a7f3cac9 WalkTarget walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get(); boolean flag = this.reachedTarget(owner, walkTarget); - if (!flag && this.tryComputePath(owner, walkTarget, level.getGameTime())) { -+ if (!org.bxteam.divinemc.DivineConfig.asyncPathfinding && !flag && this.tryComputePath(owner, walkTarget, level.getGameTime())) { // DivineMC - async path processing ++ if (!org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding && !flag && this.tryComputePath(owner, walkTarget, level.getGameTime())) { // DivineMC - async path processing this.lastTargetPos = walkTarget.getTarget().currentBlockPosition(); return true; -+ } else if (org.bxteam.divinemc.DivineConfig.asyncPathfinding && !flag) { // DivineMC - async pathfinding ++ } else if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding && !flag) { // DivineMC - async pathfinding + return true; } else { brain.eraseMemory(MemoryModuleType.WALK_TARGET); @@ -107,7 +107,7 @@ index 621ba76784f2b92790eca62be4d0688834335ab6..3f676309af0d5529413fa047a7f3cac9 @Override protected boolean canStillUse(ServerLevel level, Mob entity, long gameTime) { -+ if (org.bxteam.divinemc.DivineConfig.asyncPathfinding && !this.finishedProcessing) return true; // DivineMC - wait for processing ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding && !this.finishedProcessing) return true; // DivineMC - wait for processing if (this.path != null && this.lastTargetPos != null) { Optional memory = entity.getBrain().getMemory(MemoryModuleType.WALK_TARGET); boolean flag = memory.map(MoveToTargetSink::isWalkTargetSpectator).orElse(false); @@ -116,7 +116,7 @@ index 621ba76784f2b92790eca62be4d0688834335ab6..3f676309af0d5529413fa047a7f3cac9 @Override protected void start(ServerLevel level, Mob entity, long gameTime) { + // DivineMC start - start processing -+ if (org.bxteam.divinemc.DivineConfig.asyncPathfinding) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding) { + Brain brain = entity.getBrain(); + WalkTarget walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get(); + @@ -139,7 +139,7 @@ index 621ba76784f2b92790eca62be4d0688834335ab6..3f676309af0d5529413fa047a7f3cac9 - brain.setMemory(MemoryModuleType.PATH, path); - } + // DivineMC start - Async path processing -+ if (org.bxteam.divinemc.DivineConfig.asyncPathfinding) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding) { + if (this.path != null && !this.path.isProcessed()) return; // wait for processing - if (path != null && this.lastTargetPos != null) { @@ -222,7 +222,7 @@ index 621ba76784f2b92790eca62be4d0688834335ab6..3f676309af0d5529413fa047a7f3cac9 private boolean tryComputePath(Mob mob, WalkTarget target, long time) { BlockPos blockPos = target.getTarget().currentBlockPosition(); diff --git a/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java b/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java -index 4f9f3367b1ca3903df03a80fa2b01a3d24e6e77d..1e9383442d0a0adf4bf621fc35108b35b1375bc7 100644 +index 4f9f3367b1ca3903df03a80fa2b01a3d24e6e77d..87f218cbeda68d2996a354afabb8be70f513920e 100644 --- a/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java +++ b/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java @@ -60,17 +60,18 @@ public class SetClosestHomeAsWalkTarget { @@ -240,7 +240,7 @@ index 4f9f3367b1ca3903df03a80fa2b01a3d24e6e77d..1e9383442d0a0adf4bf621fc35108b35 - } else if (mutableInt.getValue() < 5) { - map.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < mutableLong.getValue()); + // DivineMC start - async path processing -+ if (org.bxteam.divinemc.DivineConfig.asyncPathfinding) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding) { + Path possiblePath = AcquirePoi.findPathToPois(mob, set); + + org.bxteam.divinemc.entity.pathfinding.AsyncPathProcessor.awaitProcessing(possiblePath, path -> { @@ -295,7 +295,7 @@ index d8f532c5e68ff4dff933556c4f981e9474c044e6..37f3d3888ea2a862d006cf2b201f9715 Node node = path.getNode(i); this.doorPos = new BlockPos(node.x, node.y + 1, node.z); diff --git a/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java b/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java -index 66a02fe7594522ef391d67e09856bf3f70fe597d..0cd0d1059ac3612ba34f1a47a5023a8d07ee612f 100644 +index 66a02fe7594522ef391d67e09856bf3f70fe597d..dfb8f72a83dfe27b1f9a036f2cad3f4c9a7f15b4 100644 --- a/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java +++ b/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java @@ -12,9 +12,25 @@ public class AmphibiousPathNavigation extends PathNavigation { @@ -317,7 +317,7 @@ index 66a02fe7594522ef391d67e09856bf3f70fe597d..0cd0d1059ac3612ba34f1a47a5023a8d protected PathFinder createPathFinder(int maxVisitedNodes) { this.nodeEvaluator = new AmphibiousNodeEvaluator(false); + // DivineMC start - async path processing -+ if (org.bxteam.divinemc.DivineConfig.asyncPathfinding) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding) { + return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator); + } + // DivineMC end - async path processing @@ -325,7 +325,7 @@ index 66a02fe7594522ef391d67e09856bf3f70fe597d..0cd0d1059ac3612ba34f1a47a5023a8d } diff --git a/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java b/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java -index 71ea68b56b3069bdf8e47931156b6ef49ea8ce5d..0e680d3954d5847125484c2a93d9cd8e133ad8c3 100644 +index 71ea68b56b3069bdf8e47931156b6ef49ea8ce5d..c3ce8516338d458d20e6848fd63bedaf70bea222 100644 --- a/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java +++ b/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java @@ -16,9 +16,25 @@ public class FlyingPathNavigation extends PathNavigation { @@ -347,7 +347,7 @@ index 71ea68b56b3069bdf8e47931156b6ef49ea8ce5d..0e680d3954d5847125484c2a93d9cd8e protected PathFinder createPathFinder(int maxVisitedNodes) { this.nodeEvaluator = new FlyNodeEvaluator(); + // DivineMC start - async path processing -+ if (org.bxteam.divinemc.DivineConfig.asyncPathfinding) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding) { + return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator); + } + // DivineMC end - async path processing @@ -363,7 +363,7 @@ index 71ea68b56b3069bdf8e47931156b6ef49ea8ce5d..0e680d3954d5847125484c2a93d9cd8e if (!this.isDone()) { if (this.canUpdatePath()) { diff --git a/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java b/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java -index 045cfafb3afe8271d60852ae3c7cdcb039b44d4f..f544bf28ac6531061da08c726684687416b9426c 100644 +index 045cfafb3afe8271d60852ae3c7cdcb039b44d4f..a8a3d48e9f2f31ec0a20a4b7c547a9590865d807 100644 --- a/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java +++ b/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java @@ -24,9 +24,25 @@ public class GroundPathNavigation extends PathNavigation { @@ -385,7 +385,7 @@ index 045cfafb3afe8271d60852ae3c7cdcb039b44d4f..f544bf28ac6531061da08c7266846874 protected PathFinder createPathFinder(int maxVisitedNodes) { this.nodeEvaluator = new WalkNodeEvaluator(); + // DivineMC start - async path processing -+ if (org.bxteam.divinemc.DivineConfig.asyncPathfinding) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding) { + return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator); + } + // DivineMC end - async path processing @@ -393,7 +393,7 @@ index 045cfafb3afe8271d60852ae3c7cdcb039b44d4f..f544bf28ac6531061da08c7266846874 } diff --git a/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/net/minecraft/world/entity/ai/navigation/PathNavigation.java -index 6bbdfc748f1ce66689c63424fadcf261b1e967b3..55d0ed422f25b6469f9d8ee3ecf2ef8eaf77e9cb 100644 +index 6bbdfc748f1ce66689c63424fadcf261b1e967b3..c01c1633eedee3ecd5e1eb667808d364d7b6fe4c 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 { @@ -416,7 +416,7 @@ index 6bbdfc748f1ce66689c63424fadcf261b1e967b3..55d0ed422f25b6469f9d8ee3ecf2ef8e - this.reachRange = accuracy; - this.resetStuckTimeout(); + // DivineMC start - async path processing -+ if (org.bxteam.divinemc.DivineConfig.asyncPathfinding) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding) { + // assign early a target position. most calls will only have 1 position + if (!targets.isEmpty()) this.targetPos = targets.iterator().next(); + @@ -478,7 +478,7 @@ index 6bbdfc748f1ce66689c63424fadcf261b1e967b3..55d0ed422f25b6469f9d8ee3ecf2ef8e Vec3 vec3 = new Vec3((endNode.x + this.mob.getX()) / 2.0, (endNode.y + this.mob.getY()) / 2.0, (endNode.z + this.mob.getZ()) / 2.0); return pos.closerToCenterThan(vec3, this.path.getNodeCount() - this.path.getNextNodeIndex()); diff --git a/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java b/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java -index 2979846853898d78a2df19df2287da16dbe4ae71..504911c14aad5c53aeea2c71bda3978f022601dd 100644 +index 2979846853898d78a2df19df2287da16dbe4ae71..0979e11a1c01927496184918f3a1923f175c7478 100644 --- a/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java +++ b/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java @@ -15,11 +15,27 @@ public class WaterBoundPathNavigation extends PathNavigation { @@ -502,7 +502,7 @@ index 2979846853898d78a2df19df2287da16dbe4ae71..504911c14aad5c53aeea2c71bda3978f this.nodeEvaluator = new SwimNodeEvaluator(this.allowBreaching); this.nodeEvaluator.setCanPassDoors(false); + // DivineMC start - async path processing -+ if (org.bxteam.divinemc.DivineConfig.asyncPathfinding) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding) { + return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator); + } + // DivineMC end - async path processing @@ -510,7 +510,7 @@ index 2979846853898d78a2df19df2287da16dbe4ae71..504911c14aad5c53aeea2c71bda3978f } diff --git a/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java b/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java -index 1f96fd5085bacb4c584576c7cb9f51e7898e9b03..9494dd144ff1115c9f0862614ef618035ee2565f 100644 +index 1f96fd5085bacb4c584576c7cb9f51e7898e9b03..e56869b8c700bfd9fa25f7b7db8663c4b8bad006 100644 --- a/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java +++ b/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java @@ -57,17 +57,32 @@ public class NearestBedSensor extends Sensor { @@ -528,7 +528,7 @@ index 1f96fd5085bacb4c584576c7cb9f51e7898e9b03..9494dd144ff1115c9f0862614ef61803 - } else if (this.triedCount < 5) { - this.batchCache.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < this.lastUpdate); + // DivineMC start - async pathfinding -+ if (org.bxteam.divinemc.DivineConfig.asyncPathfinding) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding) { + Path possiblePath = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes)); + org.bxteam.divinemc.entity.pathfinding.AsyncPathProcessor.awaitProcessing(possiblePath, path -> { + processPath(entity, poiManager, path); @@ -579,7 +579,7 @@ index e9dfff7e3726cd2229f89bb39fa1ca4815d99a6d..a0294937487bfd13f26a5e7eb2bd21f2 } } diff --git a/net/minecraft/world/entity/animal/frog/Frog.java b/net/minecraft/world/entity/animal/frog/Frog.java -index eb3aa96b2a5cb553b016744863818186d1d831c4..3ccc48afb7a9eb2290f16c6a3218515bee59c2bd 100644 +index eb3aa96b2a5cb553b016744863818186d1d831c4..433233f3fb346c15627cf0ad313ea55579826d86 100644 --- a/net/minecraft/world/entity/animal/frog/Frog.java +++ b/net/minecraft/world/entity/animal/frog/Frog.java @@ -482,6 +482,17 @@ public class Frog extends Animal { @@ -605,7 +605,7 @@ index eb3aa96b2a5cb553b016744863818186d1d831c4..3ccc48afb7a9eb2290f16c6a3218515b protected PathFinder createPathFinder(int maxVisitedNodes) { this.nodeEvaluator = new Frog.FrogNodeEvaluator(true); + // DivineMC start - async path processing -+ if (org.bxteam.divinemc.DivineConfig.asyncPathfinding) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding) { + return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator); + } + // DivineMC end - async path processing @@ -626,7 +626,7 @@ index b85d1e196d2bf61ac4896205afb08eba89c4397e..ea90e3d7ad84e301f975ff91fade63c5 if (target != null) { double d = this.distanceToSqr(target.getX(), target.getY(), target.getZ()); diff --git a/net/minecraft/world/entity/monster/Strider.java b/net/minecraft/world/entity/monster/Strider.java -index fe31c4a45afd61be8b74efe9d0858ccd0aced075..5f965f50294d03e7b03c5d7e912b7aec99db635c 100644 +index fe31c4a45afd61be8b74efe9d0858ccd0aced075..859c41c3c81b3d3ac05eebdc83c959d196bd5b3e 100644 --- a/net/minecraft/world/entity/monster/Strider.java +++ b/net/minecraft/world/entity/monster/Strider.java @@ -560,9 +560,25 @@ public class Strider extends Animal implements ItemSteerable { @@ -648,7 +648,7 @@ index fe31c4a45afd61be8b74efe9d0858ccd0aced075..5f965f50294d03e7b03c5d7e912b7aec protected PathFinder createPathFinder(int maxVisitedNodes) { this.nodeEvaluator = new WalkNodeEvaluator(); + // DivineMC start - async path processing -+ if (org.bxteam.divinemc.DivineConfig.asyncPathfinding) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding) { + return new PathFinder(this.nodeEvaluator, maxVisitedNodes, nodeEvaluatorGenerator); + } + // DivineMC end @@ -656,7 +656,7 @@ index fe31c4a45afd61be8b74efe9d0858ccd0aced075..5f965f50294d03e7b03c5d7e912b7aec } diff --git a/net/minecraft/world/entity/monster/warden/Warden.java b/net/minecraft/world/entity/monster/warden/Warden.java -index 60a8d79306755e9483ba9e93a07939b73ad717fe..97ee07ebbba5ad29f766dff5eb4e51fc0e12cfcb 100644 +index 60a8d79306755e9483ba9e93a07939b73ad717fe..39b9dc1e78c1f9fc6a5ccad0de56cdb6d0781a05 100644 --- a/net/minecraft/world/entity/monster/warden/Warden.java +++ b/net/minecraft/world/entity/monster/warden/Warden.java @@ -578,6 +578,16 @@ public class Warden extends Monster implements VibrationSystem { @@ -664,7 +664,7 @@ index 60a8d79306755e9483ba9e93a07939b73ad717fe..97ee07ebbba5ad29f766dff5eb4e51fc protected PathFinder createPathFinder(int maxVisitedNodes) { this.nodeEvaluator = new WalkNodeEvaluator(); + // DivineMC start - async path processing -+ if (org.bxteam.divinemc.DivineConfig.asyncPathfinding) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding) { + return new PathFinder(this.nodeEvaluator, maxVisitedNodes, GroundPathNavigation.nodeEvaluatorGenerator) { + @Override + protected float distance(Node first, Node second) { @@ -707,7 +707,7 @@ index d6d3c8f5e5dd4a8cab0d3fcc131c3a59f06130c6..839653a997f1e10970fa2956fadaf493 return false; } else if (pathentity.nodes.size() != this.nodes.size()) { diff --git a/net/minecraft/world/level/pathfinder/PathFinder.java b/net/minecraft/world/level/pathfinder/PathFinder.java -index c2baadcdceb1df6a881d6f73aa4eb4dd264bcdfe..965c1d2dd1acd542936fad8034c2de1746193355 100644 +index c2baadcdceb1df6a881d6f73aa4eb4dd264bcdfe..8997908508c1dbe839aab25e4f546b9aa664047e 100644 --- a/net/minecraft/world/level/pathfinder/PathFinder.java +++ b/net/minecraft/world/level/pathfinder/PathFinder.java @@ -22,11 +22,19 @@ public class PathFinder { @@ -739,7 +739,7 @@ index c2baadcdceb1df6a881d6f73aa4eb4dd264bcdfe..965c1d2dd1acd542936fad8034c2de17 - this.nodeEvaluator.prepare(region, mob); - Node start = this.nodeEvaluator.getStart(); + // DivineMC start - use a generated evaluator if we have one otherwise run sync -+ if (!org.bxteam.divinemc.DivineConfig.asyncPathfinding) ++ if (!org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncPathfinding) + this.openSet.clear(); // it's always cleared in processPath + NodeEvaluator nodeEvaluator = this.nodeEvaluatorGenerator == null + ? this.nodeEvaluator diff --git a/divinemc-server/minecraft-patches/features/0006-Multithreaded-Tracker.patch b/divinemc-server/minecraft-patches/features/0006-Multithreaded-Tracker.patch index 9d81fd1..5a6be12 100644 --- a/divinemc-server/minecraft-patches/features/0006-Multithreaded-Tracker.patch +++ b/divinemc-server/minecraft-patches/features/0006-Multithreaded-Tracker.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Multithreaded Tracker diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -index 02a9ef1694c796584c29430d27f0a09047368835..7a52c42845bd74d0bb7649f87764aba12f442f02 100644 +index 02a9ef1694c796584c29430d27f0a09047368835..d1148be69ffc03973f097ab421ee59c6999b6e84 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java @@ -340,7 +340,11 @@ public final class RegionizedPlayerChunkLoader { @@ -14,7 +14,7 @@ index 02a9ef1694c796584c29430d27f0a09047368835..7a52c42845bd74d0bb7649f87764aba1 private final ArrayDeque> delayedTicketOps = new ArrayDeque<>(); - private final LongOpenHashSet sentChunks = new LongOpenHashSet(); + // DivineMC start - Multithreaded tracker -+ private final LongOpenHashSet sentChunks = org.bxteam.divinemc.DivineConfig.multithreadedEnabled && !org.bxteam.divinemc.DivineConfig.multithreadedCompatModeEnabled ++ private final LongOpenHashSet sentChunks = org.bxteam.divinemc.config.DivineConfig.AsyncCategory.multithreadedEnabled && !org.bxteam.divinemc.config.DivineConfig.AsyncCategory.multithreadedCompatModeEnabled + ? new org.bxteam.divinemc.util.map.ConcurrentLongHashSet() + : new LongOpenHashSet(); + // DivineMC end - Multithreaded tracker @@ -22,7 +22,7 @@ index 02a9ef1694c796584c29430d27f0a09047368835..7a52c42845bd74d0bb7649f87764aba1 private static final byte CHUNK_TICKET_STAGE_NONE = 0; private static final byte CHUNK_TICKET_STAGE_LOADING = 1; diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java -index b28d19b2fcdff9250e95db05f6e428db54a771e6..b5028cc64e2a43c841801114908825102df41765 100644 +index b28d19b2fcdff9250e95db05f6e428db54a771e6..5ab3c01d81522caace541bcf96fd6d2e9b49a8c9 100644 --- a/net/minecraft/server/level/ChunkMap.java +++ b/net/minecraft/server/level/ChunkMap.java @@ -1013,6 +1013,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -30,7 +30,7 @@ index b28d19b2fcdff9250e95db05f6e428db54a771e6..b5028cc64e2a43c84180111490882510 protected void tick() { + // DivineMC start - Multithreaded tracker -+ if (org.bxteam.divinemc.DivineConfig.multithreadedEnabled) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.multithreadedEnabled) { + final ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel level = this.level; + org.bxteam.divinemc.entity.tracking.MultithreadedTracker.tick(level); + return; @@ -45,7 +45,7 @@ index b28d19b2fcdff9250e95db05f6e428db54a771e6..b5028cc64e2a43c84180111490882510 SectionPos lastSectionPos; - public final Set seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl + // DivineMC start - Multithreaded tracker -+ public final Set seenBy = org.bxteam.divinemc.DivineConfig.multithreadedEnabled ++ public final Set seenBy = org.bxteam.divinemc.config.DivineConfig.AsyncCategory.multithreadedEnabled + ? com.google.common.collect.Sets.newConcurrentHashSet() + : new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl + // DivineMC end - Multithreaded tracker @@ -59,7 +59,7 @@ index b28d19b2fcdff9250e95db05f6e428db54a771e6..b5028cc64e2a43c84180111490882510 + final int playersLen = players.size(); // Ensure length won't change in the future tasks + + // DivineMC start - Multithreaded tracker -+ if (org.bxteam.divinemc.DivineConfig.multithreadedEnabled && org.bxteam.divinemc.DivineConfig.multithreadedCompatModeEnabled) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.multithreadedEnabled && org.bxteam.divinemc.config.DivineConfig.AsyncCategory.multithreadedCompatModeEnabled) { + final boolean isServerPlayer = this.entity instanceof ServerPlayer; + final boolean isRealPlayer = isServerPlayer && ((ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer) this.entity).moonrise$isRealPlayer(); + Runnable updatePlayerTasks = () -> { @@ -147,12 +147,12 @@ index b28d19b2fcdff9250e95db05f6e428db54a771e6..b5028cc64e2a43c84180111490882510 public void updatePlayer(ServerPlayer player) { - org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot if (player != this.entity) { -+ if (org.bxteam.divinemc.DivineConfig.multithreadedEnabled && player == null) return; // DivineMC - Multithreaded tracker ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.multithreadedEnabled && player == null) return; // DivineMC - Multithreaded tracker // Paper start - remove allocation of Vec3D here // Vec3 vec3 = player.position().subtract(this.entity.position()); double vec3_dx = player.getX() - this.entity.getX(); diff --git a/net/minecraft/server/level/ServerBossEvent.java b/net/minecraft/server/level/ServerBossEvent.java -index f106373ef3ac4a8685c2939c9e8361688a285913..3b4dff8867e91884b5720ca8a9cb64af655f8475 100644 +index f106373ef3ac4a8685c2939c9e8361688a285913..b844b6dd89bc53b74c0d1bdbf4657c115a892dc7 100644 --- a/net/minecraft/server/level/ServerBossEvent.java +++ b/net/minecraft/server/level/ServerBossEvent.java @@ -13,7 +13,11 @@ import net.minecraft.util.Mth; @@ -161,7 +161,7 @@ index f106373ef3ac4a8685c2939c9e8361688a285913..3b4dff8867e91884b5720ca8a9cb64af public class ServerBossEvent extends BossEvent { - private final Set players = Sets.newHashSet(); + // DivineMC start - Multithreaded tracker - players can be removed in async tracking -+ private final Set players = org.bxteam.divinemc.DivineConfig.multithreadedEnabled ++ private final Set players = org.bxteam.divinemc.config.DivineConfig.AsyncCategory.multithreadedEnabled + ? Sets.newConcurrentHashSet() + : Sets.newHashSet(); + // DivineMC end - Multithreaded tracker @@ -189,7 +189,7 @@ index b118e91f1e0b5a8b8c0b2a4a32faabc5a34a5954..19214d03a149e62b02ead0c9a1de8e99 attributesToSync.clear(); diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index c03895b2fc783d748fe52660b9ef30367143d0f5..8fa3af0ebcb92138d0dae858c131db0a710df693 100644 +index c1730d2a27d290e43ebe3c7d6919cdcd3203b920..2f69b1e05ef258d6b28ee912167b8a5bb83fc703 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -2481,7 +2481,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -211,7 +211,7 @@ index c03895b2fc783d748fe52660b9ef30367143d0f5..8fa3af0ebcb92138d0dae858c131db0a } } diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index d94a82f02bfebd023780d0005f7069c770779f16..c9f714d8aec6460e663c7ce24bc185ea45b56990 100644 +index 9aedd605330bd8e2049482fb5507898901e8350a..32053aaa7b2a9c582615e47b13dbe99e98e61337 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1884,7 +1884,7 @@ public class ServerGamePacketListenerImpl @@ -224,7 +224,7 @@ index d94a82f02bfebd023780d0005f7069c770779f16..c9f714d8aec6460e663c7ce24bc185ea if (this.player.isRemoved()) { LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName()); diff --git a/net/minecraft/world/entity/ai/attributes/AttributeInstance.java b/net/minecraft/world/entity/ai/attributes/AttributeInstance.java -index 3ac9f36eae87369354e992a1d9b5c5b2d87d17cb..3a6c481fae0d3cb5ffdd39caf85252f164774323 100644 +index 3ac9f36eae87369354e992a1d9b5c5b2d87d17cb..f133dd8b4fe6f7428f096d5780019609ae179a3f 100644 --- a/net/minecraft/world/entity/ai/attributes/AttributeInstance.java +++ b/net/minecraft/world/entity/ai/attributes/AttributeInstance.java @@ -26,8 +26,11 @@ public class AttributeInstance { @@ -234,7 +234,7 @@ index 3ac9f36eae87369354e992a1d9b5c5b2d87d17cb..3a6c481fae0d3cb5ffdd39caf85252f1 - private final Map modifierById = new Object2ObjectArrayMap<>(); - private final Map permanentModifiers = new Object2ObjectArrayMap<>(); + // DivineMC start - Multithreaded tracker -+ private final boolean multiThreadedTrackingEnabled = org.bxteam.divinemc.DivineConfig.multithreadedEnabled; ++ private final boolean multiThreadedTrackingEnabled = org.bxteam.divinemc.config.DivineConfig.AsyncCategory.multithreadedEnabled; + private final Map modifierById = multiThreadedTrackingEnabled ? new java.util.concurrent.ConcurrentHashMap<>() : new Object2ObjectArrayMap<>(); + private final Map permanentModifiers = multiThreadedTrackingEnabled ? new java.util.concurrent.ConcurrentHashMap<>() : new Object2ObjectArrayMap<>(); + // DivineMC end - Multithreaded tracker @@ -242,7 +242,7 @@ index 3ac9f36eae87369354e992a1d9b5c5b2d87d17cb..3a6c481fae0d3cb5ffdd39caf85252f1 private boolean dirty = true; private double cachedValue; diff --git a/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/net/minecraft/world/entity/ai/attributes/AttributeMap.java -index 23576e631ad4a12ec3ff3630be253738534588f3..b37a49c44ecb456c798d153fddf3cb6090a9a296 100644 +index 23576e631ad4a12ec3ff3630be253738534588f3..66e0f892c9832f2ed65d5f147020d18ab32c8ce7 100644 --- a/net/minecraft/world/entity/ai/attributes/AttributeMap.java +++ b/net/minecraft/world/entity/ai/attributes/AttributeMap.java @@ -14,9 +14,12 @@ import net.minecraft.nbt.ListTag; @@ -253,7 +253,7 @@ index 23576e631ad4a12ec3ff3630be253738534588f3..b37a49c44ecb456c798d153fddf3cb60 - private final Set attributesToSync = new ObjectOpenHashSet<>(); - private final Set attributesToUpdate = new ObjectOpenHashSet<>(); + // DivineMC start - Multithreaded tracker -+ private final boolean multiThreadedTrackingEnabled = org.bxteam.divinemc.DivineConfig.multithreadedEnabled; ++ private final boolean multiThreadedTrackingEnabled = org.bxteam.divinemc.config.DivineConfig.AsyncCategory.multithreadedEnabled; + private final Map, AttributeInstance> attributes = multiThreadedTrackingEnabled ? new java.util.concurrent.ConcurrentHashMap<>() : new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(0); + private final Set attributesToSync = multiThreadedTrackingEnabled ? com.google.common.collect.Sets.newConcurrentHashSet() : new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0); + private final Set attributesToUpdate = multiThreadedTrackingEnabled ? com.google.common.collect.Sets.newConcurrentHashSet() : new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0); diff --git a/divinemc-server/minecraft-patches/features/0009-Chunk-System-Optimizations.patch b/divinemc-server/minecraft-patches/features/0009-Chunk-System-Optimizations.patch index 115ab14..5f6bd50 100644 --- a/divinemc-server/minecraft-patches/features/0009-Chunk-System-Optimizations.patch +++ b/divinemc-server/minecraft-patches/features/0009-Chunk-System-Optimizations.patch @@ -104,7 +104,7 @@ index ba20e87d2105ce53cdaf4049de2388d05fcd1b56..131e673c8eaa2afa801de5913982259d } diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -index 7a52c42845bd74d0bb7649f87764aba12f442f02..03ab44b69725a18ed567826e4417f1d6701f08c9 100644 +index d1148be69ffc03973f097ab421ee59c6999b6e84..529593d4c46b71849e50e2976411186134c51aab 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java @@ -187,13 +187,13 @@ public final class RegionizedPlayerChunkLoader { @@ -149,7 +149,7 @@ index 7a52c42845bd74d0bb7649f87764aba12f442f02..03ab44b69725a18ed567826e4417f1d6 - Math.abs(c2x - centerX) + Math.abs(c2z - centerZ) - ); + // DivineMC start - Chunk Loading Priority Optimization -+ if (org.bxteam.divinemc.DivineConfig.chunkTaskPriority == org.bxteam.divinemc.server.chunk.ChunkTaskPriority.EUCLIDEAN_CIRCLE_PATTERN) { ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.chunkTaskPriority == org.bxteam.divinemc.server.chunk.ChunkTaskPriority.EUCLIDEAN_CIRCLE_PATTERN) { + return Integer.compare( + (c1x - centerX) * (c1x - centerX) + (c1z - centerZ) * (c1z - centerZ), + (c2x - centerX) * (c2x - centerX) + (c2z - centerZ) * (c2z - centerZ) @@ -849,7 +849,7 @@ index 93fd23027c00cef76562098306737272fda1350a..44e443768f5163454fd11425afd3bc07 } diff --git a/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickConstants.java b/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickConstants.java -index 6d1fe8028739145b11fce98ad62b2f8044299548..2cd1197fa0d15e19749409cc857a0254de444ba5 100644 +index 6d1fe8028739145b11fce98ad62b2f8044299548..1885339f1ed5f24aa281aa2720a1d511a95740de 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickConstants.java +++ b/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickConstants.java @@ -2,7 +2,7 @@ package ca.spottedleaf.moonrise.patches.chunk_tick_iteration; @@ -857,7 +857,7 @@ index 6d1fe8028739145b11fce98ad62b2f8044299548..2cd1197fa0d15e19749409cc857a0254 public final class ChunkTickConstants { - public static final int PLAYER_SPAWN_TRACK_RANGE = 8; -+ public static final int PLAYER_SPAWN_TRACK_RANGE = (int) Math.round(org.bxteam.divinemc.DivineConfig.playerNearChunkDetectionRange / 16.0); // DivineMC - Chunk System optimization ++ public static final int PLAYER_SPAWN_TRACK_RANGE = (int) Math.round(org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.playerNearChunkDetectionRange / 16.0); // DivineMC - Chunk System optimization // the smallest distance on x/z is at 45 degrees, we need to subtract 0.5 since this is calculated from chunk center and not chunk perimeter // note: vanilla does not subtract 0.5 but the result is (luckily!) the same public static final int NARROW_SPAWN_TRACK_RANGE = (int)Math.floor(((double)PLAYER_SPAWN_TRACK_RANGE / Math.sqrt(2.0)) - 0.5); @@ -904,7 +904,7 @@ index 52b981a05ad5aabb7c85dc1e0f1d2b835163bb87..f4af8e131c2badbe0e57ccec5be8710e commands.put(Set.of("fixlight"), new FixLightCommand()); // Paper - rewrite chunk system commands.put(Set.of("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand()); // Paper - rewrite chunk system diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java -index b5028cc64e2a43c841801114908825102df41765..fb6e0beb35d1d6bb9a159debeb06e861051821b9 100644 +index 5ab3c01d81522caace541bcf96fd6d2e9b49a8c9..3ece4fc97811f680c1dd01913d6bff51722c6ba1 100644 --- a/net/minecraft/server/level/ChunkMap.java +++ b/net/minecraft/server/level/ChunkMap.java @@ -132,8 +132,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -983,7 +983,7 @@ index b5028cc64e2a43c841801114908825102df41765..fb6e0beb35d1d6bb9a159debeb06e861 final ServerPlayer player = raw[i]; - if (this.playerIsCloseEnoughForSpawning(player, chunkPos, 16384.0D)) { // Spigot + if (player == null) continue; // DivineMC - Chunk System Optimizations -+ if (this.playerIsCloseEnoughForSpawning(player, chunkPos, (org.bxteam.divinemc.DivineConfig.playerNearChunkDetectionRange^2))) { // Spigot // DivineMC - Chunk System Optimizations ++ if (this.playerIsCloseEnoughForSpawning(player, chunkPos, (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.playerNearChunkDetectionRange^2))) { // Spigot // DivineMC - Chunk System Optimizations if (ret == null) { ret = new ArrayList<>(len - i); ret.add(player); @@ -1032,7 +1032,7 @@ index 4d4139b5f42a4db6e22bf1d063a23dc7b9914f85..9a65321ce62f21b150d29be30dbae7db } diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 6268bfc05fd9d3669bef20a1ddc5477fbae0f957..2ebd77db2d13d04513689ff332404c6af6a3c11d 100644 +index 6ed2d1aeab17941b67019d45734da46efc53ffdf..d003e36a37cbc39d6467a9c45ad716dc27fd62a7 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -177,6 +177,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -1579,7 +1579,7 @@ index 2ffae24b0cb1a20c7d5a8520f1b5197c2cedea11..c3ec5e5645f680a915c95d833b589b68 public T valueFor(int id) { if (this.value != null && id == 0) { diff --git a/net/minecraft/world/level/chunk/storage/IOWorker.java b/net/minecraft/world/level/chunk/storage/IOWorker.java -index 27e1edbd8d8ffd80c1a3df17bc47f4a6936619f7..fae062a643692369175f58bb1687e766e873d8e3 100644 +index 27e1edbd8d8ffd80c1a3df17bc47f4a6936619f7..67d48ad11671e72e9dfeafbd64dc27031bd395d5 100644 --- a/net/minecraft/world/level/chunk/storage/IOWorker.java +++ b/net/minecraft/world/level/chunk/storage/IOWorker.java @@ -212,7 +212,38 @@ public class IOWorker implements ChunkScanAccess, AutoCloseable { @@ -1588,9 +1588,9 @@ index 27e1edbd8d8ffd80c1a3df17bc47f4a6936619f7..fae062a643692369175f58bb1687e766 + // DivineMC start - Chunk System optimization + private void checkHardLimit() { -+ if (this.pendingWrites.size() >= org.bxteam.divinemc.DivineConfig.chunkDataCacheLimit) { -+ LOGGER.warn("Chunk data cache size exceeded hard limit ({} >= {}), forcing writes to disk (you can increase chunkDataCacheLimit in c2me.toml)", this.pendingWrites.size(), org.bxteam.divinemc.DivineConfig.chunkDataCacheLimit); -+ while (this.pendingWrites.size() >= org.bxteam.divinemc.DivineConfig.chunkDataCacheSoftLimit * 0.75) { ++ if (this.pendingWrites.size() >= org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.chunkDataCacheLimit) { ++ LOGGER.warn("Chunk data cache size exceeded hard limit ({} >= {}), forcing writes to disk (you can increase chunkDataCacheLimit in c2me.toml)", this.pendingWrites.size(), org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.chunkDataCacheLimit); ++ while (this.pendingWrites.size() >= org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.chunkDataCacheSoftLimit * 0.75) { + writeResult0(); + } + } @@ -1610,8 +1610,8 @@ index 27e1edbd8d8ffd80c1a3df17bc47f4a6936619f7..fae062a643692369175f58bb1687e766 + // DivineMC start - Chunk System optimization + if (!this.pendingWrites.isEmpty()) { + checkHardLimit(); -+ if (this.pendingWrites.size() >= org.bxteam.divinemc.DivineConfig.chunkDataCacheSoftLimit) { -+ int writeFrequency = Math.min(1, (this.pendingWrites.size() - (int) org.bxteam.divinemc.DivineConfig.chunkDataCacheSoftLimit) / 16); ++ if (this.pendingWrites.size() >= org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.chunkDataCacheSoftLimit) { ++ int writeFrequency = Math.min(1, (this.pendingWrites.size() - (int) org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.chunkDataCacheSoftLimit) / 16); + for (int i = 0; i < writeFrequency; i++) { + writeResult0(); + } @@ -2305,14 +2305,14 @@ index 74d8202b5c9bb2a3ee832be70f95c0b5cbecb460..4c11b822fa65388c1d8d9aaa7fd70200 private static double getBeardContribution(int x, int y, int z, int height) { diff --git a/net/minecraft/world/level/levelgen/BelowZeroRetrogen.java b/net/minecraft/world/level/levelgen/BelowZeroRetrogen.java -index 3379c3893227d42bb54f3a94e697a9851d279605..161aed37d14cd283a3b4341ea15d57a4a0f088b3 100644 +index 3379c3893227d42bb54f3a94e697a9851d279605..06b1ea5fd3b9b1c6bace8be859aabff7590481ce 100644 --- a/net/minecraft/world/level/levelgen/BelowZeroRetrogen.java +++ b/net/minecraft/world/level/levelgen/BelowZeroRetrogen.java @@ -74,6 +74,7 @@ public final class BelowZeroRetrogen { } public void applyBedrockMask(ProtoChunk chunk) { -+ if (org.bxteam.divinemc.DivineConfig.smoothBedrockLayer) return; // DivineMC - Smooth bedrock layer ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.smoothBedrockLayer) return; // DivineMC - Smooth bedrock layer LevelHeightAccessor heightAccessorForGeneration = chunk.getHeightAccessorForGeneration(); int minY = heightAccessorForGeneration.getMinY(); int maxY = heightAccessorForGeneration.getMaxY(); @@ -2516,7 +2516,7 @@ index 4cf3a364595ba5f81f741295695cb9a449bdf672..44df2ac0bd972c4d97fc89cd0c2d2d83 } } diff --git a/net/minecraft/world/level/levelgen/SurfaceRules.java b/net/minecraft/world/level/levelgen/SurfaceRules.java -index bbf2995d352c22b3f6fb0de40f2932af1771c504..af852376b61d127a5e251a7a6fcb35c25d1d4e1f 100644 +index 32757c6847cf77862a2f1b38cc53e7166e6be492..92c7aa344d00067f52829f8d97a6ee219e6c2771 100644 --- a/net/minecraft/world/level/levelgen/SurfaceRules.java +++ b/net/minecraft/world/level/levelgen/SurfaceRules.java @@ -185,7 +185,7 @@ public class SurfaceRules { diff --git a/divinemc-server/minecraft-patches/features/0012-Optimize-explosions.patch b/divinemc-server/minecraft-patches/features/0012-Optimize-explosions.patch index 4dd2423..362ede7 100644 --- a/divinemc-server/minecraft-patches/features/0012-Optimize-explosions.patch +++ b/divinemc-server/minecraft-patches/features/0012-Optimize-explosions.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Optimize explosions diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java -index a772f2bd7be00172ad41353c6ad42d9239b9ec88..fb6df8b2d96727b3febfe404be0eb2d77b2edf13 100644 +index a772f2bd7be00172ad41353c6ad42d9239b9ec88..27c7a113b81160eb88021bf259005e3c0ad90ff1 100644 --- a/net/minecraft/world/level/ServerExplosion.java +++ b/net/minecraft/world/level/ServerExplosion.java @@ -372,6 +372,11 @@ public class ServerExplosion implements Explosion { @@ -13,7 +13,7 @@ index a772f2bd7be00172ad41353c6ad42d9239b9ec88..fb6df8b2d96727b3febfe404be0eb2d7 private List calculateExplodedPositions() { + // DivineMC start - Optimize explosions -+ if (org.bxteam.divinemc.DivineConfig.enableFasterTntOptimization && !level.isClientSide && !(getIndirectSourceEntity() instanceof net.minecraft.world.entity.monster.breeze.Breeze)) { ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableFasterTntOptimization && !level.isClientSide && !(getIndirectSourceEntity() instanceof net.minecraft.world.entity.monster.breeze.Breeze)) { + return doExplosionA(this); + } + // DivineMC end - Optimize explosions @@ -36,7 +36,7 @@ index a772f2bd7be00172ad41353c6ad42d9239b9ec88..fb6df8b2d96727b3febfe404be0eb2d7 + public static @org.jetbrains.annotations.NotNull List doExplosionA(ServerExplosion e) { + List toBlow; + -+ if (!org.bxteam.divinemc.DivineConfig.explosionNoBlockDamage && e.damageSource != null) { ++ if (!org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.explosionNoBlockDamage && e.damageSource != null) { + rayCalcDone = false; + firstRay = true; + getAffectedPositionsOnPlaneY(e, 0, 0, 15, 0, 15); // bottom @@ -118,7 +118,7 @@ index a772f2bd7be00172ad41353c6ad42d9239b9ec88..fb6df8b2d96727b3febfe404be0eb2d7 + double yInc = (yRel / len) * 0.3; + double zInc = (zRel / len) * 0.3; + float rand = e.level().random.nextFloat(); -+ float sizeRand = (org.bxteam.divinemc.DivineConfig.tntRandomRange >= 0 ? (float) org.bxteam.divinemc.DivineConfig.tntRandomRange : rand); ++ float sizeRand = (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.tntRandomRange >= 0 ? (float) org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.tntRandomRange : rand); + float size = e.radius() * (0.7F + sizeRand * 0.6F); + Vec3 vec3 = e.center(); + double posX = vec3.x; @@ -170,7 +170,7 @@ index a772f2bd7be00172ad41353c6ad42d9239b9ec88..fb6df8b2d96727b3febfe404be0eb2d7 + } + + private Optional noBlockCalcsWithNoBLockDamage(final ExplosionDamageCalculator instance, final Explosion explosion, final BlockGetter blockGetter, final BlockPos blockPos, final BlockState blockState, final FluidState fluidState) { -+ if (org.bxteam.divinemc.DivineConfig.explosionNoBlockDamage) return Optional.of(net.minecraft.world.level.block.Blocks.BEDROCK.getExplosionResistance()); ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.explosionNoBlockDamage) return Optional.of(net.minecraft.world.level.block.Blocks.BEDROCK.getExplosionResistance()); + return instance.getBlockExplosionResistance(explosion, blockGetter, blockPos, blockState, fluidState); + } + // DivineMC end - Optimize explosions @@ -183,7 +183,7 @@ index a772f2bd7be00172ad41353c6ad42d9239b9ec88..fb6df8b2d96727b3febfe404be0eb2d7 private void interactWithBlocks(List blocks) { + // DivineMC start - Optimize explosions -+ if (org.bxteam.divinemc.DivineConfig.explosionNoBlockDamage) { ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.explosionNoBlockDamage) { + blocks.clear(); + } + // DivineMC end - Optimize explosions diff --git a/divinemc-server/minecraft-patches/features/0013-Option-to-allow-weird-movement-and-disable-teleporti.patch b/divinemc-server/minecraft-patches/features/0013-Option-to-allow-weird-movement-and-disable-teleporti.patch index 387305d..8c85276 100644 --- a/divinemc-server/minecraft-patches/features/0013-Option-to-allow-weird-movement-and-disable-teleporti.patch +++ b/divinemc-server/minecraft-patches/features/0013-Option-to-allow-weird-movement-and-disable-teleporti.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Option to allow weird movement and disable teleporting diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index c9f714d8aec6460e663c7ce24bc185ea45b56990..376ae7bde8fdf0efed5a7d33f67a1a5ae3b5e6e7 100644 +index 32053aaa7b2a9c582615e47b13dbe99e98e61337..667cc2b415e6ef4e2685e2eacad9c2c37165e771 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -566,7 +566,7 @@ public class ServerGamePacketListenerImpl @@ -14,7 +14,7 @@ index c9f714d8aec6460e663c7ce24bc185ea45b56990..376ae7bde8fdf0efed5a7d33f67a1a5a } // Paper end - Prevent moving into unloaded chunks - if (d7 - d6 > Math.max(100.0, Mth.square(org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed)) && !this.isSingleplayerOwner()) { -+ if (!org.bxteam.divinemc.DivineConfig.alwaysAllowWeirdMovement && (d7 - d6 > Math.max(100.0, Mth.square(org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed)) && !this.isSingleplayerOwner())) { // DivineMC - stop weird movement ++ if (!org.bxteam.divinemc.config.DivineConfig.FixesCategory.alwaysAllowWeirdMovement && (d7 - d6 > Math.max(100.0, Mth.square(org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed)) && !this.isSingleplayerOwner())) { // DivineMC - stop weird movement // CraftBukkit end LOGGER.warn( "{} (vehicle of {}) moved too quickly! {},{},{}", rootVehicle.getName().getString(), this.player.getName().getString(), d3, d4, d5 @@ -23,7 +23,7 @@ index c9f714d8aec6460e663c7ce24bc185ea45b56990..376ae7bde8fdf0efed5a7d33f67a1a5a d7 = d3 * d3 + d4 * d4 + d5 * d5; boolean flag2 = false; - if (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot -+ if (!org.bxteam.divinemc.DivineConfig.alwaysAllowWeirdMovement && (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold)) { // Spigot // DivineMC - stop weird movement ++ if (!org.bxteam.divinemc.config.DivineConfig.FixesCategory.alwaysAllowWeirdMovement && (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold)) { // Spigot // DivineMC - stop weird movement flag2 = true; // Paper - diff on change, this should be moved wrongly LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", rootVehicle.getName().getString(), this.player.getName().getString(), Math.sqrt(d7)); } @@ -35,7 +35,7 @@ index c9f714d8aec6460e663c7ce24bc185ea45b56990..376ae7bde8fdf0efed5a7d33f67a1a5a - // Paper start - Add fail move event - io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY, + // DivineMC start - Stop teleporting players when they move too quickly -+ if (!org.bxteam.divinemc.DivineConfig.alwaysAllowWeirdMovement && !(org.bxteam.divinemc.DivineConfig.ignoreMovedTooQuicklyWhenLagging && player.serverLevel().getServer().lagging)) { ++ if (!org.bxteam.divinemc.config.DivineConfig.FixesCategory.alwaysAllowWeirdMovement && !(org.bxteam.divinemc.config.DivineConfig.FixesCategory.ignoreMovedTooQuicklyWhenLagging && player.serverLevel().getServer().lagging)) { + // CraftBukkit end + // Paper start - Add fail move event + io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY, @@ -67,7 +67,7 @@ index c9f714d8aec6460e663c7ce24bc185ea45b56990..376ae7bde8fdf0efed5a7d33f67a1a5a d7 = d3 * d3 + d4 * d4 + d5 * d5; boolean movedWrongly = false; // Paper - Add fail move event; rename if (!this.player.isChangingDimension() -+ && !org.bxteam.divinemc.DivineConfig.alwaysAllowWeirdMovement // DivineMC - Stop teleporting players when they move too quickly ++ && !org.bxteam.divinemc.config.DivineConfig.FixesCategory.alwaysAllowWeirdMovement // DivineMC - Stop teleporting players when they move too quickly && d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold // Spigot && !this.player.isSleeping() && !this.player.isCreative() diff --git a/divinemc-server/minecraft-patches/features/0014-Lag-compensation.patch b/divinemc-server/minecraft-patches/features/0014-Lag-compensation.patch index 5d56458..71f4cf0 100644 --- a/divinemc-server/minecraft-patches/features/0014-Lag-compensation.patch +++ b/divinemc-server/minecraft-patches/features/0014-Lag-compensation.patch @@ -25,7 +25,7 @@ index 9956405d7f9d14af7278837adeede76dea8d4bd9..86754cb52caeef962172bcb79cbc8f16 this.tickCount++; this.tickRateManager.tick(); diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index d003e36a37cbc39d6467a9c45ad716dc27fd62a7..fcd732a923e0ced69d2342fa59122dee0e98438e 100644 +index d003e36a37cbc39d6467a9c45ad716dc27fd62a7..84ed28dba0ed2a2edcfee495bdcc24ad21936486 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -213,6 +213,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -57,7 +57,7 @@ index d003e36a37cbc39d6467a9c45ad716dc27fd62a7..fcd732a923e0ced69d2342fa59122dee + // DivineMC start - Lag compensation + private long lagCompensation(long original) { -+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.timeAcceleration) return original; ++ if (!org.bxteam.divinemc.config.DivineConfig.MiscCategory.lagCompensationEnabled || !org.bxteam.divinemc.config.DivineConfig.MiscCategory.timeAcceleration) return original; + return original + this.tpsCalculator.applicableMissedTicks(); + } + // DivineMC end - Lag compensation @@ -66,7 +66,7 @@ index d003e36a37cbc39d6467a9c45ad716dc27fd62a7..fcd732a923e0ced69d2342fa59122dee this.serverLevelData.setDayTime(time); // Purpur start - Configurable daylight cycle diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index f3706dfb6aeb5035cbf0a8bf6b4d9a5243aaaa17..f598c6ae03977998f1cbf79cf3faf7997c2ba9e2 100644 +index f3706dfb6aeb5035cbf0a8bf6b4d9a5243aaaa17..808e4e2ae070b5232c2050fdcb183cc21b8fb996 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java @@ -503,6 +503,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -83,7 +83,7 @@ index f3706dfb6aeb5035cbf0a8bf6b4d9a5243aaaa17..f598c6ae03977998f1cbf79cf3faf799 + // DivineMC start - Lag Compensation + private void lagCompensation() { -+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.potionEffectAcceleration) return; ++ if (!org.bxteam.divinemc.config.DivineConfig.MiscCategory.lagCompensationEnabled || !org.bxteam.divinemc.config.DivineConfig.MiscCategory.potionEffectAcceleration) return; + if (this.level().isClientSide()) return; + + for (int i = 0; i < ((ServerLevel) this.level()).tpsCalculator.applicableMissedTicks(); i++) { @@ -96,7 +96,7 @@ index f3706dfb6aeb5035cbf0a8bf6b4d9a5243aaaa17..f598c6ae03977998f1cbf79cf3faf799 protected float getBlockSpeedFactor() { return Mth.lerp((float)this.getAttributeValue(Attributes.MOVEMENT_EFFICIENCY), super.getBlockSpeedFactor(), 1.0F); diff --git a/net/minecraft/world/entity/PortalProcessor.java b/net/minecraft/world/entity/PortalProcessor.java -index 88b07fbb96b20124777889830afa480673629d43..d2661ea79536010414f77256332f214d19106dd9 100644 +index 88b07fbb96b20124777889830afa480673629d43..91f6d43b3785ddad7db8eb529ba3293c45f3588d 100644 --- a/net/minecraft/world/entity/PortalProcessor.java +++ b/net/minecraft/world/entity/PortalProcessor.java @@ -24,10 +24,20 @@ public class PortalProcessor { @@ -110,7 +110,7 @@ index 88b07fbb96b20124777889830afa480673629d43..d2661ea79536010414f77256332f214d + // DivineMC start - Lag compensation + private int lagCompensation(int original, ServerLevel world) { -+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.portalAcceleration) return original; ++ if (!org.bxteam.divinemc.config.DivineConfig.MiscCategory.lagCompensationEnabled || !org.bxteam.divinemc.config.DivineConfig.MiscCategory.portalAcceleration) return original; + if (world.isClientSide()) return original; + + portalTime = portalTime + world.tpsCalculator.applicableMissedTicks(); @@ -122,7 +122,7 @@ index 88b07fbb96b20124777889830afa480673629d43..d2661ea79536010414f77256332f214d public TeleportTransition getPortalDestination(ServerLevel level, Entity entity) { return this.portal.getPortalDestination(level, entity, this.entryPosition); diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java -index 4ddf1cdf7a47bf06f95c5bfce8f3c4d035e87cfc..60f5232b24ace1854a3cea7aa790385ae4e90ea9 100644 +index 4ddf1cdf7a47bf06f95c5bfce8f3c4d035e87cfc..cdcf0be8f8ca51bf548ec5ae2d74b3eef4a7d3d3 100644 --- a/net/minecraft/world/entity/item/ItemEntity.java +++ b/net/minecraft/world/entity/item/ItemEntity.java @@ -160,8 +160,25 @@ public class ItemEntity extends Entity implements TraceableEntity { @@ -131,7 +131,7 @@ index 4ddf1cdf7a47bf06f95c5bfce8f3c4d035e87cfc..60f5232b24ace1854a3cea7aa790385a + // DivineMC start - Lag compensation + private void lagCompensation() { -+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.pickupAcceleration) return; ++ if (!org.bxteam.divinemc.config.DivineConfig.MiscCategory.lagCompensationEnabled || !org.bxteam.divinemc.config.DivineConfig.MiscCategory.pickupAcceleration) return; + if ((this).level().isClientSide()) return; + + if (pickupDelay == 0) return; @@ -152,7 +152,7 @@ index 4ddf1cdf7a47bf06f95c5bfce8f3c4d035e87cfc..60f5232b24ace1854a3cea7aa790385a this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } else { diff --git a/net/minecraft/world/item/Item.java b/net/minecraft/world/item/Item.java -index c52fb17d1e496a91223b7387cacb128c1865caee..30ab94fa0a6710cc5a39bd1c74c99aac08037167 100644 +index c52fb17d1e496a91223b7387cacb128c1865caee..142249b6412801cad1c7710ad6edb1955d0b5df5 100644 --- a/net/minecraft/world/item/Item.java +++ b/net/minecraft/world/item/Item.java @@ -286,10 +286,25 @@ public class Item implements FeatureElement, ItemLike { @@ -161,7 +161,7 @@ index c52fb17d1e496a91223b7387cacb128c1865caee..30ab94fa0a6710cc5a39bd1c74c99aac + // DivineMC start - Lag compensation + private int lagCompensation(int original, net.minecraft.server.level.ServerLevel level) { -+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.eatingAcceleration || original == 0) return original; ++ if (!org.bxteam.divinemc.config.DivineConfig.MiscCategory.lagCompensationEnabled || !org.bxteam.divinemc.config.DivineConfig.MiscCategory.eatingAcceleration || original == 0) return original; + return org.bxteam.divinemc.util.tps.TPSUtil.tt20(original, true, level); + } + // DivineMC end - Lag compensation @@ -183,7 +183,7 @@ index c52fb17d1e496a91223b7387cacb128c1865caee..30ab94fa0a6710cc5a39bd1c74c99aac BlocksAttacks blocksAttacks = stack.get(DataComponents.BLOCKS_ATTACKS); return blocksAttacks != null ? 72000 : 0; diff --git a/net/minecraft/world/level/GameRules.java b/net/minecraft/world/level/GameRules.java -index c9a2c4f7051639478bd9788911d3c6bead8f5152..df916f661d54bc4373eebafaaf3a94f9863ddd63 100644 +index c9a2c4f7051639478bd9788911d3c6bead8f5152..34b9baaff95189c8d9155968b00324f1b2e94209 100644 --- a/net/minecraft/world/level/GameRules.java +++ b/net/minecraft/world/level/GameRules.java @@ -355,8 +355,31 @@ public class GameRules { @@ -199,7 +199,7 @@ index c9a2c4f7051639478bd9788911d3c6bead8f5152..df916f661d54bc4373eebafaaf3a94f9 + + private int lagCompensation(int original, GameRules.Key rule) { + ServerLevel level = getOrCacheLevel(); -+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.randomTickSpeedAcceleration) return original; ++ if (!org.bxteam.divinemc.config.DivineConfig.MiscCategory.lagCompensationEnabled || !org.bxteam.divinemc.config.DivineConfig.MiscCategory.randomTickSpeedAcceleration) return original; + if (!(rule == GameRules.RULE_RANDOMTICKING)) return original; + return (int) (original * org.bxteam.divinemc.util.tps.TPSCalculator.MAX_TPS / (float) level.tpsCalculator.getMostAccurateTPS()); + } @@ -220,7 +220,7 @@ index c9a2c4f7051639478bd9788911d3c6bead8f5152..df916f661d54bc4373eebafaaf3a94f9 public static class BooleanValue extends GameRules.Value { private boolean value; diff --git a/net/minecraft/world/level/block/state/BlockBehaviour.java b/net/minecraft/world/level/block/state/BlockBehaviour.java -index 8db95b74f88f8096de93115ae8d3fb2e6184ad3b..8c0abcbf1af03092b54d2e4bdad8ac152c2431e6 100644 +index 8db95b74f88f8096de93115ae8d3fb2e6184ad3b..e044830439fe9821ab3f62695d318a6321b8a266 100644 --- a/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/net/minecraft/world/level/block/state/BlockBehaviour.java @@ -347,13 +347,21 @@ public abstract class BlockBehaviour implements FeatureElement { @@ -229,7 +229,7 @@ index 8db95b74f88f8096de93115ae8d3fb2e6184ad3b..8c0abcbf1af03092b54d2e4bdad8ac15 + // DivineMC start - Lag compensation + private float lagCompensation(float original, Player player) { -+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.blockBreakingAcceleration) return original; ++ if (!org.bxteam.divinemc.config.DivineConfig.MiscCategory.lagCompensationEnabled || !org.bxteam.divinemc.config.DivineConfig.MiscCategory.blockBreakingAcceleration) return original; + if (player.level().isClientSide) return original; + return original * org.bxteam.divinemc.util.tps.TPSCalculator.MAX_TPS / (float) ((ServerLevel) player.level()).tpsCalculator.getMostAccurateTPS(); + } @@ -248,7 +248,7 @@ index 8db95b74f88f8096de93115ae8d3fb2e6184ad3b..8c0abcbf1af03092b54d2e4bdad8ac15 } diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index 04942e23dd2bc82e4c60110756beedb5e0f074d7..7eb6da13dc47eaeac6e70d4e2935c1cc022c6400 100644 +index 04942e23dd2bc82e4c60110756beedb5e0f074d7..a40cd4f4904927598f1966c5746634fe1fa5e059 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java @@ -910,6 +910,19 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p @@ -258,8 +258,8 @@ index 04942e23dd2bc82e4c60110756beedb5e0f074d7..7eb6da13dc47eaeac6e70d4e2935c1cc + // DivineMC start - Lag compensation + private void lagCompensation(Runnable original) { + original.run(); -+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled) return; -+ if (!org.bxteam.divinemc.DivineConfig.blockEntityAcceleration) return; ++ if (!org.bxteam.divinemc.config.DivineConfig.MiscCategory.lagCompensationEnabled) return; ++ if (!org.bxteam.divinemc.config.DivineConfig.MiscCategory.blockEntityAcceleration) return; + if (LevelChunk.this.level.isClientSide()) return; + + for (int i = 0; i < ((ServerLevel) this.blockEntity.getLevel()).tpsCalculator.applicableMissedTicks(); i++) { @@ -285,7 +285,7 @@ index 04942e23dd2bc82e4c60110756beedb5e0f074d7..7eb6da13dc47eaeac6e70d4e2935c1cc // Paper start - Remove the Block Entity if it's invalid } else { diff --git a/net/minecraft/world/level/material/LavaFluid.java b/net/minecraft/world/level/material/LavaFluid.java -index e7ae29a4da3bf36b99fdab39af78f03c06696dbc..e57c04df4cb5955713d61d8237094041d3f3ca4f 100644 +index e7ae29a4da3bf36b99fdab39af78f03c06696dbc..6ae99a4dc04f48342b948fcfeaffc68babe60f96 100644 --- a/net/minecraft/world/level/material/LavaFluid.java +++ b/net/minecraft/world/level/material/LavaFluid.java @@ -187,9 +187,22 @@ public abstract class LavaFluid extends FlowingFluid { @@ -294,7 +294,7 @@ index e7ae29a4da3bf36b99fdab39af78f03c06696dbc..e57c04df4cb5955713d61d8237094041 + // DivineMC start - Lag compensation + private int lagCompensation(int original, ServerLevel level) { -+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.fluidAcceleration) return original; ++ if (!org.bxteam.divinemc.config.DivineConfig.MiscCategory.lagCompensationEnabled || !org.bxteam.divinemc.config.DivineConfig.MiscCategory.fluidAcceleration) return original; + return org.bxteam.divinemc.util.tps.TPSUtil.tt20(original, true, level); + } + // DivineMC end - Lag compensation @@ -313,7 +313,7 @@ index e7ae29a4da3bf36b99fdab39af78f03c06696dbc..e57c04df4cb5955713d61d8237094041 @Override diff --git a/net/minecraft/world/level/material/WaterFluid.java b/net/minecraft/world/level/material/WaterFluid.java -index b248fe1d66940c05d56fc322df61c52ece72e77f..8fa7883a0fe5fc2651d640ecde20198293afa654 100644 +index b248fe1d66940c05d56fc322df61c52ece72e77f..2a35dcf66dc01e787f9767a90c08a6cb283576e4 100644 --- a/net/minecraft/world/level/material/WaterFluid.java +++ b/net/minecraft/world/level/material/WaterFluid.java @@ -124,8 +124,16 @@ public abstract class WaterFluid extends FlowingFluid { @@ -322,7 +322,7 @@ index b248fe1d66940c05d56fc322df61c52ece72e77f..8fa7883a0fe5fc2651d640ecde201982 + // DivineMC start - Lag compensation + private int lagCompensation(ServerLevel level) { -+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.fluidAcceleration) return 5; ++ if (!org.bxteam.divinemc.config.DivineConfig.MiscCategory.lagCompensationEnabled || !org.bxteam.divinemc.config.DivineConfig.MiscCategory.fluidAcceleration) return 5; + return org.bxteam.divinemc.util.tps.TPSUtil.tt20(5, true, level); + } + // DivineMC end - Lag compensation diff --git a/divinemc-server/minecraft-patches/features/0025-Implement-NoChatReports.patch b/divinemc-server/minecraft-patches/features/0025-Implement-NoChatReports.patch index 47a23c1..7060940 100644 --- a/divinemc-server/minecraft-patches/features/0025-Implement-NoChatReports.patch +++ b/divinemc-server/minecraft-patches/features/0025-Implement-NoChatReports.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Implement NoChatReports diff --git a/net/minecraft/network/FriendlyByteBuf.java b/net/minecraft/network/FriendlyByteBuf.java -index 7da7d645f83f351e8c964da01734f3074a877ca1..39426086e1c417758d6ff940c3ab716fcba6cd6c 100644 +index 7da7d645f83f351e8c964da01734f3074a877ca1..8be2df6080bb1d677bbfd3e38706dfbc8d30a647 100644 --- a/net/minecraft/network/FriendlyByteBuf.java +++ b/net/minecraft/network/FriendlyByteBuf.java @@ -105,7 +105,28 @@ public class FriendlyByteBuf extends ByteBuf { @@ -15,7 +15,7 @@ index 7da7d645f83f351e8c964da01734f3074a877ca1..39426086e1c417758d6ff940c3ab716f + @SuppressWarnings({"unchecked", "rawtypes"}) // DivineMC - Implement NoChatReports public T readJsonWithCodec(Codec codec) { + // DivineMC start - Implement NoChatReports -+ if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) { ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsEnabled) { + if (codec == net.minecraft.network.protocol.status.ServerStatus.CODEC) { + JsonElement jsonElement = GsonHelper.fromJson(GSON, this.readUtf(), JsonElement.class); + DataResult dataResult = codec.parse(JsonOps.INSTANCE, jsonElement); @@ -42,8 +42,8 @@ index 7da7d645f83f351e8c964da01734f3074a877ca1..39426086e1c417758d6ff940c3ab716f public void writeJsonWithCodec(Codec codec, T value, int maxLength) { // Paper end - Adventure; add max length parameter + // DivineMC start - Implement NoChatReports -+ if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) { -+ if (org.bxteam.divinemc.DivineConfig.noChatReportsAddQueryData && codec == net.minecraft.network.protocol.status.ServerStatus.CODEC) { ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsEnabled) { ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsAddQueryData && codec == net.minecraft.network.protocol.status.ServerStatus.CODEC) { + DataResult dataResult = codec.encodeStart(JsonOps.INSTANCE, value); + JsonElement element = dataResult.getOrThrow(string -> new EncoderException("Failed to encode: " + string + " " + value)); + @@ -58,7 +58,7 @@ index 7da7d645f83f351e8c964da01734f3074a877ca1..39426086e1c417758d6ff940c3ab716f this.writeUtf(GSON.toJson(dataResult.getOrThrow(exception -> new EncoderException("Failed to encode: " + exception + " " + value))), maxLength); // Paper - Adventure; add max length parameter } diff --git a/net/minecraft/network/protocol/game/ServerboundChatCommandSignedPacket.java b/net/minecraft/network/protocol/game/ServerboundChatCommandSignedPacket.java -index 07943553b562b95076bdce232d6f0796f469400f..61ecf4c6ae37b13ed42dff8d4165d32f3a5cc0c9 100644 +index 07943553b562b95076bdce232d6f0796f469400f..478c07e8c569d35761ce138cf1deed9511b826d6 100644 --- a/net/minecraft/network/protocol/game/ServerboundChatCommandSignedPacket.java +++ b/net/minecraft/network/protocol/game/ServerboundChatCommandSignedPacket.java @@ -36,4 +36,15 @@ public record ServerboundChatCommandSignedPacket( @@ -69,7 +69,7 @@ index 07943553b562b95076bdce232d6f0796f469400f..61ecf4c6ae37b13ed42dff8d4165d32f + // DivineMC start - Implement NoChatReports + @Override + public ArgumentSignatures argumentSignatures() { -+ if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) { ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsEnabled) { + return ArgumentSignatures.EMPTY; + } + @@ -78,7 +78,7 @@ index 07943553b562b95076bdce232d6f0796f469400f..61ecf4c6ae37b13ed42dff8d4165d32f + // DivineMC end - Implement NoChatReports } diff --git a/net/minecraft/network/protocol/game/ServerboundChatPacket.java b/net/minecraft/network/protocol/game/ServerboundChatPacket.java -index b5afc05924ae899e020c303c8b86398e1d4ab8a0..3af0436ac2dff04cfaa1b3dda11a5417f2c0890c 100644 +index b5afc05924ae899e020c303c8b86398e1d4ab8a0..2a6fdec4faae3512060cbb21a2043129765a480e 100644 --- a/net/minecraft/network/protocol/game/ServerboundChatPacket.java +++ b/net/minecraft/network/protocol/game/ServerboundChatPacket.java @@ -36,4 +36,16 @@ public record ServerboundChatPacket(String message, Instant timeStamp, long salt @@ -90,7 +90,7 @@ index b5afc05924ae899e020c303c8b86398e1d4ab8a0..3af0436ac2dff04cfaa1b3dda11a5417 + @Override + @Nullable + public MessageSignature signature() { -+ if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) { ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsEnabled) { + return null; + } + @@ -99,7 +99,7 @@ index b5afc05924ae899e020c303c8b86398e1d4ab8a0..3af0436ac2dff04cfaa1b3dda11a5417 + // DivineMC end - Implement NoChatReports } diff --git a/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java b/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java -index 1df628ac0b414511aaed6e09d78f884c4170f730..d94858facc06d57139e953796ee09dad17648dbb 100644 +index 1df628ac0b414511aaed6e09d78f884c4170f730..1543f730843c1736c4db9a6ebe30be9cc9fbe36a 100644 --- a/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java +++ b/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java @@ -26,6 +26,19 @@ public record ServerboundChatSessionUpdatePacket(RemoteChatSession.Data chatSess @@ -107,12 +107,12 @@ index 1df628ac0b414511aaed6e09d78f884c4170f730..d94858facc06d57139e953796ee09dad @Override public void handle(ServerGamePacketListener handler) { + // DivineMC start - Implement NoChatReports -+ if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) { ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsEnabled) { + var impl = (net.minecraft.server.network.ServerGamePacketListenerImpl) handler; + + if (!impl.getPlayer().getServer().isSingleplayerOwner(impl.getPlayer().getGameProfile())) { -+ if (org.bxteam.divinemc.DivineConfig.noChatReportsDemandOnClient) { -+ impl.disconnect(net.minecraft.network.chat.Component.literal(org.bxteam.divinemc.DivineConfig.noChatReportsDisconnectDemandOnClientMessage)); ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsDemandOnClient) { ++ impl.disconnect(net.minecraft.network.chat.Component.literal(org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsDisconnectDemandOnClientMessage)); + } + } + @@ -206,19 +206,19 @@ index 094d1821d298fc228270b2d6cf0445949434f3e2..8f7e3e5f1d3a87ba3528c9dd61e063ec private static final String PREFIX = "data:image/png;base64,"; public static final Codec CODEC = Codec.STRING.comapFlatMap(string -> { diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java -index 116970622a4e7cc9c7c8333cdb18da71381abcff..3f9b26de801b2d8e85c56d219ca7bd61c41b3f9d 100644 +index bfd69555f3f228c7450388a1d21c1c131f3bf990..b65c8e393249b0fc731e02262d58873cb38942b8 100644 --- a/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java @@ -631,6 +631,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @Override public boolean enforceSecureProfile() { -+ if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) return false; // DivineMC - Implement NoChatReports ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsEnabled) return false; // DivineMC - Implement NoChatReports DedicatedServerProperties properties = this.getProperties(); // Paper start - Add setting for proxy online mode status return properties.enforceSecureProfile diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index b865c2fd503c3f0368d77d28c2f7a7c7fa7008bb..b3356c65992b1bb165876dfc58a8331d6fda138c 100644 +index b865c2fd503c3f0368d77d28c2f7a7c7fa7008bb..ebd10817691d29de51d8db8ecd97bd21c4a5d8b4 100644 --- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java @@ -311,10 +311,64 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack @@ -226,17 +226,17 @@ index b865c2fd503c3f0368d77d28c2f7a7c7fa7008bb..b3356c65992b1bb165876dfc58a8331d public void send(Packet packet) { + // DivineMC start - Implement NoChatReports -+ if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) { ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsEnabled) { + Object self = this; + boolean cancel = false; + + if (self instanceof ServerGamePacketListenerImpl listener) { -+ if (org.bxteam.divinemc.DivineConfig.noChatReportsDebugLog && packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat) { ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsDebugLog && packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat) { + MinecraftServer.LOGGER.info("Sending message: {}", chat.unsignedContent() != null ? chat.unsignedContent() + : chat.body().content()); + } + -+ if (org.bxteam.divinemc.DivineConfig.noChatReportsConvertToGameMessage) { ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsConvertToGameMessage) { + if (packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat) { + packet = new net.minecraft.network.protocol.game.ClientboundSystemChatPacket(chat.chatType().decorate( + chat.unsignedContent() != null ? chat.unsignedContent() @@ -259,17 +259,17 @@ index b865c2fd503c3f0368d77d28c2f7a7c7fa7008bb..b3356c65992b1bb165876dfc58a8331d public void send(Packet packet, @Nullable PacketSendListener listener) { + // DivineMC start - Implement NoChatReports -+ if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) { ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsEnabled) { + Object self = this; + boolean cancel = false; + + if (self instanceof ServerGamePacketListenerImpl listenerImpl) { -+ if (org.bxteam.divinemc.DivineConfig.noChatReportsDebugLog && packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat) { ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsDebugLog && packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat) { + MinecraftServer.LOGGER.info("Sending message: {}", chat.unsignedContent() != null ? chat.unsignedContent() + : chat.body().content()); + } + -+ if (org.bxteam.divinemc.DivineConfig.noChatReportsConvertToGameMessage) { ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsConvertToGameMessage) { + if (packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat && listener != null) { + cancel = true; + listenerImpl.send(chat); @@ -287,7 +287,7 @@ index b865c2fd503c3f0368d77d28c2f7a7c7fa7008bb..b3356c65992b1bb165876dfc58a8331d if (packet == null || this.processedDisconnect) { // Spigot return; diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index 7f74e0fe280543775710f7650c22314dc5439d7f..9f3afab438199dbaf40fa1a64b6ecdae74c0a34d 100644 +index 7f74e0fe280543775710f7650c22314dc5439d7f..21ea5de6bf2d034d63dab1d7c563b63b3e713521 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java @@ -275,7 +275,7 @@ public abstract class PlayerList { @@ -295,7 +295,7 @@ index 7f74e0fe280543775710f7650c22314dc5439d7f..9f3afab438199dbaf40fa1a64b6ecdae _boolean2, player.createCommonSpawnInfo(serverLevel), - this.server.enforceSecureProfile() -+ org.bxteam.divinemc.DivineConfig.noChatReportsEnabled || this.server.enforceSecureProfile() // DivineMC - Implement NoChatReports ++ org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsEnabled || this.server.enforceSecureProfile() // DivineMC - Implement NoChatReports ) ); player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit @@ -303,7 +303,7 @@ index 7f74e0fe280543775710f7650c22314dc5439d7f..9f3afab438199dbaf40fa1a64b6ecdae } public boolean verifyChatTrusted(PlayerChatMessage message) { -+ if (org.bxteam.divinemc.DivineConfig.noChatReportsEnabled) return true; // DivineMC - Implement NoChatReports ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.noChatReportsEnabled) return true; // DivineMC - Implement NoChatReports return message.hasSignature() && !message.hasExpiredServer(Instant.now()); } diff --git a/divinemc-server/minecraft-patches/features/0026-Virtual-Threads.patch b/divinemc-server/minecraft-patches/features/0026-Virtual-Threads.patch index 4593cde..eb8b05c 100644 --- a/divinemc-server/minecraft-patches/features/0026-Virtual-Threads.patch +++ b/divinemc-server/minecraft-patches/features/0026-Virtual-Threads.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Virtual Threads diff --git a/net/minecraft/Util.java b/net/minecraft/Util.java -index d1fcc73f579d1c4ac79213ad039c8d803ff51b1a..047ce2391a8ec4bab1b8a2020ab3f20953e5b95f 100644 +index d1fcc73f579d1c4ac79213ad039c8d803ff51b1a..a0c59cfb8a8717a308a5597cadd6df1a47bd7224 100644 --- a/net/minecraft/Util.java +++ b/net/minecraft/Util.java @@ -98,7 +98,12 @@ public class Util { @@ -14,7 +14,7 @@ index d1fcc73f579d1c4ac79213ad039c8d803ff51b1a..047ce2391a8ec4bab1b8a2020ab3f209 // Paper start - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread - public static final ExecutorService PROFILE_EXECUTOR = Executors.newFixedThreadPool(2, new java.util.concurrent.ThreadFactory() { + // DivineMC start - Virtual Threads -+ public static final ExecutorService PROFILE_EXECUTOR = org.bxteam.divinemc.DivineConfig.virtualThreadsEnabled && org.bxteam.divinemc.DivineConfig.virtualProfileLookupPool ++ public static final ExecutorService PROFILE_EXECUTOR = org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.virtualThreadsEnabled && org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.virtualProfileLookupPool + ? Executors.newVirtualThreadPerTaskExecutor() + : Executors.newFixedThreadPool(2, new java.util.concurrent.ThreadFactory() + { @@ -23,7 +23,7 @@ index d1fcc73f579d1c4ac79213ad039c8d803ff51b1a..047ce2391a8ec4bab1b8a2020ab3f209 private final AtomicInteger count = new AtomicInteger(); diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java -index 07e228b620962e507b7db70e5a743daf2e5c82ca..cff86f3a50529a9d1a8873aa6f7f77da248c6c67 100644 +index 8cfd050e1b5ebd6725a6888c8ec7aa6ce7c06efe..1df51c0190ad9756300cd5c1f40a62a01e883e26 100644 --- a/net/minecraft/commands/Commands.java +++ b/net/minecraft/commands/Commands.java @@ -473,7 +473,7 @@ public class Commands { @@ -31,12 +31,12 @@ index 07e228b620962e507b7db70e5a743daf2e5c82ca..cff86f3a50529a9d1a8873aa6f7f77da // Fixed pool, but with discard policy - public static final java.util.concurrent.ExecutorService COMMAND_SENDING_POOL = new java.util.concurrent.ThreadPoolExecutor( -+ public static final java.util.concurrent.ExecutorService COMMAND_SENDING_POOL = org.bxteam.divinemc.DivineConfig.virtualThreadsEnabled && org.bxteam.divinemc.DivineConfig.virtualCommandBuilderScheduler ? java.util.concurrent.Executors.newVirtualThreadPerTaskExecutor() : new java.util.concurrent.ThreadPoolExecutor( // DivineMC - Virtual Threads ++ public static final java.util.concurrent.ExecutorService COMMAND_SENDING_POOL = org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.virtualThreadsEnabled && org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.virtualCommandBuilderScheduler ? java.util.concurrent.Executors.newVirtualThreadPerTaskExecutor() : new java.util.concurrent.ThreadPoolExecutor( // DivineMC - Virtual Threads 2, 2, 0, java.util.concurrent.TimeUnit.MILLISECONDS, new java.util.concurrent.LinkedBlockingQueue<>(), new com.google.common.util.concurrent.ThreadFactoryBuilder() diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 1a842ecfb717f7b5ed2fdb2779040ab0e857612d..b2e90749bcaf3b9132681713ab0afae95b3197ee 100644 +index 1a842ecfb717f7b5ed2fdb2779040ab0e857612d..ce79e6db9ab1a49005d1163641dd32050a2f9a41 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -2641,8 +2641,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { + try { + // Modified from PlayerChunkSender#sendChunk diff --git a/divinemc-server/minecraft-patches/features/0028-Optimize-Structure-Generation.patch b/divinemc-server/minecraft-patches/features/0028-Optimize-Structure-Generation.patch index 96d0902..0d44e69 100644 --- a/divinemc-server/minecraft-patches/features/0028-Optimize-Structure-Generation.patch +++ b/divinemc-server/minecraft-patches/features/0028-Optimize-Structure-Generation.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Optimize Structure Generation diff --git a/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java b/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java -index e275dc8395e556e8a9412b121034e91553fbaea4..61386f6534faff3710c5ff309977aaf37b273145 100644 +index 86a54586112b84b7c2026a4cbdad99cdf1c6ef81..e4ca880b5d16ae30676ec25c39c3d5b5f6cb3c24 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; @@ -23,7 +23,7 @@ index e275dc8395e556e8a9412b121034e91553fbaea4..61386f6534faff3710c5ff309977aaf3 + // DivineMC start - Optimize Structure Generation + private boolean structureLayoutOptimizer$optimizeJigsawConnecting(StructureTemplate.JigsawBlockInfo jigsaw1, StructureTemplate.JigsawBlockInfo jigsaw2) { -+ if (!org.bxteam.divinemc.DivineConfig.enableStructureLayoutOptimizer) { ++ if (!org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableStructureLayoutOptimizer) { + return JigsawBlock.canAttach(jigsaw1, jigsaw2); + } + return org.bxteam.divinemc.util.structure.GeneralUtils.canJigsawsAttach(jigsaw1, jigsaw2); @@ -41,7 +41,7 @@ index e275dc8395e556e8a9412b121034e91553fbaea4..61386f6534faff3710c5ff309977aaf3 + } + + private List structureLayoutOptimizer$removeDuplicateTemplatePoolElementLists(StructureTemplatePool instance, RandomSource random) { -+ if (!org.bxteam.divinemc.DivineConfig.enableStructureLayoutOptimizer || !org.bxteam.divinemc.DivineConfig.deduplicateShuffledTemplatePoolElementList) { ++ if (!org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableStructureLayoutOptimizer || !org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.deduplicateShuffledTemplatePoolElementList) { + return instance.getShuffledTemplates(random); + } + @@ -67,7 +67,7 @@ index e275dc8395e556e8a9412b121034e91553fbaea4..61386f6534faff3710c5ff309977aaf3 + + private ArrayList structureLayoutOptimizer$skipDuplicateTemplatePoolElementLists1() { + // Swap with trojan list, so we can record what pieces we visited -+ return org.bxteam.divinemc.DivineConfig.deduplicateShuffledTemplatePoolElementList ? Lists.newArrayList() : new org.bxteam.divinemc.util.structure.TrojanArrayList<>(); ++ return org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.deduplicateShuffledTemplatePoolElementList ? Lists.newArrayList() : new org.bxteam.divinemc.util.structure.TrojanArrayList<>(); + } + + private List structureLayoutOptimizer$skipBlockedJigsaws( @@ -78,7 +78,7 @@ index e275dc8395e556e8a9412b121034e91553fbaea4..61386f6534faff3710c5ff309977aaf3 + StructureTemplate.StructureBlockInfo parentJigsawBlockInfo, + BlockPos parentTargetPosition) + { -+ if (!org.bxteam.divinemc.DivineConfig.enableStructureLayoutOptimizer) { ++ if (!org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableStructureLayoutOptimizer) { + return original; + } + if (voxelShapeMutableObject.getValue() instanceof org.bxteam.divinemc.util.structure.TrojanVoxelShape trojanVoxelShape) { @@ -96,10 +96,10 @@ index e275dc8395e556e8a9412b121034e91553fbaea4..61386f6534faff3710c5ff309977aaf3 + List list, + StructurePoolElement structurepoolelement1) + { -+ if (!org.bxteam.divinemc.DivineConfig.enableStructureLayoutOptimizer) { ++ if (!org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableStructureLayoutOptimizer) { + return original; + } -+ if (!org.bxteam.divinemc.DivineConfig.deduplicateShuffledTemplatePoolElementList && list instanceof org.bxteam.divinemc.util.structure.TrojanArrayList trojanArrayList) { ++ if (!org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.deduplicateShuffledTemplatePoolElementList && list instanceof org.bxteam.divinemc.util.structure.TrojanArrayList trojanArrayList) { + // Do not run this piece's logic since we already checked its 4 rotations in the past. + if (trojanArrayList.elementsAlreadyParsed.contains(structurepoolelement1)) { + @@ -177,7 +177,7 @@ index e275dc8395e556e8a9412b121034e91553fbaea4..61386f6534faff3710c5ff309977aaf3 + java.util.function.Supplier original = () -> Shapes.joinIsNotEmpty( + parentBounds, Shapes.create(AABB.of(boundingBox3).deflate(0.25)), BooleanOp.ONLY_SECOND + ); -+ if (org.bxteam.divinemc.DivineConfig.enableStructureLayoutOptimizer) { ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableStructureLayoutOptimizer) { + if (parentBounds instanceof org.bxteam.divinemc.util.structure.TrojanVoxelShape trojanVoxelShape) { + AABB pieceAABB = AABB.of(boundingBox3).deflate(0.25D); + @@ -195,7 +195,7 @@ index e275dc8395e556e8a9412b121034e91553fbaea4..61386f6534faff3710c5ff309977aaf3 Shapes.joinUnoptimized( mutableObject1.getValue(), Shapes.create(AABB.of(boundingBox3)), BooleanOp.ONLY_FIRST diff --git a/net/minecraft/world/level/levelgen/structure/pools/SinglePoolElement.java b/net/minecraft/world/level/levelgen/structure/pools/SinglePoolElement.java -index 5c081a5b3d10f713e4e82fe1a43758f553fe50e0..b039e451a95ba67140524132285ccf4b3354ad00 100644 +index 5c081a5b3d10f713e4e82fe1a43758f553fe50e0..85e84603a19964f05d9d5e62eb096ca76c36ab00 100644 --- a/net/minecraft/world/level/levelgen/structure/pools/SinglePoolElement.java +++ b/net/minecraft/world/level/levelgen/structure/pools/SinglePoolElement.java @@ -119,8 +119,16 @@ public class SinglePoolElement extends StructurePoolElement { @@ -205,7 +205,7 @@ index 5c081a5b3d10f713e4e82fe1a43758f553fe50e0..b039e451a95ba67140524132285ccf4b - Util.shuffle(jigsaws, random); - sortBySelectionPriority(jigsaws); + // DivineMC start - Optimize Structure Generation -+ if (org.bxteam.divinemc.DivineConfig.enableStructureLayoutOptimizer) { ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableStructureLayoutOptimizer) { + structureLayoutOptimizer$fasterJigsawListShuffling1(jigsaws, random); + structureLayoutOptimizer$fasterJigsawListShuffling2(jigsaws); + } else { @@ -231,7 +231,7 @@ index 5c081a5b3d10f713e4e82fe1a43758f553fe50e0..b039e451a95ba67140524132285ccf4b + // 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 df3a1b9ed4ad836bd3358b6b440964e497213ea3..c283d5320c89c0793d59dd107fd9b0ae3b0a9ba6 100644 +index df3a1b9ed4ad836bd3358b6b440964e497213ea3..3730ea5ab8a82ab39b3454c2f5beb971c7b8939e 100644 --- a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java +++ b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java @@ -247,6 +247,12 @@ public class StructureTemplate { @@ -253,7 +253,7 @@ index df3a1b9ed4ad836bd3358b6b440964e497213ea3..c283d5320c89c0793d59dd107fd9b0ae // CraftBukkit end - List list = settings.getRandomPalette(this.palettes, offset).blocks(); + // DivineMC start - Optimize Structure Generation -+ List list = org.bxteam.divinemc.DivineConfig.enableStructureLayoutOptimizer ++ List list = org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableStructureLayoutOptimizer + ? structureLayoutOptimizer$shrinkStructureTemplateBlocksList(settings.getRandomPalette(this.palettes, offset), offset, settings) + : settings.getRandomPalette(this.palettes, offset).blocks(); + // DivineMC end - Optimize Structure Generation @@ -266,7 +266,7 @@ index df3a1b9ed4ad836bd3358b6b440964e497213ea3..c283d5320c89c0793d59dd107fd9b0ae Palette(List blocks) { - this.blocks = blocks; + // DivineMC start - Optimize Structure Generation -+ this.blocks = org.bxteam.divinemc.DivineConfig.enableStructureLayoutOptimizer ++ this.blocks = org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableStructureLayoutOptimizer + ? new org.bxteam.divinemc.util.structure.PalettedStructureBlockInfoList(blocks) + : blocks; + // DivineMC end - Optimize Structure Generation diff --git a/divinemc-server/minecraft-patches/features/0029-Option-to-disable-disconnect.spam.patch b/divinemc-server/minecraft-patches/features/0029-Option-to-disable-disconnect.spam.patch index 00a1f77..0faee1e 100644 --- a/divinemc-server/minecraft-patches/features/0029-Option-to-disable-disconnect.spam.patch +++ b/divinemc-server/minecraft-patches/features/0029-Option-to-disable-disconnect.spam.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Option to disable disconnect.spam diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 8f6555d122c7d3f22b3f6e9874994d8fb1689cd3..c59ce58f526f9bc5a2912791a51bb5d09c250d8a 100644 +index afc514702a853e98a334b48499f3696ae7f95ea2..72dfe9d9a443b0e1c0267a664dfa7c89168d700a 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -812,7 +812,7 @@ public class ServerGamePacketListenerImpl @@ -13,7 +13,7 @@ index 8f6555d122c7d3f22b3f6e9874994d8fb1689cd3..c59ce58f526f9bc5a2912791a51bb5d0 // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async // CraftBukkit start - if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - configurable tab spam limits -+ if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile()) && !org.bxteam.divinemc.DivineConfig.disableDisconnectSpam) { // Paper - configurable tab spam limits // DivineMC - Option to disable disconnect.spam ++ if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile()) && !org.bxteam.divinemc.config.DivineConfig.NetworkCategory.disableDisconnectSpam) { // Paper - configurable tab spam limits // DivineMC - Option to disable disconnect.spam this.disconnectAsync(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - Kick event cause // Paper - add proper async disconnect return; } @@ -22,7 +22,7 @@ index 8f6555d122c7d3f22b3f6e9874994d8fb1689cd3..c59ce58f526f9bc5a2912791a51bb5d0 // Paper start final int index; - if (packet.getCommand().length() > 64 && ((index = packet.getCommand().indexOf(' ')) == -1 || index >= 64)) { -+ if (packet.getCommand().length() > 64 && ((index = packet.getCommand().indexOf(' ')) == -1 || index >= 64) && !org.bxteam.divinemc.DivineConfig.disableDisconnectSpam) { // DivineMC - Option to disable disconnect.spam ++ if (packet.getCommand().length() > 64 && ((index = packet.getCommand().indexOf(' ')) == -1 || index >= 64) && !org.bxteam.divinemc.config.DivineConfig.NetworkCategory.disableDisconnectSpam) { // DivineMC - Option to disable disconnect.spam this.disconnectAsync(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - add proper async disconnect return; } @@ -30,7 +30,7 @@ index 8f6555d122c7d3f22b3f6e9874994d8fb1689cd3..c59ce58f526f9bc5a2912791a51bb5d0 ParseResults parseResults = this.server.getCommands().getDispatcher().parse(stringReader, this.player.createCommandSourceStack()); // Paper start - Handle non-recoverable exceptions if (!parseResults.getExceptions().isEmpty() -+ && !org.bxteam.divinemc.DivineConfig.disableDisconnectSpam // DivineMC - Option to disable disconnect.spam ++ && !org.bxteam.divinemc.config.DivineConfig.NetworkCategory.disableDisconnectSpam // DivineMC - Option to disable disconnect.spam && parseResults.getExceptions().values().stream().anyMatch(e -> e instanceof io.papermc.paper.brigadier.TagParseCommandSyntaxException)) { this.disconnect(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); return; @@ -38,7 +38,7 @@ index 8f6555d122c7d3f22b3f6e9874994d8fb1689cd3..c59ce58f526f9bc5a2912791a51bb5d0 // this.chatSpamThrottler.increment(); if (!this.chatSpamThrottler.isIncrementAndUnderThreshold() // CraftBukkit end -+ && !org.bxteam.divinemc.DivineConfig.disableDisconnectSpam // DivineMC - Option to disable disconnect.spam ++ && !org.bxteam.divinemc.config.DivineConfig.NetworkCategory.disableDisconnectSpam // DivineMC - Option to disable disconnect.spam && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { this.disconnectAsync(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause & add proper async disconnect @@ -47,7 +47,7 @@ index 8f6555d122c7d3f22b3f6e9874994d8fb1689cd3..c59ce58f526f9bc5a2912791a51bb5d0 // Paper start - auto recipe limit if (!org.bukkit.Bukkit.isPrimaryThread()) { - if (!this.recipeSpamPackets.isIncrementAndUnderThreshold()) { -+ if (!this.recipeSpamPackets.isIncrementAndUnderThreshold() && !org.bxteam.divinemc.DivineConfig.disableDisconnectSpam) { // DivineMC - Option to disable disconnect.spam ++ if (!this.recipeSpamPackets.isIncrementAndUnderThreshold() && !org.bxteam.divinemc.config.DivineConfig.NetworkCategory.disableDisconnectSpam) { // DivineMC - Option to disable disconnect.spam this.disconnectAsync(net.minecraft.network.chat.Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause // Paper - add proper async disconnect return; } diff --git a/divinemc-server/minecraft-patches/features/0032-ModernFix-compact_bit_storage.patch b/divinemc-server/minecraft-patches/features/0032-ModernFix-compact_bit_storage.patch index 900a716..3c0fbc8 100644 --- a/divinemc-server/minecraft-patches/features/0032-ModernFix-compact_bit_storage.patch +++ b/divinemc-server/minecraft-patches/features/0032-ModernFix-compact_bit_storage.patch @@ -10,7 +10,7 @@ As part of: ModernFix (https://github.com/embeddedt/ModernFix) Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html) diff --git a/net/minecraft/world/level/chunk/PalettedContainer.java b/net/minecraft/world/level/chunk/PalettedContainer.java -index a512609aaa823b940ed269c981fc9beec49a126e..2829ebdda8e9ad8945fe7d3f96c3cdaad798a40a 100644 +index a512609aaa823b940ed269c981fc9beec49a126e..1469835b298db8d4079b791192849626b972c62f 100644 --- a/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/net/minecraft/world/level/chunk/PalettedContainer.java @@ -275,6 +275,28 @@ public class PalettedContainer implements PaletteResize, PalettedContainer @@ -18,7 +18,7 @@ index a512609aaa823b940ed269c981fc9beec49a126e..2829ebdda8e9ad8945fe7d3f96c3cdaa buffer.readFixedSizeLongArray(data.storage.getRaw()); this.data = data; + // DivineMC start - ModernFix: compact_bit_storage -+ if (org.bxteam.divinemc.DivineConfig.useCompactBitStorage && _byte > 1) { ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.useCompactBitStorage && _byte > 1) { + long[] storageArray = this.data.storage.getRaw(); + boolean empty = true; + for (long l : storageArray) { diff --git a/divinemc-server/minecraft-patches/features/0033-Command-block-parse-results-caching.patch b/divinemc-server/minecraft-patches/features/0033-Command-block-parse-results-caching.patch index a764925..796a2b8 100644 --- a/divinemc-server/minecraft-patches/features/0033-Command-block-parse-results-caching.patch +++ b/divinemc-server/minecraft-patches/features/0033-Command-block-parse-results-caching.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Command block parse results caching diff --git a/net/minecraft/world/level/BaseCommandBlock.java b/net/minecraft/world/level/BaseCommandBlock.java -index 0eb88c24c66b521fd34d2fda6e6e21e3ecc6ac88..d27eca05abcfd524ff3c22770ce94505ce2ad233 100644 +index 0eb88c24c66b521fd34d2fda6e6e21e3ecc6ac88..430084381e9aa3e53afb59b58021ab6c3c70db03 100644 --- a/net/minecraft/world/level/BaseCommandBlock.java +++ b/net/minecraft/world/level/BaseCommandBlock.java @@ -37,6 +37,10 @@ public abstract class BaseCommandBlock implements CommandSource { @@ -25,7 +25,7 @@ index 0eb88c24c66b521fd34d2fda6e6e21e3ecc6ac88..d27eca05abcfd524ff3c22770ce94505 }); - server.getCommands().dispatchServerCommand(commandSourceStack, this.command); // CraftBukkit + // DivineMC start - Command block parse results caching -+ if (org.bxteam.divinemc.DivineConfig.commandBlockParseResultsCaching) { ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.commandBlockParseResultsCaching) { + String commandCache = this.command; + // noinspection DuplicatedCode + com.google.common.base.Joiner joiner = com.google.common.base.Joiner.on(" "); diff --git a/divinemc-server/minecraft-patches/features/0035-SparklyPaper-Allow-throttling-hopper-checks-if-the-t.patch b/divinemc-server/minecraft-patches/features/0035-SparklyPaper-Allow-throttling-hopper-checks-if-the-t.patch index c901fc4..ab5afea 100644 --- a/divinemc-server/minecraft-patches/features/0035-SparklyPaper-Allow-throttling-hopper-checks-if-the-t.patch +++ b/divinemc-server/minecraft-patches/features/0035-SparklyPaper-Allow-throttling-hopper-checks-if-the-t.patch @@ -7,7 +7,7 @@ Subject: [PATCH] SparklyPaper: Allow throttling hopper checks if the target Original project: https://github.com/SparklyPower/SparklyPaper diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index 15d4f60942c0cc612c1468b4c0fda886867a67cb..d701952d940c0da245aa4f9e3664dd5cfcc8771e 100644 +index 15d4f60942c0cc612c1468b4c0fda886867a67cb..f0d53f83f7d3b4d8aa7d21bd7e3627a7052535aa 100644 --- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java @@ -423,6 +423,11 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -15,8 +15,8 @@ index 15d4f60942c0cc612c1468b4c0fda886867a67cb..d701952d940c0da245aa4f9e3664dd5c Direction opposite = blockEntity.facing.getOpposite(); if (isFullContainer(attachedContainer, opposite)) { + // DivineMC start - SparklyPaper: Allow throttling hopper checks if the target container is full -+ if (org.bxteam.divinemc.DivineConfig.hopperThrottleWhenFull && org.bxteam.divinemc.DivineConfig.hopperThrottleSkipTicks > 0) { -+ blockEntity.setCooldown(org.bxteam.divinemc.DivineConfig.hopperThrottleSkipTicks); ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.hopperThrottleWhenFull && org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.hopperThrottleSkipTicks > 0) { ++ blockEntity.setCooldown(org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.hopperThrottleSkipTicks); + } + // DivineMC end - SparklyPaper: Allow throttling hopper checks if the target container is full return false; diff --git a/divinemc-server/minecraft-patches/features/0036-Linear-region-file-format.patch b/divinemc-server/minecraft-patches/features/0036-Linear-region-file-format.patch index 815bd63..dc6f8fb 100644 --- a/divinemc-server/minecraft-patches/features/0036-Linear-region-file-format.patch +++ b/divinemc-server/minecraft-patches/features/0036-Linear-region-file-format.patch @@ -21,7 +21,7 @@ index a814512fcfb85312474ae2c2c21443843bf57831..fdccc27c528b01b16a72e614ffd96523 public MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite( final int chunkX, final int chunkZ, final CompoundTag compound diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java -index 709df35246fb328cda21679b53d44d9f96206cb3..72c5463cbdd78bfa215b0c1f9baeb3be089dcde7 100644 +index f5ed467c0880e4bcdf1b9ae773a5aac21c4381c3..95fb49f7b9ee3d132cf2405d99b2d63ee295d76d 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java @@ -1260,7 +1260,7 @@ public final class MoonriseRegionFileIO { @@ -54,7 +54,7 @@ index 51c126735ace8fdde89ad97b5cab62f244212db0..8713d00d767c9225a0823d2fdbb0b479 + public void moonrise$write(final org.bxteam.divinemc.region.IRegionFile regionFile) throws IOException; // DivineMC - Linear region file format } diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index b2e90749bcaf3b9132681713ab0afae95b3197ee..7de51e99507dfca76ec5848483fecc9e8df1b86f 100644 +index ce79e6db9ab1a49005d1163641dd32050a2f9a41..3deced447eb80fec362e1b8b3bea817b36074fbc 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -926,10 +926,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + ".linear"; + } + // DivineMC end - Linear region file format diff --git a/divinemc-server/minecraft-patches/features/0040-Async-mob-spawning.patch b/divinemc-server/minecraft-patches/features/0040-Async-mob-spawning.patch index 5d69edc..988d671 100644 --- a/divinemc-server/minecraft-patches/features/0040-Async-mob-spawning.patch +++ b/divinemc-server/minecraft-patches/features/0040-Async-mob-spawning.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Async mob spawning diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 0270e0045a76927e156f7bf54fed7ca406a113f8..d19337ce45a8ab7f6438f9101d61d17b70d68a47 100644 +index 3deced447eb80fec362e1b8b3bea817b36074fbc..b5103e14f25f4cf92438214f2fc3ada552dce742 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) { AtomicReference atomicReference = new AtomicReference<>(); diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java -index 9a65321ce62f21b150d29be30dbae7dba0ff40be..3bbaa9bdc7d49b456b5749e4880354c9f793a8b6 100644 +index 9a65321ce62f21b150d29be30dbae7dba0ff40be..4ff1f78eb963e2baf0c2871b4fea624c271f4348 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 @@ -37,7 +37,7 @@ index 9a65321ce62f21b150d29be30dbae7dba0ff40be..3bbaa9bdc7d49b456b5749e4880354c9 } + + // DivineMC start - Async mob spawning -+ if (org.bxteam.divinemc.DivineConfig.enableAsyncSpawning) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableAsyncSpawning) { + for (ServerPlayer player : this.level.players) { + for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) { + player.mobCounts[ii] = 0; @@ -82,7 +82,7 @@ index 9a65321ce62f21b150d29be30dbae7dba0ff40be..3bbaa9bdc7d49b456b5749e4880354c9 - int newBackoff = player.mobBackoffCounts[ii] - 1; // TODO make configurable bleed // TODO use nonlinear algorithm? - if (newBackoff < 0) { - newBackoff = 0; -+ if (!org.bxteam.divinemc.DivineConfig.enableAsyncSpawning) { ++ if (!org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableAsyncSpawning) { + // re-set mob counts + for (ServerPlayer player : this.level.players) { + // Paper start - per player mob spawning backoff @@ -140,7 +140,7 @@ index 9a65321ce62f21b150d29be30dbae7dba0ff40be..3bbaa9bdc7d49b456b5749e4880354c9 - NaturalSpawner.spawnForChunk(this.level, chunk, spawnState, spawnCategories); - } + // DivineMC start - Async mob spawning -+ if (!spawnCategories.isEmpty() && this.level.getWorldBorder().isWithinBounds(pos) && (!org.bxteam.divinemc.DivineConfig.enableAsyncSpawning || spawnCountsReady.get())) { // Paper - rewrite chunk system ++ if (!spawnCategories.isEmpty() && this.level.getWorldBorder().isWithinBounds(pos) && (!org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableAsyncSpawning || spawnCountsReady.get())) { // Paper - rewrite chunk system + NaturalSpawner.spawnForChunk(this.level, chunk, spawnState, spawnCategories); } + // DivineMC end - Async mob spawning diff --git a/divinemc-server/minecraft-patches/features/0042-Dynamic-Activation-of-Brain.patch b/divinemc-server/minecraft-patches/features/0042-Dynamic-Activation-of-Brain.patch index d74735b..8add89f 100644 --- a/divinemc-server/minecraft-patches/features/0042-Dynamic-Activation-of-Brain.patch +++ b/divinemc-server/minecraft-patches/features/0042-Dynamic-Activation-of-Brain.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Dynamic Activation of Brain diff --git a/io/papermc/paper/entity/activation/ActivationRange.java b/io/papermc/paper/entity/activation/ActivationRange.java -index 265f20fd771df850a0bb0029e699d3146d883837..a9326f1acc6ffe7fbacc34bf13f56d87e212027a 100644 +index 265f20fd771df850a0bb0029e699d3146d883837..62aaa45f512ed77e4901a2e703431594a32b615e 100644 --- a/io/papermc/paper/entity/activation/ActivationRange.java +++ b/io/papermc/paper/entity/activation/ActivationRange.java @@ -161,6 +161,21 @@ public final class ActivationRange { @@ -14,14 +14,14 @@ index 265f20fd771df850a0bb0029e699d3146d883837..a9326f1acc6ffe7fbacc34bf13f56d87 ActivationRange.activateEntity(entity); + + // DivineMC start - Dynamic Activation of Brain -+ if (org.bxteam.divinemc.DivineConfig.dabEnabled && entity.getType().dabEnabled && (!org.bxteam.divinemc.DivineConfig.dabDontEnableIfInWater || entity.getType().is(net.minecraft.tags.EntityTypeTags.CAN_BREATHE_UNDER_WATER) || !entity.isInWaterOrRain())) { ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.dabEnabled && entity.getType().dabEnabled && (!org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.dabDontEnableIfInWater || entity.getType().is(net.minecraft.tags.EntityTypeTags.CAN_BREATHE_UNDER_WATER) || !entity.isInWaterOrRain())) { + if (!entity.activatedPriorityReset) { + entity.activatedPriorityReset = true; -+ entity.activatedPriority = org.bxteam.divinemc.DivineConfig.dabMaximumActivationFrequency; ++ entity.activatedPriority = org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.dabMaximumActivationFrequency; + } + int squaredDistance = (int) player.distanceToSqr(entity); -+ entity.activatedPriority = squaredDistance > org.bxteam.divinemc.DivineConfig.dabStartDistanceSquared ? -+ Math.max(1, Math.min(squaredDistance >> org.bxteam.divinemc.DivineConfig.dabActivationDistanceMod, entity.activatedPriority)) : ++ entity.activatedPriority = squaredDistance > org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.dabStartDistanceSquared ? ++ Math.max(1, Math.min(squaredDistance >> org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.dabActivationDistanceMod, entity.activatedPriority)) : + 1; + } else { + entity.activatedPriority = 1; @@ -31,7 +31,7 @@ index 265f20fd771df850a0bb0029e699d3146d883837..a9326f1acc6ffe7fbacc34bf13f56d87 } } diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index d7ec2dd011a6728e7a1adb5a84f587904166df79..27ff3ae4400de969c95eb337cfd88f8137c77d3b 100644 +index 6f62f5751932a1007d63a77a28d07fbd51eaa798..4890db5bf0358d1d3bb1c7d3894339d4bdccfbaa 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -802,6 +802,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -43,7 +43,7 @@ index d7ec2dd011a6728e7a1adb5a84f587904166df79..27ff3ae4400de969c95eb337cfd88f81 if (!tickRateManager.isEntityFrozen(entity)) { entity.checkDespawn(); diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 0a23d54a6f03b1d776ab24922f88144762c90875..b98010d6d3d369c680ccc8f15da9574e4f6a139c 100644 +index d80f5b6039a4e49ddbf5598f68137e7c17b388c5..3b754db2db36d9e2398efe2f5286b70f20470c2c 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -344,6 +344,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -51,7 +51,7 @@ index 0a23d54a6f03b1d776ab24922f88144762c90875..b98010d6d3d369c680ccc8f15da9574e private final int despawnTime; // Paper - entity despawn time limit public int totalEntityAge; // Paper - age-like counter for all entities + public boolean activatedPriorityReset = false; // DivineMC - Dynamic Activation of Brain -+ public int activatedPriority = org.bxteam.divinemc.DivineConfig.dabMaximumActivationFrequency; // DivineMC - Dynamic Activation of Brain ++ public int activatedPriority = org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.dabMaximumActivationFrequency; // DivineMC - Dynamic Activation of Brain public final io.papermc.paper.entity.activation.ActivationType activationType = io.papermc.paper.entity.activation.ActivationType.activationTypeFor(this); // Paper - EAR 2/tracking ranges // Paper start - EAR 2 public final boolean defaultActivationState; @@ -68,7 +68,7 @@ index d6a0ad078fd1f0350afaac3f1743896d73b015e1..50bc352f4d918678a479a39b218973f7 @Nullable private Component description; diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java -index d618752727e2f2f5c0c1afa97f455e349cb7e76c..ed89fe2ccfb5ce3e8384a108243288f6e542bc1d 100644 +index a65c86b411c15bbdfd431dac00e510d2262e65e1..29624bff8655ec8ad6404a4b8438d845f68afc99 100644 --- a/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java @@ -206,10 +206,10 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab @@ -126,7 +126,7 @@ index f6c673b1abe53afcb14fd68d590431027ed29f67..1e5312e02298c63c168526a960d688dc } } diff --git a/net/minecraft/world/entity/ai/goal/GoalSelector.java b/net/minecraft/world/entity/ai/goal/GoalSelector.java -index b816b2de8eb327060ca6ea7c4afc17373fa77ff6..4eed0bd3670fdcb0a156c29e7db63233a47f539b 100644 +index b816b2de8eb327060ca6ea7c4afc17373fa77ff6..6d90235c35a78d1167181cbaa05c5e7644ff27a8 100644 --- a/net/minecraft/world/entity/ai/goal/GoalSelector.java +++ b/net/minecraft/world/entity/ai/goal/GoalSelector.java @@ -36,10 +36,14 @@ public class GoalSelector { @@ -136,7 +136,7 @@ index b816b2de8eb327060ca6ea7c4afc17373fa77ff6..4eed0bd3670fdcb0a156c29e7db63233 - public boolean inactiveTick() { + // DivineMC start - Dynamic Activation of Brain + public boolean inactiveTick(int tickRate, boolean inactive) { -+ if (inactive && !org.bxteam.divinemc.DivineConfig.dabEnabled) tickRate = 4; ++ if (inactive && !org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.dabEnabled) tickRate = 4; + tickRate = Math.min(tickRate, 3); this.curRate++; - return this.curRate % 3 == 0; // TODO newGoalRate was already unused in 1.20.4, check if this is correct @@ -210,7 +210,7 @@ index 0b787911c929f1564d859dcba1ee04510b4a9b7f..b3c09fe1a86f6a47448d4e71261ff346 public static AttributeSupplier.Builder createAttributes() { diff --git a/net/minecraft/world/entity/animal/frog/Frog.java b/net/minecraft/world/entity/animal/frog/Frog.java -index 3ccc48afb7a9eb2290f16c6a3218515bee59c2bd..617d47d61dd97fd1c7b56db71e47f4e334a4f491 100644 +index 433233f3fb346c15627cf0ad313ea55579826d86..e11c9aa9c7ba3ed3ecf4812679e23836d3187597 100644 --- a/net/minecraft/world/entity/animal/frog/Frog.java +++ b/net/minecraft/world/entity/animal/frog/Frog.java @@ -105,6 +105,7 @@ public class Frog extends Animal { @@ -340,7 +340,7 @@ index 0644f425cddebe8e5a65e69acae57db867380981..56fb3c23a265403a20cfab551aa00279 @Override diff --git a/net/minecraft/world/entity/monster/piglin/Piglin.java b/net/minecraft/world/entity/monster/piglin/Piglin.java -index 73049e486fbf8411819551b43e3ca641ed7a5578..acbbe69df488b085de44e7825e9713bdeb600308 100644 +index ce0dca4f8cd903037f6fe011d34a17d08ff5a907..23bf006b0698eed832a3ce28ec8dc8235792c9f6 100644 --- a/net/minecraft/world/entity/monster/piglin/Piglin.java +++ b/net/minecraft/world/entity/monster/piglin/Piglin.java @@ -128,6 +128,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento @@ -369,7 +369,7 @@ index 73049e486fbf8411819551b43e3ca641ed7a5578..acbbe69df488b085de44e7825e9713bd @Override diff --git a/net/minecraft/world/entity/monster/warden/Warden.java b/net/minecraft/world/entity/monster/warden/Warden.java -index 97ee07ebbba5ad29f766dff5eb4e51fc0e12cfcb..0898a7ea98b60edb31828d91afb92db44f63f85e 100644 +index 39b9dc1e78c1f9fc6a5ccad0de56cdb6d0781a05..db05fed2d0050796dfa32cbfc4206323252a30ca 100644 --- a/net/minecraft/world/entity/monster/warden/Warden.java +++ b/net/minecraft/world/entity/monster/warden/Warden.java @@ -110,6 +110,7 @@ public class Warden extends Monster implements VibrationSystem { @@ -414,7 +414,7 @@ index 97ee07ebbba5ad29f766dff5eb4e51fc0e12cfcb..0898a7ea98b60edb31828d91afb92db4 @Override diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java -index a08818450ed6fd78bb429743ee044726fc7994e7..abf7308a41e7c28e1d9fd82d5f86022a80159bff 100644 +index aace211c23ab9026792a77e5ed5c5eac4311f391..2e2745cd8e3383455656c95214779754cc890b33 100644 --- a/net/minecraft/world/entity/npc/Villager.java +++ b/net/minecraft/world/entity/npc/Villager.java @@ -178,6 +178,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler diff --git a/divinemc-server/minecraft-patches/features/0043-Parallel-world-ticking.patch b/divinemc-server/minecraft-patches/features/0043-Parallel-world-ticking.patch index 583ea4c..cd60328 100644 --- a/divinemc-server/minecraft-patches/features/0043-Parallel-world-ticking.patch +++ b/divinemc-server/minecraft-patches/features/0043-Parallel-world-ticking.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Parallel world ticking diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -index 60705955e231d47c60f5a0a5e869988aed8774fc..3106d183cc9fdb08b445838c7724799fbba55f7a 100644 +index 60705955e231d47c60f5a0a5e869988aed8774fc..c0322d4f9eadb26b8d5c6a3b426218ebb6302608 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 { @@ -13,7 +13,7 @@ index 60705955e231d47c60f5a0a5e869988aed8774fc..3106d183cc9fdb08b445838c7724799f return; } - if (!TickThread.isTickThread()) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && !TickThread.isTickThreadFor(world)) { // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && !TickThread.isTickThreadFor(world)) { // DivineMC - Parallel world ticking this.taskScheduler.scheduleChunkTask(() -> { final java.util.Deque pendingFullLoadUpdate = ChunkHolderManager.this.getData().pendingFullLoadUpdate; // DivineMC - Chunk System optimization for (int i = 0, len = changedFullStatus.size(); i < len; ++i) { @@ -23,7 +23,7 @@ index 60705955e231d47c60f5a0a5e869988aed8774fc..3106d183cc9fdb08b445838c7724799f public void processUnloads() { - TickThread.ensureTickThread("Cannot unload chunks off-main"); + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { + TickThread.ensureTickThread(world, "Cannot unload chunks off-main"); + } else { + TickThread.ensureTickThread("Cannot unload chunks off-main"); @@ -37,7 +37,7 @@ index 60705955e231d47c60f5a0a5e869988aed8774fc..3106d183cc9fdb08b445838c7724799f List changedFullStatus = null; - final boolean isTickThread = TickThread.isTickThread(); -+ final boolean isTickThread = org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && TickThread.isTickThreadFor(world) || TickThread.isTickThread(); // DivineMC - Parallel world ticking ++ final boolean isTickThread = org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && TickThread.isTickThreadFor(world) || TickThread.isTickThread(); // DivineMC - Parallel world ticking boolean ret = false; final boolean canProcessFullUpdates = processFullUpdates & isTickThread; @@ -59,7 +59,7 @@ index ac27ff24f018d8798921c5152e679ceed1e88d8d..ec7d1353b19e55b00c558df8981323ef 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 172c69d577e53354fd4f37702d395e8f61754336..ef2cf6d9ca57266bb0466ca1aa5d2066349f9954 100644 +index b5103e14f25f4cf92438214f2fc3ada552dce742..bc157a799b03ac0e797a6980c43f19bf4fb3f09c 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -290,6 +290,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Purpur - Ridables -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { + serverLevelTickingSemaphore.acquire(); + tasks.add( + serverLevel.tickExecutor.submit(() -> { @@ -205,12 +205,12 @@ index 172c69d577e53354fd4f37702d395e8f61754336..ef2cf6d9ca57266bb0466ca1aa5d2066 Map, ServerLevel> oldLevels = this.levels; Map, ServerLevel> newLevels = Maps.newLinkedHashMap(oldLevels); newLevels.remove(level.dimension()); -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) level.tickExecutor.shutdown(); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) level.tickExecutor.shutdown(); // DivineMC - Parallel world ticking this.levels = Collections.unmodifiableMap(newLevels); } // CraftBukkit end diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java -index 3f9b26de801b2d8e85c56d219ca7bd61c41b3f9d..8fa8cd1a06c86c8424d43b588ff13a917865e80e 100644 +index b65c8e393249b0fc731e02262d58873cb38942b8..48033df6b384a21a59e8051e7d1f880e1af3c78c 100644 --- a/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java @@ -224,6 +224,13 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -218,8 +218,8 @@ index 3f9b26de801b2d8e85c56d219ca7bd61c41b3f9d..8fa8cd1a06c86c8424d43b588ff13a91 // DivineMC end - Pufferfish SIMD + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { -+ serverLevelTickingSemaphore = new java.util.concurrent.Semaphore(org.bxteam.divinemc.DivineConfig.parallelThreadCount); ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { ++ serverLevelTickingSemaphore = new java.util.concurrent.Semaphore(org.bxteam.divinemc.config.DivineConfig.AsyncCategory.parallelThreadCount); + DedicatedServer.LOGGER.info("Using {} permits for Parallel world ticking", serverLevelTickingSemaphore.availablePermits()); + } + // DivineMC end - Parallel world ticking @@ -228,7 +228,7 @@ index 3f9b26de801b2d8e85c56d219ca7bd61c41b3f9d..8fa8cd1a06c86c8424d43b588ff13a91 this.setFlightAllowed(properties.allowFlight); this.setMotd(properties.motd); diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 9db7c44f4d5985460510e11aa7060109ed51481a..b609361d4ff1d42d3ac40411013de767ad8665d7 100644 +index 4890db5bf0358d1d3bb1c7d3894339d4bdccfbaa..a14b3c918f9d8021c5f1758fcb38572e71873e8e 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -179,7 +179,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -265,7 +265,7 @@ index 9db7c44f4d5985460510e11aa7060109ed51481a..b609361d4ff1d42d3ac40411013de767 - ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks(); + // DivineMC start - Parallel world ticking + ++this.tickedBlocksOrFluids; -+ if (!org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && (this.tickedBlocksOrFluids & 7L) != 0L) { ++ if (!org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && (this.tickedBlocksOrFluids & 7L) != 0L) { + this.server.moonrise$executeMidTickTasks(); } - // Paper end - rewrite chunk system @@ -283,7 +283,7 @@ index 9db7c44f4d5985460510e11aa7060109ed51481a..b609361d4ff1d42d3ac40411013de767 - ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks(); + // DivineMC start - Parallel world ticking + ++this.tickedBlocksOrFluids; -+ if (!org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && (this.tickedBlocksOrFluids & 7L) != 0L) { ++ if (!org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && (this.tickedBlocksOrFluids & 7L) != 0L) { + this.server.moonrise$executeMidTickTasks(); } - // Paper end - rewrite chunk system @@ -296,7 +296,7 @@ index 9db7c44f4d5985460510e11aa7060109ed51481a..b609361d4ff1d42d3ac40411013de767 } private void addPlayer(ServerPlayer player) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this, "Cannot add player off-main"); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this, "Cannot add player off-main"); // DivineMC - Parallel world ticking Entity entity = this.getEntity(player.getUUID()); if (entity != null) { LOGGER.warn("Force-added player with duplicate UUID {}", player.getUUID()); @@ -306,7 +306,7 @@ index 9db7c44f4d5985460510e11aa7060109ed51481a..b609361d4ff1d42d3ac40411013de767 private boolean addEntity(Entity entity, @Nullable org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { - org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this, "Cannot add entity off-main"); + } else { + org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot @@ -316,7 +316,7 @@ index 9db7c44f4d5985460510e11aa7060109ed51481a..b609361d4ff1d42d3ac40411013de767 // Paper start - extra debug info if (entity.valid) { diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index fa9bbf447b32e27a8714950215b36233712a025d..56c10c0537f6ca48cb4bc0e426cbba3bddc7a98a 100644 +index fa9bbf447b32e27a8714950215b36233712a025d..381b2608bb4989c2888ef8338e8fac1758be9f60 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java @@ -452,6 +452,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc @@ -339,7 +339,7 @@ index fa9bbf447b32e27a8714950215b36233712a025d..56c10c0537f6ca48cb4bc0e426cbba3b return this; } else { // CraftBukkit start -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureOnlyTickThread("Cannot change dimension of a player off-main, from world " + serverLevel().getWorld().getName() + " to world " + level.getWorld().getName()); // DivineMC - Parallel world ticking (additional concurrency issues logs) ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureOnlyTickThread("Cannot change dimension of a player off-main, from world " + serverLevel().getWorld().getName() + " to world " + level.getWorld().getName()); // DivineMC - Parallel world ticking (additional concurrency issues logs) /* this.isChangingDimension = true; LevelData levelData = level.getLevelData(); @@ -348,7 +348,7 @@ index fa9bbf447b32e27a8714950215b36233712a025d..56c10c0537f6ca48cb4bc0e426cbba3b } else { // CraftBukkit start + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && !hasTickedAtLeastOnceInNewWorld) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && !hasTickedAtLeastOnceInNewWorld) { + MinecraftServer.LOGGER.warn("Ignoring request to open container {} because we haven't ticked in the current world yet!", abstractContainerMenu, new Throwable()); + return OptionalInt.empty(); + } @@ -361,7 +361,7 @@ index fa9bbf447b32e27a8714950215b36233712a025d..56c10c0537f6ca48cb4bc0e426cbba3b @Override public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) { + // DivineMC start - Parallel world ticking (debugging) -+ if (org.bxteam.divinemc.DivineConfig.logContainerCreationStacktraces) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.logContainerCreationStacktraces) { + MinecraftServer.LOGGER.warn("Closing {} inventory that was created at", this.getBukkitEntity().getName(), this.containerMenu.containerCreationStacktrace); + } + // DivineMC end - Parallel world ticking (debugging) @@ -369,14 +369,14 @@ index fa9bbf447b32e27a8714950215b36233712a025d..56c10c0537f6ca48cb4bc0e426cbba3b // Paper end - Inventory close reason this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId)); diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index 9f3afab438199dbaf40fa1a64b6ecdae74c0a34d..8923a30daf515262e4bdbfbd55e3cb827092979c 100644 +index 21ea5de6bf2d034d63dab1d7c563b63b3e713521..1b9db93ef1ee47200c5cc01caf55821b08e6a695 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java @@ -150,6 +150,7 @@ public abstract class PlayerList { abstract public void loadAndSaveFiles(); // Paper - fix converting txt to json file; moved from DedicatedPlayerList constructor public void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie cookie) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureOnlyTickThread("Cannot place new player off-main"); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureOnlyTickThread("Cannot place new player off-main"); // DivineMC - Parallel world ticking player.isRealPlayer = true; // Paper player.loginTime = System.currentTimeMillis(); // Paper - Replace OfflinePlayer#getLastPlayed GameProfile gameProfile = player.getGameProfile(); @@ -385,7 +385,7 @@ index 9f3afab438199dbaf40fa1a64b6ecdae74c0a34d..8923a30daf515262e4bdbfbd55e3cb82 public ServerPlayer respawn(ServerPlayer player, boolean keepInventory, Entity.RemovalReason reason, @Nullable org.bukkit.event.player.PlayerRespawnEvent.RespawnReason eventReason, @Nullable org.bukkit.Location location) { + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { + if (location != null) + ca.spottedleaf.moonrise.common.util.TickThread.ensureOnlyTickThread("Cannot respawn player off-main, from world " + player.serverLevel().getWorld().getName() + " to world " + location.getWorld().getName()); + else @@ -404,7 +404,7 @@ index 9f3afab438199dbaf40fa1a64b6ecdae74c0a34d..8923a30daf515262e4bdbfbd55e3cb82 serverPlayer.connection = player.connection; serverPlayer.restoreFrom(player, keepInventory); diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index abcaa8a1f9daf4557bb24e2161e9afa01f0b7211..a1d92ad83f47bec3e07e6603103e423620a0b84c 100644 +index 3b754db2db36d9e2398efe2f5286b70f20470c2c..a458e858e70e10f9ae0f952ab85f01e4b481081e 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -3243,14 +3243,34 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -438,7 +438,7 @@ index abcaa8a1f9daf4557bb24e2161e9afa01f0b7211..a1d92ad83f47bec3e07e6603103e4236 + entity.portalProcess.confirmParallelAsHandled(); + }; + -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { + this.portalProcess.setParallelAsScheduled(); + this.getBukkitEntity().taskScheduler.schedule(portalEntityTask, entity -> {}, 0); + } else { @@ -452,12 +452,12 @@ index abcaa8a1f9daf4557bb24e2161e9afa01f0b7211..a1d92ad83f47bec3e07e6603103e4236 } private Entity teleportCrossDimension(ServerLevel level, TeleportTransition teleportTransition) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(level, "Cannot teleport entity to another world off-main, from world " + this.level.getWorld().getName() + " to world " + level.getWorld().getName()); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(level, "Cannot teleport entity to another world off-main, from world " + this.level.getWorld().getName() + " to world " + level.getWorld().getName()); // DivineMC - Parallel world ticking List passengers = this.getPassengers(); List list = new ArrayList<>(passengers.size()); this.ejectPassengers(); diff --git a/net/minecraft/world/entity/PortalProcessor.java b/net/minecraft/world/entity/PortalProcessor.java -index d2661ea79536010414f77256332f214d19106dd9..f77da420bc88df6ec304086fc1eba0690fe278b1 100644 +index 91f6d43b3785ddad7db8eb529ba3293c45f3588d..fc3ab0881bf9b275beb9b32ca5a7475d50789401 100644 --- a/net/minecraft/world/entity/PortalProcessor.java +++ b/net/minecraft/world/entity/PortalProcessor.java @@ -11,6 +11,7 @@ public class PortalProcessor { @@ -517,7 +517,7 @@ index d2661ea79536010414f77256332f214d19106dd9..f77da420bc88df6ec304086fc1eba069 + // DivineMC end - Parallel world ticking } diff --git a/net/minecraft/world/entity/ai/behavior/GoToPotentialJobSite.java b/net/minecraft/world/entity/ai/behavior/GoToPotentialJobSite.java -index 3614551856c594f3c0cfee984fcf03fad672b007..6add256046e392d8eb797e3fa9d1cbe7cca575df 100644 +index 3614551856c594f3c0cfee984fcf03fad672b007..ad52152d090c32b81044b8fd9496eae0b4e755b0 100644 --- a/net/minecraft/world/entity/ai/behavior/GoToPotentialJobSite.java +++ b/net/minecraft/world/entity/ai/behavior/GoToPotentialJobSite.java @@ -46,12 +46,22 @@ public class GoToPotentialJobSite extends Behavior { @@ -539,7 +539,7 @@ index 3614551856c594f3c0cfee984fcf03fad672b007..6add256046e392d8eb797e3fa9d1cbe7 + }; - DebugPackets.sendPoiTicketCountPacket(level, blockPos); -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { + level.moonrise$getChunkTaskScheduler().scheduleChunkTask(0, 0, releasePoiTask, ca.spottedleaf.concurrentutil.util.Priority.BLOCKING); + } else { + releasePoiTask.run(); @@ -549,7 +549,7 @@ index 3614551856c594f3c0cfee984fcf03fad672b007..6add256046e392d8eb797e3fa9d1cbe7 }); entity.getBrain().eraseMemory(MemoryModuleType.POTENTIAL_JOB_SITE); diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java -index 2e2745cd8e3383455656c95214779754cc890b33..c2796f90e4e9c57244d41ea6cbe8d1b87432ba88 100644 +index 2e2745cd8e3383455656c95214779754cc890b33..69e9d7b68cae66c65906e6db4facfe7f408375c1 100644 --- a/net/minecraft/world/entity/npc/Villager.java +++ b/net/minecraft/world/entity/npc/Villager.java @@ -795,13 +795,24 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @@ -573,7 +573,7 @@ index 2e2745cd8e3383455656c95214779754cc890b33..c2796f90e4e9c57244d41ea6cbe8d1b8 + } + }; + -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { + level.moonrise$getChunkTaskScheduler().scheduleChunkTask(0, 0, releasePoiTask, ca.spottedleaf.concurrentutil.util.Priority.BLOCKING); + } + else { @@ -584,7 +584,7 @@ index 2e2745cd8e3383455656c95214779754cc890b33..c2796f90e4e9c57244d41ea6cbe8d1b8 }); } diff --git a/net/minecraft/world/entity/projectile/ThrownEnderpearl.java b/net/minecraft/world/entity/projectile/ThrownEnderpearl.java -index 6575e8ef16f6011f7a799ba31531a2ebefee0c4d..407f00af5aac495eb116e4cf8a05fcc66c7331b1 100644 +index 6575e8ef16f6011f7a799ba31531a2ebefee0c4d..48076c0fd956141724ef30f6dd7136858b657863 100644 --- a/net/minecraft/world/entity/projectile/ThrownEnderpearl.java +++ b/net/minecraft/world/entity/projectile/ThrownEnderpearl.java @@ -122,40 +122,50 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { @@ -659,7 +659,7 @@ index 6575e8ef16f6011f7a799ba31531a2ebefee0c4d..407f00af5aac495eb116e4cf8a05fcc6 + this.playSound(serverLevel, vec3); + }; + -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { + serverPlayer.getBukkitEntity().taskScheduler.schedule(teleportPlayerCrossDimensionTask, entity -> {}, 0); + } else { + teleportPlayerCrossDimensionTask.accept(serverPlayer); @@ -669,7 +669,7 @@ index 6575e8ef16f6011f7a799ba31531a2ebefee0c4d..407f00af5aac495eb116e4cf8a05fcc6 } else { Entity entity = owner.teleport( diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java -index c4721eb0efe34f5e313bc890b4e960144eca4fe1..5965d2844713072d81a16a64a047a4907ba2b016 100644 +index c4721eb0efe34f5e313bc890b4e960144eca4fe1..804b7666ccb64e6b8d7fa19afd376f42f0475272 100644 --- a/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/net/minecraft/world/inventory/AbstractContainerMenu.java @@ -96,8 +96,14 @@ public abstract class AbstractContainerMenu { @@ -680,7 +680,7 @@ index c4721eb0efe34f5e313bc890b4e960144eca4fe1..5965d2844713072d81a16a64a047a490 protected AbstractContainerMenu(@Nullable MenuType menuType, int containerId) { + // DivineMC start - Parallel world ticking (debugging) -+ if (org.bxteam.divinemc.DivineConfig.logContainerCreationStacktraces) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.logContainerCreationStacktraces) { + this.containerCreationStacktrace = new Throwable(); + } + // DivineMC start - Parallel world ticking (debugging) @@ -705,13 +705,13 @@ index 36677cb0db42b74fa84d67b85717f629f84b4dd0..f329ad90e08bbb4fd3c4c804d6894f1a 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 3e6874f9e9a24e21f6fbfb0852d63fa6f4f4d603..5ebdd5d2b49f2165c8fbbee5e7615cc2398bea75 100644 +index 20d2368d22ee32fbcf6e433282b0567abd36cad9..5f281360ee07fffa709f920958ee72abe1c53f9c 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -160,6 +160,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl public final org.purpurmc.purpur.PurpurWorldConfig purpurConfig; // Purpur - Purpur config files - public final org.bxteam.divinemc.DivineWorldConfig divineConfig; // DivineMC - Configuration + public 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 private int tileTickPosition; @@ -720,7 +720,7 @@ index 3e6874f9e9a24e21f6fbfb0852d63fa6f4f4d603..5ebdd5d2b49f2165c8fbbee5e7615cc2 @Override public boolean setBlock(BlockPos pos, BlockState state, int flags, int recursionLeft) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel)this, pos, "Updating block asynchronously"); // DivineMC - Parallel world ticking (additional concurrency issues logs) ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel)this, pos, "Updating block asynchronously"); // DivineMC - Parallel world ticking (additional concurrency issues logs) // CraftBukkit start - tree generation if (this.captureTreeGeneration) { // Paper start - Protect Bedrock and End Portal/Frames from being destroyed @@ -733,7 +733,7 @@ index 3e6874f9e9a24e21f6fbfb0852d63fa6f4f4d603..5ebdd5d2b49f2165c8fbbee5e7615cc2 - ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)(Level)(Object)this).moonrise$midTickTasks(); + // DivineMC start - Parallel world ticking + ++tickedEntities; -+ if (!org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && (tickedEntities & 7) == 0) { ++ if (!org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && (tickedEntities & 7) == 0) { + this.moonrise$midTickTasks(); } - // Paper end - rewrite chunk system @@ -747,7 +747,7 @@ index 3e6874f9e9a24e21f6fbfb0852d63fa6f4f4d603..5ebdd5d2b49f2165c8fbbee5e7615cc2 } - this.moonrise$midTickTasks(); // Paper - rewrite chunk system + // DivineMC start - Parallel world ticking -+ if (!org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { ++ if (!org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { + this.moonrise$midTickTasks(); // Paper - rewrite chunk system + } + // DivineMC end - Parallel world ticking @@ -758,7 +758,7 @@ index 3e6874f9e9a24e21f6fbfb0852d63fa6f4f4d603..5ebdd5d2b49f2165c8fbbee5e7615cc2 @Nullable public BlockEntity getBlockEntity(BlockPos pos, boolean validate) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThreadOrAsyncThread((ServerLevel) this, "Cannot read world asynchronously"); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThreadOrAsyncThread((ServerLevel) this, "Cannot read world asynchronously"); // DivineMC - Parallel world ticking // Paper start - Perf: Optimize capturedTileEntities lookup net.minecraft.world.level.block.entity.BlockEntity blockEntity; if (!this.capturedTileEntities.isEmpty() && (blockEntity = this.capturedTileEntities.get(pos)) != null) { @@ -766,7 +766,7 @@ index 3e6874f9e9a24e21f6fbfb0852d63fa6f4f4d603..5ebdd5d2b49f2165c8fbbee5e7615cc2 } public void setBlockEntity(BlockEntity blockEntity) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel) this, "Cannot modify world asynchronously"); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel) this, "Cannot modify world asynchronously"); // DivineMC - Parallel world ticking BlockPos blockPos = blockEntity.getBlockPos(); if (!this.isOutsideBuildHeight(blockPos)) { // CraftBukkit start @@ -774,7 +774,7 @@ index 3e6874f9e9a24e21f6fbfb0852d63fa6f4f4d603..5ebdd5d2b49f2165c8fbbee5e7615cc2 @Override public List getEntities(@Nullable Entity entity, AABB boundingBox, Predicate predicate) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel)this, boundingBox, "Cannot getEntities asynchronously"); // DivineMC - Parallel world ticking (additional concurrency issues logs) ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel)this, boundingBox, "Cannot getEntities asynchronously"); // DivineMC - Parallel world ticking (additional concurrency issues logs) List list = Lists.newArrayList(); // Paper start - rewrite chunk system @@ -786,7 +786,7 @@ index 3e6874f9e9a24e21f6fbfb0852d63fa6f4f4d603..5ebdd5d2b49f2165c8fbbee5e7615cc2 - int i = this.randValue >> 2; + // DivineMC start - Parallel world ticking + int i; -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { + i = this.random.nextInt() >> 2; + } else { + this.randValue = this.randValue * 3 + 1013904223; @@ -826,7 +826,7 @@ index d306f5f524dc64618df94c9783c2168dc561a5e3..6a0c4dc2ff5e3d82e811db63dc9da7b9 return true; } else { diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java -index 1943a6aad888647953e2d9dbbeedb0bd81c6f9df..9b564348b24444c4cf717907bc92b8ea7cf40ffe 100644 +index 1943a6aad888647953e2d9dbbeedb0bd81c6f9df..9585d3164eaa7522be950fe10d8487dcc88e0f0b 100644 --- a/net/minecraft/world/level/block/RedStoneWireBlock.java +++ b/net/minecraft/world/level/block/RedStoneWireBlock.java @@ -283,7 +283,13 @@ public class RedStoneWireBlock extends Block { @@ -835,7 +835,7 @@ index 1943a6aad888647953e2d9dbbeedb0bd81c6f9df..9b564348b24444c4cf717907bc92b8ea } - turbo.updateSurroundingRedstone(worldIn, pos, state, source); + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { + worldIn.turbo.updateSurroundingRedstone(worldIn, pos, state, source); + } else { + turbo.updateSurroundingRedstone(worldIn, pos, state, source); @@ -850,7 +850,7 @@ index 1943a6aad888647953e2d9dbbeedb0bd81c6f9df..9b564348b24444c4cf717907bc92b8ea if (level.setBlock(pos, state, Block.UPDATE_KNOWN_SHAPE | Block.UPDATE_CLIENTS)) { - turbo.updateNeighborShapes(level, pos, state); + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { + level.turbo.updateNeighborShapes(level, pos, state); + } else { + turbo.updateNeighborShapes(level, pos, state); @@ -860,7 +860,7 @@ index 1943a6aad888647953e2d9dbbeedb0bd81c6f9df..9b564348b24444c4cf717907bc92b8ea } } diff --git a/net/minecraft/world/level/block/SaplingBlock.java b/net/minecraft/world/level/block/SaplingBlock.java -index a22cb810622e0ae97bc2a0d6390d026d9482b783..8ccc1dafdd035477ecbfcbed4cf9a9c503820ce3 100644 +index a22cb810622e0ae97bc2a0d6390d026d9482b783..5856178e41523700ca7ed9a46c1c802c33903b53 100644 --- a/net/minecraft/world/level/block/SaplingBlock.java +++ b/net/minecraft/world/level/block/SaplingBlock.java @@ -26,6 +26,26 @@ public class SaplingBlock extends VegetationBlock implements BonemealableBlock { @@ -872,7 +872,7 @@ index a22cb810622e0ae97bc2a0d6390d026d9482b783..8ccc1dafdd035477ecbfcbed4cf9a9c5 + + public static org.bukkit.TreeType getTreeTypeTL() { + org.bukkit.TreeType treeTypeRTCopy; -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && (treeTypeRTCopy = treeTypeTL.get()) != null) return treeTypeRTCopy; ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && (treeTypeRTCopy = treeTypeTL.get()) != null) return treeTypeRTCopy; + + synchronized (SaplingBlock.class) { + return treeType; @@ -880,7 +880,7 @@ index a22cb810622e0ae97bc2a0d6390d026d9482b783..8ccc1dafdd035477ecbfcbed4cf9a9c5 + } + + public static void setTreeTypeTL(org.bukkit.TreeType value) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) treeTypeTL.set(value); ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) treeTypeTL.set(value); + + synchronized (SaplingBlock.class) { + treeType = value; @@ -912,7 +912,7 @@ index a22cb810622e0ae97bc2a0d6390d026d9482b783..8ccc1dafdd035477ecbfcbed4cf9a9c5 } if (event == null || !event.isCancelled()) { diff --git a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java -index c63370fd458fb4f7190b79b1a8174fcc92d88f9c..6af22d8c1a244b7540cad18c6c9da8f939d8d81a 100644 +index c63370fd458fb4f7190b79b1a8174fcc92d88f9c..9076d8ea09920f08d70610724d4ca1b8da580db4 100644 --- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java @@ -79,6 +79,12 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co @@ -920,7 +920,7 @@ index c63370fd458fb4f7190b79b1a8174fcc92d88f9c..6af22d8c1a244b7540cad18c6c9da8f9 public static boolean canUnlock(Player player, LockCode code, Component displayName, @Nullable BlockEntity blockEntity) { + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && player instanceof net.minecraft.server.level.ServerPlayer serverPlayer && blockEntity != null && blockEntity.getLevel() != serverPlayer.serverLevel()) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && player instanceof net.minecraft.server.level.ServerPlayer serverPlayer && blockEntity != null && blockEntity.getLevel() != serverPlayer.serverLevel()) { + net.minecraft.server.MinecraftServer.LOGGER.warn("Player {} ({}) attempted to open a BlockEntity @ {} {}, {}, {} while they were in a different world {} than the block themselves!", serverPlayer.getScoreboardName(), serverPlayer.getStringUUID(), blockEntity.getLevel().getWorld().getName(), blockEntity.getBlockPos().getX(), blockEntity.getBlockPos().getY(), blockEntity.getBlockPos().getZ(), serverPlayer.level().getWorld().getName()); + return false; + } @@ -1030,19 +1030,19 @@ index d23f255de9208f42125fa358a9e8194c984fe4d3..92e9bc9ba577474ca1108b8d06157395 // CraftBukkit end } diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index d2eed7a0cf0c2c9dbcfb272cf89194f11d37151c..b5d74a13e6311732b9cb67f23844e64de31d9cac 100644 +index c7c984f1380f9386634f88d98fdde11e623a2d7d..2c7019bc22d217dea184bc2472c4e8ab9a069a32 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java @@ -363,6 +363,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p @Nullable @Override public BlockState setBlockState(BlockPos pos, BlockState state, int flags) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.level, pos, "Updating block asynchronously"); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.level, pos, "Updating block asynchronously"); // DivineMC - Parallel world ticking int y = pos.getY(); LevelChunkSection section = this.getSection(this.getSectionIndex(y)); boolean hasOnlyAir = section.hasOnlyAir(); diff --git a/net/minecraft/world/level/entity/EntityTickList.java b/net/minecraft/world/level/entity/EntityTickList.java -index 9e75320e51886e0f93c23683d8614128f44a613e..86c7e5a469fbd276ebbf5aee1b72531d444d6359 100644 +index 9e75320e51886e0f93c23683d8614128f44a613e..df8ede5c6d1f1af275f813d4b939136134214dff 100644 --- a/net/minecraft/world/level/entity/EntityTickList.java +++ b/net/minecraft/world/level/entity/EntityTickList.java @@ -10,17 +10,26 @@ import net.minecraft.world.entity.Entity; @@ -1062,13 +1062,13 @@ index 9e75320e51886e0f93c23683d8614128f44a613e..86c7e5a469fbd276ebbf5aee1b72531d } public void add(Entity entity) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(entity, "Asynchronous entity ticklist addition"); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(entity, "Asynchronous entity ticklist addition"); // DivineMC - Parallel world ticking this.ensureActiveIsNotIterated(); this.entities.add(entity); // Paper - rewrite chunk system } public void remove(Entity entity) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(entity, "Asynchronous entity ticklist removal"); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(entity, "Asynchronous entity ticklist removal"); // DivineMC - Parallel world ticking this.ensureActiveIsNotIterated(); this.entities.remove(entity); // Paper - rewrite chunk system } @@ -1076,7 +1076,7 @@ index 9e75320e51886e0f93c23683d8614128f44a613e..86c7e5a469fbd276ebbf5aee1b72531d } public void forEach(Consumer entity) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverLevel, "Asynchronous entity ticklist iteration"); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverLevel, "Asynchronous entity ticklist iteration"); // DivineMC - Parallel world ticking // Paper start - rewrite chunk system // To ensure nothing weird happens with dimension travelling, do not iterate over new entries... // (by dfl iterator() is configured to not iterate over new entries) diff --git a/divinemc-server/minecraft-patches/features/0045-Catch-update-suppressors.patch b/divinemc-server/minecraft-patches/features/0045-Catch-update-suppressors.patch index ef05dff..5e6bf19 100644 --- a/divinemc-server/minecraft-patches/features/0045-Catch-update-suppressors.patch +++ b/divinemc-server/minecraft-patches/features/0045-Catch-update-suppressors.patch @@ -20,7 +20,7 @@ index e65c62dbe4c1560ae153e4c4344e9194c783a2f4..e3d3b062e273fee4a9d3ba3cadc21278 if (var4 instanceof ReportedException reportedException && reportedException.getCause() instanceof OutOfMemoryError) { throw makeReportedException(var4, packet, processor); diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index c4ae883af4337e04d0944c603f298ee1576cb3d2..3a82ce898c38c5d3d971178e2614aed638e03132 100644 +index e2d30a5be27719203b3653c383fc217a0646570d..4db732950b851239de36dc7739f3607452c1db4c 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -1683,6 +1683,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop this.aquifer.computeSubstance(context, densityFunction.compute(context))); if (noiseGeneratorSettings.oreVeinsEnabled()) { list.add(OreVeinifier.create(noiseRouter1.veinToggle(), noiseRouter1.veinRidged(), noiseRouter1.veinGap(), random.oreRandom())); @@ -479,12 +479,12 @@ index 977b0d595e5637c80e7d4bb20da8896a0b64b844..991025da1005d6c4122897231095dc90 - noiseRouter.depth().mapAll(this::wrap), - noiseRouter.ridges().mapAll(this::wrap), + // DivineMC start - Density Function Compiler -+ noiseRouter.temperature().mapAll(org.bxteam.divinemc.DivineConfig.enableDensityFunctionCompiler ? modifyVisitor2(this::wrap) : this::wrap), -+ noiseRouter.vegetation().mapAll(org.bxteam.divinemc.DivineConfig.enableDensityFunctionCompiler ? modifyVisitor2(this::wrap) : this::wrap), -+ noiseRouter.continents().mapAll(org.bxteam.divinemc.DivineConfig.enableDensityFunctionCompiler ? modifyVisitor2(this::wrap) : this::wrap), -+ noiseRouter.erosion().mapAll(org.bxteam.divinemc.DivineConfig.enableDensityFunctionCompiler ? modifyVisitor2(this::wrap) : this::wrap), -+ noiseRouter.depth().mapAll(org.bxteam.divinemc.DivineConfig.enableDensityFunctionCompiler ? modifyVisitor2(this::wrap) : this::wrap), -+ noiseRouter.ridges().mapAll(org.bxteam.divinemc.DivineConfig.enableDensityFunctionCompiler ? modifyVisitor2(this::wrap) : this::wrap), ++ noiseRouter.temperature().mapAll(org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableDensityFunctionCompiler ? modifyVisitor2(this::wrap) : this::wrap), ++ noiseRouter.vegetation().mapAll(org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableDensityFunctionCompiler ? modifyVisitor2(this::wrap) : this::wrap), ++ noiseRouter.continents().mapAll(org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableDensityFunctionCompiler ? modifyVisitor2(this::wrap) : this::wrap), ++ noiseRouter.erosion().mapAll(org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableDensityFunctionCompiler ? modifyVisitor2(this::wrap) : this::wrap), ++ noiseRouter.depth().mapAll(org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableDensityFunctionCompiler ? modifyVisitor2(this::wrap) : this::wrap), ++ noiseRouter.ridges().mapAll(org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableDensityFunctionCompiler ? modifyVisitor2(this::wrap) : this::wrap), + // DivineMC end - Density Function Compiler points ); @@ -494,7 +494,7 @@ index 977b0d595e5637c80e7d4bb20da8896a0b64b844..991025da1005d6c4122897231095dc90 private DensityFunction wrapNew(DensityFunction densityFunction) { + // DivineMC start - Density Function Compiler -+ if (org.bxteam.divinemc.DivineConfig.enableDensityFunctionCompiler) { ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableDensityFunctionCompiler) { + if (this.interpolating && densityFunction instanceof DensityFunctions.Marker) { + throw new IllegalStateException("Cannot create more wrapping during interpolation loop"); + } @@ -677,7 +677,7 @@ index 977b0d595e5637c80e7d4bb20da8896a0b64b844..991025da1005d6c4122897231095dc90 + : this.noiseFiller.compute(context); + } + }; -+ if (!org.bxteam.divinemc.DivineConfig.enableDensityFunctionCompiler || context instanceof NoiseChunk) { ++ if (!org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableDensityFunctionCompiler || context instanceof NoiseChunk) { + return run.get(); + } + if (context instanceof NoisePosVanillaInterface vif && vif.getType() == EvalType.INTERPOLATION) { @@ -826,7 +826,7 @@ index 977b0d595e5637c80e7d4bb20da8896a0b64b844..991025da1005d6c4122897231095dc90 + return d; + } + }; -+ if (!org.bxteam.divinemc.DivineConfig.enableDensityFunctionCompiler || context instanceof NoiseChunk) { ++ if (!org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableDensityFunctionCompiler || context instanceof NoiseChunk) { + return run.get(); } + int blockX = context.blockX(); @@ -878,7 +878,7 @@ index 977b0d595e5637c80e7d4bb20da8896a0b64b844..991025da1005d6c4122897231095dc90 + this.lastArrayCounter = NoiseChunk.this.arrayInterpolationCounter; + } + }; -+ if (!org.bxteam.divinemc.DivineConfig.enableDensityFunctionCompiler || contextProvider instanceof NoiseChunk) { ++ if (!org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableDensityFunctionCompiler || contextProvider instanceof NoiseChunk) { + run.run(); + return; + } @@ -1115,7 +1115,7 @@ index 977b0d595e5637c80e7d4bb20da8896a0b64b844..991025da1005d6c4122897231095dc90 + : this.value; + } + }; -+ if (!org.bxteam.divinemc.DivineConfig.enableDensityFunctionCompiler || context instanceof NoiseChunk) { ++ if (!org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableDensityFunctionCompiler || context instanceof NoiseChunk) { + return original.get(); } + if (context instanceof NoisePosVanillaInterface vif && vif.getType() == EvalType.INTERPOLATION) { @@ -1155,7 +1155,7 @@ index 977b0d595e5637c80e7d4bb20da8896a0b64b844..991025da1005d6c4122897231095dc90 @Override diff --git a/net/minecraft/world/level/levelgen/RandomState.java b/net/minecraft/world/level/levelgen/RandomState.java -index f1e089ecfffa40cd794c49db30fcedf138d3fee9..4e98103b35b03cd67ab9b4bdb91c39a9c94312df 100644 +index f1e089ecfffa40cd794c49db30fcedf138d3fee9..b28221ca337ce8d76bbccdd736a4c5b2c7cd08da 100644 --- a/net/minecraft/world/level/levelgen/RandomState.java +++ b/net/minecraft/world/level/levelgen/RandomState.java @@ -122,6 +122,41 @@ public final class RandomState { @@ -1164,7 +1164,7 @@ index f1e089ecfffa40cd794c49db30fcedf138d3fee9..4e98103b35b03cd67ab9b4bdb91c39a9 ); + + // DivineMC start - Density Function Compiler -+ if (org.bxteam.divinemc.DivineConfig.enableDensityFunctionCompiler) { ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableDensityFunctionCompiler) { + com.google.common.base.Stopwatch stopwatch = com.google.common.base.Stopwatch.createStarted(); + it.unimi.dsi.fastutil.objects.Reference2ReferenceMap tempCache = new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(); + this.router = new NoiseRouter( diff --git a/divinemc-server/minecraft-patches/features/0051-Clump-experience-orbs.patch b/divinemc-server/minecraft-patches/features/0051-Clump-experience-orbs.patch index 0c45b1b..bebcdc7 100644 --- a/divinemc-server/minecraft-patches/features/0051-Clump-experience-orbs.patch +++ b/divinemc-server/minecraft-patches/features/0051-Clump-experience-orbs.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Clump experience orbs diff --git a/net/minecraft/world/entity/ExperienceOrb.java b/net/minecraft/world/entity/ExperienceOrb.java -index ff4648b3be103446ab401d36c14cc80b48840cab..18ccbb1344875dd7a2f2f8084102d341b2a9597e 100644 +index ff4648b3be103446ab401d36c14cc80b48840cab..22c42908551baf8bb91ebc8767e0a83517eceec1 100644 --- a/net/minecraft/world/entity/ExperienceOrb.java +++ b/net/minecraft/world/entity/ExperienceOrb.java @@ -47,6 +47,10 @@ public class ExperienceOrb extends Entity { @@ -24,7 +24,7 @@ index ff4648b3be103446ab401d36c14cc80b48840cab..18ccbb1344875dd7a2f2f8084102d341 private static boolean tryMergeToExisting(ServerLevel level, Vec3 pos, int amount) { + // DivineMC start - Clump experience orbs -+ if (org.bxteam.divinemc.DivineConfig.clumpOrbs) { ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.clumpOrbs) { + AABB aABB = AABB.ofSize(pos, 1.0D, 1.0D, 1.0D); + int id = level.getRandom().nextInt(40); + List list = level.getEntities(EntityTypeTest.forClass(ExperienceOrb.class), aABB, (experienceOrbx) -> canMerge(experienceOrbx, id, amount)); @@ -53,12 +53,12 @@ index ff4648b3be103446ab401d36c14cc80b48840cab..18ccbb1344875dd7a2f2f8084102d341 private boolean canMerge(ExperienceOrb orb) { - return orb != this && canMerge(orb, this.getId(), this.getValue()); -+ return org.bxteam.divinemc.DivineConfig.clumpOrbs ? orb.isAlive() && !this.is(orb) : orb != this && ExperienceOrb.canMerge(orb, this.getId(), this.getValue()); // DivineMC - Clump experience orbs ++ return org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.clumpOrbs ? orb.isAlive() && !this.is(orb) : orb != this && ExperienceOrb.canMerge(orb, this.getId(), this.getValue()); // DivineMC - Clump experience orbs } private static boolean canMerge(ExperienceOrb orb, int amount, int other) { - return !orb.isRemoved() && (orb.getId() - amount) % io.papermc.paper.configuration.GlobalConfiguration.get().misc.xpOrbGroupsPerArea.or(ORB_GROUPS_PER_AREA) == 0 && orb.getValue() == other; // Paper - Configure how many orbs will merge together -+ return org.bxteam.divinemc.DivineConfig.clumpOrbs ? orb.isAlive() : !orb.isRemoved() && (orb.getId() - amount) % io.papermc.paper.configuration.GlobalConfiguration.get().misc.xpOrbGroupsPerArea.or(ORB_GROUPS_PER_AREA) == 0 && orb.getValue() == other; // Paper - Configure how many orbs will merge together // Canvas - optimize orbs ++ return org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.clumpOrbs ? orb.isAlive() : !orb.isRemoved() && (orb.getId() - amount) % io.papermc.paper.configuration.GlobalConfiguration.get().misc.xpOrbGroupsPerArea.or(ORB_GROUPS_PER_AREA) == 0 && orb.getValue() == other; // Paper - Configure how many orbs will merge together // Canvas - optimize orbs } private void merge(ExperienceOrb orb) { @@ -67,7 +67,7 @@ index ff4648b3be103446ab401d36c14cc80b48840cab..18ccbb1344875dd7a2f2f8084102d341 } // Paper end - call orb merge event + // DivineMC start - Clump experience orbs -+ if (org.bxteam.divinemc.DivineConfig.clumpOrbs) { ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.clumpOrbs) { + java.util.Map otherMap = (orb).clumps$getClumpedMap(); + this.count = clumps$getClumpedMap().values().stream().reduce(Integer::sum).orElse(1); + this.age = Math.min(this.age, (orb).age); @@ -117,7 +117,7 @@ index ff4648b3be103446ab401d36c14cc80b48840cab..18ccbb1344875dd7a2f2f8084102d341 @Override public void playerTouch(Player entity) { + // DivineMC start - Clump experience orbs -+ if (entity instanceof ServerPlayer serverPlayer && org.bxteam.divinemc.DivineConfig.clumpOrbs && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(serverPlayer.getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { ++ if (entity instanceof ServerPlayer serverPlayer && org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.clumpOrbs && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(serverPlayer.getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { + entity.takeXpDelay = 0; + entity.take(this, 1); + @@ -191,7 +191,7 @@ index ff4648b3be103446ab401d36c14cc80b48840cab..18ccbb1344875dd7a2f2f8084102d341 + Optional randomItemWith = clumps$captureCurrentEntry(level().purpurConfig.useBetterMending ? EnchantmentHelper.getMostDamagedItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player) : EnchantmentHelper.getRandomItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player, ItemStack::isDamaged)); // Purpur - Add option to mend the most damaged equipment first // DivineMC - Clump experience orbs + + // DivineMC start - Clump experience orbs -+ if (org.bxteam.divinemc.DivineConfig.clumpOrbs) { ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.clumpOrbs) { + return clumps$currentEntry + .map(foundItem -> { + ItemStack itemstack = foundItem.itemStack(); diff --git a/divinemc-server/minecraft-patches/features/0053-Optimize-suffocation.patch b/divinemc-server/minecraft-patches/features/0053-Optimize-suffocation.patch index 2a252ab..35ce1d3 100644 --- a/divinemc-server/minecraft-patches/features/0053-Optimize-suffocation.patch +++ b/divinemc-server/minecraft-patches/features/0053-Optimize-suffocation.patch @@ -7,7 +7,7 @@ Original license: GPL v3 Original project: https://github.com/pufferfish-gg/Pufferfish diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index f598c6ae03977998f1cbf79cf3faf7997c2ba9e2..8b89a11aa0040b0d6104a4056d70d9d2ac74e331 100644 +index 808e4e2ae070b5232c2050fdcb183cc21b8fb996..aeea9dc46013632b2178818823564bb559746b13 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java @@ -406,6 +406,12 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -28,7 +28,7 @@ index f598c6ae03977998f1cbf79cf3faf7997c2ba9e2..8b89a11aa0040b0d6104a4056d70d9d2 if (this.isAlive() && this.level() instanceof ServerLevel serverLevel1) { boolean flag = this instanceof Player; - if (this.isInWall()) { -+ if ((!org.bxteam.divinemc.DivineConfig.enableSuffocationOptimization || this instanceof WitherBoss || (tickCount % 10 == 0 && couldPossiblyBeHurt(1.0F))) && this.isInWall()) { // DivineMC - Optimize suffocation ++ if ((!org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.enableSuffocationOptimization || this instanceof WitherBoss || (tickCount % 10 == 0 && couldPossiblyBeHurt(1.0F))) && this.isInWall()) { // DivineMC - Optimize suffocation this.hurtServer(serverLevel1, this.damageSources().inWall(), 1.0F); } else if (flag && !serverLevel1.getWorldBorder().isWithinBounds(this.getBoundingBox())) { double d = serverLevel1.getWorldBorder().getDistanceToBorder(this) + serverLevel1.getWorldBorder().getDamageSafeZone(); diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index dd4fe4b..3b7f419 100644 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/divinemc-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -7,7 +7,7 @@ - ServerGamePacketListenerImpl.LOGGER.warn("Disconnected on accept teleport packet. Was not expecting position data from client at this time"); // Purpur - Add more logger output for invalid movement kicks - this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause + // DivineMC start - Graceful teleport handling -+ if (org.bxteam.divinemc.DivineConfig.gracefulTeleportHandling ) { ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.gracefulTeleportHandling) { + LOGGER.info("Was not expecting position data from client at this time, gracefully returning instead of disconnect."); + } else { + ServerGamePacketListenerImpl.LOGGER.warn("Disconnected on accept teleport packet. Was not expecting position data from client at this time"); // Purpur - Add more logger output for invalid movement kicks diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/server/network/ServerStatusPacketListenerImpl.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/server/network/ServerStatusPacketListenerImpl.java.patch index 0f3dd33..8db46a9 100644 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/server/network/ServerStatusPacketListenerImpl.java.patch +++ b/divinemc-server/minecraft-patches/sources/net/minecraft/server/network/ServerStatusPacketListenerImpl.java.patch @@ -7,7 +7,7 @@ - if (net.minecraft.server.MinecraftServer.getServer().getStatus().version().isEmpty()) return; // Purpur - Fix 'outdated server' showing in ping before server fully boots - do not respond to pings before we know the protocol version + // DivineMC start - Don't respond ping before start fully - rewritten Purpur patch (configurable) + var status = net.minecraft.server.MinecraftServer.getServer().getStatus(); -+ if (org.bxteam.divinemc.DivineConfig.dontRespondPingBeforeStart && (status == null || status.version().isEmpty())) return; ++ if (org.bxteam.divinemc.config.DivineConfig.NetworkCategory.dontRespondPingBeforeStart && (status == null || status.version().isEmpty())) return; + // DivineMC end - Don't respond ping before start fully - rewritten Purpur patch (configurable) com.destroystokyo.paper.network.StandardPaperServerListPingEventImpl.processRequest(net.minecraft.server.MinecraftServer.getServer(), this.connection); // Paper - handle status request } diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java.patch index 91d2928..58c8ef6 100644 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java.patch +++ b/divinemc-server/minecraft-patches/sources/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java.patch @@ -5,7 +5,7 @@ @Override protected void doTick(ServerLevel level, Villager entity) { + // DivineMC start - skip useless secondary poi sensor -+ if (org.bxteam.divinemc.DivineConfig.skipUselessSecondaryPoiSensor && entity.getVillagerData().profession().value().secondaryPoi().isEmpty()) { ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.skipUselessSecondaryPoiSensor && entity.getVillagerData().profession().value().secondaryPoi().isEmpty()) { + entity.getBrain().eraseMemory(MemoryModuleType.SECONDARY_JOB_SITE); + return; + } diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/block/LeavesBlock.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/block/LeavesBlock.java.patch index 6bfd496..238c940 100644 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/block/LeavesBlock.java.patch +++ b/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/block/LeavesBlock.java.patch @@ -5,14 +5,14 @@ protected boolean decaying(BlockState state) { - return !state.getValue(PERSISTENT) && state.getValue(DISTANCE) == 7; -+ return !org.bxteam.divinemc.DivineConfig.disableLeafDecay && !state.getValue(PERSISTENT) && state.getValue(DISTANCE) == 7; // DivineMC - Disable leaf decay ++ return !org.bxteam.divinemc.config.DivineConfig.FixesCategory.disableLeafDecay && !state.getValue(PERSISTENT) && state.getValue(DISTANCE) == 7; // DivineMC - Disable leaf decay } @Override protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { - level.setBlock(pos, updateDistance(state, level, pos), 3); + // DivineMC start - Make leaves not suffocate the server -+ if (org.bxteam.divinemc.DivineConfig.disableLeafDecay) return; // DivineMC - Disable leaf decay ++ if (org.bxteam.divinemc.config.DivineConfig.FixesCategory.disableLeafDecay) return; // DivineMC - Disable leaf decay + int newValue = 7; + int oldValue = state.getValue(DISTANCE); + BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos(); diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/block/SlimeBlock.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/block/SlimeBlock.java.patch index cc50646..07460b9 100644 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/block/SlimeBlock.java.patch +++ b/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/block/SlimeBlock.java.patch @@ -4,7 +4,7 @@ Vec3 deltaMovement = entity.getDeltaMovement(); if (deltaMovement.y < 0.0) { double d = entity instanceof LivingEntity ? 1.0 : 0.8; -+ if (org.bxteam.divinemc.DivineConfig.fixIncorrectBounceLogic) entity.setOnGround(deltaMovement.y > -0.15); // DivineMC - Carpet-Fixes: Fix Slime Block Bounce Logic ++ if (org.bxteam.divinemc.config.DivineConfig.FixesCategory.fixIncorrectBounceLogic) entity.setOnGround(deltaMovement.y > -0.15); // DivineMC - Carpet-Fixes: Fix Slime Block Bounce Logic entity.setDeltaMovement(deltaMovement.x, -deltaMovement.y * d, deltaMovement.z); } } diff --git a/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/levelgen/SurfaceRules.java.patch b/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/levelgen/SurfaceRules.java.patch index e7e8709..4dcf4ce 100644 --- a/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/levelgen/SurfaceRules.java.patch +++ b/divinemc-server/minecraft-patches/sources/net/minecraft/world/level/levelgen/SurfaceRules.java.patch @@ -5,7 +5,7 @@ @Override protected boolean compute() { + // DivineMC start - Fix MC-258859 -+ if (org.bxteam.divinemc.DivineConfig.slopesVisualFix) { ++ if (org.bxteam.divinemc.config.DivineConfig.FixesCategory.slopesVisualFix) { + int x = this.context.blockX & 15; + int z = this.context.blockZ & 15; + ChunkAccess chunk = this.context.chunk; diff --git a/divinemc-server/paper-patches/features/0002-Configuration.patch b/divinemc-server/paper-patches/features/0002-Configuration.patch index e273a77..11671f3 100644 --- a/divinemc-server/paper-patches/features/0002-Configuration.patch +++ b/divinemc-server/paper-patches/features/0002-Configuration.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Configuration diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 7c79e58f86d113e5e67947e235475beef76e20ab..dc58d8707b854e53acff7c8e185db7904505aaa5 100644 +index 7c79e58f86d113e5e67947e235475beef76e20ab..b26d3a2856ed7bd0a2dcb72f74ee0e157be85ac7 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1088,6 +1088,13 @@ public final class CraftServer implements Server { @@ -14,7 +14,7 @@ index 7c79e58f86d113e5e67947e235475beef76e20ab..dc58d8707b854e53acff7c8e185db790 org.purpurmc.purpur.PurpurConfig.init((File) console.options.valueOf("purpur-settings")); // Purpur - Purpur config files + // DivineMC start - Configuration + try { -+ org.bxteam.divinemc.DivineConfig.init((File) console.options.valueOf("divinemc-settings")); ++ org.bxteam.divinemc.config.DivineConfig.init((File) console.options.valueOf("divinemc-settings")); + } catch (IOException e) { + this.logger.log(Level.WARNING, "Failed to load DivineMC configuration, " + e.getMessage()); + } diff --git a/divinemc-server/paper-patches/features/0004-Implement-Secure-Seed.patch b/divinemc-server/paper-patches/features/0004-Implement-Secure-Seed.patch index 887617b..a30f2c0 100644 --- a/divinemc-server/paper-patches/features/0004-Implement-Secure-Seed.patch +++ b/divinemc-server/paper-patches/features/0004-Implement-Secure-Seed.patch @@ -7,7 +7,7 @@ Original license: GPLv3 Original project: https://github.com/plasmoapp/matter diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java -index 400e632208d133a3f49fc7f14bceb48a1026769b..4954625e4f1af358ca7c70a57be30dee92ace0e6 100644 +index 400e632208d133a3f49fc7f14bceb48a1026769b..a1c7ba0fdb505d09407cca94e890dedd2d9cb313 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -196,7 +196,12 @@ public class CraftChunk implements Chunk { @@ -16,7 +16,7 @@ index 400e632208d133a3f49fc7f14bceb48a1026769b..4954625e4f1af358ca7c70a57be30dee // 987234911L is taken from Slime when seeing if a slime can spawn in a chunk - return this.level.paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), level.spigotConfig.slimeSeed).nextInt(10) == 0; // Paper + // DivineMC start - Implement Secure Seed -+ boolean isSlimeChunk = org.bxteam.divinemc.DivineConfig.enableSecureSeed ++ boolean isSlimeChunk = org.bxteam.divinemc.config.DivineConfig.MiscCategory.enableSecureSeed + ? this.level.getChunk(this.getX(), this.getZ()).isSlimeChunk() + : WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), this.level.spigotConfig.slimeSeed).nextInt(10) == 0; // Paper + return this.level.paperConfig().entities.spawning.allChunksAreSlimeChunks || isSlimeChunk; @@ -25,7 +25,7 @@ index 400e632208d133a3f49fc7f14bceb48a1026769b..4954625e4f1af358ca7c70a57be30dee @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index dc58d8707b854e53acff7c8e185db7904505aaa5..4aadf1a020136dcf458e0470db141e24a0b7006e 100644 +index b26d3a2856ed7bd0a2dcb72f74ee0e157be85ac7..ec77f0c59bd79dc680bf3f4f4e1257c8cf6125cb 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1385,7 +1385,11 @@ public final class CraftServer implements Server { @@ -34,7 +34,7 @@ index dc58d8707b854e53acff7c8e185db7904505aaa5..4aadf1a020136dcf458e0470db141e24 LevelSettings levelSettings; - WorldOptions worldOptions = new WorldOptions(creator.seed(), creator.generateStructures(), creator.bonusChest()); + // DivineMC start - Implement Secure Seed -+ WorldOptions worldOptions = org.bxteam.divinemc.DivineConfig.enableSecureSeed ++ WorldOptions worldOptions = org.bxteam.divinemc.config.DivineConfig.MiscCategory.enableSecureSeed + ? new WorldOptions(creator.seed(), su.plo.matter.Globals.createRandomWorldSeed(), creator.generateStructures(), false) + : new WorldOptions(creator.seed(), creator.generateStructures(), false); + // DivineMC end - Implement Secure Seed diff --git a/divinemc-server/paper-patches/features/0005-Chunk-System-Optimizations.patch b/divinemc-server/paper-patches/features/0005-Chunk-System-Optimizations.patch index 75923aa..f4238ec 100644 --- a/divinemc-server/paper-patches/features/0005-Chunk-System-Optimizations.patch +++ b/divinemc-server/paper-patches/features/0005-Chunk-System-Optimizations.patch @@ -507,14 +507,14 @@ index ab2fa1563d5e32a5313dfcc1da411cab45fb5ca0..1bababc2515d8c805e4ee0c943065f45 } 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 632920e04686d8a0fd0a60e87348be1fe7862a3c..f10c6c156b8dd9acecc8b1ee81bd28260fb6e4d8 100644 +index 632920e04686d8a0fd0a60e87348be1fe7862a3c..06a0624663a080d8be9f7816fda569fda9fdd1e1 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java @@ -3,6 +3,12 @@ package ca.spottedleaf.moonrise.common.util; import ca.spottedleaf.concurrentutil.executor.thread.PrioritisedThreadPool; import ca.spottedleaf.moonrise.common.PlatformHooks; import com.mojang.logging.LogUtils; -+import org.bxteam.divinemc.DivineConfig; ++import org.bxteam.divinemc.config.DivineConfig; +import org.bxteam.divinemc.server.chunk.ChunkSystemAlgorithms; +import org.bxteam.divinemc.server.chunk.TheChunkSystem; +import org.bxteam.divinemc.spark.ThreadDumperRegistry; @@ -567,7 +567,7 @@ index 632920e04686d8a0fd0a60e87348be1fe7862a3c..f10c6c156b8dd9acecc8b1ee81bd2826 - - int workerThreads = configWorkerThreads; + public static void init(final int configWorkerThreads, final int configIoThreads) { -+ ChunkSystemAlgorithms algorithm = DivineConfig.chunkWorkerAlgorithm; ++ ChunkSystemAlgorithms algorithm = DivineConfig.PerformanceCategory.chunkWorkerAlgorithm; + int workerThreads = algorithm.evalWorkers(configWorkerThreads, configIoThreads); + int ioThreads = algorithm.evalIO(configWorkerThreads, configIoThreads); @@ -591,7 +591,7 @@ index 632920e04686d8a0fd0a60e87348be1fe7862a3c..f10c6c156b8dd9acecc8b1ee81bd2826 + return new TheChunkSystem(workerThreads, new ThreadBuilder() { + @Override + public void accept(final Thread thread) { -+ thread.setPriority(DivineConfig.threadPoolPriority); ++ thread.setPriority(DivineConfig.PerformanceCategory.threadPoolPriority); + thread.setDaemon(true); + thread.setUncaughtExceptionHandler((thread1, throwable) -> LOGGER.error("Uncaught exception in thread {}", thread1.getName(), throwable)); + thread.setName("World Gen Worker #" + getAndIncrementId()); @@ -651,7 +651,7 @@ index 632920e04686d8a0fd0a60e87348be1fe7862a3c..f10c6c156b8dd9acecc8b1ee81bd2826 LOGGER.info("Awaiting termination of I/O pool for up to 60s..."); if (!MoonriseCommon.IO_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java -index 559c959aff3c9deef867b9e425fba3e2e669cac6..a5b0585b56d71d21c9da3b129d213def142bb1f6 100644 +index 559c959aff3c9deef867b9e425fba3e2e669cac6..7d0281cc946d6b0dc6f21fa6798e5320ae589bcf 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java @@ -4,7 +4,7 @@ import ca.spottedleaf.moonrise.common.PlatformHooks; @@ -659,7 +659,7 @@ index 559c959aff3c9deef867b9e425fba3e2e669cac6..a5b0585b56d71d21c9da3b129d213def public final class MoonriseConstants { - public static final int MAX_VIEW_DISTANCE = Integer.getInteger(PlatformHooks.get().getBrand() + ".MaxViewDistance", 32); -+ public static final int MAX_VIEW_DISTANCE = Integer.getInteger(PlatformHooks.get().getBrand() + ".MaxViewDistance", org.bxteam.divinemc.DivineConfig.maxViewDistance); // DivineMC - Configurable view distance ++ public static final int MAX_VIEW_DISTANCE = Integer.getInteger(PlatformHooks.get().getBrand() + ".MaxViewDistance", org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.maxViewDistance); // DivineMC - Configurable view distance private MoonriseConstants() {} diff --git a/divinemc-server/paper-patches/features/0008-Configurable-thread-pool-priority.patch b/divinemc-server/paper-patches/features/0008-Configurable-thread-pool-priority.patch index ee4865d..4103d45 100644 --- a/divinemc-server/paper-patches/features/0008-Configurable-thread-pool-priority.patch +++ b/divinemc-server/paper-patches/features/0008-Configurable-thread-pool-priority.patch @@ -5,14 +5,14 @@ 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 f10c6c156b8dd9acecc8b1ee81bd28260fb6e4d8..c720304d8f2427cd4433d76e28ede13552181648 100644 +index 06a0624663a080d8be9f7816fda569fda9fdd1e1..c2a52a071dbb82b8498499b9e9386bdcdfe39c9c 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java @@ -66,6 +66,7 @@ public final class MoonriseCommon { LOGGER.error("Uncaught exception in thread {}", thread.getName(), throwable); } }); -+ thread.setPriority(DivineConfig.threadPoolPriority); // DivineMC - Configurable thread pool priority ++ thread.setPriority(DivineConfig.PerformanceCategory.threadPoolPriority); // DivineMC - Configurable thread pool priority } } ); diff --git a/divinemc-server/paper-patches/features/0009-Virtual-Threads.patch b/divinemc-server/paper-patches/features/0009-Virtual-Threads.patch index 81e48bc..80f48f8 100644 --- a/divinemc-server/paper-patches/features/0009-Virtual-Threads.patch +++ b/divinemc-server/paper-patches/features/0009-Virtual-Threads.patch @@ -5,7 +5,7 @@ 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..9332a1b995ca0b56e4c326c5af17fc592fc62fe4 100644 +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 { @@ -13,12 +13,12 @@ index 8492a06883e2ff597bbbdaa74fe5e5cdd0a0a1b1..9332a1b995ca0b56e4c326c5af17fc59 } }; - public static final ExecutorService ASYNC_EXECUTOR = Executors.newFixedThreadPool(2, new ThreadFactoryBuilder() -+ public static final ExecutorService ASYNC_EXECUTOR = org.bxteam.divinemc.DivineConfig.virtualThreadsEnabled && org.bxteam.divinemc.DivineConfig.virtualAsyncExecutor ? Executors.newVirtualThreadPerTaskExecutor() : Executors.newFixedThreadPool(2, new ThreadFactoryBuilder() // DivineMC - Virtual Threads ++ 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..bfa84901c5e0e50ab3f713293035aefbcf4488e6 100644 +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; @@ -35,7 +35,7 @@ index 0ca279fb71d39c81b1f608e0ee9ba3e498d55fa3..bfa84901c5e0e50ab3f713293035aefb - - private final ThreadPoolExecutor executor = new ThreadPoolExecutor( + // DivineMC start - Virtual Threads -+ private final ExecutorService executor = org.bxteam.divinemc.DivineConfig.virtualThreadsEnabled && org.bxteam.divinemc.DivineConfig.virtualBukkitScheduler ++ 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 @@ -49,7 +49,7 @@ index 0ca279fb71d39c81b1f608e0ee9ba3e498d55fa3..bfa84901c5e0e50ab3f713293035aefb - executor.allowCoreThreadTimeOut(true); - executor.prestartAllCoreThreads(); + // DivineMC start - Virtual Threads -+ if (!org.bxteam.divinemc.DivineConfig.virtualThreadsEnabled && !org.bxteam.divinemc.DivineConfig.virtualBukkitScheduler) { ++ if (!org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.virtualThreadsEnabled && !org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.virtualBukkitScheduler) { + ((ThreadPoolExecutor) executor).allowCoreThreadTimeOut(true); + ((ThreadPoolExecutor) executor).prestartAllCoreThreads(); + } diff --git a/divinemc-server/paper-patches/features/0010-Multithreaded-Tracker.patch b/divinemc-server/paper-patches/features/0010-Multithreaded-Tracker.patch index a94aa86..ad8a6e0 100644 --- a/divinemc-server/paper-patches/features/0010-Multithreaded-Tracker.patch +++ b/divinemc-server/paper-patches/features/0010-Multithreaded-Tracker.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Multithreaded Tracker 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..a9ec83b5bcb329bf3d2f3fb0e502685a37f9dcbc 100644 +index d7398b1ecf2660c29fb7d106b48fe02d3736603e..ab499a7eaccdc1578ec64f90f54f79b0da3c0e96 100644 --- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java @@ -42,6 +42,12 @@ class PaperEventManager { @@ -13,7 +13,7 @@ index d7398b1ecf2660c29fb7d106b48fe02d3736603e..a9ec83b5bcb329bf3d2f3fb0e502685a throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously."); } else if (!event.isAsynchronous() && !this.server.isPrimaryThread() && !this.server.isStopping()) { + // DivineMC start - Multithreaded Tracker -+ if (org.bxteam.divinemc.DivineConfig.multithreadedEnabled) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.multithreadedEnabled) { + net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(event::callEvent); + return; + } @@ -22,7 +22,7 @@ index d7398b1ecf2660c29fb7d106b48fe02d3736603e..a9ec83b5bcb329bf3d2f3fb0e502685a } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index f32316b0357f1cb0501a052361a0221f8e9d1438..2e28891cb4c058c022b06040c0283aacf4c2445e 100644 +index 5300a513a295d472752d31a6e8af48bb64b06704..399fd8841e9d7c068b4fccb3754b371ec95c2e59 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -1751,6 +1751,26 @@ public class CraftEventFactory { @@ -30,7 +30,7 @@ index f32316b0357f1cb0501a052361a0221f8e9d1438..2e28891cb4c058c022b06040c0283aac public static boolean handleBlockFormEvent(Level world, BlockPos pos, net.minecraft.world.level.block.state.BlockState state, int flags, @Nullable Entity entity, boolean checkSetResult) { + // DivineMC start - Multithreaded Tracker -+ if (org.bxteam.divinemc.DivineConfig.multithreadedEnabled && Thread.currentThread() instanceof org.bxteam.divinemc.entity.tracking.MultithreadedTracker.MultithreadedTrackerThread) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.multithreadedEnabled && Thread.currentThread() instanceof org.bxteam.divinemc.entity.tracking.MultithreadedTracker.MultithreadedTrackerThread) { + java.util.concurrent.CompletableFuture future = new java.util.concurrent.CompletableFuture<>(); + net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> { + boolean resultFlag = false; diff --git a/divinemc-server/paper-patches/features/0014-Parallel-world-ticking.patch b/divinemc-server/paper-patches/features/0014-Parallel-world-ticking.patch index 841553a..53c4b21 100644 --- a/divinemc-server/paper-patches/features/0014-Parallel-world-ticking.patch +++ b/divinemc-server/paper-patches/features/0014-Parallel-world-ticking.patch @@ -5,14 +5,14 @@ Subject: [PATCH] Parallel world ticking diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java -index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..c153e79ebe1f2338f0d0ca6b45b392794ecd2fd7 100644 +index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..a4adaba06c1bc4bb8029ccb128fde90ec2564525 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java @@ -14,6 +14,7 @@ import java.util.concurrent.atomic.AtomicInteger; public class TickThread extends Thread { private static final Logger LOGGER = LoggerFactory.getLogger(TickThread.class); -+ public static final boolean HARD_THROW = !org.bxteam.divinemc.DivineConfig.disableHardThrow; // DivineMC - Parallel world ticking ++ public static final boolean HARD_THROW = !org.bxteam.divinemc.config.DivineConfig.AsyncCategory.disableHardThrow; // DivineMC - Parallel world ticking private static String getThreadContext() { return "thread=" + Thread.currentThread().getName(); @@ -222,7 +222,7 @@ index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..c153e79ebe1f2338f0d0ca6b45b39279 + // 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 a9ec83b5bcb329bf3d2f3fb0e502685a37f9dcbc..adf526bcb5b4df3b798a8b80ad11b7b2c30775d7 100644 +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; @@ -238,7 +238,7 @@ index a9ec83b5bcb329bf3d2f3fb0e502685a37f9dcbc..adf526bcb5b4df3b798a8b80ad11b7b2 // DivineMC end - Skip event if no listeners if (event.isAsynchronous() && this.server.isPrimaryThread()) { + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && org.bxteam.divinemc.DivineConfig.pwtCompatabilityMode) { ++ 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; + } @@ -247,7 +247,7 @@ index a9ec83b5bcb329bf3d2f3fb0e502685a37f9dcbc..adf526bcb5b4df3b798a8b80ad11b7b2 } else if (!event.isAsynchronous() && !this.server.isPrimaryThread() && !this.server.isStopping()) { // DivineMC start - Multithreaded Tracker diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 0ea7df63498492e320f98ddec5bdf33b203cc770..9418a1771287142950d31c3bf31c85c8e7848dc4 100644 +index 0ea7df63498492e320f98ddec5bdf33b203cc770..7ab2ca6768b59d24bbae993b33d3a72a42045f06 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -447,7 +447,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -256,7 +256,7 @@ index 0ea7df63498492e320f98ddec5bdf33b203cc770..9418a1771287142950d31c3bf31c85c8 public boolean unloadChunkRequest(int x, int z) { - org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x, z, "Cannot unload chunk asynchronously"); + } else { + org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot @@ -269,7 +269,7 @@ index 0ea7df63498492e320f98ddec5bdf33b203cc770..9418a1771287142950d31c3bf31c85c8 @Override public boolean refreshChunk(int x, int z) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x, z, "Cannot refresh chunk asynchronously"); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x, z, "Cannot refresh chunk asynchronously"); // DivineMC - Parallel world ticking ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z)); if (playerChunk == null) return false; @@ -279,7 +279,7 @@ index 0ea7df63498492e320f98ddec5bdf33b203cc770..9418a1771287142950d31c3bf31c85c8 public boolean loadChunk(int x, int z, boolean generate) { - org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.getHandle(), x, z, "May not sync load chunks asynchronously"); + } else { + org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot @@ -292,7 +292,7 @@ index 0ea7df63498492e320f98ddec5bdf33b203cc770..9418a1771287142950d31c3bf31c85c8 @Override public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, loc.getX(), loc.getZ(), "Cannot generate tree asynchronously"); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, loc.getX(), loc.getZ(), "Cannot generate tree asynchronously"); // DivineMC - Parallel world ticking this.world.captureTreeGeneration = true; this.world.captureBlockStates = true; boolean grownTree = this.generateTree(loc, type); @@ -300,7 +300,7 @@ index 0ea7df63498492e320f98ddec5bdf33b203cc770..9418a1771287142950d31c3bf31c85c8 } public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks, Entity source, Consumer configurator) { // Paper end - expand explosion API -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x, z, "Cannot create explosion asynchronously"); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x, z, "Cannot create explosion asynchronously"); // DivineMC - Parallel world ticking net.minecraft.world.level.Level.ExplosionInteraction explosionType; if (!breakBlocks) { explosionType = net.minecraft.world.level.Level.ExplosionInteraction.NONE; // Don't break blocks @@ -308,7 +308,7 @@ index 0ea7df63498492e320f98ddec5bdf33b203cc770..9418a1771287142950d31c3bf31c85c8 @Override public int getHighestBlockYAt(int x, int z, org.bukkit.HeightMap heightMap) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x >> 4, z >> 4, "Cannot retrieve chunk asynchronously"); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x >> 4, z >> 4, "Cannot retrieve chunk asynchronously"); // DivineMC - Parallel world ticking warnUnsafeChunk("getting a faraway chunk", x >> 4, z >> 4); // Paper // Transient load for this tick return this.world.getChunk(x >> 4, z >> 4).getHeight(CraftHeightMap.toNMS(heightMap), x, z); @@ -316,7 +316,7 @@ index 0ea7df63498492e320f98ddec5bdf33b203cc770..9418a1771287142950d31c3bf31c85c8 @Override public void setBiome(int x, int y, int z, Holder bb) { BlockPos pos = new BlockPos(x, 0, z); -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, pos, "Cannot retrieve chunk asynchronously"); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, pos, "Cannot retrieve chunk asynchronously"); // DivineMC - Parallel world ticking if (this.world.hasChunkAt(pos)) { net.minecraft.world.level.chunk.LevelChunk chunk = this.world.getChunkAt(pos); @@ -324,12 +324,12 @@ index 0ea7df63498492e320f98ddec5bdf33b203cc770..9418a1771287142950d31c3bf31c85c8 @Override public void sendGameEvent(Entity sourceEntity, org.bukkit.GameEvent gameEvent, Vector position) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, position.getX(), position.getZ(), "Cannot send game event asynchronously"); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, position.getX(), position.getZ(), "Cannot send game event asynchronously"); // DivineMC - Parallel world ticking 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 diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index a4d5c65edc1db59f3486ce5d3757cc306211a54b..427719a50edc89f4bb7214577279f7464764bf9e 100644 +index a4d5c65edc1db59f3486ce5d3757cc306211a54b..d8f68164b0b4430ccdc7e4a419eace7185c82cd1 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -75,6 +75,11 @@ public class CraftBlock implements Block { @@ -337,7 +337,7 @@ index a4d5c65edc1db59f3486ce5d3757cc306211a54b..427719a50edc89f4bb7214577279f746 public net.minecraft.world.level.block.state.BlockState getNMS() { + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously"); + } + // DivineMC end - Parallel world ticking @@ -349,7 +349,7 @@ index a4d5c65edc1db59f3486ce5d3757cc306211a54b..427719a50edc89f4bb7214577279f746 private void setData(final byte data, int flags) { + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously"); + } + // DivineMC end - Parallel world ticking @@ -361,7 +361,7 @@ index a4d5c65edc1db59f3486ce5d3757cc306211a54b..427719a50edc89f4bb7214577279f746 public static boolean setBlockState(LevelAccessor world, BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState, boolean applyPhysics) { + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, pos, "Cannot modify world asynchronously"); + } + // DivineMC end - Parallel world ticking @@ -373,7 +373,7 @@ index a4d5c65edc1db59f3486ce5d3757cc306211a54b..427719a50edc89f4bb7214577279f746 @Override public Biome getBiome() { + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously"); + } + // DivineMC end - Parallel world ticking @@ -384,7 +384,7 @@ index a4d5c65edc1db59f3486ce5d3757cc306211a54b..427719a50edc89f4bb7214577279f746 @Override public Biome getComputedBiome() { + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously"); + } + // DivineMC end - Parallel world ticking @@ -395,7 +395,7 @@ index a4d5c65edc1db59f3486ce5d3757cc306211a54b..427719a50edc89f4bb7214577279f746 @Override public void setBiome(Biome bio) { + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously"); + } + // DivineMC end - Parallel world ticking @@ -407,7 +407,7 @@ index a4d5c65edc1db59f3486ce5d3757cc306211a54b..427719a50edc89f4bb7214577279f746 @Override public boolean isBlockFaceIndirectlyPowered(BlockFace face) { + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously"); + } + // DivineMC end - Parallel world ticking @@ -419,7 +419,7 @@ index a4d5c65edc1db59f3486ce5d3757cc306211a54b..427719a50edc89f4bb7214577279f746 @Override public int getBlockPower(BlockFace face) { + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously"); + } + // DivineMC end - Parallel world ticking @@ -431,7 +431,7 @@ index a4d5c65edc1db59f3486ce5d3757cc306211a54b..427719a50edc89f4bb7214577279f746 @Override public boolean breakNaturally() { + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously"); + } + // DivineMC end - Parallel world ticking @@ -443,7 +443,7 @@ index a4d5c65edc1db59f3486ce5d3757cc306211a54b..427719a50edc89f4bb7214577279f746 @Override public boolean applyBoneMeal(BlockFace face) { + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously"); + } + // DivineMC end - Parallel world ticking @@ -468,7 +468,7 @@ index a4d5c65edc1db59f3486ce5d3757cc306211a54b..427719a50edc89f4bb7214577279f746 @Override public RayTraceResult rayTrace(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode) { + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously"); + } + // DivineMC end - Parallel world ticking @@ -480,7 +480,7 @@ index a4d5c65edc1db59f3486ce5d3757cc306211a54b..427719a50edc89f4bb7214577279f746 @Override public boolean canPlace(BlockData data) { + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously"); + } + // DivineMC end - Parallel world ticking @@ -492,7 +492,7 @@ index a4d5c65edc1db59f3486ce5d3757cc306211a54b..427719a50edc89f4bb7214577279f746 @Override public void tick() { + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && world instanceof ServerLevel serverWorld) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously"); + } + // DivineMC end - Parallel world ticking @@ -500,7 +500,7 @@ index a4d5c65edc1db59f3486ce5d3757cc306211a54b..427719a50edc89f4bb7214577279f746 this.getNMS().tick(level, this.position, level.random); } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java -index 3422970353dcd886934b9ee906467769d39abbde..cb60c1b09f06872c07d05b04b7bacc5921fea78d 100644 +index 3422970353dcd886934b9ee906467769d39abbde..a313c75ddb2c631b20c8d91a8f7ff3a4b77c1128 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java @@ -26,6 +26,25 @@ public abstract class CraftBlockEntityState extends Craft @@ -511,7 +511,7 @@ index 3422970353dcd886934b9ee906467769d39abbde..cb60c1b09f06872c07d05b04b7bacc59 + public static ThreadLocal DISABLE_SNAPSHOT_TL = ThreadLocal.withInitial(() -> Boolean.FALSE); + + public static boolean getDisableSnapshotTL() { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && DISABLE_SNAPSHOT_TL.get()) return true; ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && DISABLE_SNAPSHOT_TL.get()) return true; + + synchronized (CraftBlockEntityState.class) { + return DISABLE_SNAPSHOT; @@ -519,7 +519,7 @@ index 3422970353dcd886934b9ee906467769d39abbde..cb60c1b09f06872c07d05b04b7bacc59 + } + + public static void setDisableSnapshotTL(boolean value) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) DISABLE_SNAPSHOT_TL.set(value); ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) DISABLE_SNAPSHOT_TL.set(value); + + synchronized (CraftBlockEntityState.class) { + DISABLE_SNAPSHOT = value; @@ -543,7 +543,7 @@ index 3422970353dcd886934b9ee906467769d39abbde..cb60c1b09f06872c07d05b04b7bacc59 } else { this.snapshot = this.createSnapshot(blockEntity); diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java -index 196835bdf95ba0e149b2977e9ef41698971f501f..bf70de08a9f5d49905b253bf549f6aeb8e2d3250 100644 +index 196835bdf95ba0e149b2977e9ef41698971f501f..b35dbe2b6e75ec89483aef093474c6757983a73f 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java @@ -218,6 +218,12 @@ public class CraftBlockState implements BlockState { @@ -551,7 +551,7 @@ index 196835bdf95ba0e149b2977e9ef41698971f501f..bf70de08a9f5d49905b253bf549f6aeb CraftBlock block = this.getBlock(); + // DivineMC start - Parallel world ticking -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && access instanceof net.minecraft.server.level.ServerLevel serverWorld) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && access instanceof net.minecraft.server.level.ServerLevel serverWorld) { + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously"); + } + // DivineMC end - Parallel world ticking @@ -563,7 +563,7 @@ index 196835bdf95ba0e149b2977e9ef41698971f501f..bf70de08a9f5d49905b253bf549f6aeb @Override public java.util.Collection getDrops(org.bukkit.inventory.ItemStack item, org.bukkit.entity.Entity entity) { -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(world.getHandle(), position, "Cannot modify world asynchronously"); // DivineMC - Parallel world ticking ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(world.getHandle(), position, "Cannot modify world asynchronously"); // DivineMC - Parallel world ticking this.requirePlaced(); net.minecraft.world.item.ItemStack nms = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(item); @@ -592,7 +592,7 @@ index 2338e7c115037430cefae26a571ded71f77983c4..6d5af7f72158e9e4abbfb6ae650833a6 } diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java -index e4e2e42d0ca25df7fe9f2dd4275610e45fcb2c84..8d0816dcc4159b62e5bbb03e3897b255feb961e6 100644 +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 { @@ -600,13 +600,13 @@ index e4e2e42d0ca25df7fe9f2dd4275610e45fcb2c84..8d0816dcc4159b62e5bbb03e3897b255 @Override public boolean isSync() { - return false; -+ return org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && org.bxteam.divinemc.DivineConfig.pwtCompatabilityMode; // DivineMC - Parallel world ticking ++ 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.DivineConfig.enableParallelWorldTicking && org.bxteam.divinemc.DivineConfig.pwtCompatabilityMode) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking && org.bxteam.divinemc.config.DivineConfig.AsyncCategory.pwtCompatabilityMode) { + try { + super.run(); + } catch (final Throwable t) { diff --git a/divinemc-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/command/CraftCommandMap.java.patch b/divinemc-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/command/CraftCommandMap.java.patch index 66c4e57..b7b1a06 100644 --- a/divinemc-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/command/CraftCommandMap.java.patch +++ b/divinemc-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/command/CraftCommandMap.java.patch @@ -9,7 +9,7 @@ + @Override + public Command getCommand(String name) { + Command target = super.getCommand(name); -+ if (org.bxteam.divinemc.DivineConfig.forceMinecraftCommand && !(target instanceof org.bukkit.craftbukkit.command.VanillaCommandWrapper)) { ++ if (org.bxteam.divinemc.config.DivineConfig.FixesCategory.forceMinecraftCommand && !(target instanceof org.bukkit.craftbukkit.command.VanillaCommandWrapper)) { + Command minecraftTarget = super.getCommand("minecraft:" + name); + if (minecraftTarget != null) { + return minecraftTarget; diff --git a/divinemc-server/purpur-patches/features/0003-MSPT-Tracking-for-each-world.patch b/divinemc-server/purpur-patches/features/0003-MSPT-Tracking-for-each-world.patch index 5585073..f3d8685 100644 --- a/divinemc-server/purpur-patches/features/0003-MSPT-Tracking-for-each-world.patch +++ b/divinemc-server/purpur-patches/features/0003-MSPT-Tracking-for-each-world.patch @@ -5,7 +5,7 @@ Subject: [PATCH] MSPT Tracking for each world diff --git a/src/main/java/org/purpurmc/purpur/task/TPSBarTask.java b/src/main/java/org/purpurmc/purpur/task/TPSBarTask.java -index 8769993e7ca59da309087051a3cd38fc562c15d1..3d1b183da57e7e267973db27867c7d9a6a64c044 100644 +index 8769993e7ca59da309087051a3cd38fc562c15d1..28da3818844f649736af5f1a3226376dee1eb8b1 100644 --- a/src/main/java/org/purpurmc/purpur/task/TPSBarTask.java +++ b/src/main/java/org/purpurmc/purpur/task/TPSBarTask.java @@ -4,6 +4,8 @@ import net.kyori.adventure.bossbar.BossBar; @@ -25,7 +25,7 @@ index 8769993e7ca59da309087051a3cd38fc562c15d1..3d1b183da57e7e267973db27867c7d9a - bossbar.color(getBossBarColor()); - bossbar.name(MiniMessage.miniMessage().deserialize(PurpurConfig.commandTPSBarTitle, + // DivineMC start - MSPT Tracking for each world -+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) { ++ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) { + ServerLevel serverLevel = ((CraftWorld)player.getWorld()).getHandle(); + + double worldMspt = calculateWorldMSPT(serverLevel); diff --git a/divinemc-server/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java b/divinemc-server/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java index 595320c..ced79fa 100644 --- a/divinemc-server/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java +++ b/divinemc-server/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java @@ -15,7 +15,7 @@ import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.Logger; import org.apache.logging.log4j.core.appender.AbstractAppender; import org.apache.logging.log4j.core.filter.AbstractFilter; -import org.bxteam.divinemc.DivineConfig; +import org.bxteam.divinemc.config.DivineConfig; import java.util.Map; @@ -32,7 +32,7 @@ public class PufferfishSentryAppender extends AbstractAppender { @Override public void append(LogEvent logEvent) { - if (logEvent.getLevel().isMoreSpecificThan(logLevel) && (logEvent.getThrown() != null || !DivineConfig.onlyLogThrown)) { + if (logEvent.getLevel().isMoreSpecificThan(logLevel) && (logEvent.getThrown() != null || !DivineConfig.MiscCategory.onlyLogThrown)) { try { logException(logEvent); } catch (Exception e) { diff --git a/divinemc-server/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java b/divinemc-server/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java index e6cdd4d..cea8b93 100644 --- a/divinemc-server/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java +++ b/divinemc-server/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java @@ -4,7 +4,7 @@ import io.sentry.Sentry; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.bxteam.divinemc.DivineConfig; +import org.bxteam.divinemc.config.DivineConfig; public class SentryManager { private static final Logger LOGGER = LogManager.getLogger("SentryManager"); @@ -26,7 +26,7 @@ public class SentryManager { initialized = true; Sentry.init(options -> { - options.setDsn(DivineConfig.sentryDsn); + options.setDsn(DivineConfig.MiscCategory.sentryDsn); options.setMaxBreadcrumbs(100); }); diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java b/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java deleted file mode 100644 index d5a3426..0000000 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java +++ /dev/null @@ -1,583 +0,0 @@ -package org.bxteam.divinemc; - -import com.google.common.base.Throwables; -import gg.pufferfish.pufferfish.simd.SIMDDetection; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.EntityType; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.MemoryConfiguration; -import org.bxteam.divinemc.entity.pathfinding.PathfindTaskRejectPolicy; -import org.bxteam.divinemc.region.LinearImplementation; -import org.bxteam.divinemc.server.chunk.ChunkSystemAlgorithms; -import org.bxteam.divinemc.server.chunk.ChunkTaskPriority; -import org.jetbrains.annotations.Nullable; -import org.simpleyaml.configuration.comments.CommentType; -import org.simpleyaml.configuration.file.YamlFile; -import org.simpleyaml.exceptions.InvalidConfigurationException; -import org.bxteam.divinemc.region.RegionFileFormat; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -@SuppressWarnings({"unused", "SameParameterValue"}) -public class DivineConfig { - private static final String HEADER = """ - This is the main configuration file for DivineMC. - If you need help with the configuration or have any questions related to DivineMC, - join us in our Discord server. - - Discord: https://discord.gg/qNyybSSPm5 - Docs: https://bxteam.org/docs/divinemc - Downloads: https://github.com/BX-Team/DivineMC/releases"""; - - public static final Logger LOGGER = LogManager.getLogger(DivineConfig.class.getSimpleName()); - public static final int CONFIG_VERSION = 5; - - private static File configFile; - public static final YamlFile config = new YamlFile(); - - private static ConfigurationSection convertToBukkit(org.simpleyaml.configuration.ConfigurationSection section) { - ConfigurationSection newSection = new MemoryConfiguration(); - for (String key : section.getKeys(false)) { - if (section.isConfigurationSection(key)) { - newSection.set(key, convertToBukkit(section.getConfigurationSection(key))); - } else { - newSection.set(key, section.get(key)); - } - } - return newSection; - } - - public static ConfigurationSection getConfigCopy() { - return convertToBukkit(config); - } - - public static void init(File configFile) throws IOException { - DivineConfig.configFile = configFile; - if (configFile.exists()) { - try { - config.load(configFile); - } catch (InvalidConfigurationException e) { - throw new IOException(e); - } - } - - getInt("version", CONFIG_VERSION); - config.options().header(HEADER); - - readConfig(DivineConfig.class, null); - } - - static void readConfig(Class clazz, Object instance) throws IOException { - for (Method method : clazz.getDeclaredMethods()) { - if (Modifier.isPrivate(method.getModifiers())) { - if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE) { - try { - method.setAccessible(true); - method.invoke(instance); - } catch (InvocationTargetException ex) { - throw Throwables.propagate(ex.getCause()); - } catch (Exception ex) { - LOGGER.error("Error invoking {}", method, ex); - } - } - } - } - - config.save(configFile); - } - - private static void setComment(String key, String... comment) { - if (config.contains(key)) { - config.setComment(key, String.join("\n", comment), CommentType.BLOCK); - } - } - - private static void ensureDefault(String key, Object defaultValue, String... comment) { - if (!config.contains(key)) config.set(key, defaultValue); - if (comment.length > 0) config.setComment(key, String.join("\n", comment), CommentType.BLOCK); - } - - private static boolean getBoolean(String key, boolean defaultValue, String... comment) { - return getBoolean(key, null, defaultValue, comment); - } - - private static boolean getBoolean(String key, @Nullable String oldKey, boolean defaultValue, String... comment) { - ensureDefault(key, defaultValue, comment); - return config.getBoolean(key, defaultValue); - } - - private static int getInt(String key, int defaultValue, String... comment) { - return getInt(key, null, defaultValue, comment); - } - - private static int getInt(String key, @Nullable String oldKey, int defaultValue, String... comment) { - ensureDefault(key, defaultValue, comment); - return config.getInt(key, defaultValue); - } - - private static double getDouble(String key, double defaultValue, String... comment) { - return getDouble(key, null, defaultValue, comment); - } - - private static double getDouble(String key, @Nullable String oldKey, double defaultValue, String... comment) { - ensureDefault(key, defaultValue, comment); - return config.getDouble(key, defaultValue); - } - - private static long getLong(String key, long defaultValue, String... comment) { - return getLong(key, null, defaultValue, comment); - } - - private static long getLong(String key, @Nullable String oldKey, long defaultValue, String... comment) { - ensureDefault(key, defaultValue, comment); - return config.getLong(key, defaultValue); - } - - private static String getString(String key, String defaultValue, String... comment) { - return getOldString(key, null, defaultValue, comment); - } - - private static String getOldString(String key, @Nullable String oldKey, String defaultValue, String... comment) { - ensureDefault(key, defaultValue, comment); - return config.getString(key, defaultValue); - } - - private static List getStringList(String key, List defaultValue, String... comment) { - return getStringList(key, null, defaultValue, comment); - } - - private static List getStringList(String key, @Nullable String oldKey, List defaultValue, String... comment) { - ensureDefault(key, defaultValue, comment); - return config.getStringList(key); - } - - public static boolean enableParallelWorldTicking = false; - public static int parallelThreadCount = 4; - public static boolean logContainerCreationStacktraces = false; - public static boolean disableHardThrow = false; - public static boolean pwtCompatabilityMode = false; - private static void parallelWorldTicking() { - enableParallelWorldTicking = getBoolean("settings.parallel-world-ticking.enable", enableParallelWorldTicking, - "Enables Parallel World Ticking, which executes each world’s tick in a separate thread while ensuring that all worlds complete their tick before the next cycle begins.", - "", - "Read more info about this feature at https://bxteam.org/docs/divinemc/features/parallel-world-ticking"); - parallelThreadCount = getInt("settings.parallel-world-ticking.thread-count", parallelThreadCount); - logContainerCreationStacktraces = getBoolean("settings.parallel-world-ticking.log-container-creation-stacktraces", logContainerCreationStacktraces); - disableHardThrow = getBoolean("settings.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("settings.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."); - } - - public static long chunkDataCacheSoftLimit = 8192L; - public static long chunkDataCacheLimit = 32678L; - public static int maxViewDistance = 32; - public static int playerNearChunkDetectionRange = 128; - public static ChunkSystemAlgorithms chunkWorkerAlgorithm = ChunkSystemAlgorithms.C2ME; - public static ChunkTaskPriority chunkTaskPriority = ChunkTaskPriority.EUCLIDEAN_CIRCLE_PATTERN; - public static int threadPoolPriority = Thread.NORM_PRIORITY + 1; - public static boolean asyncChunkSendingEnabled = true; - public static boolean enableSecureSeed = false; - public static boolean smoothBedrockLayer = false; - public static boolean slopesVisualFix = false; - public static boolean enableDensityFunctionCompiler = false; - public static boolean enableStructureLayoutOptimizer = true; - public static boolean deduplicateShuffledTemplatePoolElementList = false; - private static void chunkSettings() { - chunkDataCacheSoftLimit = getLong("settings.chunks.chunk-data-cache-soft-limit", chunkDataCacheSoftLimit); - chunkDataCacheLimit = getLong("settings.chunks.chunk-data-cache-limit", chunkDataCacheLimit); - maxViewDistance = getInt("settings.chunks.max-view-distance", maxViewDistance, - "Changes the maximum view distance for the server, allowing clients to have render distances higher than 32"); - playerNearChunkDetectionRange = getInt("settings.chunks.player-near-chunk-detection-range", playerNearChunkDetectionRange, - "In certain checks, like if a player is near a chunk(primarily used for spawning), it checks if the player is within a certain", - "circular range of the chunk. This configuration allows configurability of the distance(in blocks) the player must be to pass the check.", - "", - "This value is used in the calculation 'range/16' to get the distance in chunks any player must be to allow the check to pass.", - "By default, this range is computed to 8, meaning a player must be within an 8 chunk radius of a chunk position to pass.", - "Keep in mind the result is rounded to the nearest whole number."); - - if (playerNearChunkDetectionRange < 0) { - LOGGER.warn("Invalid player near chunk detection range: {}, resetting to default (128)", playerNearChunkDetectionRange); - playerNearChunkDetectionRange = 128; - } - - chunkWorkerAlgorithm = ChunkSystemAlgorithms.valueOf(getString("settings.chunks.chunk-worker-algorithm", chunkWorkerAlgorithm.name(), - "Modifies what algorithm the chunk system will use to define thread counts.", - "Valid values:", - " - MOONRISE: Default algorithm, used by default in Paper", - " - C2ME: Algorithm used by C2ME (old)", - " - C2ME_NEW: Modern algorithm used by C2ME")); - chunkTaskPriority = ChunkTaskPriority.valueOf(getString("settings.chunks.chunk-task-priority", chunkTaskPriority.name(), - "Sets the algorithm for determining chunk task priorities (generation, loading and etc.).", - "Valid values:", - " - EUCLIDEAN_CIRCLE_PATTERN: Euclidean distance squared algorithm, chunk priorities will be ordered in a circle pattern", - " - DEFAULT_DIAMOND_PATTERN: Default one, chunk priorities will be ordered in a diamond pattern")); - threadPoolPriority = getInt("settings.chunks.thread-pool-priority", threadPoolPriority, - "Sets the priority of the thread pool used for chunk generation"); - - enableSecureSeed = getBoolean("settings.chunks.enable-secure-seed", enableSecureSeed, - "This feature is based on Secure Seed mod by Earthcomputer.", - "", - "Terrain and biome generation remains the same, but all the ores and structures are generated with 1024-bit seed, instead of the usual 64-bit seed.", - "This seed is almost impossible to crack, and there are no weird links between structures."); - asyncChunkSendingEnabled = getBoolean("settings.chunks.enable-async-chunk-sending", asyncChunkSendingEnabled, - "Makes chunk sending asynchronous, which can significantly reduce main thread load when many players are loading chunks."); - - smoothBedrockLayer = getBoolean("settings.chunks.smooth-bedrock-layer", smoothBedrockLayer, - "Smoothens the bedrock layer at the bottom of overworld, and on the top of nether during the world generation."); - slopesVisualFix = getBoolean("settings.chunks.slopes-visual-fix", slopesVisualFix, - "Fixes MC-258859, fixing slopes visual bug in biomes like Snowy Slopes, Frozen Peaks, Jagged Peaks, and including Terralith."); - - enableDensityFunctionCompiler = getBoolean("settings.chunks.experimental.enable-density-function-compiler", enableDensityFunctionCompiler, - "Whether to use density function compiler to accelerate world generation", - "", - "Density function: https://minecraft.wiki/w/Density_function", - "", - "This functionality compiles density functions from world generation", - "datapacks (including vanilla generation) to JVM bytecode to increase", - "performance by allowing JVM JIT to better optimize the code.", - "All functions provided by vanilla are implemented."); - enableStructureLayoutOptimizer = getBoolean("settings.chunks.experimental.enable-structure-layout-optimizer", enableStructureLayoutOptimizer, - "Enables a port of the mod StructureLayoutOptimizer, which optimizes general Jigsaw structure generation"); - deduplicateShuffledTemplatePoolElementList = getBoolean("settings.chunks.experimental.deduplicate-shuffled-template-pool-element-list", deduplicateShuffledTemplatePoolElementList, - "Whether to use an alternative strategy to make structure layouts generate slightly even faster than", - "the default optimization this mod has for template pool weights. This alternative strategy works by", - "changing the list of pieces that structures collect from the template pool to not have duplicate entries.", - "", - "This will not break the structure generation, but it will make the structure layout different than", - "if this config was off (breaking vanilla seed parity). The cost of speed may be worth it in large", - "modpacks where many structure mods are using very high weight values in their template pools."); - } - - public static boolean skipUselessSecondaryPoiSensor = true; - public static boolean clumpOrbs = true; - public static boolean ignoreMovedTooQuicklyWhenLagging = true; - public static boolean alwaysAllowWeirdMovement = true; - public static boolean updateSuppressionCrashFix = true; - public static boolean enableSuffocationOptimization = true; - public static boolean useCompactBitStorage = false; - public static boolean fixIncorrectBounceLogic = false; - public static boolean forceMinecraftCommand = false; - public static boolean disableLeafDecay = false; - public static boolean commandBlockParseResultsCaching = true; - public static boolean enableAsyncSpawning = true; - public static boolean sheepOptimization = true; - public static boolean hopperThrottleWhenFull = false; - public static int hopperThrottleSkipTicks = 0; - private static void miscSettings() { - skipUselessSecondaryPoiSensor = getBoolean("settings.misc.skip-useless-secondary-poi-sensor", skipUselessSecondaryPoiSensor); - clumpOrbs = getBoolean("settings.misc.clump-orbs", clumpOrbs, - "Clumps experience orbs together to reduce entity count"); - ignoreMovedTooQuicklyWhenLagging = getBoolean("settings.misc.ignore-moved-too-quickly-when-lagging", ignoreMovedTooQuicklyWhenLagging, - "Improves general gameplay experience of the player when the server is lagging, as they won't get lagged back (message 'moved too quickly')"); - alwaysAllowWeirdMovement = getBoolean("settings.misc.always-allow-weird-movement", alwaysAllowWeirdMovement, - "Means ignoring messages like 'moved too quickly' and 'moved wrongly'"); - updateSuppressionCrashFix = getBoolean("settings.misc.update-suppression-crash-fix", updateSuppressionCrashFix); - enableSuffocationOptimization = getBoolean("settings.misc.enable-suffocation-optimization", enableSuffocationOptimization, - "Optimizes the suffocation check by selectively skipping the check in a way that still appears vanilla.", - "This option should be left enabled on most servers, but is provided as a configuration option if the vanilla deviation is undesirable."); - useCompactBitStorage = getBoolean("settings.misc.use-compact-bit-storage", useCompactBitStorage, - "Fixes memory waste caused by sending empty chunks as if they contain blocks. Can significantly reduce memory usage."); - fixIncorrectBounceLogic = getBoolean("settings.misc.fix-incorrect-bounce-logic", fixIncorrectBounceLogic, - "Fixes incorrect bounce logic in SlimeBlock."); - forceMinecraftCommand = getBoolean("settings.misc.force-minecraft-command", forceMinecraftCommand, - "Whether to force the use of vanilla commands over plugin commands."); - disableLeafDecay = getBoolean("settings.misc.disable-leaf-decay", disableLeafDecay, - "Disables leaf block decay."); - commandBlockParseResultsCaching = getBoolean("settings.misc.command-block-parse-results-caching", commandBlockParseResultsCaching, - "Caches the parse results of command blocks, can significantly reduce performance impact."); - enableAsyncSpawning = getBoolean("settings.misc.enable-async-spawning", enableAsyncSpawning, - "Enables optimization that will offload much of the computational effort involved with spawning new mobs to a different thread."); - sheepOptimization = getBoolean("settings.misc.sheep-optimization", sheepOptimization, - "Enables optimization from Carpet Fixes mod, using a prebaked list of all the possible colors and combinations for sheep."); - - hopperThrottleWhenFull = getBoolean("settings.misc.hopper-throttle-when-full.enabled", hopperThrottleWhenFull, - "When enabled, hoppers will throttle if target container is full."); - hopperThrottleSkipTicks = getInt("settings.misc.hopper-throttle-when-full.skip-ticks", hopperThrottleSkipTicks, - "The amount of ticks to skip when the hopper is throttled."); - } - - public static String sentryDsn = ""; - public static String logLevel = "WARN"; - public static boolean onlyLogThrown = true; - private static void sentrySettings() { - sentryDsn = getString("settings.sentry.dsn", sentryDsn, - "The DSN for Sentry, a service that provides real-time crash reporting that helps you monitor and fix crashes in real time. Leave blank to disable. Obtain link at https://sentry.io"); - logLevel = getString("settings.sentry.log-level", logLevel, - "Logs with a level higher than or equal to this level will be recorded."); - onlyLogThrown = getBoolean("settings.sentry.only-log-thrown", onlyLogThrown, - "Only log Throwable exceptions to Sentry."); - - if (sentryDsn != null && !sentryDsn.isBlank()) gg.pufferfish.pufferfish.sentry.SentryManager.init(Level.getLevel(logLevel)); - } - - public static boolean disableDisconnectSpam = false; - public static boolean gracefulTeleportHandling = false; - public static boolean dontRespondPingBeforeStart = true; - public static boolean playerProfileResultCachingEnabled = true; - public static int playerProfileResultCachingTimeout = 1440; - private static void networkSettings() { - disableDisconnectSpam = getBoolean("settings.network.disable-disconnect-spam", disableDisconnectSpam, - "Prevents players being disconnected by 'disconnect.spam' when sending too many chat packets"); - gracefulTeleportHandling = getBoolean("settings.network.graceful-teleport-handling", gracefulTeleportHandling , - "Disables being disconnected from 'multiplayer.disconnect.invalid_player_movement' (also declines the packet handling)."); - dontRespondPingBeforeStart = getBoolean("settings.network.dont-respond-ping-before-start", dontRespondPingBeforeStart, - "Prevents the server from responding to pings before the server is fully booted."); - - playerProfileResultCachingEnabled = getBoolean("settings.network.player-profile-result-caching.enabled", playerProfileResultCachingEnabled, - "Enables caching of player profile results on first join."); - playerProfileResultCachingTimeout = getInt("settings.network.player-profile-result-caching.timeout", playerProfileResultCachingTimeout, - "The amount of time in minutes to cache player profile results."); - } - - public static boolean enableFasterTntOptimization = true; - public static boolean explosionNoBlockDamage = false; - public static double tntRandomRange = -1; - private static void tntOptimization() { - enableFasterTntOptimization = getBoolean("settings.tnt-optimization.enable-faster-tnt-optimization", enableFasterTntOptimization); - explosionNoBlockDamage = getBoolean("settings.tnt-optimization.explosion-no-block-damage", explosionNoBlockDamage); - tntRandomRange = getDouble("settings.tnt-optimization.tnt-random-range", tntRandomRange); - } - - public static boolean lagCompensationEnabled = true; - public static boolean blockEntityAcceleration = false; - public static boolean blockBreakingAcceleration = true; - public static boolean eatingAcceleration = true; - public static boolean potionEffectAcceleration = true; - public static boolean fluidAcceleration = true; - public static boolean pickupAcceleration = true; - public static boolean portalAcceleration = true; - public static boolean timeAcceleration = true; - public static boolean randomTickSpeedAcceleration = true; - private static void lagCompensation() { - lagCompensationEnabled = getBoolean("settings.lag-compensation.enabled", lagCompensationEnabled, "Improves the player experience when TPS is low"); - blockEntityAcceleration = getBoolean("settings.lag-compensation.block-entity-acceleration", blockEntityAcceleration); - blockBreakingAcceleration = getBoolean("settings.lag-compensation.block-breaking-acceleration", blockBreakingAcceleration); - eatingAcceleration = getBoolean("settings.lag-compensation.eating-acceleration", eatingAcceleration); - potionEffectAcceleration = getBoolean("settings.lag-compensation.potion-effect-acceleration", potionEffectAcceleration); - fluidAcceleration = getBoolean("settings.lag-compensation.fluid-acceleration", fluidAcceleration); - pickupAcceleration = getBoolean("settings.lag-compensation.pickup-acceleration", pickupAcceleration); - portalAcceleration = getBoolean("settings.lag-compensation.portal-acceleration", portalAcceleration); - timeAcceleration = getBoolean("settings.lag-compensation.time-acceleration", timeAcceleration); - randomTickSpeedAcceleration = getBoolean("settings.lag-compensation.random-tick-speed-acceleration", randomTickSpeedAcceleration); - } - - public static boolean noChatReportsEnabled = false; - public static boolean noChatReportsAddQueryData = true; - public static boolean noChatReportsConvertToGameMessage = true; - public static boolean noChatReportsDebugLog = false; - public static boolean noChatReportsDemandOnClient = false; - public static String noChatReportsDisconnectDemandOnClientMessage = "You do not have No Chat Reports, and this server is configured to require it on client!"; - private static void noChatReports() { - noChatReportsEnabled = getBoolean("settings.no-chat-reports.enabled", noChatReportsEnabled, - "Enables or disables the No Chat Reports feature"); - noChatReportsAddQueryData = getBoolean("settings.no-chat-reports.add-query-data", noChatReportsAddQueryData, - "Should server include extra query data to help clients know that your server is secure"); - noChatReportsConvertToGameMessage = getBoolean("settings.no-chat-reports.convert-to-game-message", noChatReportsConvertToGameMessage, - "Should the server convert all player messages to system messages"); - noChatReportsDebugLog = getBoolean("settings.no-chat-reports.debug-log", noChatReportsDebugLog); - noChatReportsDemandOnClient = getBoolean("settings.no-chat-reports.demand-on-client", noChatReportsDemandOnClient, - "Should the server require No Chat Reports on the client side"); - noChatReportsDisconnectDemandOnClientMessage = getString("settings.no-chat-reports.disconnect-demand-on-client-message", noChatReportsDisconnectDemandOnClientMessage, - "Message to send to the client when they are disconnected for not having No Chat Reports"); - } - - public static boolean virtualThreadsEnabled = false; - public static boolean virtualBukkitScheduler = false; - public static boolean virtualChatScheduler = false; - public static boolean virtualAuthenticatorScheduler = false; - public static boolean virtualTabCompleteScheduler = false; - public static boolean virtualAsyncExecutor = false; - public static boolean virtualCommandBuilderScheduler = false; - public static boolean virtualProfileLookupPool = false; - public static boolean virtualServerTextFilterPool = false; - private static void virtualThreads() { - virtualThreadsEnabled = getBoolean("settings.virtual-threads.enabled", virtualThreadsEnabled, - "Enables use of virtual threads that was added in Java 21"); - - virtualBukkitScheduler = getBoolean("settings.virtual-threads.bukkit-scheduler", virtualBukkitScheduler, - "Uses virtual threads for the Bukkit scheduler."); - virtualChatScheduler = getBoolean("settings.virtual-threads.chat-scheduler", virtualChatScheduler, - "Uses virtual threads for the Chat scheduler."); - virtualAuthenticatorScheduler = getBoolean("settings.virtual-threads.authenticator-scheduler", virtualAuthenticatorScheduler, - "Uses virtual threads for the Authenticator scheduler."); - virtualTabCompleteScheduler = getBoolean("settings.virtual-threads.tab-complete-scheduler", virtualTabCompleteScheduler, - "Uses virtual threads for the Tab Complete scheduler."); - virtualAsyncExecutor = getBoolean("settings.virtual-threads.async-executor", virtualAsyncExecutor, - "Uses virtual threads for the MCUtil async executor."); - virtualCommandBuilderScheduler = getBoolean("settings.virtual-threads.command-builder-scheduler", virtualCommandBuilderScheduler, - "Uses virtual threads for the Async Command Builder Thread Pool."); - virtualProfileLookupPool = getBoolean("settings.virtual-threads.profile-lookup-pool", virtualProfileLookupPool, - "Uses virtual threads for the Profile Lookup Pool, that is used for fetching player profiles."); - virtualServerTextFilterPool = getBoolean("settings.virtual-threads.server-text-filter-pool", virtualServerTextFilterPool, - "Uses virtual threads for the server text filter pool."); - } - - public static boolean dabEnabled = true; - public static int dabStartDistance = 12; - public static int dabStartDistanceSquared; - public static int dabMaximumActivationFrequency = 20; - public static int dabActivationDistanceMod = 8; - public static boolean dabDontEnableIfInWater = false; - public static List dabBlackedEntities = new ArrayList<>(); - private static void dab() { - dabEnabled = getBoolean("settings.dab.enabled", dabEnabled, - "Enables DAB feature"); - dabStartDistance = getInt("settings.dab.start-distance", dabStartDistance, - "This value determines how far away an entity has to be"); - dabStartDistanceSquared = dabStartDistance * dabStartDistance; - dabMaximumActivationFrequency = getInt("settings.dab.maximum-activation-frequency", dabMaximumActivationFrequency, - "How often in ticks, the furthest entity will get their pathfinders and behaviors ticked."); - dabActivationDistanceMod = getInt("settings.dab.activation-distance-mod", dabActivationDistanceMod, - "Modifies an entity's tick frequency.", - "The exact calculation to obtain the tick frequency for an entity is: freq = (distanceToPlayer^2) / (2^value), where value is this configuration setting.", - "Large servers may want to reduce the value to 7, but this value should never be reduced below 6. If you want further away entities to tick more often, set the value to 9"); - dabDontEnableIfInWater = getBoolean("settings.dab.dont-enable-if-in-water", dabDontEnableIfInWater, - "When this is enabled, non-aquatic entities in the water will not be affected by DAB."); - dabBlackedEntities = getStringList("settings.dab.blacked-entities", dabBlackedEntities, - "Use this configuration option to specify that certain entities should not be impacted by DAB."); - - setComment("settings.dab", - "DAB is an optimization that reduces the frequency of brain ticks. Brain ticks are very intensive, which is why they", - "are limited. DAB can be tuned to meet your preferred performance-experience tradeoff. The farther away entities", - "are from players, the less frequently their brains will be ticked. While DAB does impact the AI goal selector", - "behavior of all entities, the only entities who's brain ticks are limited are: Villager, Axolotl, Hoglin, Zombified Piglin and Goat"); - - for (EntityType entityType : BuiltInRegistries.ENTITY_TYPE) { - entityType.dabEnabled = true; - } - - final String DEFAULT_PREFIX = ResourceLocation.DEFAULT_NAMESPACE + ResourceLocation.NAMESPACE_SEPARATOR; - for (String name : dabBlackedEntities) { - String lowerName = name.toLowerCase(Locale.ROOT); - String typeId = lowerName.startsWith(DEFAULT_PREFIX) ? lowerName : DEFAULT_PREFIX + lowerName; - - EntityType.byString(typeId).ifPresentOrElse(entityType -> entityType.dabEnabled = false, () -> LOGGER.warn("Unknown entity {}, in {}", name, "settings.dab.blacked-entities")); - } - } - - public static boolean asyncPathfinding = true; - public static int asyncPathfindingMaxThreads = 2; - public static int asyncPathfindingKeepalive = 60; - public static int asyncPathfindingQueueSize = 0; - public static PathfindTaskRejectPolicy asyncPathfindingRejectPolicy = PathfindTaskRejectPolicy.FLUSH_ALL; - private static void asyncPathfinding() { - asyncPathfinding = getBoolean("settings.async-pathfinding.enable", asyncPathfinding); - asyncPathfindingMaxThreads = getInt("settings.async-pathfinding.max-threads", asyncPathfindingMaxThreads); - asyncPathfindingKeepalive = getInt("settings.async-pathfinding.keepalive", asyncPathfindingKeepalive); - asyncPathfindingQueueSize = getInt("settings.async-pathfinding.queue-size", asyncPathfindingQueueSize); - - final int maxThreads = Runtime.getRuntime().availableProcessors(); - if (asyncPathfindingMaxThreads < 0) { - asyncPathfindingMaxThreads = Math.max(maxThreads + asyncPathfindingMaxThreads, 1); - } else if (asyncPathfindingMaxThreads == 0) { - asyncPathfindingMaxThreads = Math.max(maxThreads / 4, 1); - } - - if (!asyncPathfinding) { - asyncPathfindingMaxThreads = 0; - } else { - LOGGER.info("Using {} threads for Async Pathfinding", asyncPathfindingMaxThreads); - } - - if (asyncPathfindingQueueSize <= 0) asyncPathfindingQueueSize = asyncPathfindingMaxThreads * 256; - - asyncPathfindingRejectPolicy = PathfindTaskRejectPolicy.fromString(getString("settings.async-pathfinding.reject-policy", maxThreads >= 12 && asyncPathfindingQueueSize < 512 ? PathfindTaskRejectPolicy.FLUSH_ALL.toString() : PathfindTaskRejectPolicy.CALLER_RUNS.toString(), - "The policy to use when the queue is full and a new task is submitted.", - "FLUSH_ALL: All pending tasks will be run on server thread.", - "CALLER_RUNS: Newly submitted task will be run on server thread.")); - } - - public static boolean multithreadedEnabled = true; - public static boolean multithreadedCompatModeEnabled = false; - public static int asyncEntityTrackerMaxThreads = 1; - public static int asyncEntityTrackerKeepalive = 60; - public static int asyncEntityTrackerQueueSize = 0; - private static void multithreadedTracker() { - multithreadedEnabled = getBoolean("settings.multithreaded-tracker.enable", multithreadedEnabled, - "Make entity tracking saving asynchronously, can improve performance significantly,", - "especially in some massive entities in small area situations."); - multithreadedCompatModeEnabled = getBoolean("settings.multithreaded-tracker.compat-mode", multithreadedCompatModeEnabled, - "Enable compat mode ONLY if Citizens or NPC plugins using real entity has installed.", - "Compat mode fixes visible issues with player type NPCs of Citizens.", - "But we recommend to use packet based / virtual entity NPC plugin, e.g. ZNPC Plus, Adyeshach, Fancy NPC and etc."); - - asyncEntityTrackerMaxThreads = getInt("settings.multithreaded-tracker.max-threads", asyncEntityTrackerMaxThreads); - asyncEntityTrackerKeepalive = getInt("settings.multithreaded-tracker.keepalive", asyncEntityTrackerKeepalive); - asyncEntityTrackerQueueSize = getInt("settings.multithreaded-tracker.queue-size", asyncEntityTrackerQueueSize); - - if (asyncEntityTrackerMaxThreads < 0) { - asyncEntityTrackerMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() + asyncEntityTrackerMaxThreads, 1); - } else if (asyncEntityTrackerMaxThreads == 0) { - asyncEntityTrackerMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() / 4, 1); - } - - if (!multithreadedEnabled) { - asyncEntityTrackerMaxThreads = 0; - } else { - LOGGER.info("Using {} threads for Async Entity Tracker", asyncEntityTrackerMaxThreads); - } - - if (asyncEntityTrackerQueueSize <= 0) asyncEntityTrackerQueueSize = asyncEntityTrackerMaxThreads * 384; - } - - public static RegionFileFormat regionFormatTypeName = RegionFileFormat.ANVIL; - public static LinearImplementation linearImplementation = LinearImplementation.V2; - public static int linearFlushMaxThreads = 4; - public static int linearFlushDelay = 100; - public static boolean linearUseVirtualThread = false; - public static int linearCompressionLevel = 1; - private static void linearRegionFormat() { - regionFormatTypeName = RegionFileFormat.fromName(getString("settings.linear-region-format.type", regionFormatTypeName.name(), - "The type of region file format to use for storing chunk data.", - "Valid values:", - " - LINEAR: Linear region file format", - " - ANVIL: Anvil region file format (default)")); - linearImplementation = LinearImplementation.valueOf(getString("settings.linear-region-format.implementation", linearImplementation.name(), - "The implementation of the linear region file format to use.", - "Valid values:", - " - V1: Basic and default linear implementation", - " - V2: Introduces a grid-based compression scheme for better data management and flexibility (default)")); - - linearFlushMaxThreads = getInt("settings.linear-region-format.flush-max-threads", linearFlushMaxThreads, - "The maximum number of threads to use for flushing linear region files.", - "If this value is less than or equal to 0, it will be set to the number of available processors + this value."); - linearFlushDelay = getInt("settings.linear-region-format.flush-delay", linearFlushDelay, - "The delay in milliseconds to wait before flushing next files."); - linearUseVirtualThread = getBoolean("settings.linear-region-format.use-virtual-thread", linearUseVirtualThread, - "Whether to use virtual threads for flushing."); - linearCompressionLevel = getInt("settings.linear-region-format.compression-level", linearCompressionLevel, - "The compression level to use for the linear region file format."); - - setComment("settings.linear-region-format", - "The linear region file format is a custom region file format that is designed to be more efficient than the ANVIL format.", - "It uses uses ZSTD compression instead of ZLIB. This format saves about 50% of disk space.", - "Read more information about linear region format at https://github.com/xymb-endcrystalme/LinearRegionFileFormatTools", - "WARNING: If you are want to use this format, make sure to create backup of your world before switching to it, there is potential risk to lose chunk data."); - - if (regionFormatTypeName == RegionFileFormat.UNKNOWN) { - LOGGER.error("Unknown region file type: {}, falling back to ANVIL format.", regionFormatTypeName); - regionFormatTypeName = RegionFileFormat.ANVIL; - } - - if (linearFlushMaxThreads <= 0) { - linearFlushMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() + linearFlushMaxThreads, 1); - } - - if (linearCompressionLevel > 22 || linearCompressionLevel < 1) { - LOGGER.warn("Invalid linear compression level: {}, resetting to default (1)", playerNearChunkDetectionRange); - linearCompressionLevel = 1; - } - } -} diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/command/subcommands/MSPTCommand.java b/divinemc-server/src/main/java/org/bxteam/divinemc/command/subcommands/MSPTCommand.java index e8531ef..2ec4aaa 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/command/subcommands/MSPTCommand.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/command/subcommands/MSPTCommand.java @@ -6,7 +6,7 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import org.bukkit.command.CommandSender; import org.bukkit.permissions.PermissionDefault; -import org.bxteam.divinemc.DivineConfig; +import org.bxteam.divinemc.config.DivineConfig; import org.bxteam.divinemc.command.DivineCommand; import org.bxteam.divinemc.command.DivineSubCommandPermission; import org.checkerframework.checker.nullness.qual.NonNull; @@ -35,7 +35,7 @@ public final class MSPTCommand extends DivineSubCommandPermission { @Override public boolean execute(CommandSender sender, String subCommand, String[] args) { - if (!DivineConfig.enableParallelWorldTicking) { + if (!DivineConfig.AsyncCategory.enableParallelWorldTicking) { sender.sendMessage(Component.text("Per-world MSPT tracking is only available when parallel world ticking is enabled.", RED)); sender.sendMessage(Component.text("Please enable it in divinemc.yml to use this command.", GRAY)); return true; @@ -160,7 +160,7 @@ public final class MSPTCommand extends DivineSubCommandPermission { @Override public List tabComplete(CommandSender sender, String subCommand, String[] args) { - if (!DivineConfig.enableParallelWorldTicking) { + if (!DivineConfig.AsyncCategory.enableParallelWorldTicking) { return Collections.emptyList(); } if (args.length == 1) { diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/command/subcommands/ReloadCommand.java b/divinemc-server/src/main/java/org/bxteam/divinemc/command/subcommands/ReloadCommand.java index 47109b9..2df61ad 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/command/subcommands/ReloadCommand.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/command/subcommands/ReloadCommand.java @@ -9,7 +9,7 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.permissions.PermissionDefault; import org.bxteam.divinemc.command.DivineCommand; import org.bxteam.divinemc.command.DivineSubCommandPermission; -import org.bxteam.divinemc.DivineConfig; +import org.bxteam.divinemc.config.DivineConfig; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.framework.qual.DefaultQualifier; diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/config/ConfigCategory.java b/divinemc-server/src/main/java/org/bxteam/divinemc/config/ConfigCategory.java new file mode 100644 index 0000000..56945c5 --- /dev/null +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/config/ConfigCategory.java @@ -0,0 +1,19 @@ +package org.bxteam.divinemc.config; + +public enum ConfigCategory { + ASYNC("async"), + PERFORMANCE("performance"), + FIXES("fixes"), + NETWORK("network"), + MISC("misc"); + + private final String name; + + ConfigCategory(String name) { + this.name = name; + } + + public String key(String sub) { + return name + "." + sub; + } +} 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 new file mode 100644 index 0000000..490b91f --- /dev/null +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java @@ -0,0 +1,711 @@ +package org.bxteam.divinemc.config; + +import com.google.common.base.Throwables; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.EntityType; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.MemoryConfiguration; +import org.bxteam.divinemc.entity.pathfinding.PathfindTaskRejectPolicy; +import org.bxteam.divinemc.region.LinearImplementation; +import org.bxteam.divinemc.server.chunk.ChunkSystemAlgorithms; +import org.bxteam.divinemc.server.chunk.ChunkTaskPriority; +import org.jetbrains.annotations.Nullable; +import org.simpleyaml.configuration.comments.CommentType; +import org.simpleyaml.configuration.file.YamlFile; +import org.simpleyaml.exceptions.InvalidConfigurationException; +import org.bxteam.divinemc.region.RegionFileFormat; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +@SuppressWarnings({"unused", "SameParameterValue"}) +public class DivineConfig { + private static final String HEADER = """ + This is the main configuration file for DivineMC. + If you need help with the configuration or have any questions related to DivineMC, + join us in our Discord server. + + Discord: https://discord.gg/qNyybSSPm5 + Docs: https://bxteam.org/docs/divinemc + Downloads: https://github.com/BX-Team/DivineMC/releases"""; + + public static final Logger LOGGER = LogManager.getLogger(DivineConfig.class.getSimpleName()); + public static final int CONFIG_VERSION = 6; + + private static File configFile; + public static final YamlFile config = new YamlFile(); + + private static ConfigurationSection convertToBukkit(org.simpleyaml.configuration.ConfigurationSection section) { + ConfigurationSection newSection = new MemoryConfiguration(); + for (String key : section.getKeys(false)) { + if (section.isConfigurationSection(key)) { + newSection.set(key, convertToBukkit(section.getConfigurationSection(key))); + } else { + newSection.set(key, section.get(key)); + } + } + return newSection; + } + + public static ConfigurationSection getConfigCopy() { + return convertToBukkit(config); + } + + public static void init(File configFile) throws IOException { + DivineConfig.configFile = configFile; + if (configFile.exists()) { + try { + config.load(configFile); + } catch (InvalidConfigurationException e) { + throw new IOException(e); + } + } + + getInt("version", CONFIG_VERSION); + config.options().header(HEADER); + + readConfig(DivineConfig.class, null); + } + + static void readConfig(Class clazz, Object instance) throws IOException { + for (Method method : clazz.getDeclaredMethods()) { + if (Modifier.isPrivate(method.getModifiers()) && + method.getParameterTypes().length == 0 && + method.getReturnType() == Void.TYPE) { + try { + method.setAccessible(true); + method.invoke(instance); + } catch (InvocationTargetException ex) { + throw Throwables.propagate(ex.getCause()); + } catch (Exception ex) { + LOGGER.error("Error invoking {}", method, ex); + } + } + } + + for (Class innerClass : clazz.getDeclaredClasses()) { + if (Modifier.isStatic(innerClass.getModifiers())) { + try { + Object innerInstance = null; + + Method loadMethod = null; + try { + loadMethod = innerClass.getDeclaredMethod("load"); + } catch (NoSuchMethodException ignored) { + readConfig(innerClass, null); + continue; + } + + if (loadMethod != null) { + try { + innerInstance = innerClass.getDeclaredConstructor().newInstance(); + } catch (NoSuchMethodException e) { + innerInstance = null; + } + + loadMethod.setAccessible(true); + loadMethod.invoke(innerInstance); + } + } catch (Exception ex) { + LOGGER.error("Error processing inner class {}", innerClass.getName(), ex); + } + } + } + + config.save(configFile); + } + + private static void setComment(String key, String... comment) { + if (config.contains(key)) { + config.setComment(key, String.join("\n", comment), CommentType.BLOCK); + } + } + + private static void ensureDefault(String key, Object defaultValue, String... comment) { + if (!config.contains(key)) config.set(key, defaultValue); + if (comment.length > 0) config.setComment(key, String.join("\n", comment), CommentType.BLOCK); + } + + private static boolean getBoolean(String key, boolean defaultValue, String... comment) { + return getBoolean(key, null, defaultValue, comment); + } + + private static boolean getBoolean(String key, @Nullable String oldKey, boolean defaultValue, String... comment) { + ensureDefault(key, defaultValue, comment); + return config.getBoolean(key, defaultValue); + } + + private static int getInt(String key, int defaultValue, String... comment) { + return getInt(key, null, defaultValue, comment); + } + + private static int getInt(String key, @Nullable String oldKey, int defaultValue, String... comment) { + ensureDefault(key, defaultValue, comment); + return config.getInt(key, defaultValue); + } + + private static double getDouble(String key, double defaultValue, String... comment) { + return getDouble(key, null, defaultValue, comment); + } + + private static double getDouble(String key, @Nullable String oldKey, double defaultValue, String... comment) { + ensureDefault(key, defaultValue, comment); + return config.getDouble(key, defaultValue); + } + + private static long getLong(String key, long defaultValue, String... comment) { + return getLong(key, null, defaultValue, comment); + } + + private static long getLong(String key, @Nullable String oldKey, long defaultValue, String... comment) { + ensureDefault(key, defaultValue, comment); + return config.getLong(key, defaultValue); + } + + private static String getString(String key, String defaultValue, String... comment) { + return getOldString(key, null, defaultValue, comment); + } + + private static String getOldString(String key, @Nullable String oldKey, String defaultValue, String... comment) { + ensureDefault(key, defaultValue, comment); + return config.getString(key, defaultValue); + } + + private static List getStringList(String key, List defaultValue, String... comment) { + return getStringList(key, null, defaultValue, comment); + } + + private static List getStringList(String key, @Nullable String oldKey, List defaultValue, String... comment) { + ensureDefault(key, defaultValue, comment); + return config.getStringList(key); + } + + public static class AsyncCategory { + // Parallel world ticking settings + public static boolean enableParallelWorldTicking = false; + public static int parallelThreadCount = 4; + public static boolean logContainerCreationStacktraces = false; + public static boolean disableHardThrow = false; + public static boolean pwtCompatabilityMode = false; + + // Async pathfinding settings + public static boolean asyncPathfinding = true; + public static int asyncPathfindingMaxThreads = 2; + public static int asyncPathfindingKeepalive = 60; + public static int asyncPathfindingQueueSize = 0; + public static PathfindTaskRejectPolicy asyncPathfindingRejectPolicy = PathfindTaskRejectPolicy.FLUSH_ALL; + + // Multithreaded tracker settings + public static boolean multithreadedEnabled = true; + public static boolean multithreadedCompatModeEnabled = false; + public static int asyncEntityTrackerMaxThreads = 1; + public static int asyncEntityTrackerKeepalive = 60; + public static int asyncEntityTrackerQueueSize = 0; + + // Async chunk sending settings + public static boolean asyncChunkSendingEnabled = true; + + // Async mob spawning settings + public static boolean enableAsyncSpawning = true; + + public static void load() { + parallelWorldTicking(); + asyncPathfinding(); + multithreadedTracker(); + asyncChunkSending(); + asyncMobSpawning(); + } + + private static void parallelWorldTicking() { + enableParallelWorldTicking = getBoolean(ConfigCategory.ASYNC.key("parallel-world-ticking.enable"), enableParallelWorldTicking, + "Enables Parallel World Ticking, which executes each world's tick in a separate thread while ensuring that all worlds complete their tick before the next cycle begins.", + "", + "Read more info about this feature at https://bxteam.org/docs/divinemc/features/parallel-world-ticking"); + parallelThreadCount = getInt(ConfigCategory.ASYNC.key("parallel-world-ticking.thread-count"), parallelThreadCount); + 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."); + } + + private static void asyncPathfinding() { + asyncPathfinding = getBoolean(ConfigCategory.ASYNC.key("pathfinding.enable"), asyncPathfinding); + asyncPathfindingMaxThreads = getInt(ConfigCategory.ASYNC.key("pathfinding.max-threads"), asyncPathfindingMaxThreads); + asyncPathfindingKeepalive = getInt(ConfigCategory.ASYNC.key("pathfinding.keepalive"), asyncPathfindingKeepalive); + asyncPathfindingQueueSize = getInt(ConfigCategory.ASYNC.key("pathfinding.queue-size"), asyncPathfindingQueueSize); + + final int maxThreads = Runtime.getRuntime().availableProcessors(); + if (asyncPathfindingMaxThreads < 0) { + asyncPathfindingMaxThreads = Math.max(maxThreads + asyncPathfindingMaxThreads, 1); + } else if (asyncPathfindingMaxThreads == 0) { + asyncPathfindingMaxThreads = Math.max(maxThreads / 4, 1); + } + + if (!asyncPathfinding) { + asyncPathfindingMaxThreads = 0; + } else { + LOGGER.info("Using {} threads for Async Pathfinding", asyncPathfindingMaxThreads); + } + + if (asyncPathfindingQueueSize <= 0) asyncPathfindingQueueSize = asyncPathfindingMaxThreads * 256; + + asyncPathfindingRejectPolicy = PathfindTaskRejectPolicy.fromString(getString(ConfigCategory.ASYNC.key("pathfinding.reject-policy"), maxThreads >= 12 && asyncPathfindingQueueSize < 512 ? PathfindTaskRejectPolicy.FLUSH_ALL.toString() : PathfindTaskRejectPolicy.CALLER_RUNS.toString(), + "The policy to use when the queue is full and a new task is submitted.", + "FLUSH_ALL: All pending tasks will be run on server thread.", + "CALLER_RUNS: Newly submitted task will be run on server thread.")); + } + + private static void multithreadedTracker() { + multithreadedEnabled = getBoolean(ConfigCategory.ASYNC.key("multithreaded-tracker.enable"), multithreadedEnabled, + "Make entity tracking saving asynchronously, can improve performance significantly,", + "especially in some massive entities in small area situations."); + multithreadedCompatModeEnabled = getBoolean(ConfigCategory.ASYNC.key("multithreaded-tracker.compat-mode"), multithreadedCompatModeEnabled, + "Enable compat mode ONLY if Citizens or NPC plugins using real entity has installed.", + "Compat mode fixes visible issues with player type NPCs of Citizens.", + "But we recommend to use packet based / virtual entity NPC plugin, e.g. ZNPC Plus, Adyeshach, Fancy NPC and etc."); + + asyncEntityTrackerMaxThreads = getInt(ConfigCategory.ASYNC.key("multithreaded-tracker.max-threads"), asyncEntityTrackerMaxThreads); + asyncEntityTrackerKeepalive = getInt(ConfigCategory.ASYNC.key("multithreaded-tracker.keepalive"), asyncEntityTrackerKeepalive); + asyncEntityTrackerQueueSize = getInt(ConfigCategory.ASYNC.key("multithreaded-tracker.queue-size"), asyncEntityTrackerQueueSize); + + if (asyncEntityTrackerMaxThreads < 0) { + asyncEntityTrackerMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() + asyncEntityTrackerMaxThreads, 1); + } else if (asyncEntityTrackerMaxThreads == 0) { + asyncEntityTrackerMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() / 4, 1); + } + + if (!multithreadedEnabled) { + asyncEntityTrackerMaxThreads = 0; + } else { + LOGGER.info("Using {} threads for Async Entity Tracker", asyncEntityTrackerMaxThreads); + } + + if (asyncEntityTrackerQueueSize <= 0) asyncEntityTrackerQueueSize = asyncEntityTrackerMaxThreads * 384; + } + + private static void asyncChunkSending() { + asyncChunkSendingEnabled = getBoolean(ConfigCategory.ASYNC.key("chunk-sending.enable"), asyncChunkSendingEnabled, + "Makes chunk sending asynchronous, which can significantly reduce main thread load when many players are loading chunks."); + } + + private static void asyncMobSpawning() { + enableAsyncSpawning = getBoolean(ConfigCategory.ASYNC.key("mob-spawning.enable"), enableAsyncSpawning, + "Enables optimization that will offload much of the computational effort involved with spawning new mobs to a different thread."); + } + } + + public static class PerformanceCategory { + // Chunk settings + public static long chunkDataCacheSoftLimit = 8192L; + public static long chunkDataCacheLimit = 32678L; + public static int maxViewDistance = 32; + public static int playerNearChunkDetectionRange = 128; + public static ChunkSystemAlgorithms chunkWorkerAlgorithm = ChunkSystemAlgorithms.C2ME; + public static ChunkTaskPriority chunkTaskPriority = ChunkTaskPriority.EUCLIDEAN_CIRCLE_PATTERN; + public static int threadPoolPriority = Thread.NORM_PRIORITY + 1; + public static boolean smoothBedrockLayer = false; + public static boolean enableDensityFunctionCompiler = false; + public static boolean enableStructureLayoutOptimizer = true; + public static boolean deduplicateShuffledTemplatePoolElementList = false; + + // TNT optimization + public static boolean enableFasterTntOptimization = true; + public static boolean explosionNoBlockDamage = false; + public static double tntRandomRange = -1; + + // General optimizations + public static boolean skipUselessSecondaryPoiSensor = true; + public static boolean clumpOrbs = true; + public static boolean enableSuffocationOptimization = true; + public static boolean useCompactBitStorage = false; + public static boolean commandBlockParseResultsCaching = true; + public static boolean sheepOptimization = true; + public static boolean hopperThrottleWhenFull = false; + public static int hopperThrottleSkipTicks = 0; + + // DAB settings + public static boolean dabEnabled = true; + public static int dabStartDistance = 12; + public static int dabStartDistanceSquared; + public static int dabMaximumActivationFrequency = 20; + public static int dabActivationDistanceMod = 8; + public static boolean dabDontEnableIfInWater = false; + public static List dabBlackedEntities = new ArrayList<>(); + + // Virtual threads + public static boolean virtualThreadsEnabled = false; + public static boolean virtualBukkitScheduler = false; + public static boolean virtualChatScheduler = false; + public static boolean virtualAuthenticatorScheduler = false; + public static boolean virtualTabCompleteScheduler = false; + public static boolean virtualAsyncExecutor = false; + public static boolean virtualCommandBuilderScheduler = false; + public static boolean virtualProfileLookupPool = false; + public static boolean virtualServerTextFilterPool = false; + + public static void load() { + chunkSettings(); + tntOptimization(); + optimizationSettings(); + dab(); + virtualThreads(); + } + + private static void chunkSettings() { + chunkDataCacheSoftLimit = getLong(ConfigCategory.PERFORMANCE.key("chunks.chunk-data-cache-soft-limit"), chunkDataCacheSoftLimit); + chunkDataCacheLimit = getLong(ConfigCategory.PERFORMANCE.key("chunks.chunk-data-cache-limit"), chunkDataCacheLimit); + maxViewDistance = getInt(ConfigCategory.PERFORMANCE.key("chunks.max-view-distance"), maxViewDistance, + "Changes the maximum view distance for the server, allowing clients to have render distances higher than 32"); + playerNearChunkDetectionRange = getInt(ConfigCategory.PERFORMANCE.key("chunks.player-near-chunk-detection-range"), playerNearChunkDetectionRange, + "In certain checks, like if a player is near a chunk(primarily used for spawning), it checks if the player is within a certain", + "circular range of the chunk. This configuration allows configurability of the distance(in blocks) the player must be to pass the check.", + "", + "This value is used in the calculation 'range/16' to get the distance in chunks any player must be to allow the check to pass.", + "By default, this range is computed to 8, meaning a player must be within an 8 chunk radius of a chunk position to pass.", + "Keep in mind the result is rounded to the nearest whole number."); + + if (playerNearChunkDetectionRange < 0) { + LOGGER.warn("Invalid player near chunk detection range: {}, resetting to default (128)", playerNearChunkDetectionRange); + playerNearChunkDetectionRange = 128; + } + + chunkWorkerAlgorithm = ChunkSystemAlgorithms.valueOf(getString(ConfigCategory.PERFORMANCE.key("chunks.chunk-worker-algorithm"), chunkWorkerAlgorithm.name(), + "Modifies what algorithm the chunk system will use to define thread counts.", + "Valid values:", + " - MOONRISE: Default algorithm, used by default in Paper", + " - C2ME: Algorithm used by C2ME (old)", + " - C2ME_NEW: Modern algorithm used by C2ME")); + chunkTaskPriority = ChunkTaskPriority.valueOf(getString(ConfigCategory.PERFORMANCE.key("chunks.chunk-task-priority"), chunkTaskPriority.name(), + "Sets the algorithm for determining chunk task priorities (generation, loading and etc.).", + "Valid values:", + " - EUCLIDEAN_CIRCLE_PATTERN: Euclidean distance squared algorithm, chunk priorities will be ordered in a circle pattern", + " - DEFAULT_DIAMOND_PATTERN: Default one, chunk priorities will be ordered in a diamond pattern")); + threadPoolPriority = getInt(ConfigCategory.PERFORMANCE.key("chunks.thread-pool-priority"), threadPoolPriority, + "Sets the priority of the thread pool used for chunk generation"); + + smoothBedrockLayer = getBoolean(ConfigCategory.PERFORMANCE.key("chunks.smooth-bedrock-layer"), smoothBedrockLayer, + "Smoothens the bedrock layer at the bottom of overworld, and on the top of nether during the world generation."); + + enableDensityFunctionCompiler = getBoolean(ConfigCategory.PERFORMANCE.key("chunks.experimental.enable-density-function-compiler"), enableDensityFunctionCompiler, + "Whether to use density function compiler to accelerate world generation", + "", + "Density function: https://minecraft.wiki/w/Density_function", + "", + "This functionality compiles density functions from world generation", + "datapacks (including vanilla generation) to JVM bytecode to increase", + "performance by allowing JVM JIT to better optimize the code.", + "All functions provided by vanilla are implemented."); + enableStructureLayoutOptimizer = getBoolean(ConfigCategory.PERFORMANCE.key("chunks.experimental.enable-structure-layout-optimizer"), enableStructureLayoutOptimizer, + "Enables a port of the mod StructureLayoutOptimizer, which optimizes general Jigsaw structure generation"); + deduplicateShuffledTemplatePoolElementList = getBoolean(ConfigCategory.PERFORMANCE.key("chunks.experimental.deduplicate-shuffled-template-pool-element-list"), deduplicateShuffledTemplatePoolElementList, + "Whether to use an alternative strategy to make structure layouts generate slightly even faster than", + "the default optimization this mod has for template pool weights. This alternative strategy works by", + "changing the list of pieces that structures collect from the template pool to not have duplicate entries.", + "", + "This will not break the structure generation, but it will make the structure layout different than", + "if this config was off (breaking vanilla seed parity). The cost of speed may be worth it in large", + "modpacks where many structure mods are using very high weight values in their template pools."); + } + + private static void tntOptimization() { + enableFasterTntOptimization = getBoolean(ConfigCategory.PERFORMANCE.key("tnt-optimization.enable-faster-tnt-optimization"), enableFasterTntOptimization); + explosionNoBlockDamage = getBoolean(ConfigCategory.PERFORMANCE.key("tnt-optimization.explosion-no-block-damage"), explosionNoBlockDamage); + tntRandomRange = getDouble(ConfigCategory.PERFORMANCE.key("tnt-optimization.tnt-random-range"), tntRandomRange); + } + + private static void optimizationSettings() { + skipUselessSecondaryPoiSensor = getBoolean(ConfigCategory.PERFORMANCE.key("optimizations.skip-useless-secondary-poi-sensor"), skipUselessSecondaryPoiSensor); + clumpOrbs = getBoolean(ConfigCategory.PERFORMANCE.key("optimizations.clump-orbs"), clumpOrbs, + "Clumps experience orbs together to reduce entity count"); + enableSuffocationOptimization = getBoolean(ConfigCategory.PERFORMANCE.key("optimizations.enable-suffocation-optimization"), enableSuffocationOptimization, + "Optimizes the suffocation check by selectively skipping the check in a way that still appears vanilla.", + "This option should be left enabled on most servers, but is provided as a configuration option if the vanilla deviation is undesirable."); + useCompactBitStorage = getBoolean(ConfigCategory.PERFORMANCE.key("optimizations.use-compact-bit-storage"), useCompactBitStorage, + "Fixes memory waste caused by sending empty chunks as if they contain blocks. Can significantly reduce memory usage."); + commandBlockParseResultsCaching = getBoolean(ConfigCategory.PERFORMANCE.key("optimizations.command-block-parse-results-caching"), commandBlockParseResultsCaching, + "Caches the parse results of command blocks, can significantly reduce performance impact."); + sheepOptimization = getBoolean(ConfigCategory.PERFORMANCE.key("optimizations.sheep-optimization"), sheepOptimization, + "Enables optimization from Carpet Fixes mod, using a prebaked list of all the possible colors and combinations for sheep."); + + hopperThrottleWhenFull = getBoolean(ConfigCategory.PERFORMANCE.key("optimizations.hopper-throttle-when-full.enabled"), hopperThrottleWhenFull, + "When enabled, hoppers will throttle if target container is full."); + hopperThrottleSkipTicks = getInt(ConfigCategory.PERFORMANCE.key("optimizations.hopper-throttle-when-full.skip-ticks"), hopperThrottleSkipTicks, + "The amount of ticks to skip when the hopper is throttled."); + } + + private static void dab() { + dabEnabled = getBoolean(ConfigCategory.PERFORMANCE.key("dab.enabled"), dabEnabled, + "Enables DAB feature"); + dabStartDistance = getInt(ConfigCategory.PERFORMANCE.key("dab.start-distance"), dabStartDistance, + "This value determines how far away an entity has to be"); + dabStartDistanceSquared = dabStartDistance * dabStartDistance; + dabMaximumActivationFrequency = getInt(ConfigCategory.PERFORMANCE.key("dab.maximum-activation-frequency"), dabMaximumActivationFrequency, + "How often in ticks, the furthest entity will get their pathfinders and behaviors ticked."); + dabActivationDistanceMod = getInt(ConfigCategory.PERFORMANCE.key("dab.activation-distance-mod"), dabActivationDistanceMod, + "Modifies an entity's tick frequency.", + "The exact calculation to obtain the tick frequency for an entity is: freq = (distanceToPlayer^2) / (2^value), where value is this configuration setting.", + "Large servers may want to reduce the value to 7, but this value should never be reduced below 6. If you want further away entities to tick more often, set the value to 9"); + dabDontEnableIfInWater = getBoolean(ConfigCategory.PERFORMANCE.key("dab.dont-enable-if-in-water"), dabDontEnableIfInWater, + "When this is enabled, non-aquatic entities in the water will not be affected by DAB."); + dabBlackedEntities = getStringList(ConfigCategory.PERFORMANCE.key("dab.blacked-entities"), dabBlackedEntities, + "Use this configuration option to specify that certain entities should not be impacted by DAB."); + + setComment(ConfigCategory.PERFORMANCE.key("dab"), + "DAB is an optimization that reduces the frequency of brain ticks. Brain ticks are very intensive, which is why they", + "are limited. DAB can be tuned to meet your preferred performance-experience tradeoff. The farther away entities", + "are from players, the less frequently their brains will be ticked. While DAB does impact the AI goal selector", + "behavior of all entities, the only entities who's brain ticks are limited are: Villager, Axolotl, Hoglin, Zombified Piglin and Goat"); + + for (EntityType entityType : BuiltInRegistries.ENTITY_TYPE) { + entityType.dabEnabled = true; + } + + final String DEFAULT_PREFIX = ResourceLocation.DEFAULT_NAMESPACE + ResourceLocation.NAMESPACE_SEPARATOR; + for (String name : dabBlackedEntities) { + String lowerName = name.toLowerCase(Locale.ROOT); + String typeId = lowerName.startsWith(DEFAULT_PREFIX) ? lowerName : DEFAULT_PREFIX + lowerName; + + EntityType.byString(typeId).ifPresentOrElse(entityType -> entityType.dabEnabled = false, () -> LOGGER.warn("Unknown entity {}, in {}", name, ConfigCategory.PERFORMANCE.key("dab.blacked-entities"))); + } + } + + private static void virtualThreads() { + virtualThreadsEnabled = getBoolean(ConfigCategory.PERFORMANCE.key("virtual-threads.enabled"), virtualThreadsEnabled, + "Enables use of virtual threads that was added in Java 21"); + + virtualBukkitScheduler = getBoolean(ConfigCategory.PERFORMANCE.key("virtual-threads.bukkit-scheduler"), virtualBukkitScheduler, + "Uses virtual threads for the Bukkit scheduler."); + virtualChatScheduler = getBoolean(ConfigCategory.PERFORMANCE.key("virtual-threads.chat-scheduler"), virtualChatScheduler, + "Uses virtual threads for the Chat scheduler."); + virtualAuthenticatorScheduler = getBoolean(ConfigCategory.PERFORMANCE.key("virtual-threads.authenticator-scheduler"), virtualAuthenticatorScheduler, + "Uses virtual threads for the Authenticator scheduler."); + virtualTabCompleteScheduler = getBoolean(ConfigCategory.PERFORMANCE.key("virtual-threads.tab-complete-scheduler"), virtualTabCompleteScheduler, + "Uses virtual threads for the Tab Complete scheduler."); + virtualAsyncExecutor = getBoolean(ConfigCategory.PERFORMANCE.key("virtual-threads.async-executor"), virtualAsyncExecutor, + "Uses virtual threads for the MCUtil async executor."); + virtualCommandBuilderScheduler = getBoolean(ConfigCategory.PERFORMANCE.key("virtual-threads.command-builder-scheduler"), virtualCommandBuilderScheduler, + "Uses virtual threads for the Async Command Builder Thread Pool."); + virtualProfileLookupPool = getBoolean(ConfigCategory.PERFORMANCE.key("virtual-threads.profile-lookup-pool"), virtualProfileLookupPool, + "Uses virtual threads for the Profile Lookup Pool, that is used for fetching player profiles."); + virtualServerTextFilterPool = getBoolean(ConfigCategory.PERFORMANCE.key("virtual-threads.server-text-filter-pool"), virtualServerTextFilterPool, + "Uses virtual threads for the server text filter pool."); + } + } + + public static class FixesCategory { + // Gameplay fixes + public static boolean fixIncorrectBounceLogic = false; + public static boolean updateSuppressionCrashFix = true; + public static boolean ignoreMovedTooQuicklyWhenLagging = true; + public static boolean alwaysAllowWeirdMovement = true; + + // Miscellaneous fixes + public static boolean forceMinecraftCommand = false; + public static boolean disableLeafDecay = false; + + // Bug fixes (MC-*) + public static boolean slopesVisualFix = false; + + public static void load() { + gameplayFixes(); + miscFixes(); + bugFixes(); + } + + private static void gameplayFixes() { + fixIncorrectBounceLogic = getBoolean(ConfigCategory.FIXES.key("gameplay.fix-incorrect-bounce-logic"), fixIncorrectBounceLogic, + "Fixes incorrect bounce logic in SlimeBlock."); + updateSuppressionCrashFix = getBoolean(ConfigCategory.FIXES.key("gameplay.update-suppression-crash-fix"), updateSuppressionCrashFix); + ignoreMovedTooQuicklyWhenLagging = getBoolean(ConfigCategory.FIXES.key("gameplay.ignore-moved-too-quickly-when-lagging"), ignoreMovedTooQuicklyWhenLagging, + "Improves general gameplay experience of the player when the server is lagging, as they won't get lagged back (message 'moved too quickly')"); + alwaysAllowWeirdMovement = getBoolean(ConfigCategory.FIXES.key("gameplay.always-allow-weird-movement"), alwaysAllowWeirdMovement, + "Means ignoring messages like 'moved too quickly' and 'moved wrongly'"); + } + + private static void miscFixes() { + forceMinecraftCommand = getBoolean(ConfigCategory.FIXES.key("misc.force-minecraft-command"), forceMinecraftCommand, + "Whether to force the use of vanilla commands over plugin commands."); + disableLeafDecay = getBoolean(ConfigCategory.FIXES.key("misc.disable-leaf-decay"), disableLeafDecay, + "Disables leaf block decay."); + } + + private static void bugFixes() { + slopesVisualFix = getBoolean(ConfigCategory.FIXES.key("bug.fix-mc-258859"), slopesVisualFix, + "Fixes MC-258859, fixing slopes visual bug in biomes like Snowy Slopes, Frozen Peaks, Jagged Peaks, and including Terralith."); + } + } + + public static class MiscCategory { + // Secure seed + public static boolean enableSecureSeed = false; + + // Lag compensation + public static boolean lagCompensationEnabled = true; + public static boolean blockEntityAcceleration = false; + public static boolean blockBreakingAcceleration = true; + public static boolean eatingAcceleration = true; + public static boolean potionEffectAcceleration = true; + public static boolean fluidAcceleration = true; + public static boolean pickupAcceleration = true; + public static boolean portalAcceleration = true; + public static boolean timeAcceleration = true; + public static boolean randomTickSpeedAcceleration = true; + + // Region format + public static RegionFileFormat regionFormatTypeName = RegionFileFormat.ANVIL; + public static LinearImplementation linearImplementation = LinearImplementation.V2; + public static int linearFlushMaxThreads = 4; + public static int linearFlushDelay = 100; + public static boolean linearUseVirtualThread = false; + public static int linearCompressionLevel = 1; + + // Sentry + public static String sentryDsn = ""; + public static String logLevel = "WARN"; + public static boolean onlyLogThrown = true; + + public static void load() { + secureSeed(); + lagCompensation(); + linearRegionFormat(); + sentrySettings(); + } + + private static void secureSeed() { + enableSecureSeed = getBoolean(ConfigCategory.MISC.key("secure-seed.enable"), enableSecureSeed, + "This feature is based on Secure Seed mod by Earthcomputer.", + "", + "Terrain and biome generation remains the same, but all the ores and structures are generated with 1024-bit seed, instead of the usual 64-bit seed.", + "This seed is almost impossible to crack, and there are no weird links between structures."); + } + + private static void lagCompensation() { + lagCompensationEnabled = getBoolean(ConfigCategory.MISC.key("lag-compensation.enabled"), lagCompensationEnabled, + "Improves the player experience when TPS is low"); + blockEntityAcceleration = getBoolean(ConfigCategory.MISC.key("lag-compensation.block-entity-acceleration"), blockEntityAcceleration); + blockBreakingAcceleration = getBoolean(ConfigCategory.MISC.key("lag-compensation.block-breaking-acceleration"), blockBreakingAcceleration); + eatingAcceleration = getBoolean(ConfigCategory.MISC.key("lag-compensation.eating-acceleration"), eatingAcceleration); + potionEffectAcceleration = getBoolean(ConfigCategory.MISC.key("lag-compensation.potion-effect-acceleration"), potionEffectAcceleration); + fluidAcceleration = getBoolean(ConfigCategory.MISC.key("lag-compensation.fluid-acceleration"), fluidAcceleration); + pickupAcceleration = getBoolean(ConfigCategory.MISC.key("lag-compensation.pickup-acceleration"), pickupAcceleration); + portalAcceleration = getBoolean(ConfigCategory.MISC.key("lag-compensation.portal-acceleration"), portalAcceleration); + timeAcceleration = getBoolean(ConfigCategory.MISC.key("lag-compensation.time-acceleration"), timeAcceleration); + randomTickSpeedAcceleration = getBoolean(ConfigCategory.MISC.key("lag-compensation.random-tick-speed-acceleration"), randomTickSpeedAcceleration); + } + + private static void linearRegionFormat() { + regionFormatTypeName = RegionFileFormat.fromName(getString(ConfigCategory.MISC.key("region-format.type"), regionFormatTypeName.name(), + "The type of region file format to use for storing chunk data.", + "Valid values:", + " - LINEAR: Linear region file format", + " - ANVIL: Anvil region file format (default)")); + linearImplementation = LinearImplementation.valueOf(getString(ConfigCategory.MISC.key("region-format.implementation"), linearImplementation.name(), + "The implementation of the linear region file format to use.", + "Valid values:", + " - V1: Basic and default linear implementation", + " - V2: Introduces a grid-based compression scheme for better data management and flexibility (default)")); + + linearFlushMaxThreads = getInt(ConfigCategory.MISC.key("region-format.flush-max-threads"), linearFlushMaxThreads, + "The maximum number of threads to use for flushing linear region files.", + "If this value is less than or equal to 0, it will be set to the number of available processors + this value."); + linearFlushDelay = getInt(ConfigCategory.MISC.key("region-format.flush-delay"), linearFlushDelay, + "The delay in milliseconds to wait before flushing next files."); + linearUseVirtualThread = getBoolean(ConfigCategory.MISC.key("region-format.use-virtual-thread"), linearUseVirtualThread, + "Whether to use virtual threads for flushing."); + linearCompressionLevel = getInt(ConfigCategory.MISC.key("region-format.compression-level"), linearCompressionLevel, + "The compression level to use for the linear region file format."); + + setComment(ConfigCategory.MISC.key("region-format"), + "The linear region file format is a custom region file format that is designed to be more efficient than the ANVIL format.", + "It uses uses ZSTD compression instead of ZLIB. This format saves about 50% of disk space.", + "Read more information about linear region format at https://github.com/xymb-endcrystalme/LinearRegionFileFormatTools", + "WARNING: If you are want to use this format, make sure to create backup of your world before switching to it, there is potential risk to lose chunk data."); + + if (regionFormatTypeName == RegionFileFormat.UNKNOWN) { + LOGGER.error("Unknown region file type: {}, falling back to ANVIL format.", regionFormatTypeName); + regionFormatTypeName = RegionFileFormat.ANVIL; + } + + if (linearFlushMaxThreads <= 0) { + linearFlushMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() + linearFlushMaxThreads, 1); + } + + if (linearCompressionLevel > 22 || linearCompressionLevel < 1) { + LOGGER.warn("Invalid linear compression level: {}, resetting to default (1)", linearCompressionLevel); + linearCompressionLevel = 1; + } + } + + private static void sentrySettings() { + sentryDsn = getString(ConfigCategory.MISC.key("sentry.dsn"), sentryDsn, + "The DSN for Sentry, a service that provides real-time crash reporting that helps you monitor and fix crashes in real time. Leave blank to disable. Obtain link at https://sentry.io"); + logLevel = getString(ConfigCategory.MISC.key("sentry.log-level"), logLevel, + "Logs with a level higher than or equal to this level will be recorded."); + onlyLogThrown = getBoolean(ConfigCategory.MISC.key("sentry.only-log-thrown"), onlyLogThrown, + "Only log Throwable exceptions to Sentry."); + + if (sentryDsn != null && !sentryDsn.isBlank()) gg.pufferfish.pufferfish.sentry.SentryManager.init(Level.getLevel(logLevel)); + } + } + + public static class NetworkCategory { + // General network settings + public static boolean disableDisconnectSpam = false; + public static boolean gracefulTeleportHandling = false; + public static boolean dontRespondPingBeforeStart = true; + public static boolean playerProfileResultCachingEnabled = true; + public static int playerProfileResultCachingTimeout = 1440; + + // No chat reports + public static boolean noChatReportsEnabled = false; + public static boolean noChatReportsAddQueryData = true; + public static boolean noChatReportsConvertToGameMessage = true; + public static boolean noChatReportsDebugLog = false; + public static boolean noChatReportsDemandOnClient = false; + public static String noChatReportsDisconnectDemandOnClientMessage = "You do not have No Chat Reports, and this server is configured to require it on client!"; + + public static void load() { + networkSettings(); + noChatReports(); + } + + private static void networkSettings() { + disableDisconnectSpam = getBoolean(ConfigCategory.NETWORK.key("general.disable-disconnect-spam"), disableDisconnectSpam, + "Prevents players being disconnected by 'disconnect.spam' when sending too many chat packets"); + gracefulTeleportHandling = getBoolean(ConfigCategory.NETWORK.key("general.graceful-teleport-handling"), gracefulTeleportHandling, + "Disables being disconnected from 'multiplayer.disconnect.invalid_player_movement' (also declines the packet handling)."); + dontRespondPingBeforeStart = getBoolean(ConfigCategory.NETWORK.key("general.dont-respond-ping-before-start"), dontRespondPingBeforeStart, + "Prevents the server from responding to pings before the server is fully booted."); + + playerProfileResultCachingEnabled = getBoolean(ConfigCategory.NETWORK.key("player-profile-result-caching.enabled"), playerProfileResultCachingEnabled, + "Enables caching of player profile results on first join."); + playerProfileResultCachingTimeout = getInt(ConfigCategory.NETWORK.key("player-profile-result-caching.timeout"), playerProfileResultCachingTimeout, + "The amount of time in minutes to cache player profile results."); + } + + private static void noChatReports() { + noChatReportsEnabled = getBoolean(ConfigCategory.NETWORK.key("no-chat-reports.enabled"), noChatReportsEnabled, + "Enables or disables the No Chat Reports feature"); + noChatReportsAddQueryData = getBoolean(ConfigCategory.NETWORK.key("no-chat-reports.add-query-data"), noChatReportsAddQueryData, + "Should server include extra query data to help clients know that your server is secure"); + noChatReportsConvertToGameMessage = getBoolean(ConfigCategory.NETWORK.key("no-chat-reports.convert-to-game-message"), noChatReportsConvertToGameMessage, + "Should the server convert all player messages to system messages"); + noChatReportsDebugLog = getBoolean(ConfigCategory.NETWORK.key("no-chat-reports.debug-log"), noChatReportsDebugLog); + noChatReportsDemandOnClient = getBoolean(ConfigCategory.NETWORK.key("no-chat-reports.demand-on-client"), noChatReportsDemandOnClient, + "Should the server require No Chat Reports on the client side"); + noChatReportsDisconnectDemandOnClientMessage = getString(ConfigCategory.NETWORK.key("no-chat-reports.disconnect-demand-on-client-message"), noChatReportsDisconnectDemandOnClientMessage, + "Message to send to the client when they are disconnected for not having No Chat Reports"); + } + } +} diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/DivineWorldConfig.java b/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineWorldConfig.java similarity index 99% rename from divinemc-server/src/main/java/org/bxteam/divinemc/DivineWorldConfig.java rename to divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineWorldConfig.java index ecdc912..5be02f4 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/DivineWorldConfig.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineWorldConfig.java @@ -1,4 +1,4 @@ -package org.bxteam.divinemc; +package org.bxteam.divinemc.config; import org.bukkit.World; import org.jetbrains.annotations.Nullable; diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/entity/pathfinding/AsyncPathProcessor.java b/divinemc-server/src/main/java/org/bxteam/divinemc/entity/pathfinding/AsyncPathProcessor.java index 5a49663..484f88f 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/entity/pathfinding/AsyncPathProcessor.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/entity/pathfinding/AsyncPathProcessor.java @@ -5,7 +5,7 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.world.level.pathfinder.Path; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.bxteam.divinemc.DivineConfig; +import org.bxteam.divinemc.config.DivineConfig; import org.bxteam.divinemc.util.NamedAgnosticThreadFactory; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -26,8 +26,8 @@ public class AsyncPathProcessor { private static long lastWarnMillis = System.currentTimeMillis(); private static final ThreadPoolExecutor pathProcessingExecutor = new ThreadPoolExecutor( 1, - DivineConfig.asyncPathfindingMaxThreads, - DivineConfig.asyncPathfindingKeepalive, TimeUnit.SECONDS, + DivineConfig.AsyncCategory.asyncPathfindingMaxThreads, + DivineConfig.AsyncCategory.asyncPathfindingKeepalive, TimeUnit.SECONDS, getQueueImpl(), new NamedAgnosticThreadFactory<>(THREAD_PREFIX, TickThread::new, Thread.NORM_PRIORITY - 2), new RejectedTaskHandler() @@ -38,7 +38,7 @@ public class AsyncPathProcessor { public void rejectedExecution(Runnable rejectedTask, ThreadPoolExecutor executor) { BlockingQueue workQueue = executor.getQueue(); if (!executor.isShutdown()) { - switch (DivineConfig.asyncPathfindingRejectPolicy) { + switch (DivineConfig.AsyncCategory.asyncPathfindingRejectPolicy) { case FLUSH_ALL -> { if (!workQueue.isEmpty()) { List pendingTasks = new ArrayList<>(workQueue.size()); @@ -92,7 +92,7 @@ public class AsyncPathProcessor { } private static BlockingQueue getQueueImpl() { - final int queueCapacity = DivineConfig.asyncPathfindingQueueSize; + final int queueCapacity = DivineConfig.AsyncCategory.asyncPathfindingQueueSize; return new LinkedBlockingQueue<>(queueCapacity); } diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/entity/pathfinding/PathfindTaskRejectPolicy.java b/divinemc-server/src/main/java/org/bxteam/divinemc/entity/pathfinding/PathfindTaskRejectPolicy.java index ebe6e94..36886ea 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/entity/pathfinding/PathfindTaskRejectPolicy.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/entity/pathfinding/PathfindTaskRejectPolicy.java @@ -1,6 +1,6 @@ package org.bxteam.divinemc.entity.pathfinding; -import org.bxteam.divinemc.DivineConfig; +import org.bxteam.divinemc.config.DivineConfig; import java.util.Locale; public enum PathfindTaskRejectPolicy { diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/entity/tracking/MultithreadedTracker.java b/divinemc-server/src/main/java/org/bxteam/divinemc/entity/tracking/MultithreadedTracker.java index 298946c..669c6c5 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/entity/tracking/MultithreadedTracker.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/entity/tracking/MultithreadedTracker.java @@ -12,7 +12,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.bxteam.divinemc.DivineConfig; +import org.bxteam.divinemc.config.DivineConfig; import org.bxteam.divinemc.util.NamedAgnosticThreadFactory; import org.jetbrains.annotations.NotNull; @@ -46,7 +46,7 @@ public class MultithreadedTracker { public static void tick(ChunkSystemServerLevel level) { try { - if (!DivineConfig.multithreadedCompatModeEnabled) { + if (!DivineConfig.AsyncCategory.multithreadedCompatModeEnabled) { tickAsync(level); } else { tickAsyncWithCompatMode(level); @@ -135,15 +135,15 @@ public class MultithreadedTracker { } private static int getMaxPoolSize() { - return DivineConfig.asyncEntityTrackerMaxThreads; + return DivineConfig.AsyncCategory.asyncEntityTrackerMaxThreads; } private static long getKeepAliveTime() { - return DivineConfig.asyncEntityTrackerKeepalive; + return DivineConfig.AsyncCategory.asyncEntityTrackerKeepalive; } private static BlockingQueue getQueueImpl() { - final int queueCapacity = DivineConfig.asyncEntityTrackerQueueSize; + final int queueCapacity = DivineConfig.AsyncCategory.asyncEntityTrackerQueueSize; return new LinkedBlockingQueue<>(queueCapacity); } diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/region/LinearRegionFile.java b/divinemc-server/src/main/java/org/bxteam/divinemc/region/LinearRegionFile.java index 282cb4c..3e25b24 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/region/LinearRegionFile.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/region/LinearRegionFile.java @@ -10,7 +10,7 @@ import net.jpountz.lz4.LZ4FastDecompressor; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.ChunkPos; import net.openhft.hashing.LongHashFunction; -import org.bxteam.divinemc.DivineConfig; +import org.bxteam.divinemc.config.DivineConfig; import org.bxteam.divinemc.spark.ThreadDumperRegistry; import org.jspecify.annotations.Nullable; import org.slf4j.Logger; @@ -75,7 +75,7 @@ public class LinearRegionFile implements IRegionFile { Runnable flushCheck = () -> { while (!close) { synchronized (SAVE_LOCK) { - if (markedToSave && activeSaveThreads < DivineConfig.linearFlushMaxThreads) { + if (markedToSave && activeSaveThreads < DivineConfig.MiscCategory.linearFlushMaxThreads) { activeSaveThreads++; Runnable flushOperation = () -> { try { @@ -88,7 +88,7 @@ public class LinearRegionFile implements IRegionFile { } } }; - Thread saveThread = DivineConfig.linearUseVirtualThread + Thread saveThread = DivineConfig.MiscCategory.linearUseVirtualThread ? Thread.ofVirtual().name("Linear IO - " + this.hashCode()).unstarted(flushOperation) : Thread.ofPlatform().name("Linear IO - " + this.hashCode()).unstarted(flushOperation); saveThread.setPriority(Thread.NORM_PRIORITY - 3); @@ -96,10 +96,10 @@ public class LinearRegionFile implements IRegionFile { ThreadDumperRegistry.REGISTRY.add(saveThread.getName()); } } - LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(DivineConfig.linearFlushDelay)); + LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(DivineConfig.MiscCategory.linearFlushDelay)); } }; - this.schedulingThread = DivineConfig.linearUseVirtualThread + this.schedulingThread = DivineConfig.MiscCategory.linearUseVirtualThread ? Thread.ofVirtual().unstarted(flushCheck) : Thread.ofPlatform().unstarted(flushCheck); this.schedulingThread.setName("Linear IO Schedule - " + this.hashCode()); diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/region/RegionFileFactory.java b/divinemc-server/src/main/java/org/bxteam/divinemc/region/RegionFileFactory.java index fbcdd68..6d9584b 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/region/RegionFileFactory.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/region/RegionFileFactory.java @@ -3,7 +3,7 @@ package org.bxteam.divinemc.region; import net.minecraft.world.level.chunk.storage.RegionFile; import net.minecraft.world.level.chunk.storage.RegionFileVersion; import net.minecraft.world.level.chunk.storage.RegionStorageInfo; -import org.bxteam.divinemc.DivineConfig; +import org.bxteam.divinemc.config.DivineConfig; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -23,7 +23,7 @@ public class RegionFileFactory { final String extensionName = fullNameSplit[fullNameSplit.length - 1]; switch (RegionFileFormat.fromExtension(extensionName)) { case LINEAR -> { - return new LinearRegionFile(path, DivineConfig.linearImplementation, DivineConfig.linearCompressionLevel); + return new LinearRegionFile(path, DivineConfig.MiscCategory.linearImplementation, DivineConfig.MiscCategory.linearCompressionLevel); } default -> { diff --git a/divinemc-server/src/main/java/su/plo/matter/Globals.java b/divinemc-server/src/main/java/su/plo/matter/Globals.java index 6a8134b..4256b8d 100644 --- a/divinemc-server/src/main/java/su/plo/matter/Globals.java +++ b/divinemc-server/src/main/java/su/plo/matter/Globals.java @@ -2,7 +2,7 @@ package su.plo.matter; import com.google.common.collect.Iterables; import net.minecraft.server.level.ServerLevel; -import org.bxteam.divinemc.DivineConfig; +import org.bxteam.divinemc.config.DivineConfig; import java.math.BigInteger; import java.security.SecureRandom; @@ -37,7 +37,7 @@ public class Globals { } public static void setupGlobals(ServerLevel world) { - if (!DivineConfig.enableSecureSeed) return; + if (!DivineConfig.MiscCategory.enableSecureSeed) return; long[] seed = world.getServer().getWorldData().worldGenOptions().featureSeed(); System.arraycopy(seed, 0, worldSeed, 0, WORLD_SEED_LONGS); diff --git a/patches/removed/1.21.5/server/0033-Regionized-Chunk-Ticking.patch b/patches/removed/1.21.5/server/0033-Regionized-Chunk-Ticking.patch index 5569b2b..d3a799d 100644 --- a/patches/removed/1.21.5/server/0033-Regionized-Chunk-Ticking.patch +++ b/patches/removed/1.21.5/server/0033-Regionized-Chunk-Ticking.patch @@ -13,7 +13,7 @@ index ae0e36d198ad8243920c8e8a55c0be4945542763..7f982949304535376dabf42aab1848ca private final DistanceManager distanceManager; private final ServerLevel level; + // DivineMC - Regionized Chunk Ticking -+ public static final Executor REGION_EXECUTOR = java.util.concurrent.Executors.newFixedThreadPool(org.bxteam.divinemc.DivineConfig.regionizedChunkTickingExecutorThreadCount, new org.bxteam.divinemc.util.NamedAgnosticThreadFactory<>("region_ticking", ca.spottedleaf.moonrise.common.util.TickThread::new, org.bxteam.divinemc.DivineConfig.regionizedChunkTickingExecutorThreadPriority)); ++ public static final Executor REGION_EXECUTOR = java.util.concurrent.Executors.newFixedThreadPool(org.bxteam.divinemc.config.DivineConfig.regionizedChunkTickingExecutorThreadCount, new org.bxteam.divinemc.util.NamedAgnosticThreadFactory<>("region_ticking", ca.spottedleaf.moonrise.common.util.TickThread::new, org.bxteam.divinemc.config.DivineConfig.regionizedChunkTickingExecutorThreadPriority)); + public volatile int tickingRegionsCount = 0; + // DivineMC end - Regionized Chunk Ticking public final Thread mainThread; @@ -72,7 +72,7 @@ index ae0e36d198ad8243920c8e8a55c0be4945542763..7f982949304535376dabf42aab1848ca // Paper end - chunk tick iteration optimisation - this.tickChunks(l, list); + // DivineMC start - Regionized Chunk Ticking -+ if (org.bxteam.divinemc.DivineConfig.enableRegionizedChunkTicking) { ++ if (org.bxteam.divinemc.config.DivineConfig.enableRegionizedChunkTicking) { + List[] regions = splitChunksIntoRegions(list); + int regionCount = regions.length; + this.tickingRegionsCount = regionCount;