From 6046717ae0257d18be5c85ed5a7fba36ed9a258d Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Mon, 19 Jan 2026 22:28:10 +0800 Subject: [PATCH 01/11] Prevents entities from moving into weak loaded chunks --- ...s-from-moving-into-weak-loaded-chunk.patch | 94 +++++++++++++++++++ .../PreventMoveIntoWeakLoadedChunks.java | 35 +++++++ 2 files changed, 129 insertions(+) create mode 100644 leaf-server/minecraft-patches/features/0295-Prevents-entities-from-moving-into-weak-loaded-chunk.patch create mode 100644 leaf-server/src/main/java/org/dreeam/leaf/config/modules/gameplay/PreventMoveIntoWeakLoadedChunks.java diff --git a/leaf-server/minecraft-patches/features/0295-Prevents-entities-from-moving-into-weak-loaded-chunk.patch b/leaf-server/minecraft-patches/features/0295-Prevents-entities-from-moving-into-weak-loaded-chunk.patch new file mode 100644 index 000000000..730de4ace --- /dev/null +++ b/leaf-server/minecraft-patches/features/0295-Prevents-entities-from-moving-into-weak-loaded-chunk.patch @@ -0,0 +1,94 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> +Date: Mon, 19 Jan 2026 22:26:07 +0800 +Subject: [PATCH] Prevents entities from moving into weak loaded chunks + + +diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java +index cf2a365bcbb1a278e5553c16ffef6d9ae81f4d41..1a37a469924da67cfc34a9564a346fee9f3dbe7e 100644 +--- a/net/minecraft/server/level/ServerLevel.java ++++ b/net/minecraft/server/level/ServerLevel.java +@@ -250,7 +250,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + } + + // Paper start +- public final boolean areChunksLoadedForMove(AABB box) { ++ public final boolean areChunksLoadedForMove(AABB box) { // Leaf - diff on change - update areChunksLoadedForEntityMove if this changed + // copied code from collision methods, so that we can guarantee that they won't load chunks (we don't override + // CollisionGetter methods for VoxelShapes) + // be more strict too, add a block (dumb plugins in move events?) +@@ -276,8 +276,40 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + } + } + ++ return true; ++ } // Leaf - diff on change - update areChunksLoadedForEntityMove if this changed ++ ++ // Leaf start - Prevent entity from moving into weak loaded chunks ++ public final boolean areChunksLoadedForEntityMove(AABB box) { ++ // copied code from collision methods, so that we can guarantee that they won't load chunks (we don't override ++ // CollisionGetter methods for VoxelShapes) ++ // be more strict too, add a block (dumb plugins in move events?) ++ int minBlockX = Mth.floor(box.minX - 1.0E-7D) - 3; ++ int maxBlockX = Mth.floor(box.maxX + 1.0E-7D) + 3; ++ ++ int minBlockZ = Mth.floor(box.minZ - 1.0E-7D) - 3; ++ int maxBlockZ = Mth.floor(box.maxZ + 1.0E-7D) + 3; ++ ++ int minChunkX = minBlockX >> 4; ++ int maxChunkX = maxBlockX >> 4; ++ ++ int minChunkZ = minBlockZ >> 4; ++ int maxChunkZ = maxBlockZ >> 4; ++ ++ ServerChunkCache chunkProvider = this.getChunkSource(); ++ ++ for (int cx = minChunkX; cx <= maxChunkX; ++cx) { ++ for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) { ++ LevelChunk chunk = chunkProvider.getChunkAtIfLoadedImmediately(cx, cz); ++ if (chunk == null || !chunk.getFullStatus().isOrAfter(FullChunkStatus.ENTITY_TICKING)) { // check chunk status ++ return false; ++ } ++ } ++ } ++ + return true; + } ++ // Leaf end - Prevent entity from moving into weak loaded chunks + + public final void loadChunksForMoveAsync(AABB box, ca.spottedleaf.concurrentutil.util.Priority priority, + java.util.function.Consumer> onLoad) { +diff --git a/net/minecraft/world/entity/projectile/ThrowableProjectile.java b/net/minecraft/world/entity/projectile/ThrowableProjectile.java +index 47f2e940b68738cb02719cd82a5c0fff56fba062..9b2144e4f73bdb1d1aab1b7185149380bd04b4a0 100644 +--- a/net/minecraft/world/entity/projectile/ThrowableProjectile.java ++++ b/net/minecraft/world/entity/projectile/ThrowableProjectile.java +@@ -12,6 +12,7 @@ import net.minecraft.world.phys.Vec3; + + public abstract class ThrowableProjectile extends Projectile { + private static final float MIN_CAMERA_DISTANCE_SQUARED = 12.25F; ++ protected boolean preventMoveIntoWeakLoadedChunks = org.dreeam.leaf.config.modules.gameplay.PreventMoveIntoWeakLoadedChunks.isThrowableProjectilesEnabled(); // Leaf - Prevent entity from moving into weak loaded chunks + + protected ThrowableProjectile(EntityType type, Level level) { + super(type, level); +@@ -57,7 +58,20 @@ public abstract class ThrowableProjectile extends Projectile { + if (hitResultOnMoveVector.getType() != HitResult.Type.MISS) { + location = hitResultOnMoveVector.getLocation(); + } else { +- location = this.position().add(this.getDeltaMovement()); ++ // Leaf start - Prevent entity from moving into weak loaded chunks ++ if (preventMoveIntoWeakLoadedChunks) { ++ Vec3 previousLocation = this.position(); ++ location = this.position().add(this.getDeltaMovement()); ++ if (this.level() instanceof net.minecraft.server.level.ServerLevel serverLevel) { ++ if (!serverLevel.areChunksLoadedForEntityMove(this.getBoundingBox().expandTowards(location.subtract(previousLocation)))) { ++ location = previousLocation; ++ this.setDeltaMovement(Vec3.ZERO); ++ } ++ } ++ } else { ++ location = this.position().add(this.getDeltaMovement()); ++ } ++ // Leaf end - Prevent entity from moving into weak loaded chunks + } + + this.setPos(location); diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/gameplay/PreventMoveIntoWeakLoadedChunks.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/gameplay/PreventMoveIntoWeakLoadedChunks.java new file mode 100644 index 000000000..a2b3b89f1 --- /dev/null +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/gameplay/PreventMoveIntoWeakLoadedChunks.java @@ -0,0 +1,35 @@ +package org.dreeam.leaf.config.modules.gameplay; + +import org.dreeam.leaf.config.ConfigModules; +import org.dreeam.leaf.config.EnumConfigCategory; + +public class PreventMoveIntoWeakLoadedChunks extends ConfigModules { + public String getBasePath() { + return EnumConfigCategory.GAMEPLAY.getBaseKeyName() + ".prevent-moving-into-weak-loaded-chunks"; + } + + public static boolean enabled = false; + public static boolean throwableProjectiles = false; + + public static boolean isThrowableProjectilesEnabled() { + return enabled && throwableProjectiles; + } + + @Override + public void onLoaded() { + config.addCommentRegionBased(getBasePath(), + "Prevents entities from moving into weak loaded chunks.", + "阻止实体进入弱加载区块." + ); + + enabled = config.getBoolean(getBasePath(), enabled, config().pickStringRegionBased( + "Set to true to enable features below.", + "设置为 true 以启用以下功能." + )); + + throwableProjectiles = config.getBoolean(getBasePath() + ".throwable-projectiles", throwableProjectiles, config().pickStringRegionBased( + "Prevents throwable projectiles from moving into weak loaded chunks.", + "阻止投掷物进入弱加载区块." + )); + } +} From edbdb1b6194f6f040816aafd37c53364320195d4 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Mon, 19 Jan 2026 22:32:14 +0800 Subject: [PATCH 02/11] skip for ender pearls --- ...ies-from-moving-into-weak-loaded-chunk.patch | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/leaf-server/minecraft-patches/features/0295-Prevents-entities-from-moving-into-weak-loaded-chunk.patch b/leaf-server/minecraft-patches/features/0295-Prevents-entities-from-moving-into-weak-loaded-chunk.patch index 730de4ace..f9dcd465c 100644 --- a/leaf-server/minecraft-patches/features/0295-Prevents-entities-from-moving-into-weak-loaded-chunk.patch +++ b/leaf-server/minecraft-patches/features/0295-Prevents-entities-from-moving-into-weak-loaded-chunk.patch @@ -92,3 +92,20 @@ index 47f2e940b68738cb02719cd82a5c0fff56fba062..9b2144e4f73bdb1d1aab1b7185149380 } this.setPos(location); +diff --git a/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java b/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java +index 4d416d3a8402a78b8ad6383d842f589a821ddbe9..2fe748ab39602b1f3d2c4f9982375e582806828c 100644 +--- a/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java ++++ b/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java +@@ -33,10 +33,12 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { + + public ThrownEnderpearl(EntityType type, Level level) { + super(type, level); ++ this.preventMoveIntoWeakLoadedChunks = false; // Leaf - Prevent entity from moving into weak loaded chunks + } + + public ThrownEnderpearl(Level level, LivingEntity owner, ItemStack item) { + super(EntityType.ENDER_PEARL, owner, level, item); ++ this.preventMoveIntoWeakLoadedChunks = false; // Leaf - Prevent entity from moving into weak loaded chunks + } + + @Override From b06f2bbe35a7de16e93158adadc7742ba718a8fb Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Mon, 19 Jan 2026 22:35:33 +0800 Subject: [PATCH 03/11] Fix config --- .../modules/gameplay/PreventMoveIntoWeakLoadedChunks.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/gameplay/PreventMoveIntoWeakLoadedChunks.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/gameplay/PreventMoveIntoWeakLoadedChunks.java index a2b3b89f1..4333afaf6 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/gameplay/PreventMoveIntoWeakLoadedChunks.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/gameplay/PreventMoveIntoWeakLoadedChunks.java @@ -22,7 +22,7 @@ public void onLoaded() { "阻止实体进入弱加载区块." ); - enabled = config.getBoolean(getBasePath(), enabled, config().pickStringRegionBased( + enabled = config.getBoolean(getBasePath() + ".enabled", enabled, config().pickStringRegionBased( "Set to true to enable features below.", "设置为 true 以启用以下功能." )); From 3bf4a7a4d6be51ed9bc235a70a31055befee161b Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Mon, 19 Jan 2026 22:45:47 +0800 Subject: [PATCH 04/11] move to fixes section --- ...events-entities-from-moving-into-weak-loaded-chunk.patch | 6 +++--- .../PreventMoveIntoWeakLoadedChunks.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename leaf-server/src/main/java/org/dreeam/leaf/config/modules/{gameplay => fixes}/PreventMoveIntoWeakLoadedChunks.java (96%) diff --git a/leaf-server/minecraft-patches/features/0295-Prevents-entities-from-moving-into-weak-loaded-chunk.patch b/leaf-server/minecraft-patches/features/0295-Prevents-entities-from-moving-into-weak-loaded-chunk.patch index f9dcd465c..7e7804a40 100644 --- a/leaf-server/minecraft-patches/features/0295-Prevents-entities-from-moving-into-weak-loaded-chunk.patch +++ b/leaf-server/minecraft-patches/features/0295-Prevents-entities-from-moving-into-weak-loaded-chunk.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> -Date: Mon, 19 Jan 2026 22:26:07 +0800 +Date: Tue, 9 Nov 2077 00:00:00 +0800 Subject: [PATCH] Prevents entities from moving into weak loaded chunks @@ -59,14 +59,14 @@ index cf2a365bcbb1a278e5553c16ffef6d9ae81f4d41..1a37a469924da67cfc34a9564a346fee public final void loadChunksForMoveAsync(AABB box, ca.spottedleaf.concurrentutil.util.Priority priority, java.util.function.Consumer> onLoad) { diff --git a/net/minecraft/world/entity/projectile/ThrowableProjectile.java b/net/minecraft/world/entity/projectile/ThrowableProjectile.java -index 47f2e940b68738cb02719cd82a5c0fff56fba062..9b2144e4f73bdb1d1aab1b7185149380bd04b4a0 100644 +index 47f2e940b68738cb02719cd82a5c0fff56fba062..36802bc5be98a505283659a6d0de2c35590d9687 100644 --- a/net/minecraft/world/entity/projectile/ThrowableProjectile.java +++ b/net/minecraft/world/entity/projectile/ThrowableProjectile.java @@ -12,6 +12,7 @@ import net.minecraft.world.phys.Vec3; public abstract class ThrowableProjectile extends Projectile { private static final float MIN_CAMERA_DISTANCE_SQUARED = 12.25F; -+ protected boolean preventMoveIntoWeakLoadedChunks = org.dreeam.leaf.config.modules.gameplay.PreventMoveIntoWeakLoadedChunks.isThrowableProjectilesEnabled(); // Leaf - Prevent entity from moving into weak loaded chunks ++ protected boolean preventMoveIntoWeakLoadedChunks = org.dreeam.leaf.config.modules.fixes.PreventMoveIntoWeakLoadedChunks.isThrowableProjectilesEnabled(); // Leaf - Prevent entity from moving into weak loaded chunks protected ThrowableProjectile(EntityType type, Level level) { super(type, level); diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/gameplay/PreventMoveIntoWeakLoadedChunks.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java similarity index 96% rename from leaf-server/src/main/java/org/dreeam/leaf/config/modules/gameplay/PreventMoveIntoWeakLoadedChunks.java rename to leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java index 4333afaf6..5870262bb 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/gameplay/PreventMoveIntoWeakLoadedChunks.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java @@ -1,4 +1,4 @@ -package org.dreeam.leaf.config.modules.gameplay; +package org.dreeam.leaf.config.modules.fixes; import org.dreeam.leaf.config.ConfigModules; import org.dreeam.leaf.config.EnumConfigCategory; From d07478bf8b5fa43c1d23a53c5889298806e0da76 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Tue, 20 Jan 2026 09:14:55 +0800 Subject: [PATCH 05/11] Add check for HurtingProjectile --- ...from-moving-into-weak-loaded-chunks.patch} | 62 ++++++++++++++++--- .../PreventMoveIntoWeakLoadedChunks.java | 10 +-- 2 files changed, 59 insertions(+), 13 deletions(-) rename leaf-server/minecraft-patches/features/{0295-Prevents-entities-from-moving-into-weak-loaded-chunk.patch => 0295-Prevent-entities-from-moving-into-weak-loaded-chunks.patch} (60%) diff --git a/leaf-server/minecraft-patches/features/0295-Prevents-entities-from-moving-into-weak-loaded-chunk.patch b/leaf-server/minecraft-patches/features/0295-Prevent-entities-from-moving-into-weak-loaded-chunks.patch similarity index 60% rename from leaf-server/minecraft-patches/features/0295-Prevents-entities-from-moving-into-weak-loaded-chunk.patch rename to leaf-server/minecraft-patches/features/0295-Prevent-entities-from-moving-into-weak-loaded-chunks.patch index 7e7804a40..d408219b6 100644 --- a/leaf-server/minecraft-patches/features/0295-Prevents-entities-from-moving-into-weak-loaded-chunk.patch +++ b/leaf-server/minecraft-patches/features/0295-Prevent-entities-from-moving-into-weak-loaded-chunks.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> -Date: Tue, 9 Nov 2077 00:00:00 +0800 -Subject: [PATCH] Prevents entities from moving into weak loaded chunks +Date: Mon, 19 Jan 2026 22:26:07 +0800 +Subject: [PATCH] Prevent entities from moving into weak loaded chunks diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java @@ -58,18 +58,30 @@ index cf2a365bcbb1a278e5553c16ffef6d9ae81f4d41..1a37a469924da67cfc34a9564a346fee public final void loadChunksForMoveAsync(AABB box, ca.spottedleaf.concurrentutil.util.Priority priority, java.util.function.Consumer> onLoad) { +diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java +index 8d092716cdcc48b829a1c0ee2e5416d648143a37..259b9dae8fbf115e31da5e8f8b5d127e07b95372 100644 +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -387,6 +387,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name + public boolean isTemporarilyActive; + public long activatedImmunityTick = Integer.MIN_VALUE; + public @Nullable Boolean immuneToFire = null; // Purpur - Fire immune API ++ protected boolean preventMoveIntoWeakLoadedChunks = false; + + public void inactiveTick() { + } diff --git a/net/minecraft/world/entity/projectile/ThrowableProjectile.java b/net/minecraft/world/entity/projectile/ThrowableProjectile.java -index 47f2e940b68738cb02719cd82a5c0fff56fba062..36802bc5be98a505283659a6d0de2c35590d9687 100644 +index 47f2e940b68738cb02719cd82a5c0fff56fba062..b36d6de4a8f9817dd942884c5288bd43493e4014 100644 --- a/net/minecraft/world/entity/projectile/ThrowableProjectile.java +++ b/net/minecraft/world/entity/projectile/ThrowableProjectile.java -@@ -12,6 +12,7 @@ import net.minecraft.world.phys.Vec3; - - public abstract class ThrowableProjectile extends Projectile { - private static final float MIN_CAMERA_DISTANCE_SQUARED = 12.25F; -+ protected boolean preventMoveIntoWeakLoadedChunks = org.dreeam.leaf.config.modules.fixes.PreventMoveIntoWeakLoadedChunks.isThrowableProjectilesEnabled(); // Leaf - Prevent entity from moving into weak loaded chunks +@@ -15,6 +15,7 @@ public abstract class ThrowableProjectile extends Projectile { protected ThrowableProjectile(EntityType type, Level level) { super(type, level); ++ this.preventMoveIntoWeakLoadedChunks = org.dreeam.leaf.config.modules.fixes.PreventMoveIntoWeakLoadedChunks.isProjectileEnabled(); // Leaf - Prevent entity from moving into weak loaded chunks + } + + protected ThrowableProjectile(EntityType type, double x, double y, double z, Level level) { @@ -57,7 +58,20 @@ public abstract class ThrowableProjectile extends Projectile { if (hitResultOnMoveVector.getType() != HitResult.Type.MISS) { location = hitResultOnMoveVector.getLocation(); @@ -92,6 +104,40 @@ index 47f2e940b68738cb02719cd82a5c0fff56fba062..36802bc5be98a505283659a6d0de2c35 } this.setPos(location); +diff --git a/net/minecraft/world/entity/projectile/hurtingprojectile/AbstractHurtingProjectile.java b/net/minecraft/world/entity/projectile/hurtingprojectile/AbstractHurtingProjectile.java +index 6edff432866ae72db657b47bf9726be9a4ef1562..586a9eab1cca57eb78308043d8a704d7f583b063 100644 +--- a/net/minecraft/world/entity/projectile/hurtingprojectile/AbstractHurtingProjectile.java ++++ b/net/minecraft/world/entity/projectile/hurtingprojectile/AbstractHurtingProjectile.java +@@ -27,6 +27,7 @@ public abstract class AbstractHurtingProjectile extends Projectile { + + protected AbstractHurtingProjectile(EntityType type, Level level) { + super(type, level); ++ this.preventMoveIntoWeakLoadedChunks = org.dreeam.leaf.config.modules.fixes.PreventMoveIntoWeakLoadedChunks.isProjectileEnabled(); // Leaf - Prevent entity from moving into weak loaded chunks + } + + protected AbstractHurtingProjectile(EntityType type, double x, double y, double z, Level level) { +@@ -76,7 +77,20 @@ public abstract class AbstractHurtingProjectile extends Projectile { + if (hitResultOnMoveVector.getType() != HitResult.Type.MISS) { + location = hitResultOnMoveVector.getLocation(); + } else { +- location = this.position().add(this.getDeltaMovement()); ++ // Leaf start - Prevent entity from moving into weak loaded chunks ++ if (preventMoveIntoWeakLoadedChunks) { ++ Vec3 previousLocation = this.position(); ++ location = this.position().add(this.getDeltaMovement()); ++ if (this.level() instanceof net.minecraft.server.level.ServerLevel serverLevel) { ++ if (!serverLevel.areChunksLoadedForEntityMove(this.getBoundingBox().expandTowards(location.subtract(previousLocation)))) { ++ location = previousLocation; ++ this.setDeltaMovement(Vec3.ZERO); ++ } ++ } ++ } else { ++ location = this.position().add(this.getDeltaMovement()); ++ } ++ // Leaf end - Prevent entity from moving into weak loaded chunks + } + + ProjectileUtil.rotateTowardsMovement(this, 0.2F); diff --git a/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java b/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java index 4d416d3a8402a78b8ad6383d842f589a821ddbe9..2fe748ab39602b1f3d2c4f9982375e582806828c 100644 --- a/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java index 5870262bb..5da293466 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java @@ -9,10 +9,10 @@ public String getBasePath() { } public static boolean enabled = false; - public static boolean throwableProjectiles = false; + public static boolean projectiles = false; - public static boolean isThrowableProjectilesEnabled() { - return enabled && throwableProjectiles; + public static boolean isProjectileEnabled() { + return enabled && projectiles; } @Override @@ -27,8 +27,8 @@ public void onLoaded() { "设置为 true 以启用以下功能." )); - throwableProjectiles = config.getBoolean(getBasePath() + ".throwable-projectiles", throwableProjectiles, config().pickStringRegionBased( - "Prevents throwable projectiles from moving into weak loaded chunks.", + projectiles = config.getBoolean(getBasePath() + ".projectiles", projectiles, config().pickStringRegionBased( + "Prevents projectiles from moving into weak loaded chunks.", "阻止投掷物进入弱加载区块." )); } From ceba13ccecc820f808244aa5dc8061815d4a216f Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Tue, 20 Jan 2026 09:17:41 +0800 Subject: [PATCH 06/11] [ci skip] pat pat --- .../config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java index 5da293466..db18dfb9f 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java @@ -5,7 +5,7 @@ public class PreventMoveIntoWeakLoadedChunks extends ConfigModules { public String getBasePath() { - return EnumConfigCategory.GAMEPLAY.getBaseKeyName() + ".prevent-moving-into-weak-loaded-chunks"; + return EnumConfigCategory.FIXES.getBaseKeyName() + ".prevent-moving-into-weak-loaded-chunks"; } public static boolean enabled = false; From 48acf27e26b88487cb0237f33edc55be44c16668 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Tue, 20 Jan 2026 09:39:23 +0800 Subject: [PATCH 07/11] Special case for AbstractHurtingProjectiles Fireballs don't have gravity applied, just discard them --- ...-from-moving-into-weak-loaded-chunks.patch | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/leaf-server/minecraft-patches/features/0295-Prevent-entities-from-moving-into-weak-loaded-chunks.patch b/leaf-server/minecraft-patches/features/0295-Prevent-entities-from-moving-into-weak-loaded-chunks.patch index d408219b6..bb8bf9ae6 100644 --- a/leaf-server/minecraft-patches/features/0295-Prevent-entities-from-moving-into-weak-loaded-chunks.patch +++ b/leaf-server/minecraft-patches/features/0295-Prevent-entities-from-moving-into-weak-loaded-chunks.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> -Date: Mon, 19 Jan 2026 22:26:07 +0800 +Date: Tue, 9 Nov 2077 00:00:00 +0800 Subject: [PATCH] Prevent entities from moving into weak loaded chunks @@ -105,10 +105,14 @@ index 47f2e940b68738cb02719cd82a5c0fff56fba062..b36d6de4a8f9817dd942884c5288bd43 this.setPos(location); diff --git a/net/minecraft/world/entity/projectile/hurtingprojectile/AbstractHurtingProjectile.java b/net/minecraft/world/entity/projectile/hurtingprojectile/AbstractHurtingProjectile.java -index 6edff432866ae72db657b47bf9726be9a4ef1562..586a9eab1cca57eb78308043d8a704d7f583b063 100644 +index 6edff432866ae72db657b47bf9726be9a4ef1562..bdc56b878cc052f159db1e229850019c22b8f2ec 100644 --- a/net/minecraft/world/entity/projectile/hurtingprojectile/AbstractHurtingProjectile.java +++ b/net/minecraft/world/entity/projectile/hurtingprojectile/AbstractHurtingProjectile.java -@@ -27,6 +27,7 @@ public abstract class AbstractHurtingProjectile extends Projectile { +@@ -24,9 +24,11 @@ public abstract class AbstractHurtingProjectile extends Projectile { + public double accelerationPower = 0.1; + public float bukkitYield = 1; // CraftBukkit + public boolean isIncendiary = true; // CraftBukkit ++ private boolean scheduleForRemoval = false; // Leaf - Prevent entity from moving into weak loaded chunks protected AbstractHurtingProjectile(EntityType type, Level level) { super(type, level); @@ -116,7 +120,14 @@ index 6edff432866ae72db657b47bf9726be9a4ef1562..586a9eab1cca57eb78308043d8a704d7 } protected AbstractHurtingProjectile(EntityType type, double x, double y, double z, Level level) { -@@ -76,7 +77,20 @@ public abstract class AbstractHurtingProjectile extends Projectile { +@@ -70,13 +72,27 @@ public abstract class AbstractHurtingProjectile extends Projectile { + public void tick() { + Entity owner = this.getOwner(); + this.applyInertia(); +- if (this.level().isClientSide() || (owner == null || !owner.isRemoved()) && this.level().hasChunkAt(this.blockPosition())) { ++ if (this.level().isClientSide() || (owner == null || !owner.isRemoved()) && this.level().hasChunkAt(this.blockPosition()) && !this.scheduleForRemoval) { // Leaf - Prevent entity from moving into weak loaded chunks + HitResult hitResultOnMoveVector = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity, this.getClipType()); + Vec3 location; if (hitResultOnMoveVector.getType() != HitResult.Type.MISS) { location = hitResultOnMoveVector.getLocation(); } else { @@ -129,6 +140,7 @@ index 6edff432866ae72db657b47bf9726be9a4ef1562..586a9eab1cca57eb78308043d8a704d7 + if (!serverLevel.areChunksLoadedForEntityMove(this.getBoundingBox().expandTowards(location.subtract(previousLocation)))) { + location = previousLocation; + this.setDeltaMovement(Vec3.ZERO); ++ this.scheduleForRemoval = true; + } + } + } else { From 1c39ba4a586359b8affa64472867ec2e4fd6224f Mon Sep 17 00:00:00 2001 From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> Date: Wed, 21 Jan 2026 12:13:34 -0500 Subject: [PATCH 08/11] Improve config comments --- .../modules/fixes/PreventMoveIntoWeakLoadedChunks.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java index db18dfb9f..ad7a24bc9 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java @@ -4,6 +4,7 @@ import org.dreeam.leaf.config.EnumConfigCategory; public class PreventMoveIntoWeakLoadedChunks extends ConfigModules { + public String getBasePath() { return EnumConfigCategory.FIXES.getBaseKeyName() + ".prevent-moving-into-weak-loaded-chunks"; } @@ -19,17 +20,17 @@ public static boolean isProjectileEnabled() { public void onLoaded() { config.addCommentRegionBased(getBasePath(), "Prevents entities from moving into weak loaded chunks.", - "阻止实体进入弱加载区块." + "阻止实体进入弱加载区块。" ); enabled = config.getBoolean(getBasePath() + ".enabled", enabled, config().pickStringRegionBased( "Set to true to enable features below.", - "设置为 true 以启用以下功能." + "设置为 true 以启用以下功能。" )); projectiles = config.getBoolean(getBasePath() + ".projectiles", projectiles, config().pickStringRegionBased( "Prevents projectiles from moving into weak loaded chunks.", - "阻止投掷物进入弱加载区块." + "阻止投掷物进入弱加载区块。" )); } } From 335eac27b3f1c6f1a2b4ac3ada22d9c6b21746e8 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Thu, 22 Jan 2026 22:31:22 +0800 Subject: [PATCH 09/11] Final cleanup --- ...-from-moving-into-weak-loaded-chunks.patch | 75 ++++++++++++++----- 1 file changed, 58 insertions(+), 17 deletions(-) diff --git a/leaf-server/minecraft-patches/features/0295-Prevent-entities-from-moving-into-weak-loaded-chunks.patch b/leaf-server/minecraft-patches/features/0295-Prevent-entities-from-moving-into-weak-loaded-chunks.patch index bb8bf9ae6..ae4561056 100644 --- a/leaf-server/minecraft-patches/features/0295-Prevent-entities-from-moving-into-weak-loaded-chunks.patch +++ b/leaf-server/minecraft-patches/features/0295-Prevent-entities-from-moving-into-weak-loaded-chunks.patch @@ -70,25 +70,70 @@ index 8d092716cdcc48b829a1c0ee2e5416d648143a37..259b9dae8fbf115e31da5e8f8b5d127e public void inactiveTick() { } -diff --git a/net/minecraft/world/entity/projectile/ThrowableProjectile.java b/net/minecraft/world/entity/projectile/ThrowableProjectile.java -index 47f2e940b68738cb02719cd82a5c0fff56fba062..b36d6de4a8f9817dd942884c5288bd43493e4014 100644 ---- a/net/minecraft/world/entity/projectile/ThrowableProjectile.java -+++ b/net/minecraft/world/entity/projectile/ThrowableProjectile.java -@@ -15,6 +15,7 @@ public abstract class ThrowableProjectile extends Projectile { +diff --git a/net/minecraft/world/entity/projectile/LlamaSpit.java b/net/minecraft/world/entity/projectile/LlamaSpit.java +index 56d78249c3fd7da0ff963712fe3a5c722b907c09..9dc0f5ecef467632061bb46745d47b0285b51cf4 100644 +--- a/net/minecraft/world/entity/projectile/LlamaSpit.java ++++ b/net/minecraft/world/entity/projectile/LlamaSpit.java +@@ -62,6 +62,18 @@ public class LlamaSpit extends Projectile { + } else { + this.setDeltaMovement(deltaMovement.scale(0.99F)); + this.applyGravity(); ++ // Leaf start - Prevent entity from moving into weak loaded chunks ++ if (this.preventMoveIntoWeakLoadedChunks) { ++ if (this.level() instanceof net.minecraft.server.level.ServerLevel serverLevel) { ++ if (!serverLevel.areChunksLoadedForEntityMove(this.getBoundingBox().expandTowards(this.getDeltaMovement()))) { ++ d = this.getX(); ++ d1 = this.getY(); ++ d2 = this.getZ(); ++ this.setDeltaMovement(Vec3.ZERO); ++ } ++ } ++ } ++ // Leaf end - Prevent entity from moving into weak loaded chunks + this.setPos(d, d1, d2); + } + } +diff --git a/net/minecraft/world/entity/projectile/Projectile.java b/net/minecraft/world/entity/projectile/Projectile.java +index c95ca23bc51780c9c68bc791bdd33822894ddf3c..7035d9fb406ea846fc8053017aeb6095ce596278 100644 +--- a/net/minecraft/world/entity/projectile/Projectile.java ++++ b/net/minecraft/world/entity/projectile/Projectile.java +@@ -48,6 +48,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { - protected ThrowableProjectile(EntityType type, Level level) { + protected Projectile(EntityType type, Level level) { super(type, level); + this.preventMoveIntoWeakLoadedChunks = org.dreeam.leaf.config.modules.fixes.PreventMoveIntoWeakLoadedChunks.isProjectileEnabled(); // Leaf - Prevent entity from moving into weak loaded chunks } - protected ThrowableProjectile(EntityType type, double x, double y, double z, Level level) { -@@ -57,7 +58,20 @@ public abstract class ThrowableProjectile extends Projectile { + // Gale start - Airplane - reduce projectile chunk loading +diff --git a/net/minecraft/world/entity/projectile/ShulkerBullet.java b/net/minecraft/world/entity/projectile/ShulkerBullet.java +index 7ab335a90c2b873b7d4eff148303bcc3f031dd64..810fe8e89046330fe5459dcb3071400abe66eff7 100644 +--- a/net/minecraft/world/entity/projectile/ShulkerBullet.java ++++ b/net/minecraft/world/entity/projectile/ShulkerBullet.java +@@ -227,6 +227,13 @@ public class ShulkerBullet extends Projectile { + } + + Vec3 deltaMovement = this.getDeltaMovement(); ++ // Leaf start - Prevent entity from moving into weak loaded chunks ++ if (this.preventMoveIntoWeakLoadedChunks && this.level() instanceof ServerLevel serverLevel && !serverLevel.areChunksLoadedForEntityMove(this.getBoundingBox().expandTowards(deltaMovement))) { ++ this.setDeltaMovement(Vec3.ZERO); ++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); ++ return; ++ } ++ // Leaf end - Prevent entity from moving into weak loaded chunks + this.setPos(this.position().add(deltaMovement)); + this.applyEffectsFromBlocks(); + if (this.portalProcess != null && this.portalProcess.isInsidePortalThisTick()) { +diff --git a/net/minecraft/world/entity/projectile/ThrowableProjectile.java b/net/minecraft/world/entity/projectile/ThrowableProjectile.java +index 47f2e940b68738cb02719cd82a5c0fff56fba062..b4cecd58a0e63542aaa3846a0a24ae4e395868ba 100644 +--- a/net/minecraft/world/entity/projectile/ThrowableProjectile.java ++++ b/net/minecraft/world/entity/projectile/ThrowableProjectile.java +@@ -57,7 +57,20 @@ public abstract class ThrowableProjectile extends Projectile { if (hitResultOnMoveVector.getType() != HitResult.Type.MISS) { location = hitResultOnMoveVector.getLocation(); } else { - location = this.position().add(this.getDeltaMovement()); + // Leaf start - Prevent entity from moving into weak loaded chunks -+ if (preventMoveIntoWeakLoadedChunks) { ++ if (this.preventMoveIntoWeakLoadedChunks) { + Vec3 previousLocation = this.position(); + location = this.position().add(this.getDeltaMovement()); + if (this.level() instanceof net.minecraft.server.level.ServerLevel serverLevel) { @@ -105,10 +150,10 @@ index 47f2e940b68738cb02719cd82a5c0fff56fba062..b36d6de4a8f9817dd942884c5288bd43 this.setPos(location); diff --git a/net/minecraft/world/entity/projectile/hurtingprojectile/AbstractHurtingProjectile.java b/net/minecraft/world/entity/projectile/hurtingprojectile/AbstractHurtingProjectile.java -index 6edff432866ae72db657b47bf9726be9a4ef1562..bdc56b878cc052f159db1e229850019c22b8f2ec 100644 +index 6edff432866ae72db657b47bf9726be9a4ef1562..e0f75669792932a14898ff35f3cc7be25d43c356 100644 --- a/net/minecraft/world/entity/projectile/hurtingprojectile/AbstractHurtingProjectile.java +++ b/net/minecraft/world/entity/projectile/hurtingprojectile/AbstractHurtingProjectile.java -@@ -24,9 +24,11 @@ public abstract class AbstractHurtingProjectile extends Projectile { +@@ -24,6 +24,7 @@ public abstract class AbstractHurtingProjectile extends Projectile { public double accelerationPower = 0.1; public float bukkitYield = 1; // CraftBukkit public boolean isIncendiary = true; // CraftBukkit @@ -116,11 +161,7 @@ index 6edff432866ae72db657b47bf9726be9a4ef1562..bdc56b878cc052f159db1e229850019c protected AbstractHurtingProjectile(EntityType type, Level level) { super(type, level); -+ this.preventMoveIntoWeakLoadedChunks = org.dreeam.leaf.config.modules.fixes.PreventMoveIntoWeakLoadedChunks.isProjectileEnabled(); // Leaf - Prevent entity from moving into weak loaded chunks - } - - protected AbstractHurtingProjectile(EntityType type, double x, double y, double z, Level level) { -@@ -70,13 +72,27 @@ public abstract class AbstractHurtingProjectile extends Projectile { +@@ -70,13 +71,27 @@ public abstract class AbstractHurtingProjectile extends Projectile { public void tick() { Entity owner = this.getOwner(); this.applyInertia(); @@ -133,7 +174,7 @@ index 6edff432866ae72db657b47bf9726be9a4ef1562..bdc56b878cc052f159db1e229850019c } else { - location = this.position().add(this.getDeltaMovement()); + // Leaf start - Prevent entity from moving into weak loaded chunks -+ if (preventMoveIntoWeakLoadedChunks) { ++ if (this.preventMoveIntoWeakLoadedChunks) { + Vec3 previousLocation = this.position(); + location = this.position().add(this.getDeltaMovement()); + if (this.level() instanceof net.minecraft.server.level.ServerLevel serverLevel) { From 924588aa01d4a98b9a5be5f09b04eb033cd275b8 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Thu, 22 Jan 2026 22:39:21 +0800 Subject: [PATCH 10/11] [ci skip] Change remove reason --- ...tities-from-moving-into-weak-loaded-chunks.patch | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/leaf-server/minecraft-patches/features/0295-Prevent-entities-from-moving-into-weak-loaded-chunks.patch b/leaf-server/minecraft-patches/features/0295-Prevent-entities-from-moving-into-weak-loaded-chunks.patch index ae4561056..93fb220dc 100644 --- a/leaf-server/minecraft-patches/features/0295-Prevent-entities-from-moving-into-weak-loaded-chunks.patch +++ b/leaf-server/minecraft-patches/features/0295-Prevent-entities-from-moving-into-weak-loaded-chunks.patch @@ -71,10 +71,10 @@ index 8d092716cdcc48b829a1c0ee2e5416d648143a37..259b9dae8fbf115e31da5e8f8b5d127e public void inactiveTick() { } diff --git a/net/minecraft/world/entity/projectile/LlamaSpit.java b/net/minecraft/world/entity/projectile/LlamaSpit.java -index 56d78249c3fd7da0ff963712fe3a5c722b907c09..9dc0f5ecef467632061bb46745d47b0285b51cf4 100644 +index 56d78249c3fd7da0ff963712fe3a5c722b907c09..1a42e405ee0372d1c68662c9d5192c2a95e56b01 100644 --- a/net/minecraft/world/entity/projectile/LlamaSpit.java +++ b/net/minecraft/world/entity/projectile/LlamaSpit.java -@@ -62,6 +62,18 @@ public class LlamaSpit extends Projectile { +@@ -62,6 +62,17 @@ public class LlamaSpit extends Projectile { } else { this.setDeltaMovement(deltaMovement.scale(0.99F)); this.applyGravity(); @@ -82,10 +82,9 @@ index 56d78249c3fd7da0ff963712fe3a5c722b907c09..9dc0f5ecef467632061bb46745d47b02 + if (this.preventMoveIntoWeakLoadedChunks) { + if (this.level() instanceof net.minecraft.server.level.ServerLevel serverLevel) { + if (!serverLevel.areChunksLoadedForEntityMove(this.getBoundingBox().expandTowards(this.getDeltaMovement()))) { -+ d = this.getX(); -+ d1 = this.getY(); -+ d2 = this.getZ(); + this.setDeltaMovement(Vec3.ZERO); ++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); ++ return; + } + } + } @@ -106,7 +105,7 @@ index c95ca23bc51780c9c68bc791bdd33822894ddf3c..7035d9fb406ea846fc8053017aeb6095 // Gale start - Airplane - reduce projectile chunk loading diff --git a/net/minecraft/world/entity/projectile/ShulkerBullet.java b/net/minecraft/world/entity/projectile/ShulkerBullet.java -index 7ab335a90c2b873b7d4eff148303bcc3f031dd64..810fe8e89046330fe5459dcb3071400abe66eff7 100644 +index 7ab335a90c2b873b7d4eff148303bcc3f031dd64..5e7d8d184d943470978b2086c18fc78f96c56cec 100644 --- a/net/minecraft/world/entity/projectile/ShulkerBullet.java +++ b/net/minecraft/world/entity/projectile/ShulkerBullet.java @@ -227,6 +227,13 @@ public class ShulkerBullet extends Projectile { @@ -116,7 +115,7 @@ index 7ab335a90c2b873b7d4eff148303bcc3f031dd64..810fe8e89046330fe5459dcb3071400a + // Leaf start - Prevent entity from moving into weak loaded chunks + if (this.preventMoveIntoWeakLoadedChunks && this.level() instanceof ServerLevel serverLevel && !serverLevel.areChunksLoadedForEntityMove(this.getBoundingBox().expandTowards(deltaMovement))) { + this.setDeltaMovement(Vec3.ZERO); -+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); ++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); + return; + } + // Leaf end - Prevent entity from moving into weak loaded chunks From 97c56cdd62d78e3070d3c16d1259484e79a56a4b Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Sat, 24 Jan 2026 21:32:52 +0800 Subject: [PATCH 11/11] [ci skip] correct config comment --- .../config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java index ad7a24bc9..218c4063b 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/fixes/PreventMoveIntoWeakLoadedChunks.java @@ -30,7 +30,7 @@ public void onLoaded() { projectiles = config.getBoolean(getBasePath() + ".projectiles", projectiles, config().pickStringRegionBased( "Prevents projectiles from moving into weak loaded chunks.", - "阻止投掷物进入弱加载区块。" + "阻止弹射物进入弱加载区块。" )); } }