diff --git a/leaf-server/minecraft-patches/features/0179-Optimize-isEyeInFluid.patch b/leaf-server/minecraft-patches/features/0179-Optimize-isEyeInFluid.patch new file mode 100644 index 00000000..a5b9e95d --- /dev/null +++ b/leaf-server/minecraft-patches/features/0179-Optimize-isEyeInFluid.patch @@ -0,0 +1,77 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: wling-art +Date: Sat, 17 May 2025 08:25:33 +0800 +Subject: [PATCH] Optimize isEyeInFluid + + +diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java +index 5eb740476dff894e91c2bd779ef6b760213a78a5..64f24d3e0ecb91e0b4df6229354aeac549234f1b 100644 +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -262,6 +262,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + protected Object2DoubleMap> fluidHeight = new Object2DoubleArrayMap<>(2); + protected boolean wasEyeInWater; + private final Set> fluidOnEyes = new HashSet<>(); ++ private static final int FLUID_WATER = 1; // Leaf - Optimize isEyeInFluid ++ private static final int FLUID_LAVA = 2; // Leaf - Optimize isEyeInFluid ++ private int fluidCache = 0; // Leaf - Optimize isEyeInFluid + public int invulnerableTime; + protected boolean firstTick = true; + protected final SynchedEntityData entityData; +@@ -2022,7 +2025,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + + private void updateFluidOnEyes() { + this.wasEyeInWater = this.isEyeInFluid(FluidTags.WATER); +- this.fluidOnEyes.clear(); ++ if (org.dreeam.leaf.config.modules.opt.EyeFluidCache.enabled) fluidCache = 0; else this.fluidOnEyes.clear(); // Leaf - Optimize isEyeInFluid ++ + double eyeY = this.getEyeY(); + if (!( + this.getVehicle() instanceof AbstractBoat abstractBoat +@@ -2034,7 +2038,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + FluidState fluidState = this.level().getFluidState(blockPos); + double d = blockPos.getY() + fluidState.getHeight(this.level(), blockPos); + if (d > eyeY) { +- this.fluidOnEyes.addAll(fluidState.getTagsAsSet()); // Leaf - Remove stream in updateFluidOnEyes ++ // Leaf start - Optimize isEyeInFluid ++ if (org.dreeam.leaf.config.modules.opt.EyeFluidCache.enabled) { ++ if (fluidState.is(FluidTags.WATER)) { ++ setFluidStatus(FluidTags.WATER, true); ++ } ++ if (fluidState.is(FluidTags.LAVA)) { ++ setFluidStatus(FluidTags.LAVA, true); ++ } ++ } else { ++ this.fluidOnEyes.addAll(fluidState.getTagsAsSet()); // Leaf - Remove stream in updateFluidOnEyes ++ } ++ // Leaf end - Optimize isEyeInFluid + } + } + } +@@ -2114,9 +2129,25 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + } + ++ // Leaf start - Optimize isEyeInFluid + public boolean isEyeInFluid(TagKey fluidTag) { +- return this.fluidOnEyes.contains(fluidTag); ++ if (!org.dreeam.leaf.config.modules.opt.EyeFluidCache.enabled) { ++ return this.fluidOnEyes.contains(fluidTag); ++ } ++ return fluidTag == FluidTags.WATER ? (fluidCache & FLUID_WATER) != 0 ++ : fluidTag == FluidTags.LAVA && (fluidCache & FLUID_LAVA) != 0; ++ } ++ ++ public void setFluidStatus(TagKey fluidTag, boolean isInFluid) { ++ int bit = fluidTag == FluidTags.WATER ? FLUID_WATER ++ : fluidTag == FluidTags.LAVA ? FLUID_LAVA ++ : 0; ++ ++ if (bit == 0) return; ++ ++ fluidCache = isInFluid ? (fluidCache | bit) : (fluidCache & ~bit); + } ++ // Leaf end - Optimize isEyeInFluid + + public boolean isInLava() { + return !this.firstTick && this.fluidHeight.getDouble(FluidTags.LAVA) > 0.0; diff --git a/leaf-server/minecraft-patches/features/0179-Paw-optimization.patch b/leaf-server/minecraft-patches/features/0180-Paw-optimization.patch similarity index 96% rename from leaf-server/minecraft-patches/features/0179-Paw-optimization.patch rename to leaf-server/minecraft-patches/features/0180-Paw-optimization.patch index f64e4834..10785958 100644 --- a/leaf-server/minecraft-patches/features/0179-Paw-optimization.patch +++ b/leaf-server/minecraft-patches/features/0180-Paw-optimization.patch @@ -126,10 +126,10 @@ index e6fd46b8148e050c4807abf6c8a03e4747bc0da2..0d8b71bbe5835187d5dfc1a301b6a01b private void tickPassenger(Entity ridingEntity, Entity passengerEntity, final boolean isActive) { // Paper - EAR 2 diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 5eb740476dff894e91c2bd779ef6b760213a78a5..e8a24178cb74afee749bfb067ac010f5178e070c 100644 +index 64f24d3e0ecb91e0b4df6229354aeac549234f1b..df23d80d6b18e900414aa02e5c1812f0a10f0fb7 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -1142,31 +1142,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1145,31 +1145,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this.onGround; } @@ -161,7 +161,7 @@ index 5eb740476dff894e91c2bd779ef6b760213a78a5..e8a24178cb74afee749bfb067ac010f5 public void move(MoverType type, Vec3 movement) { // Gale start - VMP - skip entity move if movement is zero if (!this.boundingBoxChanged && movement.equals(Vec3.ZERO)) { -@@ -1174,16 +1149,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1177,16 +1152,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } // Gale end - VMP - skip entity move if movement is zero final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity @@ -178,7 +178,7 @@ index 5eb740476dff894e91c2bd779ef6b760213a78a5..e8a24178cb74afee749bfb067ac010f5 if (this.noPhysics) { this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z); } else { -@@ -1304,13 +1270,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1307,13 +1273,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // Gale end - skip negligible planar movement multiplication } } @@ -192,7 +192,7 @@ index 5eb740476dff894e91c2bd779ef6b760213a78a5..e8a24178cb74afee749bfb067ac010f5 } private void applyMovementEmissionAndPlaySound(Entity.MovementEmission movementEmission, Vec3 movement, BlockPos pos, BlockState state) { -@@ -4848,9 +4807,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4879,9 +4838,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public void setDeltaMovement(Vec3 deltaMovement) { @@ -202,7 +202,7 @@ index 5eb740476dff894e91c2bd779ef6b760213a78a5..e8a24178cb74afee749bfb067ac010f5 } public void addDeltaMovement(Vec3 addend) { -@@ -4956,9 +4913,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4987,9 +4944,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } // Paper end - Fix MC-4 if (this.position.x != x || this.position.y != y || this.position.z != z) { diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/EyeFluidCache.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/EyeFluidCache.java new file mode 100644 index 00000000..36f3fdb9 --- /dev/null +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/EyeFluidCache.java @@ -0,0 +1,21 @@ +package org.dreeam.leaf.config.modules.opt; + +import org.dreeam.leaf.config.ConfigModules; +import org.dreeam.leaf.config.EnumConfigCategory; + +public class EyeFluidCache extends ConfigModules { + + public String getBasePath() { + return EnumConfigCategory.PERF.getBaseKeyName(); + } + + public static boolean enabled = false; + + @Override + public void onLoaded() { + enabled = config.getBoolean(getBasePath() + ".cache-eye-fluid-status", enabled, + config.pickStringRegionBased( + "Whether to cache the isEyeInFluid method to improve performance and reduce memory usage.", + "是否为 isEyeInFluid 方法启用缓存,以优化性能并减少内存使用.")); + } +}