Fix save/load NaN Entity Motion (#12269)

This commit is contained in:
Pedro 2025-04-30 13:53:32 -04:00 committed by GitHub
parent cd4fe5b7d0
commit 5acfdd6af4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 11 deletions

View File

@ -28597,7 +28597,7 @@ index 8cc5c0716392ba06501542ff5cbe71ee43979e5d..09fd99c9cbd23b5f3c899bfb00c9b896
+ // Paper end - block counting + // Paper end - block counting
} }
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e36b7294f 100644 index 609b52150aab93b0bed3b41632c19a00e372fc64..f6cb7754e865b9df3f2e204a7ea9b522fb01851b 100644
--- a/net/minecraft/world/entity/Entity.java --- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java
@@ -140,7 +140,7 @@ import net.minecraft.world.scores.ScoreHolder; @@ -140,7 +140,7 @@ import net.minecraft.world.scores.ScoreHolder;
@ -28950,7 +28950,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e
} }
private static float[] collectCandidateStepUpHeights(AABB box, List<VoxelShape> colliders, float deltaY, float maxUpStep) { private static float[] collectCandidateStepUpHeights(AABB box, List<VoxelShape> colliders, float deltaY, float maxUpStep) {
@@ -2599,21 +2747,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -2600,21 +2748,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
} }
public boolean isInWall() { public boolean isInWall() {
@ -29072,7 +29072,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e
} }
public InteractionResult interact(Player player, InteractionHand hand) { public InteractionResult interact(Player player, InteractionHand hand) {
@@ -4061,15 +4298,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -4062,15 +4299,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
} }
public Iterable<Entity> getIndirectPassengers() { public Iterable<Entity> getIndirectPassengers() {
@ -29098,7 +29098,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e
} }
public int countPlayerPassengers() { public int countPlayerPassengers() {
@@ -4212,77 +4451,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -4213,77 +4452,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return Mth.lerp(partialTick, this.yRotO, this.yRot); return Mth.lerp(partialTick, this.yRotO, this.yRot);
} }
@ -29289,7 +29289,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e
public boolean touchingUnloadedChunk() { public boolean touchingUnloadedChunk() {
AABB aabb = this.getBoundingBox().inflate(1.0); AABB aabb = this.getBoundingBox().inflate(1.0);
@@ -4437,6 +4735,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -4438,6 +4736,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
} }
public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) { public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) {
@ -29305,7 +29305,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e
if (!checkPosition(this, x, y, z)) { if (!checkPosition(this, x, y, z)) {
return; return;
} }
@@ -4570,6 +4877,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -4571,6 +4878,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@Override @Override
public final void setRemoved(Entity.RemovalReason removalReason, @Nullable org.bukkit.event.entity.EntityRemoveEvent.Cause cause) { // CraftBukkit - add Bukkit remove cause public final void setRemoved(Entity.RemovalReason removalReason, @Nullable org.bukkit.event.entity.EntityRemoveEvent.Cause cause) { // CraftBukkit - add Bukkit remove cause
@ -29318,7 +29318,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e
org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit
final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers
if (this.removalReason == null) { if (this.removalReason == null) {
@@ -4580,7 +4893,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -4581,7 +4894,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
this.stopRiding(); this.stopRiding();
} }
@ -29327,7 +29327,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e
this.levelCallback.onRemove(removalReason); this.levelCallback.onRemove(removalReason);
this.onRemoval(removalReason); this.onRemoval(removalReason);
// Paper start - Folia schedulers // Paper start - Folia schedulers
@@ -4614,7 +4927,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -4615,7 +4928,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
public boolean shouldBeSaved() { public boolean shouldBeSaved() {
return (this.removalReason == null || this.removalReason.shouldSave()) return (this.removalReason == null || this.removalReason.shouldSave())
&& !this.isPassenger() && !this.isPassenger()

View File

@ -694,7 +694,7 @@
return true; return true;
} }
} }
@@ -1805,14 +_,34 @@ @@ -1805,14 +_,35 @@
} }
public CompoundTag saveWithoutId(CompoundTag compound) { public CompoundTag saveWithoutId(CompoundTag compound) {
@ -715,6 +715,7 @@
} }
+ } // CraftBukkit + } // CraftBukkit
+ this.setDeltaMovement(io.papermc.paper.util.MCUtil.sanitizeNanInf(this.deltaMovement, 0D)); // Paper - remove NaN values before usage in saving
compound.store("Motion", Vec3.CODEC, this.getDeltaMovement()); compound.store("Motion", Vec3.CODEC, this.getDeltaMovement());
+ // CraftBukkit start - Checking for NaN pitch/yaw and resetting to zero + // CraftBukkit start - Checking for NaN pitch/yaw and resetting to zero
+ // TODO: make sure this is the best way to address this. + // TODO: make sure this is the best way to address this.
@ -810,6 +811,15 @@
return compound; return compound;
} catch (Throwable var8) { } catch (Throwable var8) {
CrashReport crashReport = CrashReport.forThrowable(var8, "Saving entity NBT"); CrashReport crashReport = CrashReport.forThrowable(var8, "Saving entity NBT");
@@ -1888,7 +_,7 @@
public void load(CompoundTag compound) {
try {
Vec3 vec3 = compound.read("Pos", Vec3.CODEC).orElse(Vec3.ZERO);
- Vec3 vec31 = compound.read("Motion", Vec3.CODEC).orElse(Vec3.ZERO);
+ Vec3 vec31 = compound.read("Motion", Vec3.CODEC).orElse(Vec3.ZERO); vec31 = io.papermc.paper.util.MCUtil.sanitizeNanInf(vec31, 0D); // Paper - avoid setting NaN values
Vec2 vec2 = compound.read("Rotation", Vec2.CODEC).orElse(Vec2.ZERO);
this.setDeltaMovement(Math.abs(vec31.x) > 10.0 ? 0.0 : vec31.x, Math.abs(vec31.y) > 10.0 ? 0.0 : vec31.y, Math.abs(vec31.z) > 10.0 ? 0.0 : vec31.z);
this.hasImpulse = true;
@@ -1932,6 +_,67 @@ @@ -1932,6 +_,67 @@
} else { } else {
throw new IllegalStateException("Entity has invalid rotation"); throw new IllegalStateException("Entity has invalid rotation");

View File

@ -22,9 +22,7 @@ import net.minecraft.core.Vec3i;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import org.bukkit.Location;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.bukkit.craftbukkit.util.Waitable; import org.bukkit.craftbukkit.util.Waitable;
@ -103,6 +101,18 @@ public final class MCUtil {
run.run(); run.run();
} }
public static double sanitizeNanInf(final double value, final double defaultValue) {
return Double.isNaN(value) || Double.isInfinite(value) ? defaultValue : value;
}
public static Vec3 sanitizeNanInf(final Vec3 vec3, final double defaultValue) {
return new Vec3(
sanitizeNanInf(vec3.x, defaultValue),
sanitizeNanInf(vec3.y, defaultValue),
sanitizeNanInf(vec3.z, defaultValue)
);
}
public static <T> T ensureMain(Supplier<T> run) { public static <T> T ensureMain(Supplier<T> run) {
return ensureMain(null, run); return ensureMain(null, run);
} }