diff --git a/divinemc-server/minecraft-patches/features/0055-Carpet-AMS-Addition-Optimized-dragon-respawn.patch b/divinemc-server/minecraft-patches/features/0055-Carpet-AMS-Addition-Optimized-dragon-respawn.patch new file mode 100644 index 0000000..4d360ca --- /dev/null +++ b/divinemc-server/minecraft-patches/features/0055-Carpet-AMS-Addition-Optimized-dragon-respawn.patch @@ -0,0 +1,104 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> +Date: Wed, 11 Jun 2025 19:33:13 +0300 +Subject: [PATCH] Carpet-AMS-Addition: Optimized dragon respawn + + +diff --git a/net/minecraft/world/level/block/state/pattern/BlockPattern.java b/net/minecraft/world/level/block/state/pattern/BlockPattern.java +index f7bb979f08634a7e1b77c59040f59fb5e11aafa5..e0eca73d9e8a77b2a4972db61001394c6bf1d2c4 100644 +--- a/net/minecraft/world/level/block/state/pattern/BlockPattern.java ++++ b/net/minecraft/world/level/block/state/pattern/BlockPattern.java +@@ -59,7 +59,7 @@ public class BlockPattern { + } + + @Nullable +- private BlockPattern.BlockPatternMatch matches(BlockPos pos, Direction finger, Direction thumb, LoadingCache cache) { ++ public BlockPattern.BlockPatternMatch matches(BlockPos pos, Direction finger, Direction thumb, LoadingCache cache) { // DivineMC - Carpet-AMS-Addition: Optimized dragon respawn - make public + for (int i = 0; i < this.width; i++) { + for (int i1 = 0; i1 < this.height; i1++) { + for (int i2 = 0; i2 < this.depth; i2++) { +diff --git a/net/minecraft/world/level/dimension/end/EndDragonFight.java b/net/minecraft/world/level/dimension/end/EndDragonFight.java +index 8ccd40c70e150bd5a8d89818c229258642f2349e..d498dbdc5d29c9bb94ccbf2ae84d5d6caf2943f2 100644 +--- a/net/minecraft/world/level/dimension/end/EndDragonFight.java ++++ b/net/minecraft/world/level/dimension/end/EndDragonFight.java +@@ -273,8 +273,68 @@ public class EndDragonFight { + return false; + } + ++ // DivineMC start - Carpet-AMS-Addition: Optimized dragon respawn ++ private int cachePortalChunkIteratorX = -8; ++ private int cachePortalChunkIteratorZ = -8; ++ private int cachePortalOriginIteratorY = -1; ++ + @Nullable + public BlockPattern.BlockPatternMatch findExitPortal() { ++ if (org.bxteam.divinemc.config.DivineConfig.PerformanceCategory.optimizedDragonRespawn) { ++ int i, j; ++ for (i = cachePortalChunkIteratorX; i <= 8; ++i) { ++ for (j = cachePortalChunkIteratorZ; j <= 8; ++j) { ++ LevelChunk worldChunk = this.level.getChunk(i, j); ++ for (BlockEntity blockEntity : worldChunk.getBlockEntities().values()) { ++ if (blockEntity instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity) { ++ continue; ++ } ++ if (blockEntity instanceof TheEndPortalBlockEntity) { ++ BlockPattern.BlockPatternMatch blockPatternMatch = this.exitPortalPattern.find(this.level, blockEntity.getBlockPos()); ++ if (blockPatternMatch != null) { ++ BlockPos blockPos = blockPatternMatch.getBlock(3, 3, 3).getPos(); ++ if (this.portalLocation == null) { ++ this.portalLocation = blockPos; ++ } ++ ++ cachePortalChunkIteratorX = i; ++ cachePortalChunkIteratorZ = j; ++ return blockPatternMatch; ++ } ++ } ++ } ++ } ++ } ++ ++ if (this.needsStateScanning || this.portalLocation == null) { ++ if (cachePortalOriginIteratorY != -1) { ++ i = cachePortalOriginIteratorY; ++ } else { ++ i = this.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, EndPodiumFeature.getLocation(BlockPos.ZERO)).getY(); ++ } ++ boolean notFirstSearch = false; ++ for (j = i; j >= 0; --j) { ++ BlockPattern.BlockPatternMatch result2 = null; ++ if (notFirstSearch) { ++ result2 = org.bxteam.divinemc.util.BlockPatternHelper.partialSearchAround(this.exitPortalPattern, this.level, new BlockPos(EndPodiumFeature.getLocation(BlockPos.ZERO).getY(), j, EndPodiumFeature.getLocation(BlockPos.ZERO).getZ())); ++ } else { ++ result2 = this.exitPortalPattern.find(this.level, new BlockPos(EndPodiumFeature.getLocation(BlockPos.ZERO).getX(), j, EndPodiumFeature.getLocation(BlockPos.ZERO).getZ())); ++ } ++ if (result2 != null) { ++ if (this.portalLocation == null) { ++ this.portalLocation = result2.getBlock(3, 3, 3).getPos(); ++ } ++ cachePortalOriginIteratorY = j; ++ return result2; ++ } ++ notFirstSearch = true; ++ } ++ } ++ ++ return null; ++ } ++ // DivineMC end - Carpet-AMS-Addition: Optimized dragon respawn ++ + ChunkPos chunkPos = new ChunkPos(this.origin); + + for (int i = -8 + chunkPos.x; i <= 8 + chunkPos.x; i++) { +@@ -572,6 +632,11 @@ public class EndDragonFight { + } + + public boolean respawnDragon(List crystals) { // CraftBukkit - return boolean ++ // DivineMC start - Carpet-AMS-Addition: Optimized dragon respawn ++ cachePortalChunkIteratorX = -8; ++ cachePortalChunkIteratorZ = -8; ++ cachePortalOriginIteratorY = -1; ++ // DivineMC end - Carpet-AMS-Addition: Optimized dragon respawn + if (this.dragonKilled && this.respawnStage == null) { + for (BlockPattern.BlockPatternMatch blockPatternMatch = this.findExitPortal(); blockPatternMatch != null; blockPatternMatch = this.findExitPortal()) { + for (int i = 0; i < this.exitPortalPattern.getWidth(); i++) { diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java b/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java index dfb6c13..0d935c4 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java @@ -331,6 +331,7 @@ public class DivineConfig { public static boolean useCompactBitStorage = false; public static boolean commandBlockParseResultsCaching = true; public static boolean sheepOptimization = true; + public static boolean optimizedDragonRespawn = false; public static boolean reduceChuckLoadAndLookup = true; public static boolean hopperThrottleWhenFull = false; public static int hopperThrottleSkipTicks = 0; @@ -438,6 +439,8 @@ public class DivineConfig { "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."); + optimizedDragonRespawn = getBoolean(ConfigCategory.PERFORMANCE.key("optimizations.optimized-dragon-respawn"), optimizedDragonRespawn, + "When enabled, improving performance and reducing lag during the dragon’s resurrection event."); reduceChuckLoadAndLookup = getBoolean(ConfigCategory.PERFORMANCE.key("optimizations.reduce-chunk-load-and-lookup"), reduceChuckLoadAndLookup, "If enabled, optimizes chunk loading and block state lookups by reducing the number of chunk accesses required during operations such as Enderman teleportation."); diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/util/BlockPatternHelper.java b/divinemc-server/src/main/java/org/bxteam/divinemc/util/BlockPatternHelper.java new file mode 100644 index 0000000..4e7404d --- /dev/null +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/util/BlockPatternHelper.java @@ -0,0 +1,27 @@ +package org.bxteam.divinemc.util; + +import com.google.common.cache.LoadingCache; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.pattern.BlockInWorld; +import net.minecraft.world.level.block.state.pattern.BlockPattern; + +public class BlockPatternHelper { + public static BlockPattern.BlockPatternMatch partialSearchAround(BlockPattern pattern, Level world, BlockPos pos) { + LoadingCache loadingCache = BlockPattern.createLevelCache(world, false); + int i = Math.max(Math.max(pattern.getWidth(), pattern.getHeight()), pattern.getDepth()); + + for (BlockPos blockPos : BlockPos.betweenClosed(pos, pos.offset(i - 1, 0, i - 1))) { + for (Direction direction : Direction.values()) { + for (Direction direction2 : Direction.values()) { + BlockPattern.BlockPatternMatch result; + if (direction2 == direction || direction2 == direction.getOpposite() || (result = pattern.matches(blockPos, direction, direction2, loadingCache)) == null) + continue; + return result; + } + } + } + return null; + } +}