From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Mariell Hoversholm Date: Sun, 24 Oct 2021 16:20:31 -0400 Subject: [PATCH] Add Raw Byte Entity Serialization diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index 1869eb6067da68e7c43b3749738c8376d18ed4cf..8963bc6cfd3edfd493cc73918513478a5bc03903 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -1826,6 +1826,15 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i } } + // Paper start - Entity serialization api + public boolean serializeEntity(CompoundTag compound) { + List pass = new java.util.ArrayList<>(this.getPassengers()); + this.passengers = ImmutableList.of(); + boolean result = save(compound); + this.passengers = ImmutableList.copyOf(pass); + return result; + } + // Paper end public boolean save(CompoundTag nbt) { return this.isPassenger() ? false : this.saveAsPassenger(nbt); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index ee50ea695585639d0ff184b675f3fb3b205b9f86..5aae88e20bc04560d6ad52cfcaa872d28bfcee8f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -1276,5 +1276,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } return set; } + + @Override + public boolean spawnAt(Location location, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { + Preconditions.checkNotNull(location, "location cannot be null"); + Preconditions.checkNotNull(reason, "reason cannot be null"); + entity.level = ((CraftWorld) location.getWorld()).getHandle(); + entity.setPos(location.getX(), location.getY(), location.getZ()); + entity.setRot(location.getYaw(), location.getPitch()); + return !entity.valid && entity.level.addFreshEntity(entity, reason); + } // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java index b43a6df5665f88e0d715ead5ca71a8f9f03e8e4b..90e68a8cfd00e4ad7ffaddfc8e8d5df26c49cf7a 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -421,6 +421,30 @@ public final class CraftMagicNumbers implements UnsafeValues { return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.of((CompoundTag) converted.getValue())); } + @Override + public byte[] serializeEntity(org.bukkit.entity.Entity entity) { + Preconditions.checkNotNull(entity, "null cannot be serialized"); + Preconditions.checkArgument(entity instanceof org.bukkit.craftbukkit.entity.CraftEntity, "only CraftEntities can be serialized"); + + CompoundTag compound = new CompoundTag(); + ((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().serializeEntity(compound); + return serializeNbtToBytes(compound); + } + + @Override + public org.bukkit.entity.Entity deserializeEntity(byte[] data, org.bukkit.World world, boolean preserveUUID) { + Preconditions.checkNotNull(data, "null cannot be deserialized"); + Preconditions.checkArgument(data.length > 0, "cannot deserialize nothing"); + + CompoundTag compound = deserializeNbtFromBytes(data); + int dataVersion = compound.getInt("DataVersion"); + Dynamic converted = DataFixers.getDataFixer().update(References.ENTITY_TREE, new Dynamic<>(NbtOps.INSTANCE, compound), dataVersion, getDataVersion()); + compound = (CompoundTag) converted.getValue(); + if (!preserveUUID) compound.remove("UUID"); // Generate a new UUID so we don't have to worry about deserializing the same entity twice + return net.minecraft.world.entity.EntityType.create(compound, ((org.bukkit.craftbukkit.CraftWorld) world).getHandle()) + .orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?")).getBukkitEntity(); + } + private byte[] serializeNbtToBytes(CompoundTag compound) { compound.putInt("DataVersion", getDataVersion()); java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream();