protected override void ParseBody(ByteBuffer buf) { #if DEBUG Client.LogManager.Log(ToString() + " Decoded Data:" + Utils.Util.ToHex(buf.ToByteArray())); #endif buf.GetChar();//length or sth.. ReplyCode = buf.Get(); int len = 0; switch (ReplyCode) { case 0x00://success! Client.LogManager.Log(ToString() + ":0x" + ReplyCode.ToString("X2") + " Login Success!"); len = buf.GetChar();//0x0020 Client.QQUser.QQKey.LoginInfo_Token = buf.GetByteArray(len); Client.QQUser.QQKey.LoginInfo_UnknowData = buf.GetByteArray(4); //buf.GetInt() Client.ServerTime = buf.GetByteArray(4); len = buf.GetChar(); Client.QQUser.QQKey.LoginInfo_Data_Token = buf.GetByteArray(len); len = buf.GetChar(); Client.QQUser.QQKey.LoginInfo_Magic_Token = buf.GetByteArray(len); Client.QQUser.QQKey.LoginInfo_Key1 = buf.GetByteArray(16); buf.GetChar();//0x00 00 if (buf.Position + 3 < buf.Length)//判断来的包是否包含LoginInfo_Key3 因为有的版本没这个key 应该说本人用的正式版本没这个 { Client.QQUser.QQKey.LoginInfo_Key3 = buf.GetByteArray(16); #if DEBUG Client.LogManager.Log(ToString() + "Client.QQUser.QQKey.LoginInfo_Key3:" + Utils.Util.ToHex(Client.QQUser.QQKey.LoginInfo_Key3)); #endif } buf.GetChar();//0x00 00 return; case 0x33: case 0x51://denied! Client.LogManager.Log(ToString() + ":0x" + ReplyCode.ToString("X2") + " Denied!"); break; case 0xBF: Client.LogManager.Log(ToString() + ":0x" + ReplyCode.ToString("X2") + " No this QQ number!"); break; case 0x34: Client.LogManager.Log(ToString() + ":0x" + ReplyCode.ToString("X2") + " Wrong password!"); break; default: Client.LogManager.Log(ToString() + ":0x" + ReplyCode.ToString("X2") + " Unknow ReplyCode!"); break; } buf.Position = 11; len =(int) buf.GetChar(); byte[] data = buf.GetByteArray(len); ReplyMessage = Utils.Util.GetString(data); Client.LogManager.Log(ToString() + ":0x" + ReplyCode.ToString("X2") + " Message Data(UTF-8): "+Utils.Util.ToHex(data)+"-->" + ReplyMessage); }
protected override void ParseBody(ByteBuffer buf) { #if DEBUG Client.LogManager.Log(ToString() + " Decoded Data:" + Utils.Util.ToHex(buf.ToByteArray())); #endif buf.GetChar();//01 66 length or sth... buf.GetChar();//01 00 Client.QQUser.QQKey.LoginInfo_Key2 = buf.GetByteArray(16); buf.Position += 8;//00 00 00 01 00 00 00 64 Client.QQUser.QQKey.LoginInfo_UnknowData2 = buf.GetByteArray(4); Client.ServerTime = buf.GetByteArray(4); Client.ClientIP = buf.GetByteArray(4); buf.GetInt();//00000000 int len = (int)buf.GetChar(); Client.QQUser.QQKey.LoginInfo_Large_Token = buf.GetByteArray(len); buf.GetInt();//???? len = (int)buf.Get(); NickName = Utils.Util.GetString(buf.GetByteArray(len)); Client.LogManager.Log(ToString() + ": Hello," + NickName); }
protected override void ParseBody(ByteBuffer buf) { #if DEBUG Client.LogManager.Log(ToString() + " " + Utils.Util.ToHex(buf.ToByteArray())); #endif buf.Get();//00 Onlines = buf.GetInt(); IP = Utils.Util.GetIpStringFromBytes(buf.GetByteArray(4));//client ip Port = (int)buf.GetChar(); buf.GetChar();//unknown 00 3c ServerTime = Utils.Util.GetDateTimeFromMillis(buf.GetInt() * 1000L); Client.LogManager.Log(ToString() + " Onlines:" +Onlines.ToString()+" IP:"+IP+" ServerTime:"+ServerTime.ToString()); }
/// <summary> /// 给定一个输入流,解析SendFileRequest结构 /// </summary> /// <param name="buf">The buf.</param> public void Read(ByteBuffer buf) { // 跳过空格符和分隔符 buf.GetChar(); // 获取后面的所有内容 byte[] b = buf.GetByteArray(buf.Remaining()); // 找到分隔符 int i = Array.IndexOf<byte>(b, 0, (byte)0x1F); // 得到文件名 FileName = Utils.Util.GetString(b, 0, i); // 得到文件大小的字符串形式 String sizeStr = Utils.Util.GetString(b, i + 1, b.Length - 6 - i); FileSize = Utils.Util.GetInt(sizeStr, 0); }
/// <summary>读取移动QQ用户消息(通过手机号描述) /// </summary> /// <param name="buf">The buf.</param> public void ReadMobileQQ2SMS(ByteBuffer buf) { // 未知1字节 buf.Get(); // 发送者,这种情况下都置为10000 Sender = 10000; // 手机号码 SenderName = Utils.Util.GetString(buf, (byte)0, 18); // 未知2字节 buf.GetChar(); // 时间 Time = (long)buf.GetInt() * 1000L; // 未知的1字节,0x03 buf.Get(); // 消息内容 Message = Utils.Util.GetString(buf, (byte)0); }
/// <summary> /// 给定一个输入流,解析FriendStatus结构 /// </summary> /// <param name="buf">The buf.</param> public void Read(ByteBuffer buf) { // 000-003: 好友QQ号 QQ = buf.GetInt(); // 004: 0x01,未知含义 Unknown1 = buf.Get(); // 005-008: 好友IP IP = buf.GetByteArray(4); // 009-010: 好友端口 Port = buf.GetUShort(); // 011: 0x01,未知含义 Unknown2 = buf.Get(); // 012: 好友状态 Status = (QQStatus)buf.Get(); // 013-014: 未知含义 Version = buf.GetChar(); // 015-030: key,未知含义 UnknownKey = buf.GetByteArray(QQGlobal.QQ_LENGTH_KEY); UserFlag = buf.GetUInt(); // 2个未知字节 Unknown3 = buf.GetUShort(); // 1个未知字节 Unknown4 = buf.Get(); buf.GetInt(); }
///// <summary> ///// QQ群列表 ///// </summary> //public List<ClusterInfo> ClusterList { get; set; } protected override void ParseBody(ByteBuffer buf) { #if DEBUG Client.LogManager.Log(ToString() + " Decoded Data:" + Utils.Util.ToHex(buf.ToByteArray())); #endif ReplyCode = buf.GetChar();//00 9C buf.GetInt();//00 00 00 00 NextPos = buf.GetUShort(); Finished = !(ReplyCode == 0x038A && NextPos > 0); //this.ClusterList = new List<ClusterInfo>(); //this.QQFriendList = new List<QQFriend>(); this.QQList = new List<QQBasicInfo>(); while (buf.Position + 2 < buf.Length) { int number = buf.GetInt(); QQType type =(QQType) buf.Get(); byte gid = buf.Get(); QQBasicInfo qq = new QQBasicInfo(number, type, ((int)gid) / 4); //qq.UIN = number; //qq.GroupId = ((int)gid) / 4; //qq.Type = (QQType)type; this.QQList.Add(qq); //if (type == 0x04) //{ // ClusterInfo ci = new ClusterInfo(); // ci.ClusterId =(uint) number;//群内部号码 // this.ClusterList.Add(ci); //} //else if (type == 0x01) //{ // QQFriend friend = new QQFriend(); // friend.QQ = number; // friend.GroupId = ((int)gid)/4; // this.QQFriendList.Add(friend); //} //else //{ // Client.LogManager.Log("unknown type: type=0x"+type.ToString("X2")+" number="+number.ToString() +" gid=0x"+gid.ToString("X2")); //} } }
/// <summary> /// 读取临时群信息 /// </summary> /// <param name="buf">The buf.</param> public void ReadTempClusterInfo(ByteBuffer buf) { Type = (ClusterType)buf.Get(); // 父群内部ID ExternalId = buf.GetUInt(); // 临时群内部ID ClusterId = buf.GetUInt(); Creator = buf.GetUInt(); AuthType = (AuthType)buf.Get(); // 未知的1字节 buf.Get(); Category = buf.GetChar(); // 群组名称的长度 int len = (int)buf.Get(); byte[] b1 = buf.GetByteArray(len); Name = Util.GetString(b1); }
protected override void ParseBody(ByteBuffer buf) { #if DEBUG Client.LogManager.Log(ToString() + " " + Utils.Util.ToHex(buf.ToByteArray())); #endif FriendQQ = buf.GetUInt(); buf.GetUInt(); buf.GetUInt(); Status = (QQStatus)buf.Get(); Client.QQUser.Friends.SetFriendStatus((int)FriendQQ, Status); ClientVersion = buf.GetChar(); UnknownKey = buf.GetByteArray(QQGlobal.QQ_LENGTH_KEY); UserFlag = buf.GetUInt(); MyQQ = buf.GetUInt(); buf.GetChar(); buf.Get(); }
/// <summary> /// 给定一个输入流,解析NormalIMHeader结构 /// </summary> /// <param name="buf">The buf.</param> public void Read(ByteBuffer buf) { // 发送者的QQ版本 SenderVersion = buf.GetChar(); // 发送者的QQ号 Sender = buf.GetInt(); // 接受者的QQ号 Receiver = buf.GetInt(); // md5处理的发送方的uid和session key,用来在传送文件时加密一些消息 FileSessionKey = buf.GetByteArray(16); // 普通消息类型,比如是文本消息还是其他什么消息 Type = (NormalIMType)buf.GetUShort(); // 消息序号 Sequence = buf.GetChar(); // 发送时间 SendTime = (long)buf.GetUInt() * 1000L; // 发送者头像 SenderHeader = buf.GetChar(); }
protected override void ParseBody(ByteBuffer buf) { #if DEBUG Client.LogManager.Log(ToString() + " " + Utils.Util.ToHex(buf.ToByteArray())); #endif SubCommand = buf.Get(); buf.GetChar();//0006 byte verify = buf.Get(); if (verify != 0) { if (buf.Position == buf.Length)//输入的验证码不正确 { //应该返回验证码不正确的消息 IsWrongVerifyCode = true; Client.LogManager.Log(ToString() + " 验证码不正确!"); return; } NeedVerify = true;//需要输入验证码 int len = buf.GetUShort(); Url = Utils.Util.GetString(buf.GetByteArray(len)); // string getQQSession = ""; // VerifyCodeFileName=Utils.Util.MapPath("\\verify\\" + Client.QQUser.QQ + ".jpg"); // Utils.Util.DownLoadFileFromUrl(url, VerifyCodeFileName, out getQQSession); //#if DEBUG // Client.LogManager.Log(ToString() + string.Format(" url:{0}, Session:{1},Code File:{2}", url, getQQSession, VerifyCodeFileName)); //#endif // Client.QQUser.QQKey.QQSessionToken = Utils.Util.GetBytes(getQQSession); } else { int len = buf.GetUShort(); Token = buf.GetByteArray(len); } }
/// <summary> /// </summary> /// <param name="buf">The buf.</param> public void Read09(ByteBuffer buf) { fontFlag = buf.GetChar(); // 分析字体属性到具体的变量 // 字体大小 FontSize = fontFlag & 0x1F; // 组体,斜体,下画线 bold = (fontFlag & 0x20) != 0; italic = (fontFlag & 0x40) != 0; underline = (fontFlag & 0x80) != 0; // 字体颜色rgb Red = (int)buf.Get(); Green = (int)buf.Get(); Blue = (int)buf.Get(); // 1个未知字节 buf.Get(); // 消息编码,这个据Gaim QQ的注释,这个字段用处不大,说是如果在一个英文windows // 里面输入了中文,那么编码是英文的,按照这个encoding来解码就不行了 // 不过我们还是得到这个字段吧,后面我们采用先缺省GBK解码,不行就这个encoding // 解码,再不行就ISO-8859-1的方式 EncodingCode = (Charset)buf.GetChar(); Encoding = Utils.Util.GetEncodingString(EncodingCode); // 字体名称,字体名称也有中文的也有英文的,所以。。先来试试缺省的 FontName = Utils.Util.GetString(buf.GetByteArray(buf.Length - buf.Position - 1)); }
protected override void ParseBody(ByteBuffer buf) { #if DEBUG Client.LogManager.Log(ToString() + " " + Utils.Util.ToHex(buf.ToByteArray())); #endif ReplyCode = buf.Get(); buf.GetInt(); switch (ReplyCode) { case 0x88: buf.GetInt();//00000003 unknown this.Level = buf.GetUShort(); this.ActiveDays = buf.GetUShort(); buf.GetChar();//unknown this.UpgradeDays = buf.GetUShort(); Client.LogManager.Log(ToString() + " " + string.Format("level:{0} active_days:{1} upgrade_days:{2}", this.Level, this.ActiveDays, this.UpgradeDays)); break; default: Client.LogManager.Log(ToString()+"unknown ReplyCode:0x"+ReplyCode.ToString("X")); break; } }
/// <summary> /// 解析包体,从buf的开头位置解析起 /// <remark>abu 2008-02-18 </remark> /// </summary> /// <param name="buf">The buf.</param> protected override void ParseBody(ByteBuffer buf) { #if DEBUG Client.LogManager.Log(ToString() + " " + Utils.Util.ToHex(buf.ToByteArray())); #endif // 操作字节,下载为0x1F SubCommand = buf.Get(); if (SubCommand == 0x1F) { // 起始好友号 BeginFrom = buf.GetUInt(); if (BeginFrom == 0x1000000) //no group labels info ?? { return; } if (BeginFrom != 0x00) { Client.LogManager.Log("BeginFrom==0x"+BeginFrom.ToString("X")); } buf.Get();//0x17 buf.GetChar(); // 循环读取各好友信息,加入到list中 Groups = new List<Group>(); while (buf.HasRemaining()) { Group g = new Group(buf); Groups.Add(g); } } }
/// <summary>检查一个包是否是tcp包 /// </summary> /// <param name="buf">The buf.</param> /// <returns>true表示是</returns> private bool CheckTcp(ByteBuffer buf) { //buffer length不大于2则连个长度字段都没有 int bufferLength = buf.Length - buf.Position; if (bufferLength < 2) return false; // 如果可读内容小于包长,则这个包还没收完 length = buf.GetChar(offset); if (length <= 0 || length > bufferLength) return false; // 再检查包头包尾 if (buf.Get(offset + 2) == QQGlobal.QQ_HEADER_BASIC_FAMILY) if (buf.Get(offset + length - 1) == QQGlobal.QQ_TAIL_BASIC_FAMILY) return true; return false; }
/// <summary> /// 给定一个输入流,解析ClusterInfo结构,这个方法适合于得到群信息的回复包 /// 2010/2/22 Veonax 修改 /// </summary> /// <param name="buf">The buf.</param> public void ReadClusterInfo(ByteBuffer buf) { ClusterId = buf.GetUInt(); ExternalId = buf.GetUInt(); Type = (ClusterType)buf.Get(); Unknown1 = buf.GetUInt(); Creator = buf.GetUInt(); AuthType = (AuthType)buf.Get(); OldCategory = buf.GetUInt(); Unknown2 = buf.GetChar(); Category = buf.GetUInt(); Unknown3 = buf.GetChar(); Unknown4 = buf.Get(); VersionId = buf.GetUInt(); // unknown' 未知的4字节 buf.GetUInt(); // 群组名称的长度 int len = (int)buf.Get(); byte[] b1 = buf.GetByteArray(len); Unknown5 = buf.GetChar(); // 群声明长度 len = (int)buf.Get(); byte[] b2 = buf.GetByteArray(len); // 群描述长度 len = (int)buf.Get(); byte[] b3 = buf.GetByteArray(len); // 转换成字符串 Name = Util.GetString(b1, "GB2312"); Notice = Util.GetString(b2, "GB2312"); Description = Util.GetString(b3, "GB2312"); }
protected override void ParseBody(ByteBuffer buf) { //怎么我得到的数据是//01 00 05 00 00 20 78 09 D7 43 99 8B DD 87 59 82 EA 85 7D 09 9A B2 92 77 53 5B 6D E3 6C B6 66 B3 21 75 6B 0B 37 85 #if DEBUG Client.LogManager.Log(ToString() + " Decoded Data:" + Utils.Util.ToHex(buf.ToByteArray())); #endif ReplyCode = buf.Get();//03: ok 04: need verifying 可是我得到的是01是由于前面错了了一个byte buf.Get();//0x00 buf.Get();//0x05 Png_Data = buf.Get(); int len = 0; if (Png_Data == 0x00 && ReplyCode == 0x01) { len = (int)buf.Get(); while (len == 0) { len = (int)buf.Get(); } } else //ReplyCode != 0x01按下面走 兼容多版本 { buf.GetInt();//需要验证码时为00 00 01 23,不需要时为全0 len=(int)buf.GetChar(); } Answer_Token = buf.GetByteArray(len); if (Png_Data== 0x01)//有验证码数据 { len = (int)buf.GetChar(); byte[] data = buf.GetByteArray(len); buf.Get(); Next = buf.Get(); string directory = Utils.Util.MapPath("/Verify/"); this.CodeFileName = Path.Combine(directory, Client.QQUser.QQ + ".png"); FileStream fs=null; if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } if (Next != 0x00) { fs = new FileStream(this.CodeFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); } else fs = new FileStream(this.CodeFileName, FileMode.Append, FileAccess.Write, FileShare.Read); //fs.Seek(0, SeekOrigin.End); fs.Write(data,0,data.Length); fs.Close(); fs=null; len = (int)buf.GetChar(); Png_Token = buf.GetByteArray(len); } // if (Png_Data!=0x00) { if (Next!=0x00) { //prot_login_request(qq, &png_token, 0, 1); Client.LogManager.Log("接收到部分验证码图片数据,继续接收...."); OutPacket outPacket = new LoginRequestPacket(Client, Png_Token, 0, 1);//发送一个请求验证码的包 Client.PacketManager.SendPacketAnyway(outPacket, QQPort.Main.Name); } else { //qq->data.verify_token = answer_token; //qqclient_set_process(qq, P_VERIFYING); Client.LoginStatus = LoginStatus.NeedVerifyCode; Client.QQUser.QQKey.Verify_Token = Answer_Token; Client.LogManager.Log("Need input Verify Code"); //Client.LoginManager.OnLoginNeedVerifyCode(e); } } else { //DBG("process verify password"); //qq->data.token_c = answer_token; //prot_login_verify(qq); Client.LogManager.Log("Process LoginRequest Success! Now Process Verify Password..."); Client.QQUser.QQKey.Answer_Token = Answer_Token; OutPacket outPacket = new LoginVerifyPacket(Client);//发送一个登陆请求包 Client.PacketManager.SendPacketAnyway(outPacket, QQPort.Main.Name); } }
/// <summary> /// 从搜索群的回复中生成一个ClusterInfo结构 /// </summary> /// <param name="buf">The buf.</param> public void ReadClusterInfoFromSearchReply(ByteBuffer buf) { ClusterId = buf.GetUInt(); ExternalId = buf.GetUInt(); Type = (ClusterType)buf.Get(); // 未知的4字节 buf.GetUInt(); Creator = buf.GetUInt(); OldCategory = buf.GetUInt(); // 未知的2字节 buf.GetChar(); // 群名称长度和群名称 int len = (int)buf.Get(); byte[] b1 = buf.GetByteArray(len); // 两个未知字节 buf.GetChar(); // 认证类型 AuthType = (AuthType)buf.Get(); // 群描述长度和群描述 len = (int)buf.Get(); byte[] b2 = buf.GetByteArray(len); Name = Util.GetString(b1); Description = Util.GetString(b2); }
protected override void ParseHeader(ByteBuffer buf) { if (!user.IsUdp) buf.GetChar(); Header = buf.Get(); Source = buf.GetChar(); Command = (QQCommand)buf.GetUShort(); Sequence = buf.GetChar(); qqNum = buf.GetUInt(); }
private static void testHet(int level, ByteBuffer b) { int p = b.Position; b.Limit = (b.Capacity); Show(level, b); output.Write(" put:"); b.PutChar((char)1); b.PutChar((char)char.MaxValue); output.Write(" char"); b.PutShort((short)1); b.PutShort((short)short.MaxValue); output.Write(" short"); b.PutInt(1); b.PutInt(int.MaxValue); output.Write(" int"); b.PutLong((long)1); b.PutLong((long)long.MaxValue); output.Write(" long"); b.PutFloat((float)1); b.PutFloat((float)float.MinValue); b.PutFloat((float)float.MaxValue); output.Write(" float"); b.PutDouble((double)1); b.PutDouble((double)double.MinValue); b.PutDouble((double)double.MaxValue); output.Write(" double"); output.WriteLine(); b.Limit = (b.Position); b.Position = (p); Show(level, b); output.Write(" get:"); ck(b, b.GetChar(), 1); ck(b, b.GetChar(), char.MaxValue); output.Write(" char"); ck(b, b.GetShort(), 1); ck(b, b.GetShort(), short.MaxValue); output.Write(" short"); ck(b, b.GetInt(), 1); ck(b, b.GetInt(), int.MaxValue); output.Write(" int"); ck(b, b.GetLong(), 1); ck(b, b.GetLong(), long.MaxValue); output.Write(" long"); ck(b, (long)b.GetFloat(), 1); ck(b, (long)b.GetFloat(), unchecked((long)float.MinValue)); ck(b, (long)b.GetFloat(), unchecked((long)float.MaxValue)); output.Write(" float"); ck(b, (long)b.GetDouble(), 1); ck(b, (long)b.GetDouble(), unchecked((long)double.MinValue)); ck(b, (long)b.GetDouble(), unchecked((long)double.MaxValue)); output.Write(" double"); output.WriteLine(); }