mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2026-01-06 15:51:31 +00:00
* fix despawnInPeacefulOverride API and inline check despawn
* Revert "fix despawnInPeacefulOverride API and inline check despawn"
This reverts commit 82e37493fd.
* check despawn
* fix frozen
* rebuild patches
166 lines
9.0 KiB
Diff
166 lines
9.0 KiB
Diff
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
|
|
|
|
HOW IT WORKS:
|
|
In the default implementation, totalEntityAge only increments when an entity is actively ticked.
|
|
Consequently, if an entity resides in a weak-loaded chunk, its aging process effectively pauses, allowing it to exist far beyond the configured despawn time.
|
|
|
|
This patch addresses this discrepancy by synchronizing entity age with absolute server time:
|
|
Introduces lastTickTime to record the MinecraftServer.currentTick when an entity was last ticked.
|
|
Once the entity is ticked again or unloaded, the system calculates the elapsed time (currentTick - lastTickTime), and adds it to the totalEntityAge.
|
|
Also, it moves the despawn logic of projectiles to their own tick method (see ThrowableProjectile#tick), making it faster to despawn massive stuck projectiles.
|
|
|
|
Benchmarks (60,000 snowballs):
|
|
Before: Around 120 seconds, server thread is struggling to process projectile physics.
|
|
After: 1.5 seconds
|
|
|
|
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 cb1be4947ea2d85c6dcdc7424a4b712dcce0a40e..01f7390f3fb2a423cec373a2bb5ccbee57278783 100644
|
|
--- a/net/minecraft/server/level/ServerLevel.java
|
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
|
@@ -1509,6 +1509,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
|
|
@@ -1533,6 +1534,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 fef583625899091b13439e0d459b7538c866d712..e84ff9d5a1b495170b503dece72f7766b347c2d0 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 lastTickTime; // 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() {
|
|
+ this.syncEntityAge();
|
|
+ if (this.despawnTime >= 0) {
|
|
+ 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.lastTickTime;
|
|
+ }
|
|
+
|
|
+ private void syncEntityAge() {
|
|
+ int missedTicks = this.calculateMissedTicks();
|
|
+ if (missedTicks > 1) {
|
|
+ this.totalEntityAge += missedTicks;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void updateLastTick() {
|
|
+ this.lastTickTime = 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,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
if (this.maxAirTicks != this.getDefaultMaxAirSupply()) {
|
|
output.putInt("Bukkit.MaxAirSupply", this.getMaxAirSupply());
|
|
}
|
|
+ this.syncEntityAge(); // Leaf - Rewrite entity despawn time
|
|
output.putInt("Spigot.ticksLived", this.totalEntityAge); // Paper
|
|
// CraftBukkit end
|
|
output.storeNullable("CustomName", ComponentSerialization.CODEC, this.getCustomName());
|
|
@@ -2721,7 +2760,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
|
|
// CraftBukkit start
|
|
// Spigot start
|
|
- if (this instanceof net.minecraft.world.entity.LivingEntity) {
|
|
+ if (true || this instanceof net.minecraft.world.entity.LivingEntity) { // Leaf - Rewrite entity despawn time
|
|
this.totalEntityAge = input.getIntOr("Spigot.ticksLived", 0); // Paper
|
|
}
|
|
// Spigot end
|
|
@@ -5320,9 +5359,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
|
|
@Override
|
|
public boolean shouldBeSaved() {
|
|
+ this.syncEntityAge(); // Leaf - Rewrite entity despawn time
|
|
return (this.removalReason == null || this.removalReason.shouldSave())
|
|
&& !this.isPassenger()
|
|
- && (!this.isVehicle() || !((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)this).moonrise$hasAnyPlayerPassengers()); // Paper - rewrite chunk system
|
|
+ && (!this.isVehicle() || !((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)this).moonrise$hasAnyPlayerPassengers()) && (this.despawnTime < 0 || this.totalEntityAge < this.despawnTime); // Paper - rewrite chunk system // Leaf - Rewrite entity despawn time
|
|
}
|
|
|
|
@Override
|
|
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();
|