From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 4 Jul 2018 01:40:13 -0400
Subject: [PATCH] Add MinecraftKey Information to Objects

Stores the reference to the objects respective MinecraftKey

diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
index b8868b86338ce0e89bc74eccccf714b910d7a4fe..9cb2f3b31921870ddba044840e99eb04babe26bb 100644
--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
@@ -178,7 +178,7 @@ public class PaperCommand extends Command {
 
                 Collection<Entity> entities = world.entitiesById.values();
                 entities.forEach(e -> {
-                    MinecraftKey key = new MinecraftKey(""); // TODO: update in next patch
+                    MinecraftKey key = e.getMinecraftKey();
 
                     MutablePair<Integer, Map<ChunkCoordIntPair, Integer>> info = list.computeIfAbsent(key, k -> MutablePair.of(0, Maps.newHashMap()));
                     ChunkCoordIntPair chunk = new ChunkCoordIntPair(e.chunkX, e.chunkZ);
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index f7ebe8e05613e638dc1dd386f4cf9a48c7b1e2a7..1a29857b41713126e86131b6eac01f0190fa11e7 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -51,7 +51,7 @@ import org.bukkit.event.player.PlayerTeleportEvent;
 import org.bukkit.plugin.PluginManager;
 // CraftBukkit end
 
-public abstract class Entity implements INamableTileEntity, ICommandListener {
+public abstract class Entity implements INamableTileEntity, ICommandListener, KeyedObject { // Paper
 
     // CraftBukkit start
     private static final int CURRENT_LEVEL = 2;
@@ -1668,12 +1668,31 @@ public abstract class Entity implements INamableTileEntity, ICommandListener {
         return true;
     }
 
+    // Paper start
+    private MinecraftKey entityKey;
+    private String entityKeyString;
+
+    @Override
+    public MinecraftKey getMinecraftKey() {
+        if (entityKey == null) {
+            this.entityKey = EntityTypes.getName(this.getEntityType());
+            this.entityKeyString = this.entityKey != null ? this.entityKey.toString() : null;
+        }
+        return entityKey;
+    }
+
+    @Override
+    public String getMinecraftKeyString() {
+        getMinecraftKey(); // Try to load if it doesn't exists. see: https://github.com/PaperMC/Paper/issues/1280
+        return entityKeyString;
+    }
     @Nullable
     public final String getSaveID() {
         EntityTypes<?> entitytypes = this.getEntityType();
         MinecraftKey minecraftkey = EntityTypes.getName(entitytypes);
 
-        return entitytypes.a() && minecraftkey != null ? minecraftkey.toString() : null;
+        return entitytypes != null && entitytypes.isPersistable() ? getMinecraftKeyString() : null;
+        // Paper end
     }
 
     protected abstract void loadData(NBTTagCompound nbttagcompound);
diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java
index e08ccba8134846ef11928183d118a6cce53b6d89..ffb8685e7c457483bcf4b2ed1065fec0fbaa69e2 100644
--- a/src/main/java/net/minecraft/server/EntityTypes.java
+++ b/src/main/java/net/minecraft/server/EntityTypes.java
@@ -253,6 +253,7 @@ public class EntityTypes<T extends Entity> {
         }
     }
 
+    public boolean isPersistable() { return a(); } // Paper - OBFHELPER
     public boolean a() {
         return this.bi;
     }
diff --git a/src/main/java/net/minecraft/server/KeyedObject.java b/src/main/java/net/minecraft/server/KeyedObject.java
new file mode 100644
index 0000000000000000000000000000000000000000..743142d0303fa25fe48a2abb07040d1228d04402
--- /dev/null
+++ b/src/main/java/net/minecraft/server/KeyedObject.java
@@ -0,0 +1,9 @@
+package net.minecraft.server;
+
+public interface KeyedObject {
+    MinecraftKey getMinecraftKey();
+    default String getMinecraftKeyString() {
+        MinecraftKey key = getMinecraftKey();
+        return key != null ? key.toString() : null;
+    }
+}
diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
index 6f6f58672d882f36296bc4f65d075261fc6da912..cfbca7cfde3160e888e14c5bb3bc48267f1cb599 100644
--- a/src/main/java/net/minecraft/server/TileEntity.java
+++ b/src/main/java/net/minecraft/server/TileEntity.java
@@ -11,7 +11,7 @@ import org.bukkit.inventory.InventoryHolder;
 // CraftBukkit end
 import org.spigotmc.CustomTimingsHandler; // Spigot
 
-public abstract class TileEntity {
+public abstract class TileEntity implements KeyedObject { // Paper
 
     public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getTileEntityTimings(this); // Spigot
     // CraftBukkit start - data containers
@@ -19,7 +19,7 @@ public abstract class TileEntity {
     public CraftPersistentDataContainer persistentDataContainer;
     // CraftBukkit end
     private static final Logger LOGGER = LogManager.getLogger();
-    private final TileEntityTypes<?> tileType;
+    private final TileEntityTypes<?> tileType; public TileEntityTypes getTileEntityType() { return tileType; } // Paper - OBFHELPER
     @Nullable
     protected World world;
     protected BlockPosition position;
@@ -33,6 +33,26 @@ public abstract class TileEntity {
         this.tileType = tileentitytypes;
     }
 
+    // Paper start
+    private String tileEntityKeyString = null;
+    private MinecraftKey tileEntityKey = null;
+
+    @Override
+    public MinecraftKey getMinecraftKey() {
+        if (tileEntityKey == null) {
+            tileEntityKey = TileEntityTypes.a(this.getTileEntityType());
+            tileEntityKeyString = tileEntityKey != null ? tileEntityKey.toString() : null;
+        }
+        return tileEntityKey;
+    }
+
+    @Override
+    public String getMinecraftKeyString() {
+        getMinecraftKey(); // Try to load if it doesn't exists.
+        return tileEntityKeyString;
+    }
+    // Paper end
+
     @Nullable
     public World getWorld() {
         return this.world;