From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Sat, 9 Jan 2021 21:21:27 +0100
Subject: [PATCH] Add unsafe Entity serialization API

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java
index 632e53338c4d902aea7e8589152b1c1b6e6dde6a..e64d28359c6f5180f1dfd3896a5ba99fd30a943c 100644
--- a/src/main/java/org/bukkit/UnsafeValues.java
+++ b/src/main/java/org/bukkit/UnsafeValues.java
@@ -136,4 +136,28 @@ public interface UnsafeValues {
     public int nextEntityId();
 
     // Paper end
+
+    // Purpur start
+
+    /**
+     * Serialize entity to byte array
+     *
+     * @param entity entity to serialize
+     * @return serialized entity
+     */
+    byte[] serializeEntity(org.bukkit.entity.Entity entity);
+
+    /**
+     * Deserialize an entity from byte array
+     * <p>
+     * The entity is not automatically spawned in the world. You will have to spawn
+     * the entity yourself with {@link org.bukkit.entity.Entity#spawnAt(Location)} or
+     * {@link org.bukkit.entity.Entity#spawnAt(Location, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason)}
+     *
+     * @param data serialized entity
+     * @param world world entity belongs in
+     * @return deserialized entity
+     */
+    org.bukkit.entity.Entity deserializeEntity(byte[] data, org.bukkit.World world);
+    // Purpur end
 }
diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
index c51d545e137eec2017c9f2ff944db70f2fdffdfc..1e25f387e053b648477a3e9dace1a6c95e7f8cba 100644
--- a/src/main/java/org/bukkit/entity/Entity.java
+++ b/src/main/java/org/bukkit/entity/Entity.java
@@ -751,5 +751,24 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
      * @return True if ridable in water
      */
     boolean isRidableInWater();
+
+    /**
+     * Spawn this entity in the world at the given {@link Location} with the default spawn reason.
+     *
+     * @param location The location at which to spawn the entity.
+     * @return Whether the entity was successfully spawned.
+     */
+    default boolean spawnAt(@NotNull Location location) {
+        return spawnAt(location, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT);
+    }
+
+    /**
+     * Spawn this entity in the world at the given {@link Location} with the reason given.
+     *
+     * @param location The location at which to spawn the entity.
+     * @param spawnReason The reason for which the entity was spawned.
+     * @return Whether the entity was successfully spawned.
+     */
+    boolean spawnAt(@NotNull Location location, @NotNull org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason);
     // Purpur end
 }
