From 97d6e946342a6fd49c89ef42f92e460f808ea389 Mon Sep 17 00:00:00 2001 From: TrollyLoki Date: Thu, 12 Oct 2023 11:10:02 -0400 Subject: [PATCH 1/4] Add raw byte block state serialization --- ...d-raw-byte-block-state-serialization.patch | 21 +++++ ...d-raw-byte-block-state-serialization.patch | 85 +++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 patches/api/0442-Add-raw-byte-block-state-serialization.patch create mode 100644 patches/server/1039-Add-raw-byte-block-state-serialization.patch diff --git a/patches/api/0442-Add-raw-byte-block-state-serialization.patch b/patches/api/0442-Add-raw-byte-block-state-serialization.patch new file mode 100644 index 0000000000..6669014364 --- /dev/null +++ b/patches/api/0442-Add-raw-byte-block-state-serialization.patch @@ -0,0 +1,21 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: TrollyLoki +Date: Thu, 12 Oct 2023 11:05:20 -0400 +Subject: [PATCH] Add raw byte block state serialization + + +diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java +index 9237e2fca0557890b718de9029207a552396e45a..954fc604ca66a92ed1b8106592d8291a8f826fa5 100644 +--- a/src/main/java/org/bukkit/UnsafeValues.java ++++ b/src/main/java/org/bukkit/UnsafeValues.java +@@ -138,6 +138,10 @@ public interface UnsafeValues { + + org.bukkit.entity.Entity deserializeEntity(byte[] data, World world, boolean preserveUUID); + ++ byte[] serializeBlock(org.bukkit.block.BlockState blockState); ++ ++ org.bukkit.block.BlockState deserializeBlock(byte[] data, org.bukkit.block.Block block); ++ + /** + * Creates and returns the next EntityId available. + *

diff --git a/patches/server/1039-Add-raw-byte-block-state-serialization.patch b/patches/server/1039-Add-raw-byte-block-state-serialization.patch new file mode 100644 index 0000000000..b83e8578a8 --- /dev/null +++ b/patches/server/1039-Add-raw-byte-block-state-serialization.patch @@ -0,0 +1,85 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: TrollyLoki +Date: Thu, 12 Oct 2023 11:05:19 -0400 +Subject: [PATCH] Add raw byte block state serialization + + +diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java +index 716021520c228b5bbced525b751f5d4126d882eb..4c498eb645e57d0cbb2860d08e4d18174e9f8d12 100644 +--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java ++++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java +@@ -231,13 +231,17 @@ public final class CraftBlockStates { + return CraftBlockStates.getBlockState(block, true); + } + public static BlockState getBlockState(Block block, boolean useSnapshot) { ++ return CraftBlockStates.getBlockState(block, useSnapshot, null, null); ++ } ++ // customTileEntity is ignored if customBlockData is null ++ public static BlockState getBlockState(Block block, boolean useSnapshot, net.minecraft.world.level.block.state.BlockState customBlockData, BlockEntity customTileEntity) { + // Paper end + Preconditions.checkNotNull(block, "block is null"); + CraftBlock craftBlock = (CraftBlock) block; + CraftWorld world = (CraftWorld) block.getWorld(); + BlockPos blockPosition = craftBlock.getPosition(); +- net.minecraft.world.level.block.state.BlockState blockData = craftBlock.getNMS(); +- BlockEntity tileEntity = craftBlock.getHandle().getBlockEntity(blockPosition); ++ net.minecraft.world.level.block.state.BlockState blockData = customBlockData != null ? customBlockData : craftBlock.getNMS(); // Paper - use customBlockData if provided ++ BlockEntity tileEntity = customBlockData != null ? customTileEntity : craftBlock.getHandle().getBlockEntity(blockPosition); // Paper - use customTileEntity if customBlockData provided + // Paper start - block state snapshots + boolean prev = CraftBlockEntityState.DISABLE_SNAPSHOT; + CraftBlockEntityState.DISABLE_SNAPSHOT = !useSnapshot; +diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +index 806fb1064a1769d1251f2a2b04372275754d2aeb..b461a2ec1a9f5d9ea0050991d3570bd8574d047a 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +@@ -53,6 +53,7 @@ import org.bukkit.craftbukkit.CraftEquipmentSlot; + import org.bukkit.craftbukkit.CraftFeatureFlag; + import org.bukkit.craftbukkit.attribute.CraftAttribute; + import org.bukkit.craftbukkit.attribute.CraftAttributeInstance; ++import org.bukkit.craftbukkit.block.CraftBlockEntityState; + import org.bukkit.craftbukkit.block.data.CraftBlockData; + import org.bukkit.craftbukkit.inventory.CraftItemStack; + import org.bukkit.craftbukkit.legacy.CraftLegacy; +@@ -506,6 +507,42 @@ public final class CraftMagicNumbers implements UnsafeValues { + .orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?")).getBukkitEntity(); + } + ++ @Override ++ public byte[] serializeBlock(org.bukkit.block.BlockState blockState) { ++ Preconditions.checkNotNull(blockState, "null cannot be serialized"); ++ Preconditions.checkArgument(blockState instanceof org.bukkit.craftbukkit.block.CraftBlockState, "only CraftBlockStates can be serialized"); ++ org.bukkit.craftbukkit.block.CraftBlockState craftBlockState = (org.bukkit.craftbukkit.block.CraftBlockState) blockState; ++ ++ CompoundTag compound = new CompoundTag(); ++ compound.put("BlockState", net.minecraft.nbt.NbtUtils.writeBlockState(craftBlockState.getHandle())); ++ if (craftBlockState instanceof CraftBlockEntityState) { ++ compound.put("BlockEntity", ((CraftBlockEntityState) craftBlockState).getSnapshotNBT()); ++ } ++ return serializeNbtToBytes(compound); ++ } ++ ++ @Override ++ public org.bukkit.block.BlockState deserializeBlock(byte[] data, org.bukkit.block.Block block) { ++ Preconditions.checkNotNull(data, "null cannot be deserialized"); ++ Preconditions.checkArgument(data.length > 0, "cannot deserialize nothing"); ++ Preconditions.checkArgument(block instanceof org.bukkit.craftbukkit.block.CraftBlock, "can only deserialize to CraftBlocks"); ++ org.bukkit.craftbukkit.block.CraftBlock craftBlock = (org.bukkit.craftbukkit.block.CraftBlock) block; ++ ++ CompoundTag compound = deserializeNbtFromBytes(data); ++ int dataVersion = compound.getInt("DataVersion"); ++ ++ CompoundTag blockStateCompound = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.BLOCK_STATE, compound.getCompound("BlockState"), dataVersion, getDataVersion()); ++ BlockState blockData = net.minecraft.nbt.NbtUtils.readBlockState(craftBlock.getCraftWorld().getHandle().holderLookup(net.minecraft.core.registries.Registries.BLOCK), blockStateCompound); ++ ++ net.minecraft.world.level.block.entity.BlockEntity tileEntity = null; ++ if (compound.contains("BlockEntity", NBT.TAG_COMPOUND)) { ++ CompoundTag blockEntityCompound = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.TILE_ENTITY, compound.getCompound("BlockEntity"), dataVersion, getDataVersion()); ++ tileEntity = net.minecraft.world.level.block.entity.BlockEntity.loadStatic(craftBlock.getPosition(), blockData, blockEntityCompound); ++ } ++ ++ return org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(craftBlock, false, blockData, tileEntity); ++ } ++ + private byte[] serializeNbtToBytes(CompoundTag compound) { + compound.putInt("DataVersion", getDataVersion()); + java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream(); From 0f340abc21820caf3882bf2848d18cd2771c7292 Mon Sep 17 00:00:00 2001 From: TrollyLoki Date: Fri, 27 Oct 2023 01:51:59 -0400 Subject: [PATCH 2/4] Rebase --- ...dd-raw-byte-block-state-serialization.patch | 4 ++-- ...d-raw-byte-block-state-serialization.patch} | 18 +++++------------- 2 files changed, 7 insertions(+), 15 deletions(-) rename patches/server/{1039-Add-raw-byte-block-state-serialization.patch => 1040-Add-raw-byte-block-state-serialization.patch} (85%) diff --git a/patches/api/0442-Add-raw-byte-block-state-serialization.patch b/patches/api/0442-Add-raw-byte-block-state-serialization.patch index 6669014364..8250910ad4 100644 --- a/patches/api/0442-Add-raw-byte-block-state-serialization.patch +++ b/patches/api/0442-Add-raw-byte-block-state-serialization.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add raw byte block state serialization diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 9237e2fca0557890b718de9029207a552396e45a..954fc604ca66a92ed1b8106592d8291a8f826fa5 100644 +index a4b38f284d4fea7df7f9df9bf44e4f68fefaf20f..dbf2faae25a260d6c2c6bb353415756448d7bfe6 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -138,6 +138,10 @@ public interface UnsafeValues { +@@ -147,6 +147,10 @@ public interface UnsafeValues { org.bukkit.entity.Entity deserializeEntity(byte[] data, World world, boolean preserveUUID); diff --git a/patches/server/1039-Add-raw-byte-block-state-serialization.patch b/patches/server/1040-Add-raw-byte-block-state-serialization.patch similarity index 85% rename from patches/server/1039-Add-raw-byte-block-state-serialization.patch rename to patches/server/1040-Add-raw-byte-block-state-serialization.patch index b83e8578a8..90fa936f8b 100644 --- a/patches/server/1039-Add-raw-byte-block-state-serialization.patch +++ b/patches/server/1040-Add-raw-byte-block-state-serialization.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add raw byte block state serialization diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java -index 716021520c228b5bbced525b751f5d4126d882eb..4c498eb645e57d0cbb2860d08e4d18174e9f8d12 100644 +index e3b07d623cd64de9645f2372f1e08757edc1a9ed..c55969167cdb30a926158756c1ac21e489cde7e9 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java @@ -231,13 +231,17 @@ public final class CraftBlockStates { @@ -29,18 +29,10 @@ index 716021520c228b5bbced525b751f5d4126d882eb..4c498eb645e57d0cbb2860d08e4d1817 boolean prev = CraftBlockEntityState.DISABLE_SNAPSHOT; CraftBlockEntityState.DISABLE_SNAPSHOT = !useSnapshot; diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 806fb1064a1769d1251f2a2b04372275754d2aeb..b461a2ec1a9f5d9ea0050991d3570bd8574d047a 100644 +index 6b31f88803041c75023a2c99bdc1efd902f0205c..9bbaf03775d60361fda21161a88f7712f27e626e 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -53,6 +53,7 @@ import org.bukkit.craftbukkit.CraftEquipmentSlot; - import org.bukkit.craftbukkit.CraftFeatureFlag; - import org.bukkit.craftbukkit.attribute.CraftAttribute; - import org.bukkit.craftbukkit.attribute.CraftAttributeInstance; -+import org.bukkit.craftbukkit.block.CraftBlockEntityState; - import org.bukkit.craftbukkit.block.data.CraftBlockData; - import org.bukkit.craftbukkit.inventory.CraftItemStack; - import org.bukkit.craftbukkit.legacy.CraftLegacy; -@@ -506,6 +507,42 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -519,6 +519,42 @@ public final class CraftMagicNumbers implements UnsafeValues { .orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?")).getBukkitEntity(); } @@ -52,8 +44,8 @@ index 806fb1064a1769d1251f2a2b04372275754d2aeb..b461a2ec1a9f5d9ea0050991d3570bd8 + + CompoundTag compound = new CompoundTag(); + compound.put("BlockState", net.minecraft.nbt.NbtUtils.writeBlockState(craftBlockState.getHandle())); -+ if (craftBlockState instanceof CraftBlockEntityState) { -+ compound.put("BlockEntity", ((CraftBlockEntityState) craftBlockState).getSnapshotNBT()); ++ if (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState) { ++ compound.put("BlockEntity", ((org.bukkit.craftbukkit.block.CraftBlockEntityState) craftBlockState).getSnapshotNBT()); + } + return serializeNbtToBytes(compound); + } From 26254e31eae5cc724c93a205462da1a96173b77a Mon Sep 17 00:00:00 2001 From: TrollyLoki Date: Fri, 27 Oct 2023 12:23:59 -0400 Subject: [PATCH 3/4] Clarify how getBlockState arguments are used --- .../1040-Add-raw-byte-block-state-serialization.patch | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/patches/server/1040-Add-raw-byte-block-state-serialization.patch b/patches/server/1040-Add-raw-byte-block-state-serialization.patch index 90fa936f8b..96b9628523 100644 --- a/patches/server/1040-Add-raw-byte-block-state-serialization.patch +++ b/patches/server/1040-Add-raw-byte-block-state-serialization.patch @@ -5,16 +5,17 @@ Subject: [PATCH] Add raw byte block state serialization diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java -index e3b07d623cd64de9645f2372f1e08757edc1a9ed..c55969167cdb30a926158756c1ac21e489cde7e9 100644 +index e3b07d623cd64de9645f2372f1e08757edc1a9ed..0046a230aa1331736f7e282c872528d19796fc17 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java -@@ -231,13 +231,17 @@ public final class CraftBlockStates { +@@ -231,13 +231,18 @@ public final class CraftBlockStates { return CraftBlockStates.getBlockState(block, true); } public static BlockState getBlockState(Block block, boolean useSnapshot) { + return CraftBlockStates.getBlockState(block, useSnapshot, null, null); + } -+ // customTileEntity is ignored if customBlockData is null ++ // if customBlockData is null, customTileEntity is ignored and the state is populated from the world ++ // otherwise, the state is populated using the values of customBlockData and customTileEntity, ignoring the current state of the world + public static BlockState getBlockState(Block block, boolean useSnapshot, net.minecraft.world.level.block.state.BlockState customBlockData, BlockEntity customTileEntity) { // Paper end Preconditions.checkNotNull(block, "block is null"); From ae4eca6fd1f1c25b61e1edcda0e5fb6db2054cc3 Mon Sep 17 00:00:00 2001 From: TrollyLoki Date: Sun, 29 Oct 2023 11:10:00 -0400 Subject: [PATCH 4/4] Rebase --- ... => 0449-Add-raw-byte-block-state-serialization.patch} | 0 ... => 1052-Add-raw-byte-block-state-serialization.patch} | 8 ++++---- 2 files changed, 4 insertions(+), 4 deletions(-) rename patches/api/{0442-Add-raw-byte-block-state-serialization.patch => 0449-Add-raw-byte-block-state-serialization.patch} (100%) rename patches/server/{1040-Add-raw-byte-block-state-serialization.patch => 1052-Add-raw-byte-block-state-serialization.patch} (94%) diff --git a/patches/api/0442-Add-raw-byte-block-state-serialization.patch b/patches/api/0449-Add-raw-byte-block-state-serialization.patch similarity index 100% rename from patches/api/0442-Add-raw-byte-block-state-serialization.patch rename to patches/api/0449-Add-raw-byte-block-state-serialization.patch diff --git a/patches/server/1040-Add-raw-byte-block-state-serialization.patch b/patches/server/1052-Add-raw-byte-block-state-serialization.patch similarity index 94% rename from patches/server/1040-Add-raw-byte-block-state-serialization.patch rename to patches/server/1052-Add-raw-byte-block-state-serialization.patch index 96b9628523..2d6ba8d796 100644 --- a/patches/server/1040-Add-raw-byte-block-state-serialization.patch +++ b/patches/server/1052-Add-raw-byte-block-state-serialization.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add raw byte block state serialization diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java -index e3b07d623cd64de9645f2372f1e08757edc1a9ed..0046a230aa1331736f7e282c872528d19796fc17 100644 +index 9271ff2a9ea05569e3c81886399aa7ab47efb05d..78234964c1e2107ff73d4f31b060ca6a5c38ea27 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java -@@ -231,13 +231,18 @@ public final class CraftBlockStates { +@@ -235,13 +235,18 @@ public final class CraftBlockStates { return CraftBlockStates.getBlockState(block, true); } public static BlockState getBlockState(Block block, boolean useSnapshot) { @@ -30,10 +30,10 @@ index e3b07d623cd64de9645f2372f1e08757edc1a9ed..0046a230aa1331736f7e282c872528d1 boolean prev = CraftBlockEntityState.DISABLE_SNAPSHOT; CraftBlockEntityState.DISABLE_SNAPSHOT = !useSnapshot; diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 6b31f88803041c75023a2c99bdc1efd902f0205c..9bbaf03775d60361fda21161a88f7712f27e626e 100644 +index ec2396f0e5d62b10450eaa7239a8c5479638b3c3..866d1f5cee46594475717b247902b8832bcb315b 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -519,6 +519,42 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -526,6 +526,42 @@ public final class CraftMagicNumbers implements UnsafeValues { .orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?")).getBukkitEntity(); }