public SubPacket(SubPacket original, uint newTargetId)
 {
     this.header          = new SubPacketHeader();
     this.gameMessage     = original.gameMessage;
     header.subpacketSize = original.header.subpacketSize;
     header.type          = original.header.type;
     header.sourceId      = original.header.sourceId;
     header.targetId      = newTargetId;
     data = original.data;
 }
        public SubPacket(ushort opcode, uint sourceId, uint targetId, byte[] data)
        {
            this.header      = new SubPacketHeader();
            this.gameMessage = new GameMessageHeader();

            gameMessage.opcode = opcode;
            header.sourceId    = sourceId;
            header.targetId    = targetId;

            gameMessage.timestamp = Utils.UnixTimeStampUTC();

            header.type          = 0x03;
            header.unknown1      = 0x00;
            gameMessage.unknown4 = 0x14;
            gameMessage.unknown5 = 0x00;
            gameMessage.unknown6 = 0x00;

            this.data = data;

            header.subpacketSize = (ushort)(SUBPACKET_SIZE + GAMEMESSAGE_SIZE + data.Length);
        }
        public unsafe SubPacket(byte[] bytes, ref int offset)
        {
            if (bytes.Length < offset + SUBPACKET_SIZE)
            {
                throw new OverflowException("Packet Error: Subpacket was too small");

                fixed(byte *pdata = &bytes[offset])
                {
                    header = (SubPacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader));
                }

                if (header.type == 0x3)
                {
                    fixed(byte *pdata = &bytes[offset + SUBPACKET_SIZE])
                    {
                        gameMessage = (GameMessageHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(GameMessageHeader));
                    }
                }

                if (bytes.Length < offset + header.subpacketSize)
                {
                    throw new OverflowException("Packet Error: Subpacket size didn't equal subpacket data");
                }

                if (header.type == 0x3)
                {
                    data = new byte[header.subpacketSize - SUBPACKET_SIZE - GAMEMESSAGE_SIZE];
                    Array.Copy(bytes, offset + SUBPACKET_SIZE + GAMEMESSAGE_SIZE, data, 0, data.Length);
                }
                else
                {
                    data = new byte[header.subpacketSize - SUBPACKET_SIZE];
                    Array.Copy(bytes, offset + SUBPACKET_SIZE, data, 0, data.Length);
                }

                offset += header.subpacketSize;
        }