package openmods.sync; import com.google.common.io.ByteStreams; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.Constants; import openmods.utils.ByteUtils; import openmods.utils.ItemUtils; public class SyncableItemStack extends SyncableObjectBase { private static final String TAG_TAG = "tag"; private static final String TAG_DAMAGE = "Damage"; private static final String TAG_COUNT = "Count"; private static final String TAG_ID = "id"; private ItemStack stack; @Override public void readFromStream(DataInputStream stream) throws IOException { int length = ByteUtils.readVLI(stream); if (length > 0) { int itemId = stream.readInt(); byte size = stream.readByte(); short damage = stream.readShort(); NBTTagCompound deserialized = new NBTTagCompound(); deserialized.setInteger(TAG_ID, itemId); deserialized.setByte(TAG_COUNT, size); deserialized.setShort(TAG_DAMAGE, damage); length--; if (length > 0) { // GZIP stream reads more than needed -> needs bounding if we want to reuse stream NBTTagCompound tag = CompressedStreamTools.readCompressed(ByteStreams.limit(stream, length)); deserialized.setTag(TAG_TAG, tag); } this.stack = ItemStack.loadItemStackFromNBT(deserialized); } else { this.stack = null; } } @Override public void writeToStream(DataOutputStream stream) throws IOException { if (stack != null) { NBTTagCompound serialized = new NBTTagCompound(); stack.writeToNBT(serialized); int id = serialized.getInteger(TAG_ID); byte size = serialized.getByte(TAG_COUNT); short damage = serialized.getShort(TAG_DAMAGE); int payloadSize = 1; byte[] tagBytes = null; if (serialized.hasKey(TAG_TAG)) { NBTTagCompound tag = serialized.getCompoundTag(TAG_TAG); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); CompressedStreamTools.writeCompressed(tag, buffer); tagBytes = buffer.toByteArray(); payloadSize += tagBytes.length; } ByteUtils.writeVLI(stream, payloadSize); stream.writeInt(id); stream.writeByte(size); stream.writeShort(damage); if (tagBytes != null) stream.write(tagBytes); } else { stream.writeByte(0); } } @Override public void writeToNBT(NBTTagCompound nbt, String name) { if (stack != null) { NBTTagCompound serialized = ItemUtils.writeStack(stack); nbt.setTag(name, serialized); } } @Override public void readFromNBT(NBTTagCompound nbt, String name) { if (nbt.hasKey(name, Constants.NBT.TAG_COMPOUND)) { NBTTagCompound serialized = nbt.getCompoundTag(name); stack = ItemUtils.readStack(serialized); } else { stack = null; } } public void set(ItemStack stack) { this.stack = stack != null? stack.copy() : null; markDirty(); } public ItemStack get() { return stack; } }