diff --git a/patches/api/0189-Add-Raw-Byte-ItemStack-Serialization.patch b/patches/api/0189-Add-Raw-Byte-ItemStack-Serialization.patch index ac702b7e9..a5afbf0a8 100644 --- a/patches/api/0189-Add-Raw-Byte-ItemStack-Serialization.patch +++ b/patches/api/0189-Add-Raw-Byte-ItemStack-Serialization.patch @@ -5,6 +5,8 @@ Subject: [PATCH] Add Raw Byte ItemStack Serialization Serializes using NBT which is safer for server data migrations than bukkits format. +Co-authored-by: Nassim Jahnke + diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java index 688fccdbc5cf831008ef2f27db9d15b0921a7561..e4861a8be534bfeae0385f0197261fa6ec1e7bc0 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java @@ -20,10 +22,18 @@ index 688fccdbc5cf831008ef2f27db9d15b0921a7561..e4861a8be534bfeae0385f0197261fa6 // Paper end } diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index fd3d4dd231d756d51db0155a4c3ad970c4f456ed..1f31ff5b85217a1c631f05f43c5a65839a36b26e 100644 +index fd3d4dd231d756d51db0155a4c3ad970c4f456ed..a9ca792de95236535f8b6779fce2875e6c3bd2a9 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -650,6 +650,30 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat +@@ -26,6 +26,7 @@ import org.jetbrains.annotations.Nullable; + * returns false. + */ + public class ItemStack implements Cloneable, ConfigurationSerializable, Translatable, net.kyori.adventure.text.event.HoverEventSource { // Paper ++ private static final byte ARRAY_SERIALIZATION_VERSION = 1; // Paper + private Material type = Material.AIR; + private int amount = 0; + private MaterialData data = null; +@@ -650,6 +651,97 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat return Bukkit.getServer().getItemFactory().ensureServerConversions(this); } @@ -50,7 +60,123 @@ index fd3d4dd231d756d51db0155a4c3ad970c4f456ed..1f31ff5b85217a1c631f05f43c5a6583 + public byte[] serializeAsBytes() { + return org.bukkit.Bukkit.getUnsafe().serializeItem(this); + } ++ ++ /** ++ * Serializes a collection of items to raw bytes in NBT. ++ *

++ * If you need a string representation to put into a file, you can for example use {@link java.util.Base64} encoding. ++ * ++ * @param items items to serialize ++ * @return bytes representing the items in NBT ++ * @see #serializeAsBytes() ++ */ ++ public static byte @NotNull [] serializeItemsAsBytes(java.util.@NotNull Collection items) { ++ try (final java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream()) { ++ final java.io.DataOutput output = new java.io.DataOutputStream(outputStream); ++ output.writeByte(ARRAY_SERIALIZATION_VERSION); ++ output.writeInt(items.size()); ++ for (final ItemStack item : items) { ++ if (item == null) { ++ // Ensure the correct order by including empty/null items ++ output.writeInt(0); ++ continue; ++ } ++ ++ final byte[] itemBytes = item.serializeAsBytes(); ++ output.writeInt(itemBytes.length); ++ output.write(itemBytes); ++ } ++ return outputStream.toByteArray(); ++ } catch (final java.io.IOException e) { ++ throw new RuntimeException("Error while writing itemstack", e); ++ } ++ } ++ ++ /** ++ * Deserializes this itemstack from raw NBT bytes. ++ *

++ * If you need a string representation to put into a file, you can for example use {@link java.util.Base64} encoding. ++ * ++ * @param bytes bytes representing an item in NBT ++ * @return ItemStack array migrated to this version of Minecraft if needed ++ * @see #deserializeBytes(byte[]) ++ */ ++ public static @Nullable ItemStack @NotNull [] deserializeItemsFromBytes(final byte @NotNull [] bytes) { ++ try (final java.io.ByteArrayInputStream inputStream = new java.io.ByteArrayInputStream(bytes)) { ++ final java.io.DataInputStream input = new java.io.DataInputStream(inputStream); ++ final byte version = input.readByte(); ++ if (version != ARRAY_SERIALIZATION_VERSION) { ++ throw new IllegalArgumentException("Unsupported version or bad data: " + version); ++ } ++ ++ final int count = input.readInt(); ++ final ItemStack[] items = new ItemStack[count]; ++ for (int i = 0; i < count; i++) { ++ final int length = input.readInt(); ++ if (length == 0) { ++ // Empty item, keep entry as null ++ continue; ++ } ++ ++ final byte[] itemBytes = new byte[length]; ++ input.read(itemBytes); ++ items[i] = ItemStack.deserializeBytes(itemBytes); ++ } ++ return items; ++ } catch (final java.io.IOException e) { ++ throw new RuntimeException("Error while reading itemstack", e); ++ } ++ } + /** * Gets the Display name as seen in the Client. * Currently the server only supports the English language. To override this, +diff --git a/src/main/java/org/bukkit/util/io/BukkitObjectInputStream.java b/src/main/java/org/bukkit/util/io/BukkitObjectInputStream.java +index 0f8eb97bd5e2f8b0f0cc03f7c4342aae06c4520c..def243b303b23aa42efcdbb280a29d4a877af3f8 100644 +--- a/src/main/java/org/bukkit/util/io/BukkitObjectInputStream.java ++++ b/src/main/java/org/bukkit/util/io/BukkitObjectInputStream.java +@@ -3,8 +3,10 @@ package org.bukkit.util.io; + import java.io.IOException; + import java.io.InputStream; + import java.io.ObjectInputStream; ++import java.util.Collection; + import org.bukkit.configuration.serialization.ConfigurationSerializable; + import org.bukkit.configuration.serialization.ConfigurationSerialization; ++import org.bukkit.inventory.ItemStack; + + /** + * This class is designed to be used in conjunction with the {@link +@@ -14,7 +16,9 @@ import org.bukkit.configuration.serialization.ConfigurationSerialization; + *

+ * Behavior of implementations extending this class is not guaranteed across + * future versions. ++ * @deprecated Object streams on their own are not safe. For safer and more consistent serialization of items, use {@link ItemStack#deserializeBytes(byte[])} or {@link ItemStack#deserializeItemsFromBytes(byte[])}. + */ ++@Deprecated // Paper + public class BukkitObjectInputStream extends ObjectInputStream { + + /** +diff --git a/src/main/java/org/bukkit/util/io/BukkitObjectOutputStream.java b/src/main/java/org/bukkit/util/io/BukkitObjectOutputStream.java +index dd1b9ee5f57773f07924aa311823fd8d63195cb2..bd4d48105457dbc6226f84e0e8d1e22878e01ca3 100644 +--- a/src/main/java/org/bukkit/util/io/BukkitObjectOutputStream.java ++++ b/src/main/java/org/bukkit/util/io/BukkitObjectOutputStream.java +@@ -4,7 +4,9 @@ import java.io.IOException; + import java.io.ObjectOutputStream; + import java.io.OutputStream; + import java.io.Serializable; ++import java.util.Collection; + import org.bukkit.configuration.serialization.ConfigurationSerializable; ++import org.bukkit.inventory.ItemStack; + + /** + * This class is designed to be used in conjunction with the {@link +@@ -14,7 +16,9 @@ import org.bukkit.configuration.serialization.ConfigurationSerializable; + *

+ * Behavior of implementations extending this class is not guaranteed across + * future versions. ++ * @deprecated Object streams on their own are not safe. For safer and more consistent serialization of items, use {@link ItemStack#serializeAsBytes()} or {@link ItemStack#serializeItemsAsBytes(Collection)}. + */ ++@Deprecated // Paper + public class BukkitObjectOutputStream extends ObjectOutputStream { + + /** diff --git a/patches/api/0211-Add-methods-to-get-translation-keys.patch b/patches/api/0211-Add-methods-to-get-translation-keys.patch index 5af19e403..c37e9e2f0 100644 --- a/patches/api/0211-Add-methods-to-get-translation-keys.patch +++ b/patches/api/0211-Add-methods-to-get-translation-keys.patch @@ -478,7 +478,7 @@ index 5bd252c0ae3b09fe141d131360c67bb9bfbf5422..78587d9fabe6371a23a7963917b054db + } diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 1f31ff5b85217a1c631f05f43c5a65839a36b26e..1532b3e1b655a9b58588c11b80824ed4cec8c66a 100644 +index 01596d82ec54fdefe0acd7ea776f38c94d4d7d77..221e189503d35b59b364503d0e89dd20d1183c1f 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -25,7 +25,7 @@ import org.jetbrains.annotations.Nullable; @@ -487,10 +487,10 @@ index 1f31ff5b85217a1c631f05f43c5a65839a36b26e..1532b3e1b655a9b58588c11b80824ed4 */ -public class ItemStack implements Cloneable, ConfigurationSerializable, Translatable, net.kyori.adventure.text.event.HoverEventSource { // Paper +public class ItemStack implements Cloneable, ConfigurationSerializable, Translatable, net.kyori.adventure.text.event.HoverEventSource, net.kyori.adventure.translation.Translatable { // Paper + private static final byte ARRAY_SERIALIZATION_VERSION = 1; // Paper private Material type = Material.AIR; private int amount = 0; - private MaterialData data = null; -@@ -617,6 +617,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat +@@ -618,6 +618,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat @Override @NotNull @@ -498,7 +498,7 @@ index 1f31ff5b85217a1c631f05f43c5a65839a36b26e..1532b3e1b655a9b58588c11b80824ed4 public String getTranslationKey() { return Bukkit.getUnsafe().getTranslationKey(this); } -@@ -876,5 +877,16 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat +@@ -944,5 +945,16 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat ItemMeta itemMeta = getItemMeta(); return itemMeta != null && itemMeta.hasItemFlag(flag); } diff --git a/patches/api/0264-Item-Rarity-API.patch b/patches/api/0264-Item-Rarity-API.patch index 5e0072532..a1f44910d 100644 --- a/patches/api/0264-Item-Rarity-API.patch +++ b/patches/api/0264-Item-Rarity-API.patch @@ -88,10 +88,10 @@ index 72a29fff4c497a2a66e2746ad42553bcb712e20d..22db1d8645a450308fe91d0cd100c926 // Paper end } diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 1532b3e1b655a9b58588c11b80824ed4cec8c66a..569f67ee3f89d6af4fe1420cecc74811550b6507 100644 +index 221e189503d35b59b364503d0e89dd20d1183c1f..a85877288fe421c4c834db326f54543855df8441 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -888,5 +888,15 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat +@@ -956,5 +956,15 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat public @NotNull String translationKey() { return Bukkit.getUnsafe().getTranslationKey(this); } diff --git a/patches/api/0282-ItemStack-repair-check-API.patch b/patches/api/0282-ItemStack-repair-check-API.patch index 46650ec4b..7cf982d89 100644 --- a/patches/api/0282-ItemStack-repair-check-API.patch +++ b/patches/api/0282-ItemStack-repair-check-API.patch @@ -26,10 +26,10 @@ index a3810c693d3748fba818e4a835ceb77762f433b9..d9e3e4ad108a94ac6f0f5378d22d4784 * Returns the server's protocol version. * diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 569f67ee3f89d6af4fe1420cecc74811550b6507..78ea59c8f63b5a71ba092cf1783183bb5d0a3b79 100644 +index a85877288fe421c4c834db326f54543855df8441..73908f0e8d49377a4fb86c960fde10940998a325 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -898,5 +898,27 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat +@@ -966,5 +966,27 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat public io.papermc.paper.inventory.ItemRarity getRarity() { return Bukkit.getUnsafe().getItemStackRarity(this); } diff --git a/patches/api/0285-ItemStack-editMeta.patch b/patches/api/0285-ItemStack-editMeta.patch index 5996dc100..c1ea6e2fa 100644 --- a/patches/api/0285-ItemStack-editMeta.patch +++ b/patches/api/0285-ItemStack-editMeta.patch @@ -5,10 +5,10 @@ Subject: [PATCH] ItemStack#editMeta diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 78ea59c8f63b5a71ba092cf1783183bb5d0a3b79..12fac9cf93ae7c6b5c8daced10a4394ad29bebcb 100644 +index 73908f0e8d49377a4fb86c960fde10940998a325..777a52716a7bc70c7cb3f22522dce8dcfb0cdf44 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -558,6 +558,50 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat +@@ -559,6 +559,50 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat return result.ensureServerConversions(); // Paper } diff --git a/patches/api/0351-Add-enchantWithLevels-API.patch b/patches/api/0351-Add-enchantWithLevels-API.patch index 1c94264d8..653784110 100644 --- a/patches/api/0351-Add-enchantWithLevels-API.patch +++ b/patches/api/0351-Add-enchantWithLevels-API.patch @@ -70,10 +70,10 @@ index 198eebd45a2efa6986a8f4b613424eb8b6d3a039..f680545b6b59bf8d2ad154b0472dda4c + // Paper end - enchantWithLevels API } diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 12fac9cf93ae7c6b5c8daced10a4394ad29bebcb..f236f9bfa4d43dcbad5919abef3620fcd0696880 100644 +index 777a52716a7bc70c7cb3f22522dce8dcfb0cdf44..2de0170ddd7c3c9f30cfec0596ede3386b0fb176 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -667,6 +667,24 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat +@@ -668,6 +668,24 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat } // Paper start diff --git a/patches/api/0387-ItemStack-damage-API.patch b/patches/api/0387-ItemStack-damage-API.patch index f2c4cc435..731baa9c6 100644 --- a/patches/api/0387-ItemStack-damage-API.patch +++ b/patches/api/0387-ItemStack-damage-API.patch @@ -65,10 +65,10 @@ index 70953573a7bcfa682dbaeaa8e3db0c847b254fdd..041ff387a0f9e8037e2834118ef241dd // Paper end } diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index f236f9bfa4d43dcbad5919abef3620fcd0696880..845037909658884167136955a02b99af0040fa9c 100644 +index 2de0170ddd7c3c9f30cfec0596ede3386b0fb176..0bc0fb38204acb11a48157e8371ff9328e02e8c7 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -982,5 +982,19 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat +@@ -1050,5 +1050,19 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat public boolean canRepair(@NotNull ItemStack toBeRepaired) { return Bukkit.getUnsafe().isValidRepairItemStack(toBeRepaired, this); } diff --git a/patches/api/0434-Allow-proper-checking-of-empty-item-stacks.patch b/patches/api/0434-Allow-proper-checking-of-empty-item-stacks.patch index 716a6140d..c8e4473b7 100644 --- a/patches/api/0434-Allow-proper-checking-of-empty-item-stacks.patch +++ b/patches/api/0434-Allow-proper-checking-of-empty-item-stacks.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Allow proper checking of empty item stacks This adds a method to check if an item stack is empty or not. This mirrors vanilla's implementation of the same method. diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 845037909658884167136955a02b99af0040fa9c..c3872213acc75d913580002cf70c2abb4ec69ca0 100644 +index 0bc0fb38204acb11a48157e8371ff9328e02e8c7..95dc486f5d93113cb016142a66ffd76fb81d66c3 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -996,5 +996,24 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat +@@ -1064,5 +1064,24 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat public @NotNull ItemStack damage(int amount, @NotNull org.bukkit.entity.LivingEntity livingEntity) { return livingEntity.damageItemStack(this, amount); } diff --git a/patches/api/0442-Remove-unnecessary-durability-check-in-ItemStack-isS.patch b/patches/api/0442-Remove-unnecessary-durability-check-in-ItemStack-isS.patch index 0ac5bf3ef..07af9b972 100644 --- a/patches/api/0442-Remove-unnecessary-durability-check-in-ItemStack-isS.patch +++ b/patches/api/0442-Remove-unnecessary-durability-check-in-ItemStack-isS.patch @@ -9,10 +9,10 @@ By removing this check we avoid unnecessarily allocating useless `ItemMeta` obje This is a leftover from when checking for the item's durability was "free" because the durability was stored in the `ItemStack` itself, this [was changed in Minecraft 1.13](https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/commits/f8b2086d60942eb2cd7ac25a2a1408cb790c222c#src/main/java/org/bukkit/inventory/ItemStack.java). diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index c3872213acc75d913580002cf70c2abb4ec69ca0..7adf54c561d64e6337af8a2d86f6b574b083edb5 100644 +index 95dc486f5d93113cb016142a66ffd76fb81d66c3..f44b587ca5f6fdf09020e60fedf575e479b5d948 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -295,7 +295,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat +@@ -296,7 +296,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat return true; } Material comparisonType = (this.type.isLegacy()) ? Bukkit.getUnsafe().fromLegacy(this.getData(), true) : this.type; // This may be called from legacy item stacks, try to get the right material diff --git a/patches/api/0459-ItemStack-Tooltip-API.patch b/patches/api/0459-ItemStack-Tooltip-API.patch index 9aa55ce1a..96c684e62 100644 --- a/patches/api/0459-ItemStack-Tooltip-API.patch +++ b/patches/api/0459-ItemStack-Tooltip-API.patch @@ -119,10 +119,10 @@ index f2163b5238e1667a44bf623cd52bab90d9f2d88d..9a65c4f614a6c358d74491794d7b2517 + @NotNull java.util.List computeTooltipLines(@NotNull ItemStack itemStack, @NotNull io.papermc.paper.inventory.tooltip.TooltipContext tooltipContext, @Nullable org.bukkit.entity.Player player); // Paper - expose itemstack tooltip lines } diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 7adf54c561d64e6337af8a2d86f6b574b083edb5..245a730a54c4b241a9a67eccceefafd2763bd238 100644 +index f44b587ca5f6fdf09020e60fedf575e479b5d948..a28a588024f3face03d9f5e7682adb95d7e971c1 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -1016,4 +1016,21 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat +@@ -1084,4 +1084,21 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat return type.isAir() || amount <= 0; } // Paper end