Exemple #1
0
        public byte[] get_tlv_0004(QQClient m_PCClient)
        {
            if (m_PCClient.QQUser.QQ != 0)
            {
                return(null);
            }

            var data = new BinaryWriter(new MemoryStream());

            if (wSubVer == 0x0000)
            {
                data.BEWrite(wSubVer);                   //wSubVer
                var bufAccount = Util.HexStringToByteArray(Util.QQToHexString(m_PCClient.QQUser.QQ));
                data.BEWrite((ushort)bufAccount.Length); //账号长度
                data.Write(bufAccount);                  //账号
            }
            else
            {
                throw new Exception($"{Name} 无法识别的版本号 {wSubVer}");
            }

            fill_head(cmd);
            fill_body(data.BaseStream.ToBytesArray(), data.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #2
0
        public byte[] get_tlv_0105(QQClient m_PCClient)
        {
            var data = new BinaryWriter(new MemoryStream());

            if (wSubVer == 0x0001)
            {
                data.BEWrite(wSubVer); //wSubVer
                data.Write(1);
                data.Write(2);
                data.BEWrite(0x0014);
                data.BEWrite(0x01010010);
                data.Write(Util.RandomKey());
                data.BEWrite(0x0014);
                data.BEWrite(0x01020010);
                data.Write(Util.RandomKey());
            }
            else
            {
                throw new Exception($"{Name} 无法识别的版本号 {wSubVer}");
            }

            fill_head(cmd);
            fill_body(data.BaseStream.ToBytesArray(), data.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #3
0
        public byte[] get_tlv_0015(QQClient m_PCClient)
        {
            var data = new BinaryWriter(new MemoryStream());

            if (wSubVer == 0x0001)
            {
                data.BEWrite(wSubVer); //wSubVer

                data.Write(0x01);
                var thisKey = m_PCClient.QQUser.TXProtocol.bufComputerID;
                data.BEWrite(CRC32cs.CRC32(thisKey));
                data.Write(thisKey);

                data.Write(0x02);
                thisKey = m_PCClient.QQUser.TXProtocol.bufComputerIDEx;
                data.BEWrite(CRC32cs.CRC32(thisKey));
                data.Write(thisKey);
            }
            else
            {
                throw new Exception(string.Format("{0} 无法识别的版本号 {1}", Name, wSubVer));
            }

            fill_head(cmd);
            fill_body(data.BaseStream.ToBytesArray(), data.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #4
0
        public byte[] get_tlv_0036(QQClient m_PCClient)
        {
            var data = new BinaryWriter(new MemoryStream());

            if (this.wSubVer == 0x0002)
            {
                data.BEWrite(this.wSubVer); //wSubVer
                data.BEWrite(1);
                data.BEWrite(0);
                data.BEWrite(0);
                data.BEWrite(0);
                data.BEWrite(0);
                data.Write(0);
                data.Write(0);
            }
            else if (this.wSubVer == 0x0001)
            {
                data.BEWrite(this.wSubVer); //wSubVer
                data.BEWrite(1);
                data.BEWrite(0);
                data.BEWrite(0);
            }
            else
            {
                throw new Exception(string.Format("{0} 无法识别的版本号 {1}", this.Name, this.wSubVer));
            }
            fill_head(this.cmd);
            fill_body(data.BaseStream.ToBytesArray(), data.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #5
0
 /// <summary>
 /// 将包头部转化为字节流, 写入指定的ByteBuffer对象.
 /// </summary>
 /// <param name="buf">The buf.</param>
 protected virtual void PutHeader()
 {
     writer.Write(QQGlobal.QQ_HEADER_BASIC_FAMILY);
     writer.BEWrite(Version);
     writer.BEWrite((ushort)Command);
     writer.BEWrite(Sequence);
     writer.BEWrite(user.QQ);
 }
Exemple #6
0
 /// <summary>
 /// 普通消息
 /// </summary>
 /// <param name="writer"></param>
 /// <param name="GroupMsg"></param>
 public static void ConstructMessage(BinaryWriter writer, byte[] GroupMsg)
 {
     writer.Write(new byte[] { 0x01 });
     writer.BEWrite((ushort)(GroupMsg.Length + 3));
     writer.Write(new byte[] { 0x01 });
     writer.BEWrite((ushort)GroupMsg.Length);
     writer.Write(GroupMsg);
 }
Exemple #7
0
        /// <summary>
        ///     密码加密码一次MD5拼接后MD5加密
        /// </summary>
        /// <returns></returns>
        public byte[] Md52()
        {
            var byteBuffer = new BinaryWriter(new MemoryStream());

            byteBuffer.Write(MD51);
            byteBuffer.BEWrite(0);
            byteBuffer.BEWrite(QQ);
            return(MD5.Create().ComputeHash(((MemoryStream)byteBuffer.BaseStream).ToArray()));
        }
Exemple #8
0
        /// <summary>
        ///     初始化包体
        /// </summary>
        protected override void PutBody()
        {
            var pic      = new Bitmap(fileName);
            var Width    = pic.Size.Width;  // 图片的宽度
            var Height   = pic.Size.Height; // 图片的高度
            var picBytes = ImageHelper.ImageToBytes(pic);
            var Md5      = QQTea.MD5(picBytes);

            var _Data = new BinaryWriter(new MemoryStream());

            _Data.Write(new byte[]
            {
                0x01, 0x08, 0x01, 0x12
            });
            _Data.Write((byte)0x5A);
            _Data.Write((byte)0x08);
            _Data.Write(Util.HexStringToByteArray(Util.PB_toLength(user.QQ)));
            _Data.Write((byte)0x10);
            _Data.Write(Util.HexStringToByteArray(Util.PB_toLength(_toQQ)));
            _Data.BEWrite((ushort)0x1800);
            _Data.Write((byte)0x22);
            _Data.Write((byte)0x10);
            _Data.Write(Md5);
            _Data.Write((byte)0x28);
            _Data.Write(Util.HexStringToByteArray(Util.PB_toLength(picBytes.Length)));
            _Data.Write((byte)0x32);
            _Data.Write((byte)0x1A);
            _Data.Write(new byte[]
            {
                0x57, 0x00, 0x53, 0x00, 0x4E, 0x00, 0x53, 0x00, 0x4C, 0x00, 0x54, 0x00,
                0x31, 0x00, 0x36, 0x00, 0x47, 0x00, 0x45, 0x00, 0x4F, 0x00, 0x5B, 0x00,
                0x5F, 0x00
            });
            _Data.BEWrite((ushort)0x3801);
            _Data.BEWrite((ushort)0x4801);
            _Data.Write((byte)0x70);
            _Data.Write(Util.HexStringToByteArray(Util.PB_toLength(Width)));
            _Data.Write((byte)0x78);
            _Data.Write(Util.HexStringToByteArray(Util.PB_toLength(Height)));

            bodyWriter.Write(new byte[]
            {
                0x00, 0x00, 0x00, 0x07
            });
            //数据长度
            bodyWriter.BEWrite(_Data.BaseStream.Length);
            bodyWriter.Write(new byte[]
            {
                0x08, 0x01, 0x12, 0x03, 0x98, 0x01
            });
            //数据
            bodyWriter.Write(_Data.BaseStream.ToBytesArray());
        }
Exemple #9
0
        public byte[] get_tlv_0309(QQClient m_PCClient)
        {
            var data = new BinaryWriter(new MemoryStream());

            if (wSubVer == 0x0001)
            {
                data.BEWrite(wSubVer);                                       //wSubVer
                data.Write(Util.IPStringToByteArray(m_PCClient.dwServerIP)); //LastServerIP - 服务器最后的登录IP,可以为0
                data.Write((byte)m_PCClient.QQUser.RedirectIP.Count);        //cRedirectCount - 重定向的次数(IP的数量)
                foreach (var ip in m_PCClient.QQUser.RedirectIP)
                {
                    data.Write(ip);
                }

                data.Write(m_PCClient.QQUser.cPingType); //cPingType
            }
            else
            {
                throw new Exception($"{Name} 无法识别的版本号 {wSubVer}");
            }

            fill_head(cmd);
            fill_body(data.BaseStream.ToBytesArray(), data.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #10
0
        /// <summary>
        /// XML消息组装
        /// </summary>
        /// <param name="buf">报文</param>
        /// <param name="_DateTime">时间</param>
        /// <param name="compressMsg">压缩消息数组</param>
        public static byte[] SendXML(long _DateTime, byte[] compressMsg)
        {
            BinaryWriter bw = new BinaryWriter(new MemoryStream());

            bw.BEWrite(_DateTime);
            bw.Write(Util.RandomKey(4));
            bw.Write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x86, 0x00 });
            bw.Write(new byte[] { 0x00, 0x0C });
            bw.Write(new byte[] { 0xE5, 0xBE, 0xAE, 0xE8, 0xBD, 0xAF, 0xE9, 0x9B, 0x85, 0xE9, 0xBB, 0x91 });
            bw.Write(new byte[] { 0x00, 0x00, 0x14 });
            bw.BEWrite((ushort)(compressMsg.Length + 11));
            bw.Write((byte)0x01);
            bw.BEWrite((ushort)(compressMsg.Length + 1));
            bw.Write((byte)0x01);
            bw.Write(compressMsg);
            bw.Write(new byte[] { 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x4D });
            return(bw.BaseStream.ToBytesArray());
        }
Exemple #11
0
        public byte[] get_tlv_0312(QQClient m_PCClient)
        {
            var data = new BinaryWriter(new MemoryStream());

            data.Write(1);
            data.BEWrite(0);
            fill_head(cmd);
            fill_body(data.BaseStream.ToBytesArray(), data.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #12
0
        public byte[] get_tlv_0114(QQClient m_PCClient)
        {
            var data = new BinaryWriter(new MemoryStream());

            if (this.wSubVer == 0x0102)
            {
                data.BEWrite(this.wSubVer);                                               //wDHVer
                data.BEWrite((ushort)m_PCClient.QQUser.TXProtocol.bufDHPublicKey.Length); //bufDHPublicKey长度
                data.Write(m_PCClient.QQUser.TXProtocol.bufDHPublicKey);
                //client.TXProtocol.Key["DHDecodeKey"] = client.TXProtocol.bufDHDecodeKey;
            }
            else
            {
                throw new Exception(string.Format("{0} 无法识别的版本号 {1}", this.Name, this.wSubVer));
            }
            fill_head(this.cmd);
            fill_body(data.BaseStream.ToBytesArray(), data.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #13
0
        public byte[] get_tlv_0005(QQClient m_PCClient)
        {
            if (m_PCClient.QQUser.QQ == 0)
            {
                return(null);
            }
            var buf = new BinaryWriter(new MemoryStream());

            if (this.wSubVer == 0x0002)
            {
                buf.BEWrite((ushort)this.wSubVer);
                buf.BEWrite((uint)m_PCClient.QQUser.QQ);
            }
            else
            {
                throw new Exception(string.Format("{0} 无法识别的版本号 {1}", this.Name, this.wSubVer));
            }
            fill_head(this.cmd);
            fill_body(buf.BaseStream.ToBytesArray(), buf.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #14
0
        public byte[] get_tlv_8(QQClient m_PCClient)
        {
            //if (PCQQGlobal.dwLocaleID == 0x00000804 && PCQQGlobal.wTimeZoneoffsetMin == 0x01E0)
            //{
            //    return null;
            //}
            var data = new BinaryWriter(new MemoryStream());

            if (this.wSubVer == 0x0001)
            {
                data.BEWrite(this.wSubVer); //wSubVer
                data.BEWrite(0x00000804);   //此乃LCID
                data.BEWrite(0x01E0);       //此乃时区信息
            }
            else
            {
                throw new Exception(string.Format("{0} 无法识别的版本号 {1}", this.Name, this.wSubVer));
            }
            fill_head(this.cmd);
            fill_body(data.BaseStream.ToBytesArray(), data.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #15
0
        public byte[] get_tlv_0006(QQClient m_PCClient)
        {
            if (wSubVer == 0x0002)
            {
                if (m_PCClient.QQUser.TXProtocol.bufTGTGT == null)
                {
                    var data = new BinaryWriter(new MemoryStream());
                    data.BEWrite(new Random(Guid.NewGuid().GetHashCode()).Next()); //随机4字节??
                    data.BEWrite(wSubVer);                                         //wSubVer
                    data.BEWrite((uint)m_PCClient.QQUser.QQ);                      //QQ号码
                    data.BEWrite(QQGlobal.dwSSOVersion);
                    data.BEWrite(QQGlobal.dwServiceId);
                    data.BEWrite(QQGlobal.dwClientVer);
                    data.BEWrite(0);
                    data.Write(m_PCClient.QQUser.bRememberPwdLogin);
                    data.Write(m_PCClient.QQUser.MD51);                       //密码的一次MD5值,服务器用该MD5值验证用户密码是否正确
                    data.Write(m_PCClient.QQUser.LoginTime);                  //登录时间
                    data.Write(new byte[13]);                                 //固定13字节
                    data.Write(m_PCClient.QQUser.IP);                         //IP地址
                    data.BEWrite(QQGlobal.dwISP);                             //dwISP
                    data.BEWrite(QQGlobal.dwIDC);                             //dwIDC
                    data.Write(m_PCClient.QQUser.TXProtocol.bufComputerIDEx); //机器码
                    data.Write(m_PCClient.QQUser.QQ_PACKET_TgtgtKey);         //00DD临时密钥(通过验证时客户端用该密钥解密服务端发送回来的数据)

                    m_PCClient.QQUser.TXProtocol.bufTGTGT =
                        QQTea.Encrypt(data.BaseStream.ToBytesArray(), m_PCClient.QQUser.Md52());
                }
            }
            else
            {
                throw new Exception($"{Name} 无法识别的版本号 {wSubVer}");
            }

            var tlv = new BinaryWriter(new MemoryStream());

            tlv.Write(m_PCClient.QQUser.TXProtocol.bufTGTGT);
            fill_head(cmd);
            fill_body(tlv.BaseStream.ToBytesArray(), tlv.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #16
0
        public byte[] get_tlv_0103(QQClient m_PCClient)
        {
            if (QQGlobal.bufSID == null || QQGlobal.bufSID.Length == 0)
            {
                return(null);
            }
            var data = new BinaryWriter(new MemoryStream());

            data.BEWrite(0x0001);
            data.Write(QQGlobal.bufSID);
            fill_head(this.cmd);
            fill_body(data.BaseStream.ToBytesArray(), data.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #17
0
        public byte[] get_tlv_0005(QQClient m_PCClient)
        {
            if (m_PCClient.QQUser.QQ == 0)
            {
                return(null);
            }

            var buf = new BinaryWriter(new MemoryStream());

            if (wSubVer == 0x0002)
            {
                buf.BEWrite(wSubVer);
                buf.BEWrite((uint)m_PCClient.QQUser.QQ);
            }
            else
            {
                throw new Exception($"{Name} 无法识别的版本号 {wSubVer}");
            }

            fill_head(cmd);
            fill_body(buf.BaseStream.ToBytesArray(), buf.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #18
0
        public byte[] get_tlv_0313(QQClient m_PCClient)
        {
            var data = new BinaryWriter(new MemoryStream());

            if (wSubVer == 0x01)
            {
                data.Write(1); // wSubVer
                var GuidName = new Dictionary <string, byte[]>(6)
                {
                    { "UNKNOW1", null },
                    { "MacGuid", m_PCClient.QQUser.TXProtocol.bufMacGuid },
                    { "UNKNOW2", null },
                    { "ComputerIDEx", m_PCClient.QQUser.TXProtocol.bufComputerIDEx },
                    { "UNKNOW3", null },
                    { "MachineInfoGuid", m_PCClient.QQUser.TXProtocol.bufMachineInfoGuid }
                };
                byte k    = 0;
                byte c    = 0;
                var  guid = new BinaryWriter(new MemoryStream());
                foreach (var kv in GuidName)
                {
                    k++;
                    if (kv.Value != null)
                    {
                        c++;
                        guid.Write(k);
                        guid.Write(kv.Value);
                        guid.BEWrite(0);
                    }
                }

                data.Write(c);
                data.Write(guid.BaseStream.ToBytesArray());
            }
            else
            {
                throw new Exception($"{Name} 无法识别的版本号 {wSubVer}");
            }

            fill_head(cmd);
            fill_body(data.BaseStream.ToBytesArray(), data.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #19
0
        public byte[] get_tlv_002D(QQClient m_PCClient)
        {
            var data = new BinaryWriter(new MemoryStream());

            if (wSubVer == 0x0001)
            {
                data.BEWrite(wSubVer);                              //wSubVer
                data.Write(Util.IPStringToByteArray(GetLocalIP())); //本机内网IP地址
            }
            else
            {
                throw new Exception(string.Format("{0} 无法识别的版本号 {1}", Name, wSubVer));
            }

            fill_head(cmd);
            fill_body(data.BaseStream.ToBytesArray(), data.BaseStream.Length);
            set_length();
            return(get_buf());
        }
        public byte[] GET_TLV_0006(byte[] m_loginTime, byte[] m_loginIP)
        {
            var bw = new BinaryWriter(new MemoryStream());

            bw.Write(Util.RandomKey(4));
            bw.Write(new byte[] { 0x00, 0x02 });
            bw.BEWrite(user.QQ);
            bw.Write(user.QQ_PACKET_0825DATA2);
            bw.Write(new byte[] { 0x00, 0x00, 0x01 });
            bw.Write(user.MD51);
            bw.Write(m_loginTime);
            bw.Write(new byte[] { 0x00 }); //下面有时间时为01
            bw.Write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
            bw.Write(m_loginIP);
            bw.Write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
            bw.Write(new byte[] { 0x00, 0x10 });
            bw.Write(new byte[]
                     { 0x15, 0x74, 0xC4, 0x89, 0x85, 0x7A, 0x19, 0xF5, 0x5E, 0xA9, 0xC9, 0xA3, 0x5E, 0x8A, 0x5A, 0x9B });
            bw.Write(user.QQ_PACKET_TgtgtKey);
            return(QQTea.Encrypt(bw.BaseStream.ToBytesArray(), user.Md52()));
        }
Exemple #21
0
        public byte[] get_tlv_0110(QQClient m_PCClient)
        {
            if (m_PCClient.QQUser.TXProtocol.bufSigPic == null)
            {
                return(null);
            }
            var data = new BinaryWriter(new MemoryStream());

            if (this.wSubVer == 0x0001)
            {
                data.BEWrite(this.wSubVer); //wSubVer
                data.Write(m_PCClient.QQUser.TXProtocol.bufSigPic);
            }
            else
            {
                throw new Exception(string.Format("{0} 无法识别的版本号 {1}", this.Name, this.wSubVer));
            }
            fill_head(this.cmd);
            fill_body(data.BaseStream.ToBytesArray(), data.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #22
0
        public byte[] get_tlv_001F(QQClient m_PCClient)
        {
            if (m_PCClient.QQUser.TXProtocol.bufDeviceID == null)
            {
                return(null);
            }

            var data = new BinaryWriter(new MemoryStream());

            if (wSubVer == 0x0001)
            {
                data.BEWrite(wSubVer); //wSubVer
                data.Write(m_PCClient.QQUser.TXProtocol.bufDeviceID);
            }
            else
            {
                throw new Exception($"{Name} 无法识别的版本号 {wSubVer}");
            }

            fill_head(cmd);
            fill_body(data.BaseStream.ToBytesArray(), data.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #23
0
        public byte[] get_tlv_0018(QQClient m_PCClient)
        {
            var data = new BinaryWriter(new MemoryStream());

            if (this.wSubVer == 0x0001)
            {
                data.BEWrite(this.wSubVer);                      //wSubVer
                data.BEWrite(QQGlobal.dwSSOVersion);             //dwSSOVersion
                data.BEWrite(QQGlobal.dwServiceId);              //dwServiceId
                data.BEWrite(QQGlobal.dwClientVer);              //dwClientVer
                data.BEWrite((uint)m_PCClient.QQUser.QQ);        //dwUin
                data.BEWrite((ushort)m_PCClient.wRedirectCount); //wRedirectCount
                data.BEWrite(0);                                 //NullBuf
            }
            else
            {
                throw new Exception(string.Format("{0} 无法识别的版本号 {1}", this.Name, this.wSubVer));
            }
            fill_head(this.cmd);
            fill_body(data.BaseStream.ToBytesArray(), data.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #24
0
        public byte[] get_tlv_000C(QQClient m_PCClient)
        {
            var data = new BinaryWriter(new MemoryStream());

            if (this.wSubVer == 0x0002)
            {
                data.BEWrite(this.wSubVer); //wSubVer
                data.BEWrite(0);
                data.BEWrite(QQGlobal.dwIDC);
                data.BEWrite(QQGlobal.dwISP);
                data.Write(Util.IPStringToByteArray(m_PCClient.dwServerIP));
                data.BEWrite(m_PCClient.wServerPort);
                data.BEWrite(0);
            }
            else
            {
                throw new Exception(string.Format("{0} 无法识别的版本号 {1}", this.Name, this.wSubVer));
            }
            fill_head(this.cmd);
            fill_body(data.BaseStream.ToBytesArray(), data.BaseStream.Length);
            set_length();
            return(get_buf());
        }
Exemple #25
0
        public static List <byte[]> ConstructMessage(QQUser user, Richtext message, long toQQ)
        {
            var dateTime = Util.GetTimeSeconds(DateTime.Now);
            var md5      = user.QQ_SessionKey;
            var ret      = new List <byte[]>();
            var writer   = new BinaryWriter(new MemoryStream());
            // FIXME: 使用正确的_packetCount和_packetIndex进行分段
            byte _packetCount = 1, _packetIndex = 0;

            void Init()
            {
                writer.BEWrite(user.QQ);
                writer.BEWrite(toQQ);
                writer.Write(new byte[]
                {
                    0x00, 0x00, 0x00, 0x0D, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
                    0x01, 0x01
                });
                writer.Write(new byte[] { 0x36, 0x43 });
                writer.BEWrite(user.QQ);
                writer.BEWrite(toQQ);
                writer.Write(md5);
                writer.Write(new byte[] { 0x00, 0x0B });
                writer.Write(Util.RandomKey(2));
                writer.BEWrite(dateTime);
                writer.Write(new byte[]
                {
                    0x02, 0x34, 0x00, 0x00, 0x00, 0x00, _packetCount, _packetIndex, 0x00, 0x00, 0x01, 0x4D,
                    0x53, 0x47,
                    0x00, 0x00, 0x00, 0x00, 0x00
                });
                writer.BEWrite(dateTime);
                writer.Write(Util.RandomKey(4));
                writer.Write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x86, 0x00 });
                writer.Write(new byte[] { 0x00, 0x06 });
                writer.Write(new byte[] { 0xE5, 0xAE, 0x8B, 0xE4, 0xBD, 0x93 });
                writer.Write(new byte[] { 0x00, 0x00 });
            }

            foreach (var snippet in message.Snippets)
            {
                switch (snippet.Type)
                {
                case MessageType.Xml:
                {
                    var compressMsg = GZipByteArray.CompressBytes(snippet.Content);
                    writer.BEWrite(user.QQ);
                    writer.BEWrite(toQQ);
                    writer.Write(new byte[] { 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x04 });
                    writer.Write(new byte[] { 0x00, 0x00, 0x00, 0x00 });
                    writer.Write(new byte[] { 0x37, 0x0F });
                    writer.BEWrite(user.QQ);
                    writer.BEWrite(toQQ);
                    writer.Write(md5);
                    writer.Write(new byte[] { 0x00, 0x0B });
                    writer.Write(Util.RandomKey(2));
                    writer.BEWrite(dateTime);
                    writer.Write(new byte[]
                        {
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, _packetCount, _packetIndex, 0x00, 0x00, 0x01, 0x4D,
                            0x53, 0x47,
                            0x00, 0x00, 0x00, 0x00, 0x00
                        });
                    writer.BEWrite(dateTime);
                    writer.Write(Util.RandomKey(4));
                    writer.Write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x86, 0x00 });
                    writer.Write(new byte[] { 0x00, 0x0C });
                    writer.Write(
                        new byte[] { 0xE5, 0xBE, 0xAE, 0xE8, 0xBD, 0xAF, 0xE9, 0x9B, 0x85, 0xE9, 0xBB, 0x91 });
                    writer.Write(new byte[] { 0x00, 0x00, 0x14 });
                    writer.BEWrite((ushort)(compressMsg.Length + 11));
                    writer.Write((byte)0x01);
                    writer.BEWrite((ushort)(compressMsg.Length + 1));
                    writer.Write((byte)0x01);
                    writer.Write(compressMsg);
                    writer.Write(new byte[] { 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x4D });
                    ret.Add(writer.BaseStream.ToBytesArray());
                    return(ret);
                }

                case MessageType.Shake:
                {
                    writer.BEWrite(user.QQ);
                    writer.BEWrite(toQQ);
                    writer.Write(new byte[] { 0x00, 0x00, 0x00, 0x00 });
                    writer.Write(new byte[] { 0x37, 0x0F });
                    writer.BEWrite(user.QQ);
                    writer.BEWrite(toQQ);
                    writer.Write(Util.RandomKey());
                    writer.Write(new byte[] { 0x00, 0xAF });
                    writer.Write(Util.RandomKey(2));
                    writer.BEWrite(dateTime);
                    writer.Write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
                    writer.Write(Util.RandomKey(4));
                    writer.Write(new byte[] { 0x00, 0x00, 0x00, 0x00 });
                    ret.Add(writer.BaseStream.ToBytesArray());
                    return(ret);
                }

                case MessageType.Normal:
                {
                    if (writer.BaseStream.Position + snippet.Length > 699)
                    {
                        ret.Add(writer.BaseStream.ToBytesArray());
                        writer = new BinaryWriter(new MemoryStream());
                    }

                    if (writer.BaseStream.Position == 0)
                    {
                        Init();
                    }

                    var messageData = Encoding.UTF8.GetBytes(snippet.Content);
                    writer.Write(new byte[] { 0x01 });
                    writer.BEWrite((ushort)(messageData.Length + 3));
                    writer.Write(new byte[] { 0x01 });
                    writer.BEWrite((ushort)messageData.Length);
                    writer.Write(messageData);
                    break;
                }

                case MessageType.Emoji:
                {
                    if (writer.BaseStream.Position + snippet.Length > 699)
                    {
                        ret.Add(writer.BaseStream.ToBytesArray());
                        writer = new BinaryWriter(new MemoryStream());
                    }

                    if (writer.BaseStream.Position == 0)
                    {
                        Init();
                    }

                    var faceIndex = byte.Parse(snippet.Content);
                    writer.Write(new byte[] { 0x02, 0x00, 0x14, 0x01, 0x00, 0x01 });
                    writer.Write(faceIndex);
                    writer.Write(new byte[] { 0xFF, 0x00, 0x02, 0x14 });
                    writer.Write((byte)(faceIndex + 65));
                    writer.Write(new byte[] { 0x0B, 0x00, 0x08, 0x00, 0x01, 0x00, 0x04, 0x52, 0xCC, 0x85, 0x50 });
                    break;
                }

                default:
                {
                    throw new NotImplementedException();
                }
                }

                ret.Add(writer.BaseStream.ToBytesArray());
                writer = new BinaryWriter(new MemoryStream());
            }

            return(ret);
        }
        public static List <byte[]> ConstructMessage(QQUser user, Richtext message, long groupNum)
        {
            var dateTime = Util.GetTimeSeconds(DateTime.Now);
            var group    = GroupToGid(groupNum);
            var ret      = new List <byte[]>();
            var writer   = new BinaryWriter(new MemoryStream());
            // FIXME: 使用正确的_packetCount和_packetIndex进行分段
            byte _packetCount = 1, _packetIndex = 0;

            foreach (var snippet in message.Snippets)
            {
                switch (snippet.Type)
                {
                case MessageType.Xml:
                {
                    writer.Write((byte)0x2A);
                    writer.BEWrite(group);
                    var compressMsg = GZipByteArray.CompressBytes(snippet.Content);
                    writer.BEWrite((ushort)(compressMsg.Length + 64));
                    writer.Write(new byte[]
                        {
                            0x00, 0x01, _packetCount, _packetIndex, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x53,
                            0x47, 0x00,
                            0x00, 0x00, 0x00, 0x00
                        });
                    writer.BEWrite(dateTime);
                    writer.Write(Util.RandomKey(4));
                    writer.Write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x86, 0x00 });
                    writer.Write(new byte[] { 0x00, 0x0C });
                    writer.Write(new byte[]
                                 { 0xE5, 0xBE, 0xAE, 0xE8, 0xBD, 0xAF, 0xE9, 0x9B, 0x85, 0xE9, 0xBB, 0x91 });
                    writer.Write(new byte[] { 0x00, 0x00, 0x14 });
                    writer.BEWrite((ushort)(compressMsg.Length + 11));
                    writer.Write((byte)0x01);
                    writer.BEWrite((ushort)(compressMsg.Length + 1));
                    writer.Write((byte)0x01);
                    writer.Write(compressMsg);
                    writer.Write(new byte[] { 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x4D });
                    break;
                }

                case MessageType.Picture:
                {
                    HttpUpLoadGroupImg(user, groupNum, user.Ukey, snippet.Content);
                    writer.Write((byte)0x2A);
                    writer.BEWrite(group);
                    writer.Write(new byte[]
                        {
                            0x00, 0x01, _packetCount, _packetIndex, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x53,
                            0x47, 0x00,
                            0x00, 0x00, 0x00, 0x00
                        });
                    var guid = Encoding.UTF8.GetBytes(Util.GetMD5ToGuidHashFromFile(snippet.Content));
                    writer.BEWrite(dateTime);
                    writer.Write(Util.RandomKey(4));
                    writer.Write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x86, 0x00 });
                    writer.Write(new byte[]
                                 { 0xE5, 0xBE, 0xAE, 0xE8, 0xBD, 0xAF, 0xE9, 0x9B, 0x85, 0xE9, 0xBB, 0x91 });
                    writer.Write(new byte[] { 0x00, 0x00, 0x03, 0x00, 0xCB, 0x02 });
                    writer.Write(new byte[] { 0x00, 0x2A });
                    writer.Write(guid);
                    writer.Write(new byte[] { 0x04, 0x00, 0x04 });
                    writer.Write(new byte[]
                        {
                            0x9B, 0x53, 0xB0, 0x08, 0x05, 0x00, 0x04, 0xD9, 0x8A, 0x5A, 0x70, 0x06, 0x00,
                            0x04, 0x00, 0x00, 0x00, 0x50, 0x07, 0x00, 0x01, 0x43, 0x08, 0x00, 0x00, 0x09, 0x00, 0x01,
                            0x01,
                            0x0B,
                            0x00, 0x00, 0x14, 0x00, 0x04, 0x11, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x00, 0x02,
                            0xBC,
                            0x16,
                            0x00, 0x04, 0x00, 0x00, 0x02, 0xBC, 0x18, 0x00, 0x04, 0x00, 0x00, 0x7D, 0x5E, 0xFF, 0x00,
                            0x5C,
                            0x15,
                            0x36, 0x20, 0x39, 0x32, 0x6B, 0x41, 0x31, 0x43, 0x39, 0x62, 0x35, 0x33, 0x62, 0x30, 0x30,
                            0x38,
                            0x64,
                            0x39, 0x38, 0x61, 0x35, 0x61, 0x37, 0x30
                        });
                    writer.Write(new byte[]
                        {
                            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x35, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20,
                            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
                        });
                    writer.Write(guid);
                    writer.Write(0x41);
                    break;
                }

                case MessageType.AddGroup:
                {
                    writer.Write(new byte[] { 0x08 });
                    writer.BEWrite(group);
                    writer.Write(new byte[] { 0x01 });
                    writer.BEWrite((ushort)user.AddFriend_0020Value.Length);
                    writer.Write(user.AddFriend_0020Value);
                    writer.Write(new byte[] { 0x00, 0x00, 0x00 });
                    //备注信息
                    var messageData = Encoding.UTF8.GetBytes(snippet.Content);
                    writer.BEWrite((ushort)messageData.Length);
                    writer.Write(messageData);
                    writer.Write(new byte[] { 0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x09 });
                    break;
                }

                case MessageType.GetGroupImformation:
                {
                    writer.Write(new byte[] { 0x72 });
                    writer.BEWrite(group);
                    break;
                }

                case MessageType.ExitGroup:
                {
                    writer.Write(new byte[] { 0x09 });
                    writer.BEWrite(group);
                    break;
                }

                case MessageType.Normal:
                {
                    writer.Write((byte)0x2A);
                    writer.BEWrite(group);
                    var messageData = Encoding.UTF8.GetBytes(snippet.Content);
                    writer.BEWrite((ushort)(messageData.Length + 56));
                    writer.Write(new byte[]
                        {
                            0x00, 0x01, _packetCount, _packetIndex, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x53,
                            0x47, 0x00,
                            0x00, 0x00, 0x00, 0x00
                        });
                    writer.BEWrite(dateTime);
                    writer.Write(Util.RandomKey(4));
                    writer.Write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x86, 0x00 });
                    writer.Write(new byte[] { 0x00, 0x0C });
                    writer.Write(new byte[]
                                 { 0xE5, 0xBE, 0xAE, 0xE8, 0xBD, 0xAF, 0xE9, 0x9B, 0x85, 0xE9, 0xBB, 0x91 });
                    writer.Write(new byte[] { 0x00, 0x00 });
                    writer.Write(new byte[] { 0x01 });
                    writer.BEWrite((ushort)(messageData.Length + 3));
                    writer.Write(new byte[] { 0x01 });
                    writer.BEWrite((ushort)messageData.Length);
                    writer.Write(messageData);
                    break;
                }

                case MessageType.Emoji:
                {
                    writer.Write((byte)0x2A);
                    writer.BEWrite(group);
                    var messageData = Encoding.UTF8.GetByteCount(snippet.Content);
                    writer.BEWrite((ushort)(messageData + 56));
                    writer.Write(new byte[]
                        {
                            0x00, 0x01, _packetCount, _packetIndex, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x53,
                            0x47, 0x00,
                            0x00, 0x00, 0x00, 0x00
                        });
                    writer.BEWrite(dateTime);
                    writer.Write(Util.RandomKey(4));
                    writer.Write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x86, 0x00 });
                    writer.Write(new byte[] { 0x00, 0x0C });
                    writer.Write(new byte[]
                                 { 0xE5, 0xBE, 0xAE, 0xE8, 0xBD, 0xAF, 0xE9, 0x9B, 0x85, 0xE9, 0xBB, 0x91 });
                    writer.Write(new byte[] { 0x00, 0x00 });
                    var faceIndex = byte.Parse(snippet.Content);
                    writer.Write(new byte[] { 0x02, 0x00, 0x14, 0x01, 0x00, 0x01 });
                    writer.Write(faceIndex);
                    writer.Write(new byte[] { 0xFF, 0x00, 0x02, 0x14 });
                    writer.Write((byte)(faceIndex + 65));
                    writer.Write(new byte[] { 0x0B, 0x00, 0x08, 0x00, 0x01, 0x00, 0x04, 0x52, 0xCC, 0x85, 0x50 });
                    break;
                }

                default:
                {
                    throw new NotImplementedException();
                }
                }

                ret.Add(writer.BaseStream.ToBytesArray());
                writer = new BinaryWriter(new MemoryStream());
            }

            return(ret);
        }