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 == AT == public net.minecraft.world.entity.Entity setLevel(Lnet/minecraft/world/level/Level;)V diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index 65b1833125ce4b1190bf276a69ad4c0c88875d58..4c36bb6f61a75f20df911cd0a8a6ddc84800edd0 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2144,6 +2144,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } } + // 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 - Entity serialization api 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 7c04eb9e7eb5ff728465b46e3739eb2598ef1204..6fab713531665298d3b03e7960a17ecb1471a6d7 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -1087,6 +1087,18 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } // Paper end - tracked players API + // Paper start - raw entity serialization API + @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"); + this.entity.setLevel(((CraftWorld) location.getWorld()).getHandle()); + this.entity.setPos(location.getX(), location.getY(), location.getZ()); + this.entity.setRot(location.getYaw(), location.getPitch()); + return !this.entity.valid && this.entity.level().addFreshEntity(this.entity, reason); + } + // Paper end - raw entity serialization API + // Paper start - missing entity api @Override public boolean isInvisible() { // Paper - moved up from LivingEntity diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java index 70c06eb6e743232d0e8243b12a927084c6c9414b..c10273445c4b5ef089f86fc08a944da69d708244 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -494,7 +494,33 @@ public final class CraftMagicNumbers implements UnsafeValues { return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(MinecraftServer.getServer().registryAccess(), compound).orElseThrow()); } - private byte[] serializeNbtToBytes(CompoundTag compound) { + @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"); + + net.minecraft.nbt.CompoundTag compound = new net.minecraft.nbt.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"); + + net.minecraft.nbt.CompoundTag compound = deserializeNbtFromBytes(data); + int dataVersion = compound.getInt("DataVersion"); + compound = (net.minecraft.nbt.CompoundTag) MinecraftServer.getServer().fixerUpper.update(References.ENTITY, new Dynamic<>(NbtOps.INSTANCE, compound), dataVersion, this.getDataVersion()).getValue(); + if (!preserveUUID) { + // Generate a new UUID so we don't have to worry about deserializing the same entity twice + compound.remove("UUID"); + } + 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(net.minecraft.nbt.CompoundTag compound) { compound.putInt("DataVersion", getDataVersion()); java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream(); try {