/
ItemSerialization.java
116 lines (99 loc) · 3.47 KB
/
ItemSerialization.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package de.kumpelblase2.remoteentities.utilities;
import java.io.*;
import java.lang.reflect.Method;
import net.minecraft.server.v1_7_R1.*;
import org.bukkit.craftbukkit.v1_7_R1.inventory.CraftInventoryCustom;
import org.bukkit.craftbukkit.v1_7_R1.inventory.CraftItemStack;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
/**
* Made by Comprehenix.
* Code can be found at: https://gist.github.com/aadnk/8138345
*/
public class ItemSerialization {
private static Method WRITE_NBT;
private static Method READ_NBT;
/**
* Serializes an inventory to a encoded string.
*
* @param inventory The inventory to serialize
* @return serialized string
*/
public static String toString(Inventory inventory) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
DataOutputStream dataOutput = new DataOutputStream(outputStream);
NBTTagList itemList = new NBTTagList();
// Save every element in the list
for (int i = 0; i < inventory.getSize(); i++) {
NBTTagCompound outputObject = new NBTTagCompound();
CraftItemStack craft = getCraftVersion(inventory.getItem(i));
// Convert the item stack to a NBT compound
if (craft != null)
CraftItemStack.asNMSCopy(craft).save(outputObject);
itemList.add(outputObject);
}
// Now save the list
writeNbt(itemList, dataOutput);
// Serialize that array
return Base64Coder.encodeLines(outputStream.toByteArray());
}
/**
* Deserializes an inventory from a string
*
* @param data String to deserialize
* @return Deserialized inventory
*/
public static Inventory fromString(String data) {
ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data));
NBTTagList itemList = (NBTTagList) readNbt(new DataInputStream(inputStream), 0);
Inventory inventory = new CraftInventoryCustom(null, itemList.size());
for (int i = 0; i < itemList.size(); i++) {
NBTTagCompound inputObject = itemList.get(i);
if (!inputObject.isEmpty()) {
inventory.setItem(i, CraftItemStack.asCraftMirror(
net.minecraft.server.v1_7_R1.ItemStack.createStack(inputObject)));
}
}
// Serialize that array
return inventory;
}
private static void writeNbt(NBTBase base, DataOutput output) {
if (WRITE_NBT == null) {
try {
WRITE_NBT = NBTCompressedStreamTools.class.getDeclaredMethod("a", NBTBase.class, DataOutput.class);
WRITE_NBT.setAccessible(true);
} catch (Exception e) {
throw new IllegalStateException("Unable to find private write method.", e);
}
}
try {
WRITE_NBT.invoke(null, base, output);
} catch (Exception e) {
throw new IllegalArgumentException("Unable to write " + base + " to " + output, e);
}
}
private static NBTBase readNbt(DataInput input, int level) {
if (READ_NBT == null) {
try {
READ_NBT = NBTCompressedStreamTools.class.getDeclaredMethod("a", DataInput.class, int.class);
READ_NBT.setAccessible(true);
} catch (Exception e) {
throw new IllegalStateException("Unable to find private read method.", e);
}
}
try {
return (NBTBase) READ_NBT.invoke(null, input, level);
} catch (Exception e) {
throw new IllegalArgumentException("Unable to read from " + input, e);
}
}
private static CraftItemStack getCraftVersion(ItemStack stack) {
if (stack instanceof CraftItemStack)
return (CraftItemStack) stack;
else if (stack != null)
return CraftItemStack.asCraftCopy(stack);
else
return null;
}
}