Пример #1
0
        public static List <byte[]> WriteRichtext(Richtext richtext)
        {
            if (richtext.Snippets.Count > 1)
            {
                if (!richtext.Snippets.TrueForAll(s =>
                                                  s.Type == MessageType.Normal || s.Type == MessageType.At || s.Type == MessageType.Emoji ||
                                                  s.Type == MessageType.Picture))
                {
                    throw new NotSupportedException("富文本中包含多个非聊天代码");
                }
            }

            // TODO: 富文本支持
            var ret = new List <byte[]>();
            var bw  = new BinaryWriter(new MemoryStream());

            foreach (var snippet in richtext.Snippets)
            {
                var list = WriteSnippet(snippet, (int)bw.BaseStream.Position);
                for (var i = 0; i < list.Count; i++)
                {
                    bw.Write(list[i]);
                    // 除最后一个以外别的都开新的包
                    //   如果有多个,那前几个一定是太长了被分段了,所以开新的包
                    //   如果只有一个/是最后一个,那就不开
                    if (i == list.Count - 1)
                    {
                        break;
                    }

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

            ret.Add(bw.BaseStream.ToBytesArray());
            return(ret);
        }
Пример #2
0
 public static Richtext ReadRichtext(this BinaryReader reader)
 {
     return(Richtext.Parse(reader));
 }
Пример #3
0
        public static Richtext Parse(BinaryReader reader)
        {
            var result = new Richtext();

            // TODO: 解析富文本
            try
            {
                var messageType = reader.ReadByte();
                var dataLength  = reader.BeReadChar();
                while (reader.BaseStream.Position + dataLength < reader.BaseStream.Length)
                {
                    reader.ReadByte();
                    switch (messageType)
                    {
                    case 0x01:     //文本消息
                    {
                        var messageStr = Encoding.UTF8.GetString(reader.ReadBytes(reader.BeReadChar()));
                        if (messageStr.Contains("@"))
                        {
                            //Reader.ReadBytes(10);
                            //var AtQQ = Util.GetQQNumRetUint(Util.ToHex(Reader.ReadBytes(4)));//被At人的QQ号
                            result.Snippets.Add(new TextSnippet(messageStr, MessageType.At));
                        }
                        else
                        {
                            result.Snippets.Add(messageStr);
                        }

                        break;
                    }

                    case 0x02:     //小黄豆表情
                    {
                        result.Snippets.Add(new TextSnippet(
                                                Util.GetQQNumRetUint(Util.ToHex(reader.ReadBytes(reader.BeReadChar()))).ToString(),
                                                MessageType.Emoji));
                        break;
                    }

                    case 0x03:     //图片
                    {
                        result.Snippets.Add(new TextSnippet(
                                                Encoding.UTF8.GetString(reader.ReadBytes(reader.BeReadChar())), MessageType.Picture));
                        break;
                    }

                    case 0x0A:     //音频
                    {
                        result.Snippets.Add(new TextSnippet(Encoding.UTF8.GetString(reader.ReadBytes(reader.BeReadChar())), MessageType.Audio));
                        break;
                    }

                    case 0x0E:     //未知
                    {
                        break;
                    }

                    case 0x14:     //XML
                    {
                        reader.ReadByte();
                        result.Snippets.Add(new TextSnippet(GZipByteArray.DecompressString(reader.ReadBytes((int)(reader.BaseStream.Length - 1))), MessageType.Xml));
                        break;
                    }

                    case 0x18:     //群文件
                    {
                        reader.ReadBytes(3);
                        var fileName = reader.ReadBytes(reader.ReadByte()); //文件名称
                        reader.ReadByte();
                        reader.ReadBytes(reader.ReadByte());                //文件大小
                        result.Snippets.Add(new TextSnippet(Encoding.UTF8.GetString(fileName),
                                                            MessageType.OfflineFile));
                        break;
                    }

                    case 0x19:     //红包秘钥段
                    {
                        if (reader.ReadByte() != 0xC2)
                        {
                            break;
                        }
                        reader.ReadBytes(19);
                        reader.ReadBytes(reader.ReadByte());                       //恭喜发财
                        reader.ReadByte();
                        reader.ReadBytes(reader.ReadByte());                       //赶紧点击拆开吧
                        reader.ReadByte();
                        reader.ReadBytes(reader.ReadByte());                       //QQ红包
                        reader.ReadBytes(5);
                        reader.ReadBytes(reader.ReadByte());                       //[QQ红包]恭喜发财
                        reader.ReadBytes(22);
                        var redId = Encoding.UTF8.GetString(reader.ReadBytes(32)); //redid
                        reader.ReadBytes(12);
                        reader.ReadBytes(reader.BeReadChar());
                        reader.ReadBytes(0x10);
                        var key1 = Encoding.UTF8.GetString(reader.ReadBytes(reader.ReadByte()));     //Key1
                        reader.BeReadChar();
                        var key2 = Encoding.UTF8.GetString(reader.ReadBytes(reader.ReadByte()));     //Key2
                        result.Snippets.Add(new TextSnippet("", MessageType.RedBag, new Tuple <string, object>("RedId", redId),
                                                            new Tuple <string, object>("Key1", key1), new Tuple <string, object>("Key2", key2)));
                        break;
                    }
                    }

                    messageType = reader.ReadByte();
                    dataLength  = reader.BeReadChar();
                }
            }
            catch (Exception ex)
            {
            }

            return(result);
        }
Пример #4
0
        public static Richtext Parse(BinaryReader reader)
        {
            var result = new Richtext();

            // TODO: 解析富文本
            try
            {
                var messageType = reader.ReadByte();
                var dataLength  = reader.BeReadUInt16();
                var pos         = reader.BaseStream.Position;
                while (pos + dataLength < reader.BaseStream.Length)
                {
                    reader.ReadByte();

                    switch (messageType)
                    {
                    case 0x01:     // 纯文本消息、@
                    {
                        var messageStr = reader.BeReadString();
                        if (messageStr.StartsWith("@") && pos + dataLength - reader.BaseStream.Position == 16)
                        {
                            reader.ReadBytes(10);
                            result.Snippets.Add(new TextSnippet(messageStr, MessageType.At,
                                                                ("Target", reader.BeReadLong32())));
                        }
                        else
                        {
                            result.Snippets.Add(messageStr);
                        }

                        break;
                    }

                    case 0x02:                 // Emoji(系统表情)
                    {
                        reader.BeReadUInt16(); // 这里的数字貌似总是1:系统表情只有208个。
                        result.Snippets.Add(new TextSnippet("", MessageType.Emoji, ("Type", reader.ReadByte())));
                        break;
                    }

                    case 0x03:     // 图片
                    {
                        result.Snippets.Add(new TextSnippet(reader.BeReadString(), MessageType.Picture));
                        break;
                    }

                    case 0x0A:     // 音频
                    {
                        result.Snippets.Add(new TextSnippet(reader.BeReadString(), MessageType.Audio));
                        break;
                    }

                    case 0x0E:     // 未知
                    {
                        break;
                    }

                    case 0x12:     // 群名片
                    {
                        break;
                    }

                    case 0x14:     // XML
                    {
                        reader.ReadByte();
                        result.Snippets.Add(new TextSnippet(
                                                GZipByteArray.DecompressString(reader.ReadBytes((int)(reader.BaseStream.Length - 1))),
                                                MessageType.Xml));
                        break;
                    }

                    case 0x18:     // 群文件
                    {
                        reader.ReadBytes(5);
                        var fileName = reader.BeReadString();    // 文件名称... 长度总是一个byte
                        reader.ReadByte();
                        reader.ReadBytes(reader.ReadByte());     // 文件大小
                        result.Snippets.Add(new TextSnippet(fileName, MessageType.OfflineFile));
                        break;
                    }

                    case 0x19:     // 红包秘钥段
                    {
                        if (reader.ReadByte() != 0xC2)
                        {
                            break;
                        }

                        reader.ReadBytes(19);
                        reader.ReadBytes(reader.ReadByte());                       // 恭喜发财
                        reader.ReadByte();
                        reader.ReadBytes(reader.ReadByte());                       // 赶紧点击拆开吧
                        reader.ReadByte();
                        reader.ReadBytes(reader.ReadByte());                       // QQ红包
                        reader.ReadBytes(5);
                        reader.ReadBytes(reader.ReadByte());                       // [QQ红包]恭喜发财
                        reader.ReadBytes(22);
                        var redId = Encoding.UTF8.GetString(reader.ReadBytes(32)); //redid
                        reader.ReadBytes(12);
                        reader.ReadBytes(reader.BeReadUInt16());
                        reader.ReadBytes(0x10);
                        var key1 = Encoding.UTF8.GetString(reader.ReadBytes(reader.ReadByte()));     //Key1
                        reader.BeReadUInt16();
                        var key2 = Encoding.UTF8.GetString(reader.ReadBytes(reader.ReadByte()));     //Key2
                        result.Snippets.Add(new TextSnippet("", MessageType.RedBag, ("RedId", redId),
                                                            ("Key1", key1), ("Key2", key2)));
                        break;
                    }
                    }

                    reader.ReadBytes((int)(pos + dataLength - reader.BaseStream.Position));
                    messageType = reader.ReadByte();
                    dataLength  = reader.BeReadUInt16();
                    pos         = reader.BaseStream.Position;
                }
            }
            catch (Exception ex)
            {
            }

            // 移除所有空白的片段
            result.Snippets.RemoveAll(s => s.Type == MessageType.Normal && string.IsNullOrEmpty(s.Content));

            // 若长度大于1,那么应该只含有普通文本、At、表情、图片。
            // 虽然我看着别人好像视频也能通过转发什么的弄进来,但是反正我们现在不支持接收音视频,所以不管了
            return(result.Snippets.Count > 1 && result.Snippets.Any(s =>
                                                                    s.Type != MessageType.Normal && s.Type != MessageType.At &&
                                                                    s.Type != MessageType.Emoji && s.Type != MessageType.Picture)
                ? throw new NotSupportedException("富文本中包含多个非聊天代码")
                : result);
        }
Пример #5
0
 public static Richtext ReadRichtext(this BinaryReader br)
 {
     // TODO: 解析富文本
     // 目前进度: 仅读取第一部分
     return(Richtext.Parse(br.ReadBytes(br.BeReadChar())));
 }
Пример #6
0
 public static Richtext ReadRichtext(this BinaryReader Reader, byte _messageType, Richtext result)
 {
     // TODO: 解析富文本
     try
     {
         var Data      = Reader.ReadBytes(Reader.BeReadChar());
         var subReader = new BinaryReader(new MemoryStream(Data));
         subReader.ReadByte();
         var MessageData = subReader.ReadBytes(subReader.BeReadChar());
         if (_messageType == 0x01)//文本消息
         {
             var MessageStr = Encoding.UTF8.GetString(MessageData);
             if (MessageStr.Contains("@"))
             {
                 //Reader.ReadBytes(10);
                 //var AtQQ = Util.GetQQNumRetUint(Util.ToHex(Reader.ReadBytes(4)));//被At人的QQ号
                 result.Snippets.Add(new AtSnippet()
                 {
                     Content = MessageStr,
                     //AtQQ = AtQQ,
                     Type = Framework.MessageType.At
                 });
             }
             else
             {
                 result.Snippets.Add(new TextSnippet()
                 {
                     Content = MessageStr,
                     Type    = Framework.MessageType.Normal
                 });
             }
         }
         else if (_messageType == 0x02)//小黄豆表情
         {
             result.Snippets.Add(new TextSnippet()
             {
                 Content = Util.GetQQNumRetUint(Util.ToHex(MessageData)).ToString(),
                 Type    = Framework.MessageType.Emoji
             });
         }
         else if (_messageType == 0x03)//图片
         {
             result.Snippets.Add(new TextSnippet()
             {
                 Content = Encoding.UTF8.GetString(MessageData),
                 Type    = Framework.MessageType.Picture
             });
         }
         else if (_messageType == 0x0A)//音频
         {
             result.Snippets.Add(new TextSnippet()
             {
                 Content = Encoding.UTF8.GetString(MessageData),
                 Type    = Framework.MessageType.Audio
             });
         }
         else if (_messageType == 0x19)//红包秘钥段
         {
             var RedBagReader = new BinaryReader(new MemoryStream(MessageData));
             RedBagReader.ReadBytes(20);
             RedBagReader.ReadBytes(RedBagReader.ReadByte());                 //恭喜发财
             RedBagReader.ReadByte();
             RedBagReader.ReadBytes(RedBagReader.ReadByte());                 //赶紧点击拆开吧
             RedBagReader.ReadByte();
             RedBagReader.ReadBytes(RedBagReader.ReadByte());                 //QQ红包
             RedBagReader.ReadBytes(5);
             RedBagReader.ReadBytes(RedBagReader.ReadByte());                 //[QQ红包]恭喜发财
             RedBagReader.ReadBytes(22);
             var RedId = Encoding.UTF8.GetString(RedBagReader.ReadBytes(32)); //redid
             RedBagReader.ReadBytes(12);
             RedBagReader.ReadBytes(RedBagReader.BeReadChar());
             RedBagReader.ReadBytes(0x10);
             var Key1 = Encoding.UTF8.GetString(RedBagReader.ReadBytes(RedBagReader.ReadByte())); //Key1
             RedBagReader.BeReadChar();
             var Key2 = Encoding.UTF8.GetString(RedBagReader.ReadBytes(RedBagReader.ReadByte())); //Key2
             result.Snippets.Add(new RedBagSnippet
             {
                 RedId = RedId,
                 Key1  = Key1,
                 Key2  = Key2,
                 Type  = Framework.MessageType.RedBag
             });
         }
         var MessageType = Reader.ReadByte();
         //如果没有结束继续解析消息内容
         if (MessageType != 0x0E)
         {
             Reader.ReadRichtext(MessageType, result);
         }
     }
     catch (Exception ex)
     {
     }
     return(result);
 }