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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
@@ -0,0 +0,0 @@ public class PaperCommand extends Command {
                 ServerChunkCache chunkProviderServer = world.getChunkSource();
 
                 world.getAllEntities().forEach(e -> {
-                    ResourceLocation key = new ResourceLocation(""); // TODO: update in next patch
+                    ResourceLocation key = e.getMinecraftKey();
 
                     MutablePair<Integer, Map<ChunkPos, Integer>> info = list.computeIfAbsent(key, k -> MutablePair.of(0, Maps.newHashMap()));
                     ChunkPos chunk = e.chunkPosition();
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..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/net/minecraft/server/KeyedObject.java
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
+import net.minecraft.resources.ResourceLocation;
+
+// TODO(Mariell Hoversholm): Move stupid ass class
+public interface KeyedObject {
+    ResourceLocation getMinecraftKey();
+    default String getMinecraftKeyString() {
+        ResourceLocation key = getMinecraftKey();
+        return key != null ? key.toString() : null;
+    }
+}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ import org.bukkit.event.player.PlayerTeleportEvent;
 import org.bukkit.plugin.PluginManager;
 // CraftBukkit end
 
-public abstract class Entity implements Nameable, EntityAccess, CommandSource {
+public abstract class Entity implements Nameable, EntityAccess, CommandSource, net.minecraft.server.KeyedObject { // Paper
 
     // CraftBukkit start
     private static final int CURRENT_LEVEL = 2;
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
         return true;
     }
 
+    // Paper start
+    private ResourceLocation entityKey;
+    private String entityKeyString;
+
+    @Override
+    public ResourceLocation getMinecraftKey() {
+        if (entityKey == null) {
+            this.entityKey = EntityType.getKey(this.getType());
+            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 getEncodeId() {
         EntityType<?> entitytypes = this.getType();
         ResourceLocation minecraftkey = EntityType.getKey(entitytypes);
 
-        return entitytypes.canSerialize() && minecraftkey != null ? minecraftkey.toString() : null;
+        return entitytypes != null && entitytypes.isPersistable() ? getMinecraftKeyString() : null;
+        // Paper end
     }
 
     protected abstract void readAdditionalSaveData(CompoundTag nbt);
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
@@ -0,0 +0,0 @@ public class EntityType<T extends Entity> implements EntityTypeTest<Entity, T> {
         }
     }
 
+    public boolean isPersistable() { return canSerialize(); } // Paper - OBFHELPER
     public boolean canSerialize() {
         return this.serialize;
     }
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
@@ -0,0 +0,0 @@ import org.bukkit.inventory.InventoryHolder;
 
 import org.spigotmc.CustomTimingsHandler; // Spigot
 
-public abstract class BlockEntity {
+public abstract class BlockEntity implements net.minecraft.server.KeyedObject { // Paper
 
     public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getTileEntityTimings(this); // Spigot
     // CraftBukkit start - data containers
@@ -0,0 +0,0 @@ public abstract class BlockEntity {
         this.blockState = state;
     }
 
+    // Paper start
+    private String tileEntityKeyString = null;
+    private ResourceLocation tileEntityKey = null;
+
+    @Override
+    public ResourceLocation getMinecraftKey() {
+        if (tileEntityKey == null) {
+            tileEntityKey = BlockEntityType.getKey(this.type);
+            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 Level getLevel() {
         return this.level;
