package gregtech.api.util; import com.google.common.io.ByteArrayDataInput; import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTSizeTracker; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagInt; import javax.annotation.Nonnull; import java.io.IOException; /** * We could well have used {@link java.io.Serializable}, but that's too slow and should generally be avoided * * @author glease */ public interface ISerializableObject { @Nonnull ISerializableObject copy(); @Nonnull NBTBase saveDataToNBT(); /** * Write data to given ByteBuf * The data saved this way is intended to be stored for short amount of time over network. * DO NOT store it to disks. */ // the NBT is an unfortunate piece of tech. everything uses it but its API is not as efficient as could be void writeToByteBuf(ByteBuf aBuf); void loadDataFromNBT(NBTBase aNBT); /** * Read data from given parameter and return this. * The data read this way is intended to be stored for short amount of time over network. */ // the NBT is an unfortunate piece of tech. everything uses it but its API is not as efficient as could be @Nonnull ISerializableObject readFromPacket(ByteArrayDataInput aBuf, EntityPlayerMP aPlayer); /** * Reverse engineered and adapted {@link cpw.mods.fml.common.network.ByteBufUtils#readTag(ByteBuf)} * Given buffer must contain a serialized NBTTagCompound in minecraft encoding */ static NBTTagCompound readCompoundTagFromGreggyByteBuf(ByteArrayDataInput aBuf) { short size = aBuf.readShort(); if (size < 0) return null; else { byte[] buf = new byte[size]; // this is shit, how many copies have we been doing? aBuf.readFully(buf); try { return CompressedStreamTools.func_152457_a(buf, new NBTSizeTracker(2097152L)); } catch (IOException e) { throw new RuntimeException(e); } } } /** * Reverse engineered and adapted {@link cpw.mods.fml.common.network.ByteBufUtils#readItemStack(ByteBuf)} * Given buffer must contain a serialized ItemStack in minecraft encoding */ static ItemStack readItemStackFromGreggyByteBuf(ByteArrayDataInput aBuf) { ItemStack stack = null; short id = aBuf.readShort(); if (id >= 0) { byte size = aBuf.readByte(); short meta = aBuf.readShort(); stack = new ItemStack(Item.getItemById(id), size, meta); stack.stackTagCompound = readCompoundTagFromGreggyByteBuf(aBuf); } return stack; } final class LegacyCoverData implements ISerializableObject { private int mData; public LegacyCoverData() { } public LegacyCoverData(int mData) { this.mData = mData; } @Override @Nonnull public ISerializableObject copy() { return new LegacyCoverData(mData); } @Override @Nonnull public NBTBase saveDataToNBT() { return new NBTTagInt(mData); } @Override public void writeToByteBuf(ByteBuf aBuf) { aBuf.writeInt(mData); } @Override public void loadDataFromNBT(NBTBase aNBT) { mData = aNBT instanceof NBTBase.NBTPrimitive ? ((NBTBase.NBTPrimitive) aNBT).func_150287_d() : 0; } @Override @Nonnull public ISerializableObject readFromPacket(ByteArrayDataInput aBuf, EntityPlayerMP aPlayer) { mData = aBuf.readInt(); return this; } public int get() { return mData; } public void set(int mData) { this.mData = mData; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; LegacyCoverData that = (LegacyCoverData) o; return mData == that.mData; } @Override public int hashCode() { return mData; } @Override public String toString() { return String.valueOf(mData); } } }