diff --git a/leaf-server/minecraft-patches/features/0304-Rewrite-entity-despawn-time.patch b/leaf-server/minecraft-patches/features/0304-Rewrite-entity-despawn-time.patch new file mode 100644 index 00000000..1d6ee420 --- /dev/null +++ b/leaf-server/minecraft-patches/features/0304-Rewrite-entity-despawn-time.patch @@ -0,0 +1,136 @@ +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] Rewrite entity despawn time + +Brings the ability to despawn weak-loaded entities once they are ticked, +a solution for https://github.com/PaperMC/Paper/issues/12986 + +diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java +index f58b91b277ba85fa7c0e7ad10157ecbf10023065..b7f9f22abf60c75bc09126d9168fda9a0ee2375f 100644 +--- a/net/minecraft/server/level/ServerLevel.java ++++ b/net/minecraft/server/level/ServerLevel.java +@@ -1515,6 +1515,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + entity.tick(); + entity.postTick(); // CraftBukkit + } else {entity.inactiveTick();} // Paper - EAR 2 ++ entity.updateLastTick(); // Leaf - Rewrite entity despawn time + + for (Entity entity1 : entity.getPassengers()) { + this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2 +@@ -1539,6 +1540,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + ridingEntity.positionRider(passengerEntity); + } + // Paper end - EAR 2 ++ passengerEntity.updateLastTick(); // Leaf - Rewrite entity despawn time + + for (Entity entity : passengerEntity.getPassengers()) { + this.tickPassenger(passengerEntity, entity, isActive); // Paper - EAR 2 +diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java +index f6d619709d4e5b0e6d1b943226579d7388835cdb..fefd0df22b32bb6f933bbf9530584c2c9616bfb6 100644 +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -373,6 +373,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + public boolean fixedPose = false; // Paper - Expand Pose API + private final int despawnTime; // Paper - entity despawn time limit + public int totalEntityAge; // Paper - age-like counter for all entities ++ private int lastTickTicks; // Leaf - Rewrite entity despawn time + public boolean activatedPriorityReset = false; // Pufferfish - DAB + public int activatedPriority = org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.maximumActivationPrio; // Pufferfish - DAB (golf score) + public final io.papermc.paper.entity.activation.ActivationType activationType = io.papermc.paper.entity.activation.ActivationType.activationTypeFor(this); // Paper - EAR 2/tracking ranges +@@ -402,6 +403,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + private int sectionZ = Integer.MIN_VALUE; + private boolean updatingSectionStatus; + private static final boolean enableFMA = Boolean.getBoolean("Leaf.enableFMA"); // Leaf - Optimize Entity distanceTo ++ private final boolean shouldSkipBaseDespawnCheck = this instanceof net.minecraft.world.entity.projectile.ThrowableProjectile; // Leaf - Rewrite entity despawn time + + @Override + public final boolean moonrise$isHardColliding() { +@@ -626,6 +628,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + this.setPos(0.0, 0.0, 0.0); + this.eyeHeight = this.dimensions.eyeHeight(); + this.despawnTime = level == null || type == EntityType.PLAYER ? -1 : level.paperConfig().entities.spawning.despawnTime.getOrDefault(type, io.papermc.paper.configuration.type.number.IntOr.Disabled.DISABLED).or(-1); // Paper - entity despawn time limit ++ this.updateLastTick(); // Leaf - Rewrite entity despawn time + } + + public boolean isColliding(BlockPos pos, BlockState state) { +@@ -887,15 +890,50 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + + public void tick() { ++ // Leaf start - Rewrite entity despawn time ++ if (!this.shouldSkipBaseDespawnCheck && this.detectDespawnTime()) { ++ return; ++ } ++ /* + // Paper start - entity despawn time limit + if (this.despawnTime >= 0 && this.totalEntityAge >= this.despawnTime) { + this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); + return; + } + // Paper end - entity despawn time limit ++ */ ++ // Leaf end - Rewrite entity despawn time + this.baseTick(); + } + ++ // Leaf start - Rewrite entity despawn time ++ protected final boolean detectDespawnTime() { ++ if (this.despawnTime >= 0) { ++ int missedTicks = this.calculateMissedTicks(); ++ if (missedTicks > 1) { ++ if ((this.totalEntityAge += missedTicks) >= this.despawnTime) { ++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); ++ return true; ++ } ++ } else { ++ if (this.totalEntityAge >= this.despawnTime) { ++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); ++ return true; ++ } ++ } ++ } ++ return false; ++ } ++ ++ private int calculateMissedTicks() { ++ return net.minecraft.server.MinecraftServer.currentTick - this.lastTickTicks; ++ } ++ ++ public void updateLastTick() { ++ this.lastTickTicks = net.minecraft.server.MinecraftServer.currentTick; ++ } ++ // Leaf end - Rewrite entity despawn time ++ + // CraftBukkit start + public void postTick() { + // No clean way to break out of ticking once the entity has been copied to a new world, so instead we move the portalling later in the tick cycle +@@ -2564,6 +2602,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + if (this.maxAirTicks != this.getDefaultMaxAirSupply()) { + output.putInt("Bukkit.MaxAirSupply", this.getMaxAirSupply()); + } ++ // Leaf start - Rewrite entity despawn time ++ int missedTicks = this.calculateMissedTicks(); ++ if (missedTicks > 1) { ++ this.totalEntityAge += missedTicks; ++ } ++ // Leaf end - Rewrite entity despawn time + output.putInt("Spigot.ticksLived", this.totalEntityAge); // Paper + // CraftBukkit end + output.storeNullable("CustomName", ComponentSerialization.CODEC, this.getCustomName()); +diff --git a/net/minecraft/world/entity/projectile/ThrowableProjectile.java b/net/minecraft/world/entity/projectile/ThrowableProjectile.java +index 4c61f4552dc64b1347c7b8dfe9502aac11c75888..be0ebc017bfe92fb2916a9e40971ad19614a33b4 100644 +--- a/net/minecraft/world/entity/projectile/ThrowableProjectile.java ++++ b/net/minecraft/world/entity/projectile/ThrowableProjectile.java +@@ -44,6 +44,11 @@ public abstract class ThrowableProjectile extends Projectile { + + @Override + public void tick() { ++ // Leaf start - Rewrite entity despawn time - Check earlier for projectiles ++ if (this.detectDespawnTime()) { ++ return; ++ } ++ // Leaf end - Rewrite entity despawn time - Check earlier for projectiles + this.handleFirstTickBubbleColumn(); + this.applyGravity(); + this.applyInertia();