mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-02-17 16:37:43 +01:00
Upstream has released updates that appear to apply and compile correctly Paper Changes: b79bc31 Fix MerchantOffer BuyB Only AssertionError (#6206) d6c81c8 Don't apply cramming damage to players (#5903) 12942dc Add rate options and timings for sensors and behaviors (#6027) fc47872 Use mapped names for sensor and behavior timings/config (#6228) c75a837 Don't expose ASM in API (#6229) c225bf9 Fix book title and author being improperly serialized as components (#6190) f25facb Update email & name (DenWav) 44516b1 [ci skip] Put mappings util in a separate class to the stacktrace deobfuscator
112 lines
6.3 KiB
Diff
112 lines
6.3 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Mariell Hoversholm <proximyst@proximyst.com>
|
|
Date: Sat, 9 Jan 2021 21:22:58 +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/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
|
index 53fc3c278624d8c1d2f8bee6df27315d08875300..d79de006a0e636a23419b5be86911d16447f8891 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
|
@@ -1260,5 +1260,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
|
public boolean isRidableInWater() {
|
|
return getHandle().rideableUnderWater();
|
|
}
|
|
+
|
|
+ @Override
|
|
+ public boolean spawnAt(Location location, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {
|
|
+ entity.level = ((CraftWorld) location.getWorld()).getHandle();
|
|
+ entity.absMoveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
|
+ return !entity.valid && entity.level.addEntity(entity, spawnReason);
|
|
+ }
|
|
// Purpur end
|
|
}
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
|
index 7a8db8d481e9487ea83a640af208242f4987ad28..f12eec135f8134409f1abe5c97ffee59913a4d9e 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
|
@@ -408,9 +408,14 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
|
Preconditions.checkNotNull(item, "null cannot be serialized");
|
|
Preconditions.checkArgument(item.getType() != Material.AIR, "air cannot be serialized");
|
|
|
|
+ // Purpur start - rework NBT <-> bytes
|
|
+ return serializeNbtToBytes(CraftItemStack.asNMSCopy(item).save(new CompoundTag()), true);
|
|
+ }
|
|
+
|
|
+ public byte[] serializeNbtToBytes(CompoundTag compound, boolean addDataVersion) {
|
|
+ if (addDataVersion) compound.putInt("DataVersion", getDataVersion());
|
|
java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream();
|
|
- CompoundTag compound = (item instanceof CraftItemStack ? ((CraftItemStack) item).handle : CraftItemStack.asNMSCopy(item)).save(new CompoundTag());
|
|
- compound.putInt("DataVersion", getDataVersion());
|
|
+ // Purpur end
|
|
try {
|
|
net.minecraft.nbt.NbtIo.writeCompressed(
|
|
compound,
|
|
@@ -428,21 +433,52 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
|
Preconditions.checkNotNull(data, "null cannot be deserialized");
|
|
Preconditions.checkArgument(data.length > 0, "cannot deserialize nothing");
|
|
|
|
+ // Purpur start - rework NBT <-> bytes
|
|
+ CompoundTag compound = deserializeNbtFromBytes(data, true);
|
|
+ Dynamic<Tag> converted = DataFixers.getDataFixer().update(References.ITEM_STACK, new Dynamic<>(NbtOps.INSTANCE, compound), compound.getInt("DataVersion"), getDataVersion());
|
|
+ return net.minecraft.world.item.ItemStack.of((CompoundTag) converted.getValue()).asBukkitMirror();
|
|
+ }
|
|
+
|
|
+ public CompoundTag deserializeNbtFromBytes(byte[] data, boolean verifyDataVersion) {
|
|
+ // Purpur end
|
|
try {
|
|
CompoundTag compound = net.minecraft.nbt.NbtIo.readCompressed(
|
|
new java.io.ByteArrayInputStream(data)
|
|
);
|
|
+ if (verifyDataVersion) { // Purpur
|
|
int dataVersion = compound.getInt("DataVersion");
|
|
|
|
Preconditions.checkArgument(dataVersion <= getDataVersion(), "Newer version! Server downgrades are not supported!");
|
|
- Dynamic<Tag> converted = DataFixers.getDataFixer().update(References.ITEM_STACK, new Dynamic<Tag>(NbtOps.INSTANCE, compound), dataVersion, getDataVersion());
|
|
- return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.of((CompoundTag) converted.getValue()));
|
|
+ } // Purpur
|
|
+ return compound; // Purpur
|
|
} catch (IOException ex) {
|
|
com.destroystokyo.paper.util.SneakyThrow.sneaky(ex);
|
|
throw new RuntimeException();
|
|
}
|
|
}
|
|
|
|
+ // Purpur start
|
|
+ @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, "non-CraftEntity cannot be serialized");
|
|
+ CompoundTag compound = new CompoundTag();
|
|
+ compound.putString("id", ((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().getMinecraftKeyString());
|
|
+ return serializeNbtToBytes(((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().saveWithoutId(compound), true);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public org.bukkit.entity.Entity deserializeEntity(byte[] data, org.bukkit.World world) {
|
|
+ CompoundTag compound = deserializeNbtFromBytes(data, true);
|
|
+ Dynamic<Tag> converted = DataFixers.getDataFixer().update(References.ENTITY, new Dynamic<>(NbtOps.INSTANCE, compound), compound.getInt("DataVersion"), getDataVersion());
|
|
+ compound = (CompoundTag) converted.getValue();
|
|
+ compound.remove("UUID"); // Make the server make a new UUID for this entity; makes entities always spawnable.
|
|
+ return net.minecraft.world.entity.EntityType.create(compound, ((org.bukkit.craftbukkit.CraftWorld) world).getHandle())
|
|
+ .orElseThrow(() -> new IllegalArgumentException("unknown ID was found for the data; did you downgrade?"))
|
|
+ .getBukkitEntity();
|
|
+ }
|
|
+ // Purpur end
|
|
+
|
|
@Override
|
|
public String getTranslationKey(Material mat) {
|
|
if (mat.isBlock()) {
|