Files
Purpur/patches/server/0171-Add-unsafe-Entity-serialization-API.patch
BillyGalbreath 1362f49b24 Updated Upstream (Paper, Tuinity, & Airplane)
Upstream has released updates that appear to apply and compile correctly

Paper Changes:
bca97a8f7 replace spaces in world key (touches #5397)
de94f6485 Refactor chat message composition (#5396)
e27f334bb [CI-SKIP] Fix makemcdevsrc.sh for nms relocations (#5389)
ae15e85da Updated Upstream (CraftBukkit)
26fe0ac5a Only set despawnTimer for Wandering Traders spawned by MobSpawnerTrader (#5391)
b748eb7b8 Fix VanillaMobGoalTest#testBukkitMap (#5390)
18dbbb578 [Auto] Updated Upstream (CraftBukkit)
fac9cc5d5 [CI-SKIP] Ignore .gitignore
087aa70e7 Deprecate ItemStack#setLore(List<String>) and ItemStack#getLore, add Component based alternatives
9889c651c apply fixup
c310f0a61 Updated Upstream (Bukkit/CraftBukkit)
f17560ab0 wtf is this t file -jmp
347f3a9b8 fix compile
700e9e6a5 rebase
cf4dc464a Revert de5f4e469...c270abe96
6870db613 script & POM fix
743c6533c Replace ** with * (BSD/macOS)
376d7b097 Don't remove the .java
fcb3fd42a Fix macOS/BSD support
8cfc05249 Link correctly
ba1031ca7 Rename work dir
c8d844ab7 Actually fix preloading this time
e62aa5e3e Fix class preloading
1c03cf898 It's mojang math, not minecraft math
1034873df Apply fixups
39b125771 Use revision file
956150da7 Welcome to 1.16.5-R0.2
ccb217c01 Change cache keys
0d217001c more work
f6d820f07 It compiles
0f78e9525 More work
1718f61bf Updated Upstream (CraftBukkit/Spigot)
b28d46114 Update scripts for NMS repackaging

Tuinity Changes:
9bdcb9b8e Delete work dir when running jar
6351d7ca7 Update Upstream (Paper)
932c199a6 Generate md-dev correctly
bf3e73778 Make packet limiter work from IDE
1686f3861 Fix packet limiter config
f40f7b425 Update README.md styling (#264)
da1c3ace5 GH Actions Changes (#213)
5f325ecf1 Update Upstream (Paper)
0f83fe48d Update Upstream (Paper)

Airplane Changes:
f94d39947 Merge pull request #18 from notOM3GA/upstream/nms-repackage
0fc622631 Force build for Flare update
08439d6a9 Update Upstream (Tuinity)
2021-03-21 23:00:01 -05:00

130 lines
7.6 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/net/minecraft/world/entity/EntityTypes.java b/src/main/java/net/minecraft/world/entity/EntityTypes.java
index cc963bbc0fa909b3121a25786b511b31ee4b9561..6569f3d07e89383ff3ebed9c2ff5615b81ddd2f5 100644
--- a/src/main/java/net/minecraft/world/entity/EntityTypes.java
+++ b/src/main/java/net/minecraft/world/entity/EntityTypes.java
@@ -534,6 +534,7 @@ public class EntityTypes<T extends Entity> {
return this.bf.create(this, world);
}
+ public static Optional<Entity> loadEntityFixedData(NBTTagCompound nbtTagCompound, World world) { return a(nbtTagCompound, world); } // Purpur - OBFHELPER
public static Optional<Entity> a(NBTTagCompound nbttagcompound, World world) {
return SystemUtils.a(a(nbttagcompound).map((entitytypes) -> {
return entitytypes.a(world);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index a80f664d2cf713fd751421be3735e2f4779f0056..6c37bf58bd269c2d7e1c84e5791e8245e4c75aea 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1200,5 +1200,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
public boolean isRidableInWater() {
return getHandle().isRidableInWater();
}
+
+ @Override
+ public boolean spawnAt(Location location, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {
+ entity.world = ((CraftWorld) location.getWorld()).getHandle();
+ entity.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
+ return !entity.valid && entity.world.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 eba28b9c5cb87dea09bf8430d253725f585f87b9..609eda567751b2f1cf74e9f090ca5cb0c1d771cc 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -390,9 +390,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 NBTTagCompound()), true);
+ }
+
+ public byte[] serializeNbtToBytes(NBTTagCompound compound, boolean addDataVersion) {
+ if (addDataVersion) compound.setInt("DataVersion", getDataVersion());
java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream();
- NBTTagCompound compound = (item instanceof CraftItemStack ? ((CraftItemStack) item).getHandle() : CraftItemStack.asNMSCopy(item)).save(new NBTTagCompound());
- compound.setInt("DataVersion", getDataVersion());
+ // Purpur end
try {
net.minecraft.nbt.NBTCompressedStreamTools.writeNBT(
compound,
@@ -405,26 +410,58 @@ public final class CraftMagicNumbers implements UnsafeValues {
return outputStream.toByteArray();
}
+ public static DynamicOpsNBT getDynamicOpsNbtInstance() { return DynamicOpsNBT.a; } // Purpur - OBFHELPER - keeping out of the class because it's FULL of decompile errors
@Override
public ItemStack deserializeItem(byte[] data) {
Preconditions.checkNotNull(data, "null cannot be deserialized");
Preconditions.checkArgument(data.length > 0, "cannot deserialize nothing");
+ // Purpur start - rework NBT <-> bytes
+ NBTTagCompound compound = deserializeNbtFromBytes(data, true);
+ Dynamic<NBTBase> converted = DataConverterRegistry.getDataFixer().update(DataConverterTypes.ITEM_STACK, new Dynamic<>(getDynamicOpsNbtInstance(), compound), compound.getInt("DataVersion"), getDataVersion()); // TODO: obfhelper
+ return net.minecraft.world.item.ItemStack.fromCompound((NBTTagCompound) converted.getValue()).asBukkitMirror();
+ }
+
+ public NBTTagCompound deserializeNbtFromBytes(byte[] data, boolean verifyDataVersion) {
+ // Purpur end
try {
NBTTagCompound compound = net.minecraft.nbt.NBTCompressedStreamTools.readNBT(
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<NBTBase> converted = DataConverterRegistry.getDataFixer().update(DataConverterTypes.ITEM_STACK, new Dynamic<NBTBase>(DynamicOpsNBT.a, compound), dataVersion, getDataVersion());
- return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.fromCompound((NBTTagCompound) 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");
+ NBTTagCompound compound = new NBTTagCompound();
+ compound.setString("id", ((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().getMinecraftKeyString());
+ return serializeNbtToBytes(((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().save(compound), true);
+ }
+
+ @Override
+ public org.bukkit.entity.Entity deserializeEntity(byte[] data, org.bukkit.World world) {
+ NBTTagCompound compound = deserializeNbtFromBytes(data, true);
+ Dynamic<NBTBase> converted = DataConverterRegistry.getDataFixer().update(DataConverterTypes.ENTITY, new Dynamic<>(getDynamicOpsNbtInstance(), compound), compound.getInt("DataVersion"), getDataVersion());
+ compound = (NBTTagCompound) converted.getValue();
+ compound.remove("UUID"); // Make the server make a new UUID for this entity; makes entities always spawnable.
+ return net.minecraft.world.entity.EntityTypes.loadEntityFixedData(compound, ((org.bukkit.craftbukkit.CraftWorld) world).getHandle())
+ .orElseThrow(() -> new IllegalArgumentException("unknown ID was found for the data; did you downgrade?"))
+ .getBukkitEntity();
+ }
+ // Pupur end
+
@Override
public String getTranslationKey(Material mat) {
if (mat.isBlock()) {