Exemplo n.º 1
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);
        }
Exemplo n.º 2
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);
        }