diff --git a/sakura-server/minecraft-patches/features/0001-Track-block-changes-and-level-tick-scheduler.patch b/sakura-server/minecraft-patches/features/0001-Track-block-changes-and-level-tick-scheduler.patch new file mode 100644 index 0000000..c915c18 --- /dev/null +++ b/sakura-server/minecraft-patches/features/0001-Track-block-changes-and-level-tick-scheduler.patch @@ -0,0 +1,75 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Samsuik +Date: Sun, 9 Feb 2025 17:52:59 +0000 +Subject: [PATCH] Track block changes and level tick scheduler + + +diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java +index 3a926d4d34a7c68a24b9e00bcbcff271c8992ad2..259c2b2d459d86cb11ab848c77f48c38ed174a63 100644 +--- a/net/minecraft/server/MinecraftServer.java ++++ b/net/minecraft/server/MinecraftServer.java +@@ -1749,6 +1749,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop blockChangeListeners; ++ ++ public final void updateBlockChangeListeners(java.util.List listeners) { ++ this.blockChangeListeners = listeners; ++ } ++ ++ private void blockChange(BlockPos pos, BlockState newBlock, BlockState oldBlock) { ++ for (me.samsuik.sakura.listener.BlockChangeTracker.Listener listener : this.blockChangeListeners) { ++ if (listener.test(pos, newBlock, oldBlock)) { ++ listener.call(); ++ } ++ } ++ } ++ // Sakura end - track block changes and tick scheduler + + public LevelChunk(Level level, ChunkPos pos) { + this(level, pos, UpgradeData.EMPTY, new LevelChunkTicks<>(), new LevelChunkTicks<>(), 0L, null, null, null); +@@ -163,6 +178,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p + this.debug = !empty && this.level.isDebug(); + this.defaultBlockState = empty ? VOID_AIR_BLOCKSTATE : AIR_BLOCKSTATE; + // Paper end - get block chunk optimisation ++ this.blockChangeListeners = level.blockChangeTracker.getListenersForChunk(pos); // Sakura - track block changes and tick scheduler + } + + public LevelChunk(ServerLevel level, ProtoChunk chunk, @Nullable LevelChunk.PostLoadProcessor postLoad) { +@@ -404,6 +420,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p + if (!section.getBlockState(i, i1, i2).is(block)) { + return null; + } else { ++ this.blockChange(pos, state, blockState); // Sakura - track block changes and tick scheduler + if (!this.level.isClientSide && doPlace && (!this.level.captureBlockStates || block instanceof net.minecraft.world.level.block.BaseEntityBlock)) { // CraftBukkit - Don't place while processing the BlockPlaceEvent, unless it's a BlockContainer. Prevents blocks such as TNT from activating when cancelled. + state.onPlace(this.level, pos, blockState, isMoving); + } diff --git a/sakura-server/minecraft-patches/features/0001-Client-Visibility-Settings.patch b/sakura-server/minecraft-patches/features/0002-Client-Visibility-Settings.patch similarity index 94% rename from sakura-server/minecraft-patches/features/0001-Client-Visibility-Settings.patch rename to sakura-server/minecraft-patches/features/0002-Client-Visibility-Settings.patch index 3d20d20..799dc4e 100644 --- a/sakura-server/minecraft-patches/features/0001-Client-Visibility-Settings.patch +++ b/sakura-server/minecraft-patches/features/0002-Client-Visibility-Settings.patch @@ -4,18 +4,6 @@ Date: Tue, 21 Sep 2021 23:54:25 +0100 Subject: [PATCH] Client Visibility Settings -diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 3a926d4d34a7c68a24b9e00bcbcff271c8992ad2..f1f322f623756f0c0a06a4207a12765c9623e151 100644 ---- a/net/minecraft/server/MinecraftServer.java -+++ b/net/minecraft/server/MinecraftServer.java -@@ -1749,6 +1749,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop optional = Optional.ofNullable(serverExplosion.getHitPlayers().get(serverPlayer)); diff --git a/sakura-server/minecraft-patches/features/0002-Load-Chunks-on-Movement.patch b/sakura-server/minecraft-patches/features/0003-Load-Chunks-on-Movement.patch similarity index 100% rename from sakura-server/minecraft-patches/features/0002-Load-Chunks-on-Movement.patch rename to sakura-server/minecraft-patches/features/0003-Load-Chunks-on-Movement.patch diff --git a/sakura-server/minecraft-patches/features/0003-Slice-Packet-obfuscation-and-reduction.patch b/sakura-server/minecraft-patches/features/0004-Slice-Packet-obfuscation-and-reduction.patch similarity index 100% rename from sakura-server/minecraft-patches/features/0003-Slice-Packet-obfuscation-and-reduction.patch rename to sakura-server/minecraft-patches/features/0004-Slice-Packet-obfuscation-and-reduction.patch diff --git a/sakura-server/minecraft-patches/features/0004-Optimise-paper-explosions.patch b/sakura-server/minecraft-patches/features/0005-Optimise-paper-explosions.patch similarity index 100% rename from sakura-server/minecraft-patches/features/0004-Optimise-paper-explosions.patch rename to sakura-server/minecraft-patches/features/0005-Optimise-paper-explosions.patch diff --git a/sakura-server/minecraft-patches/features/0005-Store-Entity-Data-State.patch b/sakura-server/minecraft-patches/features/0006-Store-Entity-Data-State.patch similarity index 92% rename from sakura-server/minecraft-patches/features/0005-Store-Entity-Data-State.patch rename to sakura-server/minecraft-patches/features/0006-Store-Entity-Data-State.patch index deec8f4..767dae8 100644 --- a/sakura-server/minecraft-patches/features/0005-Store-Entity-Data-State.patch +++ b/sakura-server/minecraft-patches/features/0006-Store-Entity-Data-State.patch @@ -35,10 +35,10 @@ index 5e48d84c5ab335975f6533472aec1e1789375bbf..30e6492e60fc7b5767d09574304ad3a3 public Entity(EntityType entityType, Level level) { this.type = entityType; diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 38fc85d18f737736dcdf5142c8357f9af43e4d19..0e790ff68d87ecc6977da77a6a148270014f4766 100644 +index 1165cf61413e9a1cd4373ef5f5858e8c5a040a20..5c61a690327cd1c872cdb3604cfa89d988918360 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java -@@ -1510,6 +1510,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1514,6 +1514,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl public void guardEntityTick(Consumer consumerEntity, T entity) { try { diff --git a/sakura-server/minecraft-patches/features/0006-Merge-Cannon-Entities.patch b/sakura-server/minecraft-patches/features/0007-Merge-Cannon-Entities.patch similarity index 92% rename from sakura-server/minecraft-patches/features/0006-Merge-Cannon-Entities.patch rename to sakura-server/minecraft-patches/features/0007-Merge-Cannon-Entities.patch index 8c85c6c..c116a8a 100644 --- a/sakura-server/minecraft-patches/features/0006-Merge-Cannon-Entities.patch +++ b/sakura-server/minecraft-patches/features/0007-Merge-Cannon-Entities.patch @@ -4,23 +4,19 @@ Date: Sat, 9 Sep 2023 18:39:15 +0100 Subject: [PATCH] Merge Cannon Entities -diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index f1f322f623756f0c0a06a4207a12765c9623e151..ae1fad06d85de83f53884449cff21fc0ae62bf97 100644 ---- a/net/minecraft/server/MinecraftServer.java -+++ b/net/minecraft/server/MinecraftServer.java -@@ -1750,6 +1750,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -@@ -828,6 +829,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -829,6 +831,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe entity.stopRiding(); } @@ -279,13 +275,13 @@ index b6467f9ff64a76104076a01bfd56852ce712d95b..e6aa1d1a5fc5cd2ffc156125c4eef2d0 @Nullable diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 0e790ff68d87ecc6977da77a6a148270014f4766..2aed31848b1d4bad27e7c7cc621497182466c2bb 100644 +index 5c61a690327cd1c872cdb3604cfa89d988918360..410a086f2fe2b6f695dd9bcce5a1f064b239f5c2 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java -@@ -837,6 +837,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - return chunk != null ? chunk.getNoiseBiome(x, y, z) : this.getUncachedNoiseBiome(x, y, z); - } - // Paper end - optimise random ticking +@@ -841,6 +841,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + public final me.samsuik.sakura.listener.LevelTickScheduler levelTickScheduler = new me.samsuik.sakura.listener.LevelTickScheduler(); + public final me.samsuik.sakura.listener.BlockChangeTracker blockChangeTracker = new me.samsuik.sakura.listener.BlockChangeTracker(this); + // Sakura end - track block changes and tick scheduler + public final me.samsuik.sakura.entity.merge.EntityMergeHandler mergeHandler = new me.samsuik.sakura.entity.merge.EntityMergeHandler(); // Sakura - merge cannon entities protected Level( diff --git a/sakura-server/minecraft-patches/features/0007-Replace-explosion-density-cache.patch b/sakura-server/minecraft-patches/features/0008-Replace-explosion-density-cache.patch similarity index 87% rename from sakura-server/minecraft-patches/features/0007-Replace-explosion-density-cache.patch rename to sakura-server/minecraft-patches/features/0008-Replace-explosion-density-cache.patch index 30999a6..55f1190 100644 --- a/sakura-server/minecraft-patches/features/0007-Replace-explosion-density-cache.patch +++ b/sakura-server/minecraft-patches/features/0008-Replace-explosion-density-cache.patch @@ -4,25 +4,25 @@ Date: Mon, 22 Apr 2024 23:01:26 +0100 Subject: [PATCH] Replace explosion density cache -diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index ae1fad06d85de83f53884449cff21fc0ae62bf97..6d8c513e78fa4efd8c7f6f534cf3958d46448efb 100644 ---- a/net/minecraft/server/MinecraftServer.java -+++ b/net/minecraft/server/MinecraftServer.java -@@ -1751,6 +1751,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Explosion.BlockInteraction.DESTROY; // CraftBukkit - handle custom explosion type }; Vec3 vec3 = new Vec3(x, y, z); @@ -26,7 +26,7 @@ index 83bd1ddec7edb09e9a28eead178d7d07cbde8749..ee44ba44773f245d351aac9461bd6cff if (configurator != null) configurator.accept(serverExplosion);// Paper - Allow explosions to damage source serverExplosion.explode(); // CraftBukkit start -@@ -1874,6 +1883,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1877,6 +1886,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return serverExplosion; } // CraftBukkit end @@ -42,7 +42,7 @@ index 83bd1ddec7edb09e9a28eead178d7d07cbde8749..ee44ba44773f245d351aac9461bd6cff ParticleOptions particleOptions = serverExplosion.isSmall() ? smallExplosionParticles : largeExplosionParticles; for (ServerPlayer serverPlayer : this.players) { -@@ -1894,7 +1912,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1897,7 +1915,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } } @@ -52,7 +52,7 @@ index 83bd1ddec7edb09e9a28eead178d7d07cbde8749..ee44ba44773f245d351aac9461bd6cff private Explosion.BlockInteraction getDestroyType(GameRules.Key decayGameRule) { diff --git a/net/minecraft/world/entity/item/PrimedTnt.java b/net/minecraft/world/entity/item/PrimedTnt.java -index b378b4c4930c4ebd55795591aca173fd1fee46c9..c88fe6c244f6a88f1e42822dd0795187dcc3b655 100644 +index e6aa1d1a5fc5cd2ffc156125c4eef2d0d1aeef4a..cb972f9d619c7acc8bbed4cc18513ad4b97f19ed 100644 --- a/net/minecraft/world/entity/item/PrimedTnt.java +++ b/net/minecraft/world/entity/item/PrimedTnt.java @@ -77,20 +77,7 @@ public class PrimedTnt extends Entity implements TraceableEntity, me.samsuik.sak diff --git a/sakura-server/minecraft-patches/features/0010-Optimise-cannon-entity-movement.patch b/sakura-server/minecraft-patches/features/0011-Optimise-cannon-entity-movement.patch similarity index 100% rename from sakura-server/minecraft-patches/features/0010-Optimise-cannon-entity-movement.patch rename to sakura-server/minecraft-patches/features/0011-Optimise-cannon-entity-movement.patch diff --git a/sakura-server/minecraft-patches/features/0011-Add-maxSearch-to-getEntities.patch b/sakura-server/minecraft-patches/features/0012-Add-maxSearch-to-getEntities.patch similarity index 97% rename from sakura-server/minecraft-patches/features/0011-Add-maxSearch-to-getEntities.patch rename to sakura-server/minecraft-patches/features/0012-Add-maxSearch-to-getEntities.patch index cd89284..92878f6 100644 --- a/sakura-server/minecraft-patches/features/0011-Add-maxSearch-to-getEntities.patch +++ b/sakura-server/minecraft-patches/features/0012-Add-maxSearch-to-getEntities.patch @@ -83,10 +83,10 @@ index 7554c109c35397bc1a43dd80e87764fd78645bbf..d60f30f7afb15cc90c1bd4b816136d00 } } diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 9217983e973fb522776babe0588dd419653e3b39..e0341e79c87fe115732aab1aa0bd1d8c514ba7b8 100644 +index 4314234e1d7f7a0fedf0ecf29ac3284e51be88d7..544617311ccc2573273cebba62e9503caa8a8dc3 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java -@@ -1791,10 +1791,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1795,10 +1795,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl this.getEntities(entityTypeTest, bounds, predicate, output, Integer.MAX_VALUE); } @@ -106,7 +106,7 @@ index 9217983e973fb522776babe0588dd419653e3b39..e0341e79c87fe115732aab1aa0bd1d8c Profiler.get().incrementCounter("getEntities"); if (entityTypeTest instanceof net.minecraft.world.entity.EntityType byType) { -@@ -1811,7 +1819,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1815,7 +1823,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl if (entityTypeTest == null) { if (maxCount != Integer.MAX_VALUE) { diff --git a/sakura-server/minecraft-patches/features/0012-Use-maxEntityCollision-limit-for-entity-retrieval.patch b/sakura-server/minecraft-patches/features/0013-Use-maxEntityCollision-limit-for-entity-retrieval.patch similarity index 100% rename from sakura-server/minecraft-patches/features/0012-Use-maxEntityCollision-limit-for-entity-retrieval.patch rename to sakura-server/minecraft-patches/features/0013-Use-maxEntityCollision-limit-for-entity-retrieval.patch diff --git a/sakura-server/minecraft-patches/features/0013-Explosion-Durable-Blocks.patch b/sakura-server/minecraft-patches/features/0014-Explosion-Durable-Blocks.patch similarity index 96% rename from sakura-server/minecraft-patches/features/0013-Explosion-Durable-Blocks.patch rename to sakura-server/minecraft-patches/features/0014-Explosion-Durable-Blocks.patch index 0945ff0..c12343b 100644 --- a/sakura-server/minecraft-patches/features/0013-Explosion-Durable-Blocks.patch +++ b/sakura-server/minecraft-patches/features/0014-Explosion-Durable-Blocks.patch @@ -41,11 +41,11 @@ index 68e50c6ade879d263424f244070677cb81c34c33..8467af4ee57b6699227370ada7bf15ca return !interactionResult.consumesAction() && context.getItemInHand().has(DataComponents.CONSUMABLE) ? super.use(context.getLevel(), context.getPlayer(), context.getHand()) diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index b4a8a81f1fa091e45f1f39fdb69c61871d7dc6b9..19aa5010b019e343d0fb085359eac98bcb5b5efa 100644 +index 544617311ccc2573273cebba62e9503caa8a8dc3..7d98febf87a51fb7d9b502fa362d1bc4ac1e3eaa 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java -@@ -839,6 +839,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - // Paper end - optimise random ticking +@@ -843,6 +843,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + // Sakura end - track block changes and tick scheduler public final me.samsuik.sakura.entity.merge.EntityMergeHandler mergeHandler = new me.samsuik.sakura.entity.merge.EntityMergeHandler(); // Sakura - merge cannon entities public final me.samsuik.sakura.explosion.density.BlockDensityCache densityCache = new me.samsuik.sakura.explosion.density.BlockDensityCache(); // Sakura - explosion density cache + public final me.samsuik.sakura.explosion.durable.DurableBlockManager durabilityManager = new me.samsuik.sakura.explosion.durable.DurableBlockManager(); // Sakura - explosion durable blocks diff --git a/sakura-server/minecraft-patches/features/0014-Destroy-Waterlogged-Blocks.patch b/sakura-server/minecraft-patches/features/0015-Destroy-Waterlogged-Blocks.patch similarity index 100% rename from sakura-server/minecraft-patches/features/0014-Destroy-Waterlogged-Blocks.patch rename to sakura-server/minecraft-patches/features/0015-Destroy-Waterlogged-Blocks.patch diff --git a/sakura-server/minecraft-patches/features/0015-Configure-cannon-physics.patch b/sakura-server/minecraft-patches/features/0016-Configure-cannon-physics.patch similarity index 99% rename from sakura-server/minecraft-patches/features/0015-Configure-cannon-physics.patch rename to sakura-server/minecraft-patches/features/0016-Configure-cannon-physics.patch index 581a2b6..9a27d06 100644 --- a/sakura-server/minecraft-patches/features/0015-Configure-cannon-physics.patch +++ b/sakura-server/minecraft-patches/features/0016-Configure-cannon-physics.patch @@ -421,13 +421,13 @@ index d23193d3f11505cea428414487f891ab584ad071..ffd96218e2ee84aae7a008ef1b95f84d // Paper end - Option to prevent TNT from moving in water } diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index ee391a6fe70381ce4abc069034f7f9704029e416..cd607496df8a33f38d267c8316ffe8406868f02c 100644 +index 7d98febf87a51fb7d9b502fa362d1bc4ac1e3eaa..911a665e1ae07b2665222e04a9e1b0a80af0f877 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java -@@ -837,6 +837,170 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - return chunk != null ? chunk.getNoiseBiome(x, y, z) : this.getUncachedNoiseBiome(x, y, z); - } - // Paper end - optimise random ticking +@@ -844,6 +844,170 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + public final me.samsuik.sakura.entity.merge.EntityMergeHandler mergeHandler = new me.samsuik.sakura.entity.merge.EntityMergeHandler(); // Sakura - merge cannon entities + public final me.samsuik.sakura.explosion.density.BlockDensityCache densityCache = new me.samsuik.sakura.explosion.density.BlockDensityCache(); // Sakura - explosion density cache + public final me.samsuik.sakura.explosion.durable.DurableBlockManager durabilityManager = new me.samsuik.sakura.explosion.durable.DurableBlockManager(); // Sakura - explosion durable blocks + // Sakura start - configure cannon physics + public final net.minecraft.world.phys.BlockHitResult.Type clipLegacy(Vec3 from, Vec3 to) { + int toX = Mth.floor(to.x); @@ -592,9 +592,9 @@ index ee391a6fe70381ce4abc069034f7f9704029e416..cd607496df8a33f38d267c8316ffe840 + return x >= bb.minX && x <= bb.maxX && y >= bb.minY && y <= bb.maxY; + } + // Sakura end - configure cannon physics - public final me.samsuik.sakura.entity.merge.EntityMergeHandler mergeHandler = new me.samsuik.sakura.entity.merge.EntityMergeHandler(); // Sakura - merge cannon entities - public final me.samsuik.sakura.explosion.density.BlockDensityCache densityCache = new me.samsuik.sakura.explosion.density.BlockDensityCache(); // Sakura - explosion density cache - public final me.samsuik.sakura.explosion.durable.DurableBlockManager durabilityManager = new me.samsuik.sakura.explosion.durable.DurableBlockManager(); // Sakura - explosion durable blocks + + protected Level( + WritableLevelData levelData, diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java index 7b5a50ef269d0ca59fb067258421b53971a9998d..a4ceca6cfaaf048f3f78b18724d54780675354e7 100644 --- a/net/minecraft/world/level/ServerExplosion.java @@ -961,7 +961,7 @@ index a89a42a3ad6cecd5cc4d44e4456d52a2997ba2e5..9c3c0305aa96b4a1b40841d1c1f145af } diff --git a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -index a6413663112685554afd79f13d3d76f1cd753801..184a9c681b4d1359d028d227dc0a74d7b78b7667 100644 +index d1fdb60b3dbcfc244c16d6f61802774ec54cc6ec..933dbea525cf342a246f60510bdac98e1ff7b00a 100644 --- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java +++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java @@ -165,6 +165,12 @@ public class PistonMovingBlockEntity extends BlockEntity { diff --git a/sakura-server/minecraft-patches/features/0016-Allow-explosions-to-destroy-lava.patch b/sakura-server/minecraft-patches/features/0017-Allow-explosions-to-destroy-lava.patch similarity index 95% rename from sakura-server/minecraft-patches/features/0016-Allow-explosions-to-destroy-lava.patch rename to sakura-server/minecraft-patches/features/0017-Allow-explosions-to-destroy-lava.patch index 0b3f5d8..af6f176 100644 --- a/sakura-server/minecraft-patches/features/0016-Allow-explosions-to-destroy-lava.patch +++ b/sakura-server/minecraft-patches/features/0017-Allow-explosions-to-destroy-lava.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Allow explosions to destroy lava diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java -index 040596183eb6c61369e59112fa928e9c129adb34..ad44fb3a3ee0b6595564031f73fc61c459a8d951 100644 +index a4ceca6cfaaf048f3f78b18724d54780675354e7..0ed83fa6b8c8c38cc9f94a381276d300abdac839 100644 --- a/net/minecraft/world/level/ServerExplosion.java +++ b/net/minecraft/world/level/ServerExplosion.java @@ -407,6 +407,11 @@ public class ServerExplosion implements Explosion { diff --git a/sakura-server/minecraft-patches/features/0017-Collide-with-non-solid-blocks.patch b/sakura-server/minecraft-patches/features/0018-Collide-with-non-solid-blocks.patch similarity index 100% rename from sakura-server/minecraft-patches/features/0017-Collide-with-non-solid-blocks.patch rename to sakura-server/minecraft-patches/features/0018-Collide-with-non-solid-blocks.patch diff --git a/sakura-server/minecraft-patches/features/0018-Reduce-entity-tracker-player-updates.patch b/sakura-server/minecraft-patches/features/0019-Reduce-entity-tracker-player-updates.patch similarity index 100% rename from sakura-server/minecraft-patches/features/0018-Reduce-entity-tracker-player-updates.patch rename to sakura-server/minecraft-patches/features/0019-Reduce-entity-tracker-player-updates.patch diff --git a/sakura-server/minecraft-patches/features/0019-Legacy-lava-block-formation.patch b/sakura-server/minecraft-patches/features/0020-Legacy-lava-block-formation.patch similarity index 100% rename from sakura-server/minecraft-patches/features/0019-Legacy-lava-block-formation.patch rename to sakura-server/minecraft-patches/features/0020-Legacy-lava-block-formation.patch diff --git a/sakura-server/minecraft-patches/features/0020-Add-entity-travel-distance-limits.patch b/sakura-server/minecraft-patches/features/0021-Add-entity-travel-distance-limits.patch similarity index 94% rename from sakura-server/minecraft-patches/features/0020-Add-entity-travel-distance-limits.patch rename to sakura-server/minecraft-patches/features/0021-Add-entity-travel-distance-limits.patch index cb411bf..4abdf77 100644 --- a/sakura-server/minecraft-patches/features/0020-Add-entity-travel-distance-limits.patch +++ b/sakura-server/minecraft-patches/features/0021-Add-entity-travel-distance-limits.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add entity travel distance limits diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index ee44ba44773f245d351aac9461bd6cff18204f01..12f5f0002d2b298c4f9bd021d13626ddb5719317 100644 +index 88b377a53159a473a43bdf06b78bfd3d4a2362a1..539c2e465d4c89584b5bccaad18fadc41db0643a 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -1292,6 +1292,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1295,6 +1295,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe final boolean isActive = io.papermc.paper.entity.activation.ActivationRange.checkIfActive(entity); // Paper - EAR 2 if (isActive) { // Paper - EAR 2 entity.tick(); diff --git a/sakura-server/minecraft-patches/features/0021-Protect-scaffolding-from-creepers.patch b/sakura-server/minecraft-patches/features/0022-Protect-scaffolding-from-creepers.patch similarity index 92% rename from sakura-server/minecraft-patches/features/0021-Protect-scaffolding-from-creepers.patch rename to sakura-server/minecraft-patches/features/0022-Protect-scaffolding-from-creepers.patch index 82a8cb9..a971756 100644 --- a/sakura-server/minecraft-patches/features/0021-Protect-scaffolding-from-creepers.patch +++ b/sakura-server/minecraft-patches/features/0022-Protect-scaffolding-from-creepers.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Protect scaffolding from creepers diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java -index ad44fb3a3ee0b6595564031f73fc61c459a8d951..d2d2bb0e60f4f12761fa02b1c6fb293d15e4efed 100644 +index 0ed83fa6b8c8c38cc9f94a381276d300abdac839..b43487bd468179a9634897002df44146e9f24c1b 100644 --- a/net/minecraft/world/level/ServerExplosion.java +++ b/net/minecraft/world/level/ServerExplosion.java @@ -412,6 +412,11 @@ public class ServerExplosion implements Explosion { diff --git a/sakura-server/minecraft-patches/features/0022-Configurable-left-shooting-and-adjusting-limits.patch b/sakura-server/minecraft-patches/features/0023-Configurable-left-shooting-and-adjusting-limits.patch similarity index 100% rename from sakura-server/minecraft-patches/features/0022-Configurable-left-shooting-and-adjusting-limits.patch rename to sakura-server/minecraft-patches/features/0023-Configurable-left-shooting-and-adjusting-limits.patch diff --git a/sakura-server/minecraft-patches/features/0023-Optimise-hopper-ticking.patch b/sakura-server/minecraft-patches/features/0024-Optimise-hopper-ticking.patch similarity index 97% rename from sakura-server/minecraft-patches/features/0023-Optimise-hopper-ticking.patch rename to sakura-server/minecraft-patches/features/0024-Optimise-hopper-ticking.patch index 9d56b30..5cd558b 100644 --- a/sakura-server/minecraft-patches/features/0023-Optimise-hopper-ticking.patch +++ b/sakura-server/minecraft-patches/features/0024-Optimise-hopper-ticking.patch @@ -42,10 +42,10 @@ index 2d3721e311851c1801b090e99d4f9d0daf4e5f99..2249f5338f97471a833acddcee95f6a7 boolean isEmpty(); diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index eeb37d088cec5b2b8e1ac4bd48b4491eed0822e2..28fc6372b3e4815fa62217a27f265f182046fe73 100644 +index 911a665e1ae07b2665222e04a9e1b0a80af0f877..818887bef8265731b01f16f4edbfd88bc89cc4c9 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java -@@ -1659,7 +1659,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1663,7 +1663,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl // Spigot end if (tickingBlockEntity.isRemoved()) { toRemove.add(tickingBlockEntity); // Paper - Fix MC-117075; use removeAll @@ -282,10 +282,10 @@ index 28e3b73507b988f7234cbf29c4024c88180d0aef..a0d247aa883553708c4b921582324255 + // Sakura end - optimise hopper ticking } diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index 761fdcd4a4e18f45547afd8edff44f61c6eeacb4..04477dd45088c06c97c2f8e24e9d1a7362a62a61 100644 +index 7887799c39b6e5b1657aff49d7110cf14bec8a79..f71ae8ebf7ce494b2abf350513f826139c18eadc 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java -@@ -955,6 +955,13 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p +@@ -972,6 +972,13 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p return BlockEntityType.getKey(this.blockEntity.getType()).toString(); } @@ -299,7 +299,7 @@ index 761fdcd4a4e18f45547afd8edff44f61c6eeacb4..04477dd45088c06c97c2f8e24e9d1a73 @Override public String toString() { return "Level ticker for " + this.getType() + "@" + this.getPos(); -@@ -1003,6 +1010,13 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p +@@ -1020,6 +1027,13 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p return this.ticker.getType(); } diff --git a/sakura-server/minecraft-patches/features/0024-Optimise-entity-scheduler-ticking.patch b/sakura-server/minecraft-patches/features/0025-Optimise-entity-scheduler-ticking.patch similarity index 97% rename from sakura-server/minecraft-patches/features/0024-Optimise-entity-scheduler-ticking.patch rename to sakura-server/minecraft-patches/features/0025-Optimise-entity-scheduler-ticking.patch index 6129f91..f2d8f36 100644 --- a/sakura-server/minecraft-patches/features/0024-Optimise-entity-scheduler-ticking.patch +++ b/sakura-server/minecraft-patches/features/0025-Optimise-entity-scheduler-ticking.patch @@ -48,7 +48,7 @@ index 26207443b1223119c03db478d7e816d9cdf8e618..1664830a49f37825c39fb6b436011d81 @Override diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 6d8c513e78fa4efd8c7f6f534cf3958d46448efb..bad2fbd90d4db6b89b6346da53a41ef110307169 100644 +index 259c2b2d459d86cb11ab848c77f48c38ed174a63..fad4aabc0ff3f484e271c4784543cdf2c3c2cafd 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -1678,7 +1678,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop p.expiry().isExpired(tick)); } diff --git a/sakura-server/src/main/java/me/samsuik/sakura/listener/BlockChangeTracker.java b/sakura-server/src/main/java/me/samsuik/sakura/listener/BlockChangeTracker.java new file mode 100644 index 0000000..0efdc05 --- /dev/null +++ b/sakura-server/src/main/java/me/samsuik/sakura/listener/BlockChangeTracker.java @@ -0,0 +1,101 @@ +package me.samsuik.sakura.listener; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.LevelChunk; +import org.jspecify.annotations.NullMarked; + +import java.util.*; +import java.util.function.BiPredicate; +import java.util.function.LongConsumer; + +@NullMarked +public final class BlockChangeTracker { + private final Long2ObjectMap> chunkListeners = new Long2ObjectOpenHashMap<>(); + private final Long2ObjectMap identifiersInUse = new Long2ObjectOpenHashMap<>(); + private final Level level; + private long identifier = Long.MIN_VALUE; + + public BlockChangeTracker(Level level) { + this.level = level; + } + + public long listenForChangesOnce(BiPredicate filter, Set positions, Runnable callback) { + LongConsumer singleUseCallback = (identifier) -> { + callback.run(); + this.stopListening(identifier); + }; + return this.listenForChanges(filter, positions, singleUseCallback); + } + + public long listenForChanges(BiPredicate filter, Set positions, LongConsumer callback) { + long identifier = this.identifier++; + Listener listener = new Listener( + filter, positions, identifier, callback + ); + for (ChunkPos chunkPos : getChunkPositions(positions)) { + this.addListenerToChunk(chunkPos, listener); + } + this.identifiersInUse.put(identifier, listener); + return identifier; + } + + public void stopListening(long identifier) { + Listener listener = this.identifiersInUse.remove(identifier); + for (ChunkPos chunkPos : getChunkPositions(listener.positions())) { + this.removeListenerFronChunk(chunkPos, listener); + } + } + + private void removeListenerFronChunk(ChunkPos chunkPos, Listener listener) { + long chunkKey = chunkPos.toLong(); + List listeners = this.chunkListeners.computeIfPresent(chunkKey, (k, present) -> { + present.remove(listener); + return present.isEmpty() ? null : present; + }); + this.updateListeners(chunkPos, Objects.requireNonNullElse(listeners, Collections.emptyList())); + } + + private void addListenerToChunk(ChunkPos chunkPos, Listener listener) { + long chunkKey = chunkPos.toLong(); + List listeners = this.chunkListeners.computeIfAbsent(chunkKey, i -> new ArrayList<>()); + listeners.add(listener); + this.updateListeners(chunkPos, listeners); + } + + private void updateListeners(ChunkPos chunkPos, List listeners) { + LevelChunk chunk = ((ServerLevel) this.level).chunkSource.getChunkAtIfLoadedImmediately(chunkPos.x, chunkPos.z); + if (chunk != null) { + chunk.updateBlockChangeListeners(List.copyOf(listeners)); + } + } + + public List getListenersForChunk(ChunkPos chunkPos) { + return this.chunkListeners.getOrDefault(chunkPos.toLong(), Collections.emptyList()); + } + + private static Set getChunkPositions(Set positions) { + Set chunkPositions = new ObjectOpenHashSet<>(); + for (BlockPos pos : positions) { + chunkPositions.add(new ChunkPos(pos)); + } + return chunkPositions; + } + + public record Listener(BiPredicate filter, Set positions, + long identifier, LongConsumer callback) { + public void call() { + this.callback.accept(this.identifier); + } + + public boolean test(BlockPos pos, BlockState newBlock, BlockState oldBlock) { + return this.filter.test(newBlock, oldBlock) && this.positions.contains(pos); + } + } +} diff --git a/sakura-server/src/main/java/me/samsuik/sakura/listener/LevelTickScheduler.java b/sakura-server/src/main/java/me/samsuik/sakura/listener/LevelTickScheduler.java new file mode 100644 index 0000000..22c9e16 --- /dev/null +++ b/sakura-server/src/main/java/me/samsuik/sakura/listener/LevelTickScheduler.java @@ -0,0 +1,47 @@ +package me.samsuik.sakura.listener; + +import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import net.minecraft.world.level.Level; +import org.jspecify.annotations.NullMarked; + +import java.util.ArrayList; +import java.util.List; + +@NullMarked +public final class LevelTickScheduler { + private final Int2ObjectMap> tickTasks = new Int2ObjectLinkedOpenHashMap<>(); + private final Object2IntMap taskIntervals = new Object2IntOpenHashMap<>(); + + public void registerNewTask(Runnable runnable, int interval) { + this.registerNewTask(tick -> runnable.run(), interval); + } + + public void registerNewTask(TickTask task, int interval) { + int safeInterval = Math.max(interval + 1, 1); + this.tickTasks.computeIfAbsent(safeInterval, i -> new ArrayList<>()) + .add(task); + this.taskIntervals.put(task, Math.max(safeInterval + 1, 1)); + } + + private void runTasks(List tasks, long gameTime) { + for (TickTask tickTask : tasks) { + tickTask.run(gameTime); + } + } + + public void levelTick(Level level) { + long gameTime = level.getGameTime(); + for (int interval : this.tickTasks.keySet()) { + if (gameTime % interval == 0) { + this.runTasks(this.tickTasks.get(interval), gameTime); + } + } + } + + public interface TickTask { + void run(long tick); + } +}