package shedar.mods.ic2.nuclearcontrol.network.message; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import shedar.mods.ic2.nuclearcontrol.IC2NuclearControl; import shedar.mods.ic2.nuclearcontrol.api.IPanelDataSource; import shedar.mods.ic2.nuclearcontrol.panel.CardWrapperImpl; import shedar.mods.ic2.nuclearcontrol.tileentities.TileEntityInfoPanel; import shedar.mods.ic2.nuclearcontrol.utils.NuclearNetworkHelper; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import io.netty.buffer.ByteBuf; import cpw.mods.fml.client.FMLClientHandler; import cpw.mods.fml.common.network.ByteBufUtils; import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; import cpw.mods.fml.common.network.simpleimpl.MessageContext; public class PacketSensor implements IMessage, IMessageHandler<PacketSensor, IMessage> { private int x; private int y; private int z; private byte slot; private Map<String, Object> fields; public static final int FIELD_DOUBLE = 1; public static final int FIELD_INT = 2; public static final int FIELD_STRING = 3; public static final int FIELD_BOOLEAN = 4; public static final int FIELD_TAG = 5; public static final int FIELD_NULL = 6; public static final int FIELD_LONG = 7; public PacketSensor() { } public PacketSensor(int x, int y, int z, byte slot, Map<String, Object> fields) { this.x = x; this.y = y; this.z = z; this.slot = slot; this.fields = fields; } @Override public void fromBytes(ByteBuf buf) { x = buf.readInt(); y = buf.readInt(); z = buf.readInt(); slot = buf.readByte(); int fieldCount = buf.readShort(); fields = new HashMap<String, Object>(); for (int i = 0; i < fieldCount; i++) { String name = ByteBufUtils.readUTF8String(buf); byte type = buf.readByte(); switch (type) { case NuclearNetworkHelper.FIELD_INT: fields.put(name, buf.readInt()); break; case NuclearNetworkHelper.FIELD_BOOLEAN: fields.put(name, buf.readBoolean()); break; case NuclearNetworkHelper.FIELD_LONG: fields.put(name, buf.readLong()); break; case NuclearNetworkHelper.FIELD_DOUBLE: fields.put(name, buf.readDouble()); break; case NuclearNetworkHelper.FIELD_STRING: fields.put(name, ByteBufUtils.readUTF8String(buf)); break; case NuclearNetworkHelper.FIELD_TAG: NBTTagCompound tag; try { int size = buf.readInt(); DataInputStream dat = new DataInputStream( new ByteArrayInputStream(Arrays.copyOfRange( buf.array(), buf.readerIndex() + 1, buf.readerIndex() + 1 + size))); tag = CompressedStreamTools.readCompressed(dat); fields.put(name, tag); } catch (IOException e) { e.printStackTrace(); } break; case NuclearNetworkHelper.FIELD_NULL: fields.put(name, null); break; default: IC2NuclearControl.logger.warn("Invalid field type: %d", type); break; } } } @Override public void toBytes(ByteBuf buf) { buf.writeInt(x); buf.writeInt(y); buf.writeInt(z); buf.writeByte(slot); buf.writeShort(fields.size()); for (Map.Entry<String, Object> entry : fields.entrySet()) { ByteBufUtils.writeUTF8String(buf, entry.getKey()); Object value = entry.getValue(); if (value instanceof Long) { buf.writeByte(FIELD_LONG); buf.writeLong((Long) value); } else if (value instanceof Double) { buf.writeByte(FIELD_DOUBLE); buf.writeDouble((Double) value); } else if (value instanceof Integer) { buf.writeByte(FIELD_INT); buf.writeInt((Integer) value); } else if (value instanceof String) { buf.writeByte(FIELD_STRING); ByteBufUtils.writeUTF8String(buf, (String) value); } else if (value instanceof Boolean) { buf.writeByte(FIELD_BOOLEAN); buf.writeBoolean((Boolean) value); } else if (value instanceof NBTTagCompound) { buf.writeByte(FIELD_TAG); try { ByteArrayOutputStream stream = new ByteArrayOutputStream(); DataOutputStream output = new DataOutputStream(stream); CompressedStreamTools.writeCompressed( (NBTTagCompound) value, output); buf.writeInt(stream.size()); buf.writeBytes(stream.toByteArray()); } catch (IOException e) { e.printStackTrace(); } } else if (value == null) { buf.writeByte(FIELD_NULL); } } } @Override public IMessage onMessage(PacketSensor message, MessageContext ctx) { TileEntity tileEntity = FMLClientHandler.instance().getClient().theWorld .getTileEntity(message.x, message.y, message.z); if (tileEntity == null || !(tileEntity instanceof TileEntityInfoPanel)) { return null; } TileEntityInfoPanel panel = (TileEntityInfoPanel) tileEntity; ItemStack stack = panel.getStackInSlot(message.slot); if (stack == null || !(stack.getItem() instanceof IPanelDataSource)) { return null; } CardWrapperImpl helper = new CardWrapperImpl(stack, message.slot); for (Map.Entry<String, Object> entry : message.fields.entrySet()) { String name = entry.getKey(); Object value = entry.getValue(); if (value instanceof Long) { helper.setLong(name, (Long) value); } else if (value instanceof Double) { helper.setDouble(name, (Double) value); } else if (value instanceof Integer) { helper.setInt(name, (Integer) value); } else if (value instanceof String) { helper.setString(name, (String) value); } else if (value instanceof Boolean) { helper.setBoolean(name, (Boolean) value); } else if (value instanceof NBTTagCompound) { helper.setTag(name, (NBTTagCompound) value); } else if (value == null) { helper.clearField(name); } } panel.resetCardData(); return null; } }