C# WebQQ协议群发机器人(一)
|
admin
2016年12月23日 18:55
本文热度 5877
|
原创性申明本文地址 http://blog.csdn.net/zhujunxxxxx/article/details/38931287 转载的话请注明出处! 之前我也写过一篇使用Python来实现的一个版本 点击打开链接 前言现在我用c#语言改写过后也放出源码来让大家学习,希望大家喜欢,不懂的相互交流, 目前我实现的一些功能包括 第一次登录 二次登陆 获取群信息 获取群好友 发送群消息 发送消息给好友 先给出一些webqq的一些参数吧 如果有人需要源码可以联系我 qq: 10588690,但是不是无偿提供,请大家理解。 协议分析psessionid 这个是在第二次登录的时候在 cookie中的一个重要的值,在后面获取群信息,获取好友信息等 都要用到这个参数 vfwebqq 这个同上 ptwebqq 同上 hash 这个参数是后面发送群消息和好友消息需要用到的,以前版本没有 后面加上了 先给出腾讯密码加密算法 这部分我是用我以前python版本的 比较懒这部分没有转为c#版本的 -
- def PCMd5(self,s):
- h=hashlib.md5()
- h.update(s)
- return h.hexdigest()
-
- def hex2asc(self,s):
- _str="".join(s.split(r''\x''))
- length=len(_str)
- data=''''
- for i in range(0,length,2):
- data+=chr(int(_str[i:i+2],16))
- return data
-
- def PasswordSecret(self,password,v1,v2,md5=True):
- if md5==True:
- password=self.PCMd5(password).upper()
- length=len(password)
- temp=''''
- for i in range(0,length,2):
- temp+=r''\x''+password[i:i+2]
- return self.PCMd5(self.PCMd5(self.hex2asc(temp)+self.hex2asc(v2)).upper()+v1).upper()
Hash算法然后给的是hash算法 -
-
-
-
-
-
- public string Hash(string b, string j)
- {
- string a = j + "password error";
- string i = "";
- List<int> E = new List<int>();
- while(true)
- {
- if (i.Length <= a.Length)
- {
- i += b;
- if (i.Length == a.Length)
- {
- break;
- }
- }
- else
- {
- i = i.Substring(0, a.Length);
- break;
- }
-
- }
- for (int c = 0; c < i.Length; c++)
- {
- int tmp = (char)i[c] ^ (char)a[c];
- E.Add(tmp);
- }
- string[] seed = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};
- i = "";
- for (int c = 0; c < E.Count; c++)
- {
- i += seed[E[c] >> 4 & 15];
- i += seed[E[c] & 15];
- }
-
- return i;
- }
这个函数的参数是 第一个是你的qq号 第二个是ptwebqq 之前一直以为是vfwebqq 结果一直出错 这两个函数都是正确的,网上很多的方法已经失效了 是否需要验证码首先在登录时,你必须检查是否需要输入验证码 这个函数的返回值是一个字符串 ptui_checkVC(''0'',''!NTZ'',''\x00\x00\x00\x00\x22\x79\x9f\x0d'', ''ef0e577a40249cc2b77dc9f266a3a4141a987d06a8f3ae39117183f1ff0491720e1f6f498a9a038f032d99f8622ea628''); 第一个参数是0 表示不需要输入参数,第二个参数是一个验证码 后面用来加密密码的 -
- public bool check()
- {
- string url = "https://ssl.ptlogin2.qq.com/check?uin={$uin}&appid=1003903&js_ver=10092&js_type=0&login_sig=K5F0E8woS74td4sRIqKiSHmH6B2RYYP467z2r*6YWaH4wc7vE*4G*X7V2kGP9s1*&u1=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html&r=0.2689784204121679";
- url = url.Replace("{$uin}", this.qq);
- HttpItem item = new HttpItem()
- {
- URL = url,
- Encoding = System.Text.Encoding.GetEncoding("utf-8"),
- Method = "get",
- IsToLower = false,
- Timeout = 100000,
- ReadWriteTimeout = 30000,
- UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0",
- ContentType = "application/x-www-form-urlencoded",
- ResultType = ResultType.String,
- };
- HttpResult result = http.GetHtml(item);
- Regex reg = new Regex(@"ptui_checkVC′(.∗)′,′(.∗)′,′(.∗)′,′(.∗)′;");
- Match m = reg.Match(result.Html);
- string[] ret = new string[m.Groups.Count];
- for (int i = 0; i < m.Groups.Count; i++)
- {
- ret[i] = m.Groups[i].Value;
- }
- this.checkv2 = ret[3];
- if (ret[1] == "0")
- {
- this.checkcode = ret[2];
- this.session = ret[4];
- return false;
- }
- else
- return true;
- }
一次登录接下来是我们第一次登录 - public bool Login()
- {
- string url = "https://ssl.ptlogin2.qq.com/login?u={$uin}&p={$pwd}&verifycode={$verify}&webqq_type=10&remember_uin=1&login2qq=0&aid=1003903&u1=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html%3Flogin2qq%3D0%26webqq_type%3D10&h=1&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=2-9-33854&mibao_css=m_webqq&t=1&g=1&js_type=0&js_ver=10092&login_sig=K5F0E8woS74td4sRIqKiSHmH6B2RYYP467z2r*6YWaH4wc7vE*4G*X7V2kGP9s1*&pt_uistyle=5&pt_vcode_v1=0&pt_verifysession_v1={$session}";
- url=url.Replace("{$uin}",this.qq);
- url=url.Replace("{$verify}",this.checkcode);
- string pwd = encrypt.Encrypt_Password(this.qq,this.password,this.checkcode);
- url=url.Replace("{$pwd}",pwd);
- url = url.Replace("{$session}", this.session);
- HttpItem item = new HttpItem()
- {
- URL = url,
- Encoding = System.Text.Encoding.GetEncoding("utf-8"),
- Method = "get",
- IsToLower = false,
- Timeout = 100000,
- Referer="https://ui.ptlogin2.qq.com/cgi-bin/login?daid=164&target=self&style=5&mibao_css=m_webqq&appid=1003903&enable_qlogin=0&no_verifyimg=1&s_url=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html&f_url=loginerroralert&strong_login=1&login_state=10&t=20140612002",
- Host="d.web2.qq.com",
- UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0",
- ContentType = "application/x-www-form-urlencoded",
- ResultType = ResultType.String
- };
- HttpResult result = http.GetHtml(item);
-
- foreach (Cookie c in result.CookieCollection)
- {
- if (c.Name == "ptwebqq")
- this.ptwebqq = c.Value;
- }
- this.hash= Hash(this.qq, this.ptwebqq);
-
- Regex reg = new Regex(@"ptuiCB′(.∗)′,′(.∗)′,′(.∗)′,′(.∗)′,′(.∗)′,\s′(.∗)′;");
- Match m = reg.Match(result.Html);
- string[] ret = new string[m.Groups.Count];
- for (int i = 0; i < m.Groups.Count; i++)
- {
- ret[i] = m.Groups[i].Value;
- }
- if (ret[1] == "0")
- {
- this.proxyurl = ret[3];
- return true;
- }
- else
- return false;
-
- }
第一次登录后会返回 return ptuiCB(''0'',''0'',''http://ptlogin4.web2.qq.com/check_sig?pttype=1&uin=578395917&service=login&nodirect=0&ptsig=uV34Xt9XM3e2oQ3wuub8LIBIGsIIZATjiz-cqSVHJ5o_&s_url=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html%3Flogin2qq%3D0%26webqq_type%3D10&f_url=&ptlang=2052&ptredirect=100&aid=1003903&daid=164&j_later=0&low_login_hour=0®master=0&pt_login_type=1&pt_aid=0&pt_aaid=0&pt_light=0'',''0'',''登录成功!'', ''你的名字'');
如果第一个参数不是0的话 表示有错,如果像这样的话就表示成功了 返回结果中的那个ur链接我们用get方式打开它,这个步骤是为了获取一个关键的cookie值 p_skey 这个是第二次登录的时候有用 二次登陆接下来是我们二次登录了 - public void Login2()
- {
-
- Dictionary<string, Object> r = new Dictionary<string, Object>();
- r.Add("status", "online");
- r.Add("ptwebqq", this.ptwebqq);
- r.Add("passwd_sig", "");
- r.Add("clientid", this.clientid.ToString());
- r.Add("psessionid", null);
- Dictionary<string, Object> data = new Dictionary<string, Object>();
- data.Add("r", JsonConvert.SerializeObject(r));
- data.Add("clientid", this.clientid);
- data.Add("psessionid", "null");
- string postdata = Tool.MakePostData(data);
-
-
-
-
- HttpItem item = new HttpItem()
- {
- URL = "http://d.web2.qq.com/channel/login2",//URL 必需项
- Method = "POST",
- IsToLower = false,
- Timeout = 100000,
- Postdata=postdata,
- Host=HOST[0],
- Referer=REFERER[0],
- UserAgent = "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36",
- ContentType = "application/x-www-form-urlencoded",
- Accept="*/*",
- ResultType = ResultType.String
- };
- HttpResult result = http.GetHtml(item);
- JObject obj = (JObject)JsonConvert.DeserializeObject(result.Html);
- this.vfwebqq= obj["result"]["vfwebqq"].ToString();
- this.psessionid = obj["result"]["psessionid"].ToString();
-
- }
这个步骤很重要,获取很多有用的cookie值,上面提到的那些就要用一个变量保存下来,以便后面使用
获取群列表下面我们就要拉去我们的群组信息了 这个返回结果是一个json格式的,我们需要序列化为json对象,把里面的群相关信息存起来 -
-
-
- public void GetGroupNameList()
- {
-
- Dictionary<string, Object> r = new Dictionary<string, Object>();
- r.Add("hash", this.hash);
- r.Add("vfwebqq", this.vfwebqq);
- Dictionary<string, Object> data = new Dictionary<string, Object>();
- data.Add("r", JsonConvert.SerializeObject(r));
- string postdata = Tool.MakePostData(data);
-
-
-
-
- HttpItem item = new HttpItem()
- {
- URL = "http://s.web2.qq.com/api/get_group_name_list_mask2",
- Method = "POST",
- IsToLower = false,
- Timeout = 100000,
- Postdata = postdata,
- Host = HOST[1],
- Referer = REFERER[1],
- UserAgent = "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36",
- ContentType = "application/x-www-form-urlencoded",
- ResultType = ResultType.String
- };
- HttpResult result = http.GetHtml(item);
- JObject ret = (JObject)JsonConvert.DeserializeObject(result.Html);
- JObject retjson = (JObject)ret["result"];
- foreach (JToken jk in retjson["gnamelist"])
- {
- this.grouplist.Add(jk["gid"].ToString()+":"+jk["code"].ToString(), jk["name"].ToString());
- }
-
- }
每个群 有个gid 和code name 其中获取群成员的使用code 而向群发送消息的时候用的是gid 这部分一定要注意 我花了很多时间才发现自己的错误
群信息获取某个群的群成员信息 参数就是上面提到的code 不要用错了哦 -
-
-
-
- public void GetGroupInfo(string gcode)
- {
- string url = "http://s.web2.qq.com/api/get_group_info_ext2?gcode={$gcode}&cb=undefined&vfwebqq={$vfwebqq}&t=1409316979595";
- url=url.Replace("{$vfwebqq}",this.vfwebqq);
- url = url.Replace("{$gcode}", gcode);
-
- HttpItem item = new HttpItem()
- {
- URL = url,
- Encoding = System.Text.Encoding.GetEncoding("utf-8"),
- Method = "get",
- IsToLower = false,
- Timeout = 100000,
- ReadWriteTimeout = 30000,
- Host=HOST[1],
- Referer=REFERER[1],
- UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0",
- ContentType = "application/x-www-form-urlencoded",
- ResultType = ResultType.String,
- };
- HttpResult result = http.GetHtml(item);
- JObject ret = (JObject)JsonConvert.DeserializeObject(result.Html);
- JObject retjson = (JObject)ret["result"];
- foreach (JToken jk in retjson["cards"])
- {
- this.groupinfo.Add(jk["muin"].ToString(), jk["card"].ToString());
- }
- }
发送群消息下面是向群里面发送消息 这个用的就是刚才说的 gid 也不要用错了- public void SendGroupMsg(long groupid,string msg)
- {
- string style="\"{content}\"";
- string temp="";
- temp += style.Replace("{content}", msg) + ",";
- temp = temp.Substring(0, temp.Length - 1);
- Random rd = new Random();
- int msg_id = (rd.Next(100000) + 100000);
- string content="[{$msg},\"\",[\"font\",{\"name\":\"宋体\",\"size\":\"10\",\"style\":[0,0,0],\"color\":\"000000\"}]]";
- content = content.Replace("{$msg}", temp);
-
- Dictionary<string, Object> r = new Dictionary<string, Object>();
- r.Add("group_uin", groupid);
- r.Add("content", content);
- r.Add("msg_id", msg_id);
- r.Add("clientid", this.clientid);
- r.Add("psessionid",this.psessionid);
- Dictionary<string, Object> data = new Dictionary<string, Object>();
- data.Add("r", JsonConvert.SerializeObject(r));
- data.Add("clientid", this.clientid);
- data.Add("psessionid", this.psessionid);
- string postdata = Tool.MakePostData(data);
-
- HttpItem item = new HttpItem()
- {
- URL = "http://d.web2.qq.com/channel/send_qun_msg2",
- Accept="*/*",
- Method = "POST",
- IsToLower = false,
- KeepAlive=true,
- Timeout = 100000,
- Postdata = postdata,
- Host = HOST[0],
- Referer = REFERER[0],
- UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2041.4 Safari/537.36",
- ContentType = "application/x-www-form-urlencoded",
- ResultType = ResultType.String
- };
- HttpResult result = http.GetHtml(item);
- JObject ret = (JObject)JsonConvert.DeserializeObject(result.Html);
-
-
-
- }
接下来还有 获取好友信息和 向好友发送消息...
这一部分我放在下一篇将 头昏啊!sorry!
该文章在 2016/12/23 18:55:57 编辑过
|
|