geforkt von Mirrors/Paper
Add ItemStack array serialization methods (#10387)
Dieser Commit ist enthalten in:
Ursprung
36472a9173
Commit
e53a1f5e22
@ -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 <nassim@njahnke.dev>
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/UnsafeValues.java
|
||||
@ -50,7 +52,126 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ public byte[] serializeAsBytes() {
|
||||
+ return org.bukkit.Bukkit.getUnsafe().serializeItem(this);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The current version byte of the item array format used in {@link #serializeItemsAsBytes(java.util.Collection)}
|
||||
+ * and {@link #deserializeItemsFromBytes(byte[])} respectively.
|
||||
+ */
|
||||
+ private static final byte ARRAY_SERIALIZATION_VERSION = 1;
|
||||
+
|
||||
+ /**
|
||||
+ * Serializes a collection of items to raw bytes in NBT. Serializes empty items as null.
|
||||
+ * <p>
|
||||
+ * 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<ItemStack> 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 || item.isEmpty()) {
|
||||
+ // 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);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Serializes a collection of items to raw bytes in NBT. Serializes empty items as null.
|
||||
+ * <p>
|
||||
+ * 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(@Nullable ItemStack @NotNull [] items) {
|
||||
+ return serializeItemsAsBytes(java.util.Arrays.asList(items));
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Deserializes this itemstack from raw NBT bytes.
|
||||
+ * <p>
|
||||
+ * 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 @NotNull 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 empty
|
||||
+ items[i] = ItemStack.empty();
|
||||
+ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/util/io/BukkitObjectInputStream.java
|
||||
+++ b/src/main/java/org/bukkit/util/io/BukkitObjectInputStream.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
* <p>
|
||||
* 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 org.bukkit.inventory.ItemStack#serializeAsBytes()} or
|
||||
+ * {@link org.bukkit.inventory.ItemStack#serializeItemsAsBytes(java.util.Collection)}.
|
||||
*/
|
||||
+@Deprecated(since = "1.21") // 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/util/io/BukkitObjectOutputStream.java
|
||||
+++ b/src/main/java/org/bukkit/util/io/BukkitObjectOutputStream.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
* <p>
|
||||
* 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 org.bukkit.inventory.ItemStack#serializeAsBytes()} or
|
||||
+ * {@link org.bukkit.inventory.ItemStack#serializeItemsAsBytes(java.util.Collection)}.
|
||||
*/
|
||||
+@Deprecated(since = "1.21") // Paper
|
||||
public class BukkitObjectOutputStream extends ObjectOutputStream {
|
||||
|
||||
/**
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren