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); }
public static Richtext ReadRichtext(this BinaryReader reader) { return(Richtext.Parse(reader)); }
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); }
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); }
public static Richtext ReadRichtext(this BinaryReader br) { // TODO: 解析富文本 // 目前进度: 仅读取第一部分 return(Richtext.Parse(br.ReadBytes(br.BeReadChar()))); }
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); }