Last active
June 6, 2024 16:42
-
-
Save RealAlphaUA/e54d0e6747d668e209d678e5db9d04ea to your computer and use it in GitHub Desktop.
Small tool 🧩to read stack items in bukkit and nbt format depending on the context 👓
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.bukkit.Bukkit; | |
import org.bukkit.inventory.Inventory; | |
import org.bukkit.inventory.ItemStack; | |
import org.bukkit.util.io.BukkitObjectInputStream; | |
import org.bukkit.util.io.BukkitObjectOutputStream; | |
import java.io.*; | |
import java.lang.reflect.Constructor; | |
import java.lang.reflect.Method; | |
import java.util.Map; | |
public class InventoryMarshal { | |
private static Class<?> NBT_COMPRESSED_STREAM_TOOLS_CLAZZ; | |
private static Method WRITE_COMPRESSED_METHOD; | |
private static Method READ_COMPRESSED_METHOD; | |
private static Class<?> NTB_TAG_COMPOUND_CLAZZ; | |
private static Class<?> NMS_ITEM_STACK_CLAZZ; | |
private static Constructor<?> NMS_ITEM_STACK_CONSTRUCTOR; | |
private static Method SAVE_METHOD; | |
private static Class<?> CRAFT_ITEM_STACK_CLAZZ; | |
private static Method AS_BUKKIT_COPY_METHOD; | |
private static Method AS_NMS_COPY_METHOD; | |
static { | |
try { | |
NBT_COMPRESSED_STREAM_TOOLS_CLAZZ = getNmsClazz("NBTCompressedStreamTools"); | |
NTB_TAG_COMPOUND_CLAZZ = getNmsClazz("NBTTagCompound"); | |
WRITE_COMPRESSED_METHOD = NBT_COMPRESSED_STREAM_TOOLS_CLAZZ.getDeclaredMethod("a", NTB_TAG_COMPOUND_CLAZZ, OutputStream.class); | |
WRITE_COMPRESSED_METHOD.setAccessible(true); | |
READ_COMPRESSED_METHOD = NBT_COMPRESSED_STREAM_TOOLS_CLAZZ.getDeclaredMethod("a", InputStream.class); | |
READ_COMPRESSED_METHOD.setAccessible(true); | |
NMS_ITEM_STACK_CLAZZ = getNmsClazz("ItemStack"); | |
NMS_ITEM_STACK_CONSTRUCTOR = NMS_ITEM_STACK_CLAZZ.getDeclaredConstructor(NTB_TAG_COMPOUND_CLAZZ); | |
NMS_ITEM_STACK_CONSTRUCTOR.setAccessible(true); | |
SAVE_METHOD = NMS_ITEM_STACK_CLAZZ.getDeclaredMethod("save", NTB_TAG_COMPOUND_CLAZZ); | |
SAVE_METHOD.setAccessible(true); | |
CRAFT_ITEM_STACK_CLAZZ = getCraftBukkitClazz("inventory.CraftItemStack"); | |
AS_BUKKIT_COPY_METHOD = CRAFT_ITEM_STACK_CLAZZ.getDeclaredMethod("asBukkitCopy", NMS_ITEM_STACK_CLAZZ); | |
AS_BUKKIT_COPY_METHOD.setAccessible(true); | |
AS_NMS_COPY_METHOD = CRAFT_ITEM_STACK_CLAZZ.getDeclaredMethod("asNMSCopy", ItemStack.class); | |
AS_NMS_COPY_METHOD.setAccessible(true); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
public static Class<?> getNmsClazz(String className) throws ClassNotFoundException { | |
return Class.forName("net.minecraft.server." + Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3] + "." + className); | |
} | |
public static Class<?> getCraftBukkitClazz(String className) throws ClassNotFoundException { | |
return Class.forName("org.bukkit.craftbukkit." + Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3] + "." + className); | |
} | |
public static Object getNBTTAGCompound() throws Exception { | |
return NTB_TAG_COMPOUND_CLAZZ.newInstance(); | |
} | |
public static Object newNMSItemStack(Object nbtTagCompound) throws Exception { | |
return NMS_ITEM_STACK_CONSTRUCTOR.newInstance(nbtTagCompound); | |
} | |
public static ItemStack newBukkitItemStack(Object nmsItemStack) throws Exception { | |
return (ItemStack) AS_BUKKIT_COPY_METHOD.invoke(null, nmsItemStack); | |
} | |
public static Object getNMSItemStack(ItemStack itemStack) throws Exception { | |
return AS_NMS_COPY_METHOD.invoke(null, itemStack); | |
} | |
public static byte[] serialize(ItemStack itemStack) throws Exception { | |
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); | |
Object nmsItemStack = getNMSItemStack(itemStack); | |
Object nbtTagCompound = getNBTTAGCompound(); | |
SAVE_METHOD.invoke(nmsItemStack, nbtTagCompound); | |
WRITE_COMPRESSED_METHOD.invoke(null, nbtTagCompound, byteArrayOutputStream); | |
return byteArrayOutputStream.toByteArray(); | |
} | |
public static ItemStack deserialize(byte[] byteArray) throws Exception { | |
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArray); | |
Object nbtTagCompound = READ_COMPRESSED_METHOD.invoke(null, byteArrayInputStream); | |
Object nmsItemStack = newNMSItemStack(nbtTagCompound); | |
return newBukkitItemStack(nmsItemStack); | |
} | |
public static byte[] marshal(Inventory inventory) throws Exception { | |
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); | |
DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); | |
dataOutputStream.writeInt(inventory.getSize()); | |
for (int i = 0; i < inventory.getSize(); i++) { | |
ItemStack itemStack = inventory.getItem(i); | |
if (itemStack == null) { | |
dataOutputStream.writeInt(0); | |
continue; | |
} | |
byte[] bytes = serialize(itemStack); | |
dataOutputStream.writeInt(bytes.length); | |
dataOutputStream.write(bytes); | |
} | |
return byteArrayOutputStream.toByteArray(); | |
} | |
public static ItemStack[] unMarshal(byte[] byteArray) throws Exception { | |
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArray); | |
DataInputStream dataInputStream = new DataInputStream(byteArrayInputStream); | |
int size = dataInputStream.readInt(); | |
ItemStack[] itemStacks = new ItemStack[size]; | |
for (int i = 0; i < size; i++) { | |
int length = dataInputStream.readInt(); | |
if (length == 0) { | |
continue; | |
} | |
byte[] bytes = new byte[length]; | |
dataInputStream.readFully(bytes); | |
itemStacks[i] = deserialize(bytes); | |
} | |
return itemStacks; | |
} | |
public static byte[] bukkitMarshal(Inventory inventory) throws IOException { | |
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); | |
try (BukkitObjectOutputStream objectOutputStream = new BukkitObjectOutputStream(byteArrayOutputStream)) { | |
objectOutputStream.writeInt(inventory.getSize()); | |
for (ItemStack obj : inventory) { | |
objectOutputStream.writeObject(obj != null ? obj.serialize() : null); | |
} | |
return byteArrayOutputStream.toByteArray(); | |
} | |
} | |
public static ItemStack[] bukkitUnMarshal(byte[] byteArray) throws IOException, ClassNotFoundException { | |
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArray); | |
try (BukkitObjectInputStream objectInputStream = new BukkitObjectInputStream(byteArrayInputStream)) { | |
int size = objectInputStream.readInt(); | |
ItemStack[] content = new ItemStack[size]; | |
for (int i = 0; i < size; i++) { | |
Object readObject = objectInputStream.readObject(); | |
if (readObject != null) { | |
try { | |
content[i] = ItemStack.deserialize((Map<String, Object>) readObject); | |
} catch (NullPointerException e) { | |
//not found meta of item | |
} | |
} | |
} | |
return content; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment