import win.ui; import process; import console; /*DSG{{*/ mainForm = win.form(text="SmartQQ--by Danboy";right=543;bottom=490;max=false) mainForm.add( button={cls="button";text="扫码登录";left=48;top=435;right=174;bottom=462;ah=1;aw=1;z=10}; edit={cls="edit";left=242;top=26;right=523;bottom=113;ah=1;aw=1;bgcolor=16053492;edge=1;multiline=1;style=1539;z=1}; groupbox={cls="groupbox";left=7;top=0;right=218;bottom=467;ah=1;aw=1;bgcolor=15793151;edge=1;z=2}; groupbox2={cls="groupbox";text="消息群发:";left=226;top=10;right=537;bottom=167;ah=1;aw=1;edge=1;z=7}; groupbox3={cls="groupbox";text="消息接收";left=224;top=187;right=537;bottom=467;ah=1;aw=1;edge=1;z=9}; phtoplus={cls="plus";left=12;top=6;right=50;bottom=44;ah=1;aw=1;z=3}; qrplus={cls="plus";left=20;top=260;right=210;bottom=429;ah=1;aw=1;foreRepeat="center";z=5}; richedit={cls="richedit";left=227;top=201;right=534;bottom=463;ah=1;aw=1;bgcolor=16053492;multiline=1;vscroll=1;wrap=1;z=11}; send={cls="button";text="发送";left=345;top=124;right=422;bottom=162;ah=1;aw=1;z=8}; static={cls="static";left=65;top=28;right=207;bottom=42;ah=1;aw=1;transparent=1;z=6}; treeview={cls="treeview";left=7;top=49;right=216;bottom=463;ah=1;asel=false;aw=1;bgcolor=15856113;edge=1;hide=1;style=256;vscroll=1;z=4} ) /*}}*/
mainForm.button.oncommand = function(id,event){ thread.set("runStart",true); }
mainForm.wndproc = function(hwnd,message,wParam,lParam){ if wParam == 0xF060/*_SC_CLOSE*/ process().terminate(); } mainForm.enableDpiScaling(); mainForm.show();
mainForm.qrplus.foreground = "\res\alloylogo.png"; import win.ui.statusbar; win.ui.statusbar(mainForm).addItem('源码请访问:http://bbs.aardio.com/', 520/*宽度*/);
while ! thread.get("runStart") { win.delay(1000); }
import fsys; fsys.delete( {"C:\二维码.png";"C:\phto.png";"C:\phtos.png"}); var http = com.CreateObject("WinHttp.WinHttpRequest.5.1"); http.setOption(4,13056); //忽略错误标志 http.SetTimeouts(10000,100000,10000,10000 ); //设置超时 var t = tostring(math.random()) ++ tostring(math.random(10, 99)); http.Open("GET","https://ssl.ptlogin2.qq.com/ptqrshow?appid=501004106&e=0&l=M&s=5&d=72&v=4&t=0" ++ t , false); http.Send(); var stream = com.CreateObject("Adodb.Stream"); stream.Type = 1; stream.Mode = 3; stream.Open(); stream.Write( { _safearray = http.ResponseBody } ); //aardio13.52后版本可以直接写成:stream.Write(http.ResponseBody) stream.SaveToFile("C:\二维码.png",2); stream.Close(); mainForm.qrplus.foreground = "C:\二维码.png";
var qrsig = string.match(http.GetResponseHeader("Set-Cookie"),"qrsig=(.+?);"); import web.script; var js = web.script("JavaScript"); var hash33 = /* function hash33(o) { for (var t = 0, e = 0, n = o.length; e < n; ++e) t += (t << 5) + o.charCodeAt(e); return 2147483647 & t } hash33(" */ var ptqrtoken = js.Eval(hash33 ++ qrsig ++ '")'); var nickname; while true { http.Open("GET",'https://ssl.ptlogin2.qq.com/ptqrlogin?u1=http%3A%2F%2Fw.qq.com%2Fproxy.html&ptqrtoken=' ++ ptqrtoken ++ '&ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-1504153382266&js_ver=10228&js_type=1&login_sig=&pt_uistyle=40&aid=501004106&daid=164&mibao_css=m_webqq&',false); http.Send(); //响应信息,判断是二维码状态(是否失效、认证)和首次登录 win.delay(1000); if string.indexOf(http.ResponseText,"登录成功") { var checkUrl = string.match(http.ResponseText,"(http.+?)',"); nickname = string.left(string.split(http.ResponseText,"<'登录成功!', '>")[2],string.len(string.split(http.ResponseText,"<'登录成功!', '>")[2]) - 5,true); //登录的QQ昵称 http.setOption(6,0); //禁止自动重定向 http.Open("GET",checkUrl,false); http.Send(); //检测登录 break ; } elseif string.indexOf(http.ResponseText,"二维码已失效") { mainForm.msgbox("二维码已失效,请重试"); process().terminate(); } } var uin,skey,p_uin,p_skey,pt4_token = string.match(http.GetAllResponseHeaders(),"uin=(.+?);.+?skey=(.+?);.+?p_uin=(.+?);.+?p_skey=(.+?);.+?pt4_token=(.+?);"); var cookie = "uin=" ++ uin ++ "; skey=" ++ skey ++ "; p_uin=" ++ p_uin ++ "; p_skey=" ++ p_skey ++ "; pt4_token=" ++ pt4_token ++ "; ptwebqq=" ++ qrsig; //须加qrsig thread.set("cookie",cookie);
http.Open("GET",'http://s.web2.qq.com/api/getvfwebqq?ptwebqq=&clientid=53999199&psessionid=&t=1504250606785',false); http.SetRequestHeader("Referer", 'http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1'); http.SetRequestHeader("Cookie","uin=" ++ uin ++ "; skey=" ++ skey ++ "; p_uin=" ++ p_uin ++ "; p_skey=" ++ p_skey ++ "; pt4_token=" ++ pt4_token ++ ";"); http.Send(); import web.json; var vfwebqq = web.json.parse(http.ResponseText)["result"]["vfwebqq"]; //取得vfwebqq
//二次登录 http.Open("POST",'http://d1.web2.qq.com/channel/login2',false); http.SetRequestHeader("Referer", 'http://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2'); http.SetRequestHeader("Cookie",cookie); http.Send('r={"ptwebqq":"","clientid":53999199,"psessionid":"","status":"online"}'); var psessionid,QQ = web.json.parse(http.ResponseText)["result"]["psessionid"],web.json.parse(http.ResponseText)["result"]["uin"]; thread.set("psessionid",psessionid); thread.set("QQ",QQ);
var gethash = /* var hash2 = function(uin,ptvfwebqq){ uin += ""; var ptb = []; for (var i=0;i<ptvfwebqq.length;i++){ var ptbIndex = i%4; ptb[ptbIndex] ^= ptvfwebqq.charCodeAt(i); } var salt = ["EC", "OK"]; var uinByte = []; uinByte[0] = (((uin >> 24) & 0xFF) ^ salt[0].charCodeAt(0)); uinByte[1] = (((uin >> 16) & 0xFF) ^ salt[0].charCodeAt(1)); uinByte[2] = (((uin >> 8) & 0xFF) ^ salt[1].charCodeAt(0)); uinByte[3] = ((uin & 0xFF) ^ salt[1].charCodeAt(1)); var result = []; for (var i=0;i<8;i++){ if (i%2 == 0) result = ptb[i>>1]; else result = uinByte[i>>1]; } return byte2hex(result);
}; var byte2hex = function(bytes){//bytes array var hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']; var buf = "";
for (var i=0;i<bytes.length;i++){ buf += (hex[(bytes>>4) & 0xF]); buf += (hex[bytes & 0xF]); } return buf; } hash2(" */ var hash = js.Eval(gethash ++ QQ ++ '","' + qrsig + '")'); //获取hash
http.Open("GET", 'http://d1.web2.qq.com/channel/get_online_buddies2?vfwebqq=' + vfwebqq + '&clientid=53999199&psessionid=' + psessionid + '&t=1505017526904',false) http.SetRequestHeader("Referer", 'http://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2'); http.SetRequestHeader("Cookie",cookie); http.Send(); //获取登录状态 if string.indexOf(http.ResponseText,"online") { mainForm.static.text = nickname; mainForm.button.hide = 1; } else { mainForm.msgbox("登录失败,请重新尝试"); process().terminate(); }
http.Open("POST",'http://s.web2.qq.com/api/get_user_friends2',false); //取好友列表 http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded"); http.SetRequestHeader("Referer", 'http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1'); http.SetRequestHeader("Cookie",cookie); http.Send('r={"vfwebqq":"' + vfwebqq + '","hash":"' + hash + '"}'); var friendtab = web.json.parse(http.ResponseText); for i=1;#friendtab["result"]["categories"] - 1 { //分组名排序 for j=i+1;#friendtab["result"]["categories"] { if tonumber(friendtab["result"]["categories"]["sort"]) > tonumber(friendtab["result"]["categories"][j]["sort"]) { table.insert(friendtab["result"]["categories"],friendtab["result"]["categories"][j],i); table.remove(friendtab["result"]["categories"],j+1); } } } var hitem = mainForm.treeview.insertItem(text = "QQ好友"); var qqfs0 = mainForm.treeview.insertItem({text = "我的好友"},hitem); var qqfstab,uintab,gidtab = {},{},{}; table.push(qqfstab,qqfs0); for i=1;#friendtab["result"]["categories"] { //挑出各分组成员名 var qqfs1 = mainForm.treeview.insertItem({text = friendtab["result"]["categories"]["name"]},hitem); //分组名加到QQ好友根组下 table.push(qqfstab,qqfs1); for j=1;#friendtab["result"]["friends"] { if ! friendtab["result"]["friends"][j] continue ; if friendtab["result"]["friends"][j]["categories"] == friendtab["result"]["categories"]["index"] { //分组 for k=1;#friendtab["result"]["marknames"] { if friendtab["result"]["marknames"][k]["uin"] == friendtab["result"]["friends"][j]["uin"] { table.push(uintab,friendtab["result"]["marknames"][k]["markname"],friendtab["result"]["friends"][j]["uin"]); mainForm.treeview.insertItem({friendtab["result"]["marknames"][k]["markname"]},qqfs1); friendtab["result"]["friends"][j] = null; break ; } } for k=1;#friendtab["result"]["info"] { if ! friendtab["result"]["friends"][j] continue ; if friendtab["result"]["info"][k]["uin"] == friendtab["result"]["friends"][j]["uin"] { table.push(uintab,friendtab["result"]["info"][k]["nick"],friendtab["result"]["friends"][j]["uin"]) mainForm.treeview.insertItem({friendtab["result"]["info"][k]["nick"]},qqfs1); } } } elseif i == 1 ? friendtab["result"]["friends"][j]["categories"] == "0" { //我的好友 for k=1;#friendtab["result"]["marknames"] { if friendtab["result"]["marknames"][k]["uin"] == friendtab["result"]["friends"][j]["uin"] { table.push(uintab,friendtab["result"]["marknames"][k]["markname"],friendtab["result"]["friends"][j]["uin"]); mainForm.treeview.insertItem({friendtab["result"]["marknames"][k]["markname"]},qqfs0); friendtab["result"]["friends"][j] = null; break ; } } for k=1;#friendtab["result"]["info"] { if ! friendtab["result"]["friends"][j] continue ; if friendtab["result"]["info"][k]["uin"] == friendtab["result"]["friends"][j]["uin"] { table.push(uintab,friendtab["result"]["info"][k]["nick"],friendtab["result"]["friends"][j]["uin"]); mainForm.treeview.insertItem({friendtab["result"]["info"][k]["nick"]},qqfs0); } } } } }
http.Open("POST",'http://s.web2.qq.com/api/get_group_name_list_mask2',false); //取群列表 http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded"); http.SetRequestHeader("Referer", 'http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1'); http.SetRequestHeader("Cookie",cookie); http.Send('r={"vfwebqq":"' + vfwebqq + '","hash":"' + hash + '"}'); var grouptab = web.json.parse(http.ResponseText); var hitemq = mainForm.treeview.insertItem(text = "QQ群组"); for i=1;#grouptab["result"]["gnamelist"] { table.push(gidtab,grouptab["result"]["gnamelist"]["name"],grouptab["result"]["gnamelist"]["gid"]); mainForm.treeview.insertItem({grouptab["result"]["gnamelist"]["name"]},hitemq); } table.push(qqfstab,hitemq); thread.set("uintab",uintab); thread.set("gidtab",gidtab);
import win.ui.ctrl.treeviewex; //调用树形控件扩展库实现节点自选择--carl论坛坛主的 var treeviewEx = win.ui.ctrl.treeviewex(mainForm.treeview) treeviewEx.onnotify = function(id,code,ptr) { /*响应通知*/ return treeviewEx.exOnnotify(id,code,ptr); }; treeviewEx.exIsToggle = true;//开启点击节点时折叠的就展开,展开的就折叠,默认已开启 treeviewEx.exIsChecked = true;//开启1.打勾节点则全选所有子节点,不打勾则全不选子节点,2.子节点其中一个打勾,则父节点打勾,默认已开启
mainForm.threadCallable(); //多线程操作界面线程 thread.invoke( function(mainForm){ import win.ui; import com; import web.json; import console; import thread.table; var cookie = thread.get("cookie"); var uintab,gidtab = thread.get("uintab"),thread.get("gidtab"); var psessionid,QQ = thread.get("psessionid"),thread.get("QQ"); var http = com.CreateObject("WinHttp.WinHttpRequest.5.1"); http.setOption(4,13056); //忽略错误标志--不知道有什么用,该报错还是会报错而中断程序,只能加try了 http.SetTimeouts(10000,100000,10000,10000 ); //设置超时 mainForm.qrplus.hide = 1; mainForm.treeview.hide = 0; function GetLogo(){ try { http.Open("GET", 'https://q.qlogo.cn/g?b=qq&nk=' + QQ + '&s=100&t=1505017526894',false); //取QQ头像 http.Send(); } catch (e) { GetLogo(); } } GetLogo(); var stream = com.CreateObject("Adodb.Stream"); stream.Type = 1; stream.Mode = 3; stream.Open(); stream.Write( { _safearray = http.ResponseBody } ); stream.SaveToFile("C:\phto.png",2); stream.Close(); import gdip.image; var image = gdip.image("C:\phto.png"); image = image.getThumbnail(0.4,0.4,true); image.save("C:\phtos.png"); mainForm.phtoplus.foreground = "C:\phtos.png"; while true { try { //发送心跳包接收消息 http.Open("POST",'http://d1.web2.qq.com/channel/poll2',false); http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded"); http.SetRequestHeader("Referer", 'http://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2'); http.SetRequestHeader("Cookie",cookie); http.Send('r={"ptwebqq":"","clientid":53999199,"psessionid":"' + psessionid + '","key":""}'); if http.ResponseText { var nametab = thread.table("nametab"); var msg = web.json.parse(http.ResponseText)["result"][1]["value"]["content"][2] var uin = web.json.parse(http.ResponseText)["result"][1]["value"]["from_uin"] var name; if string.indexOf(http.ResponseText,'"message"') { //QQ好友消息 for k,v in uintab { if v = uin name = uintab[k-1] } for k,v in nametab.each() { if v = name { mainForm.richedit.log("QQ好友-" + name + ': ' + msg,'\r\n'); break ; } } } elseif string.indexOf(http.ResponseText,"group_message") { //QQ群组消息 for k,v in gidtab { if v = uin name = gidtab[k-1] } for k,v in nametab.each() { if v = name { mainForm.richedit.log("QQ群组-" + name + ': ' + msg,'\r\n'); break ; } } } if mainForm.richedit.getLength() > 2000 mainForm.richedit.clear(); } sleep(500); } } },mainForm )
mainForm.send.oncommand = function(id,event){ for i=1;#qqfstab { if mainForm.treeview.getChecked(qqfstab) { for hItem in mainForm.treeview.each(qqfstab){ if mainForm.treeview.getChecked(hItem) { var name = mainForm.treeview.getItemText(hItem); for k,v in uintab { if v = name { //发送QQ好友消息 var buf = 'r={"to":' + uintab[k+1] +',"content":"[\\"' + mainForm.edit.text +'\\",[\\"font\\",{\\"name\\":\\" 宋体\\",\\"size\\":10,\\"style\\":[0,0,0],\\"color\\":\\"000000\\"}]]","face":0,"clientid":53999199,"msg_id":20610002,"psessionid":"' + psessionid + '"}' http.Open("POST",'http://d1.web2.qq.com/channel/send_buddy_msg2',false); http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded"); http.SetRequestHeader("Referer", 'http://d1.web2.qq.com/cfproxy.html?v=20151105001&callback=1'); http.SetRequestHeader("Cookie",cookie); http.Send(buf); } } for k,v in gidtab { if v = name { //发送QQ群组消息 var buf = 'r={"group_uin":' + gidtab[k+1] +',"content":"[\\"' + mainForm.edit.text +'\\",[\\"font\\",{\\"name\\":\\" 宋体\\",\\"size\\":10,\\"style\\":[0,0,0],\\"color\\":\\"000000\\"}]]","face":0,"clientid":53999199,"msg_id":20610001,"psessionid":"' + psessionid + '"}' http.Open("POST",'http://d1.web2.qq.com/channel/send_qun_msg2',false); http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded"); http.SetRequestHeader("Referer", 'http://d1.web2.qq.com/cfproxy.html?v=20151105001&callback=1'); http.SetRequestHeader("Cookie",cookie); http.Send(buf); } } } } } } }
import thread.table; tmid = mainForm.addtimer( //多线程用不了treeview控件的each函数,只能用定时器处理了.... 500/*毫秒*/, function(hwnd,msg,id,tick){//定时执行代码 var nametab = thread.table("nametab",true); for i=1;#qqfstab { if mainForm.treeview.getChecked(qqfstab) { for hItem in mainForm.treeview.each(qqfstab){ if mainForm.treeview.getChecked(hItem) { var name = mainForm.treeview.getItemText(hItem); nametab.push(name); } } } } } );
return win.loopMessage();
|