Paper/Spigot-Server-Patches/0026-Entity-Origin-API.patch
Mariell Hoversholm 2db85c553f
fix: origin world can be unknown while knowing location
We will now store the world ID. It may not be used if the entity is
loaded before the world in question is, but it might be used later on,
should the entity come after the world.

Signed-off-by: Mariell Hoversholm <proximyst@proximyst.com>
2021-06-12 23:30:56 +01:00

146 lines
7.7 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Byteflux <byte@byteflux.net>
Date: Tue, 1 Mar 2016 23:45:08 -0600
Subject: [PATCH] Entity Origin API
diff --git a/src/main/java/net/minecraft/nbt/NBTTagList.java b/src/main/java/net/minecraft/nbt/NBTTagList.java
index 4f6f6f51f9807bafa88482c0fe776c8b163107d7..ce6572df63c4e7341708aee60330fb214a3fe416 100644
--- a/src/main/java/net/minecraft/nbt/NBTTagList.java
+++ b/src/main/java/net/minecraft/nbt/NBTTagList.java
@@ -190,6 +190,7 @@ public class NBTTagList extends NBTList<NBTBase> {
return new int[0];
}
+ public final double getDoubleAt(int i) { return this.h(i); } // Paper - OBFHELPER
public double h(int i) {
if (i >= 0 && i < this.list.size()) {
NBTBase nbtbase = (NBTBase) this.list.get(i);
diff --git a/src/main/java/net/minecraft/server/level/WorldServer.java b/src/main/java/net/minecraft/server/level/WorldServer.java
index cf38d517821659e25e786a805e229ef2d626d75f..26d461196b4a998b445f8c6e67fd7ec0606344f6 100644
--- a/src/main/java/net/minecraft/server/level/WorldServer.java
+++ b/src/main/java/net/minecraft/server/level/WorldServer.java
@@ -1246,6 +1246,11 @@ public class WorldServer extends World implements GeneratorAccessSeed {
this.navigators.add(((EntityInsentient) entity).getNavigation());
}
entity.valid = true; // CraftBukkit
+ // Paper start - Set origin location when the entity is being added to the world
+ if (entity.origin == null) {
+ entity.origin = entity.getBukkitEntity().getLocation();
+ }
+ // Paper end
}
}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index cae9da158f54438d2a397665c7ce964f6f755469..63772205358715ff77be64da418aeb31ff0c3cef 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -247,6 +247,8 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
public org.bukkit.projectiles.ProjectileSource projectileSource; // For projectiles only
public boolean forceExplosionKnockback; // SPIGOT-949
public boolean persistentInvisibility = false;
+ public org.bukkit.Location origin; // Paper
+ private @Nullable UUID originWorldId; // Paper
// Spigot start
public final org.spigotmc.ActivationRange.ActivationType activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this);
public final boolean defaultActivationState;
@@ -1625,6 +1627,15 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
this.bukkitEntity.storeBukkitValues(nbttagcompound);
}
// CraftBukkit end
+ // Paper start - Save the entity's origin location
+ if (this.origin != null) {
+ if (this.originWorldId != null) {
+ // Technically it is legal to no longer know the origin world... so that's fun.
+ nbttagcompound.setUUID("Paper.OriginWorld", this.originWorldId);
+ }
+ nbttagcompound.set("Paper.Origin", this.createList(origin.getX(), origin.getY(), origin.getZ()));
+ }
+ // Paper end
return nbttagcompound;
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.a(throwable, "Saving entity NBT");
@@ -1747,6 +1758,18 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
}
// CraftBukkit end
+ // Paper start - Restore the entity's origin location
+ NBTTagList originTag = nbttagcompound.getList("Paper.Origin", 6);
+ if (!originTag.isEmpty()) {
+ org.bukkit.World originWorld = world.getWorld();
+ if (nbttagcompound.hasKey("Paper.OriginWorld")) {
+ originWorld = Bukkit.getWorld(nbttagcompound.getUUID("Paper.OriginWorld"));
+ }
+ this.originWorldId = originWorld == null ? null : originWorld.getUID();
+ origin = new org.bukkit.Location(originWorld, originTag.getDoubleAt(0), originTag.getDoubleAt(1), originTag.getDoubleAt(2));
+ }
+ // Paper end
+
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.a(throwable, "Loading entity NBT");
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being loaded");
@@ -1808,6 +1831,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
protected abstract void saveData(NBTTagCompound nbttagcompound);
+ protected final NBTTagList createList(double... adouble) { return a(adouble); } // Paper - OBFHELPER
protected NBTTagList a(double... adouble) {
NBTTagList nbttaglist = new NBTTagList();
double[] adouble1 = adouble;
diff --git a/src/main/java/net/minecraft/world/entity/item/EntityFallingBlock.java b/src/main/java/net/minecraft/world/entity/item/EntityFallingBlock.java
index 901522f24b8bc58861e46eda400dbab92bb6401d..3f10e41b18e09186635fd6f7c653b04db7b39d8e 100644
--- a/src/main/java/net/minecraft/world/entity/item/EntityFallingBlock.java
+++ b/src/main/java/net/minecraft/world/entity/item/EntityFallingBlock.java
@@ -293,6 +293,14 @@ public class EntityFallingBlock extends Entity {
this.block = Blocks.SAND.getBlockData();
}
+ // Paper start - Try and load origin location from the old NBT tags for backwards compatibility
+ if (nbttagcompound.hasKey("SourceLoc_x")) {
+ int srcX = nbttagcompound.getInt("SourceLoc_x");
+ int srcY = nbttagcompound.getInt("SourceLoc_y");
+ int srcZ = nbttagcompound.getInt("SourceLoc_z");
+ origin = new org.bukkit.Location(world.getWorld(), srcX, srcY, srcZ);
+ }
+ // Paper end
}
public void a(boolean flag) {
diff --git a/src/main/java/net/minecraft/world/entity/item/EntityTNTPrimed.java b/src/main/java/net/minecraft/world/entity/item/EntityTNTPrimed.java
index 4f4b2b8d58223fa22d6a7af5c94cfb36399b9641..535e7d7297d81026b8586d5049b72fa65519b464 100644
--- a/src/main/java/net/minecraft/world/entity/item/EntityTNTPrimed.java
+++ b/src/main/java/net/minecraft/world/entity/item/EntityTNTPrimed.java
@@ -120,6 +120,14 @@ public class EntityTNTPrimed extends Entity {
@Override
protected void loadData(NBTTagCompound nbttagcompound) {
this.setFuseTicks(nbttagcompound.getShort("Fuse"));
+ // Paper start - Try and load origin location from the old NBT tags for backwards compatibility
+ if (nbttagcompound.hasKey("SourceLoc_x")) {
+ int srcX = nbttagcompound.getInt("SourceLoc_x");
+ int srcY = nbttagcompound.getInt("SourceLoc_y");
+ int srcZ = nbttagcompound.getInt("SourceLoc_z");
+ origin = new org.bukkit.Location(world.getWorld(), srcX, srcY, srcZ);
+ }
+ // Paper end
}
@Nullable
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 3cf81734c8580f4d88ea97b6ac737a370b413c84..220bad90bbb9a90c3f23562bf0fb109fce379682 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1062,4 +1062,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
return spigot;
}
// Spigot end
+
+ // Paper start
+ @Override
+ public Location getOrigin() {
+ Location origin = getHandle().origin;
+ return origin == null ? null : origin.clone();
+ }
+ // Paper end
}