Add a serializer for reading and writing ItemStacks to byte arrays.

To aid discoverability, we add a short-cut to this serializer in
PacketContainer, next to the getByteArrays() method.
This commit is contained in:
Kristian S. Stangeland 2013-01-02 20:37:24 +01:00
parent 3723e73e81
commit 6996db9e63
2 changed files with 82 additions and 0 deletions

View File

@ -51,6 +51,7 @@ import com.comphenix.protocol.reflect.cloning.ImmutableDetector;
import com.comphenix.protocol.reflect.cloning.AggregateCloner.BuilderParameters; import com.comphenix.protocol.reflect.cloning.AggregateCloner.BuilderParameters;
import com.comphenix.protocol.reflect.instances.DefaultInstances; import com.comphenix.protocol.reflect.instances.DefaultInstances;
import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.StreamSerializer;
import com.comphenix.protocol.wrappers.BukkitConverters; import com.comphenix.protocol.wrappers.BukkitConverters;
import com.comphenix.protocol.wrappers.ChunkPosition; import com.comphenix.protocol.wrappers.ChunkPosition;
import com.comphenix.protocol.wrappers.WrappedDataWatcher; import com.comphenix.protocol.wrappers.WrappedDataWatcher;
@ -236,6 +237,14 @@ public class PacketContainer implements Serializable {
return structureModifier.withType(byte[].class); return structureModifier.withType(byte[].class);
} }
/**
* Retrieve a serializer for reading and writing ItemStacks stored in a byte array.
* @return A instance of the serializer.
*/
public StreamSerializer getByteArraySerializer() {
return new StreamSerializer();
}
/** /**
* Retrieves a read/write structure for every int array field. * Retrieves a read/write structure for every int array field.
* @return A modifier for every int array field. * @return A modifier for every int array field.

View File

@ -0,0 +1,73 @@
package com.comphenix.protocol.utility;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import org.bukkit.inventory.ItemStack;
import com.comphenix.protocol.reflect.FuzzyReflection;
/**
* Utility methods for reading and writing Minecraft objects to streams.
*
* @author Kristian
*/
public class StreamSerializer {
// Cached methods
private static Method readItemMethod;
private static Method writeItemMethod;
/**
* Read or deserialize an item stack from an underlying input stream.
* <p>
* To supply a byte array, wrap it in a {@link java.io.ByteArrayInputStream ByteArrayInputStream}
* and {@link java.io.DataInputStream DataInputStream}.
*
* @param input - the target input stream.
* @return The resulting item stack.
* @throws IOException If the operation failed due to reflection or corrupt data.
*/
public ItemStack deserializeItemStack(DataInputStream input) throws IOException {
if (readItemMethod == null)
readItemMethod = FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).
getMethodByParameters("readPacket",
MinecraftReflection.getItemStackClass(),
new Class<?>[] {DataInputStream.class});
try {
Object nmsItem = readItemMethod.invoke(null, input);
// Convert back to a Bukkit item stack
return MinecraftReflection.getBukkitItemStack(nmsItem);
} catch (Exception e) {
throw new IOException("Cannot read item stack.", e);
}
}
/**
* Write or serialize an item stack to the given output stream.
* <p>
* To supply a byte array, wrap it in a {@link java.io.ByteArrayOutputStream ByteArrayOutputStream}
* and {@link java.io.DataOutputStream DataOutputStream}.
*
* @param output - the target output stream.
* @param stack - the item stack that will be written.
* @throws IOException If the operation fails due to reflection problems.
*/
public void serializeItemStack(DataOutputStream output, ItemStack stack) throws IOException {
Object nmsItem = MinecraftReflection.getMinecraftItemStack(stack);
if (writeItemMethod == null)
writeItemMethod = FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).
getMethodByParameters("writePacket", new Class<?>[] {
MinecraftReflection.getItemStackClass(),
DataOutputStream.class });
try {
writeItemMethod.invoke(null, nmsItem, output);
} catch (Exception e) {
throw new IOException("Cannot write item stack " + stack, e);
}
}
}