//QQ农牧场快手
//支持自动登录的QQ农场、牧场辅助工具

import win.ui;
import win.ole.image;
import inet.url;
var qq,password;	//QQ登号码、密码

var autoLogin = false;  //是否自动登录并操作
var tray;		//win.util.tray对象，用于自动登录模式时在任务栏右下角上显示信息
var response;		//最后一次网络请求的返回的数据

var urlOfMyFarm;	//我的农场URL
var urlOfFriendFarmList;	//好友农场列表URL
var urlOfMyPasture;	//我的牧场URL
var urlOfFriendPastureList;	//好友牧场列表URL

var sid;		//SessionID
/*DSG{{*/
var winform = win.form(parent=...; text="QQ农牧场快手";bottom=438;max=false;right=351;border="thin" )
winform.add( 
btnAutoLogin={ bottom=38;text="自动";left=294;top=13;font=LOGFONT( name="SimSun";h=-12 );z=12;right=341;cls="button" };
txtVerify={ disabled=1;bottom=79;right=238;left=138;top=55;font=LOGFONT( name="SimSun";h=-12 );z=9;cls="edit";text="";edge=1;hide=1 };
txtQQ={ bottom=39;right=120;left=39;top=15;font=LOGFONT( name="SimSun";h=-12 );z=3;tabstop=1;text="";edge=1;cls="edit" };
txtDebug={ vscroll=1;text="";left=356;multiline=1;top=2;font=LOGFONT( name="SimSun";h=-12 );bottom=435;z=8;right=852;hscroll=1;edge=1;cls="edit" };
static={ right=80;bottom=40;text="QQ:";left=15;top=19;font=LOGFONT( name="SimSun";h=-12 );transparent=1;z=2;cls="static" };
static2={ right=195;bottom=38;text="密码:";left=127;top=20;font=LOGFONT( name="SimSun";h=-12 );transparent=1;z=4;cls="static" };
btnVerifyOK={ disabled=1;bottom=80;right=329;left=244;top=54;font=LOGFONT( name="SimSun";h=-12 );z=7;text="确定验证码";cls="button";hide=1 };
lblLink={ notify=1;color=16711680;text="使用快手(AAuto Quicker制作) 点这里获得程序源代码";left=30;top=416;font=LOGFONT( name="";h=-12 );transparent=1;bottom=434;right=331;z=10;cls="static" };
lstInfo={ right=340;bgcolor=16777215;bottom=413;text="listbox";left=11;top=92;font=LOGFONT( name="SimSun";h=-12 );vscroll=1;z=11;
items={  };edge=1;cls="listbox" };
picVerify={ bgcolor=16777215;bottom=88;right=134;border=1;top=48;font=LOGFONT( name="SimSun";h=-12 );z=1;transparent=1;text="";left=34;cls="picturebox";hide=1 };
btnLogin={ bottom=38;text="登录";left=244;top=13;font=LOGFONT( name="SimSun";h=-12 );z=6;right=291;cls="button" };
txtPwd={ bottom=38;text="";left=158;top=14;font=LOGFONT( name="SimSun";h=-12 );right=239;z=5;password=1;tabstop=1;edge=1;cls="edit" }
)
/*}}*/

/*显示消息*/
var msg = function(s){
	if(autoLogin){	//自动登录模式下不显示可视化窗口，消息在任务栏右下角处弹出
		tray.pop(s,"QQ农牧场快手");
	}
	else{	//手动登录模式下，信息在列表框里显示
		winform.lstInfo.add(s);
		winform.lstInfo.redraw();
		::SendMessageInt(winform.lstInfo.hwnd,0x115/*_WM_VSCROLL*/,0x3/*_SB_PAGEDOWN*/,0);	//自动滚动列表框到底部
	}
}

/*发送http请求*/
var request = function(url,postdata=null){
	import inet.http;
	
	var http = inet.http("");
    var data = http.down(url,postdata);
    http.close();
    
    data = string.fromto(data);  //UTF8转换为ANSI编码
    winform.txtDebug.text = "URL:" + url + '\r\n' + data;
    winform.txtDebug.redraw();
    response = data;
    sid := string.match(response,'ontimer=\\".+\\?sid=([^\\"]+)');	//Session ID使用初始化赋值(:=)仅赋值一次
    win.delay(1);	//加延时以响应可能的窗体操作
}

/*取得效验码并等待输入*/
var getVerifyCode = function(){
	import inet.http;
	import fsys;

	var url = string.match(response,'img src=\\"([^\\"]+)\\" alt=\\"验证码\\"');
	
	var http = inet.http("");
    var data = http.down(url);
    http.close();
    var tmpFile = fsys.getTempDir() + "\_verify.gif";
	string.save(tmpFile,data);	//验证码图片存为临时图片
	
	msg("请输入验证码!");

	winform.lstInfo.top = 95;
	
	winform.txtVerify.text = "";
	winform.txtVerify.disabled = 0;
	winform.btnVerifyOK.disabled = 0;
	
	winform.txtVerify.hide = 0;
	winform.txtVerify.hide = 0;
	winform.btnVerifyOK.hide = 0;
	winform.picVerify.hide = 0;
	winform.picVerify.image = tmpFile;
	winform.redraw();
}

/*进入我的农场*/
var enterFarm = function(){
	msg(" ");
	msg("========== 正在进入QQ农场 =========");
	var haveErr = false;	//进入农场时是否发生错误

	if(sid){	//如果已经获得SessionID
		var url = (urlOfMyFarm)?urlOfMyFarm:"http://farm.z.qq.com/farm/index.jsp?sid=" ++ sid ++ "&B_UID=" ++ qq;
		request(url);
		try{
			urlOfFriendFarmList = string.replace(string.match(response,'([^\\"]+)\\"\\>好友农场\\<\\/a\\>'),"@friend_list.jsp","friend_list_exp.jsp");
			//成功进入农场
			winform.txtQQ.disabled = 1;
			winform.txtPwd.disabled = 1;
			winform.btnLogin.disabled = 1;
			haveErr = false;
		}
		catch(e){
			haveErr = true;
		}
	}
	else {
		haveErr = true;	
	}
	return (!haveErr);
}

/*收获自己的菜*/
var gatherMyCrop = function(){
	msg(" ");
	msg("★ 收自己的菜");
	var count = 0;
	for s in string.gmatch( response,'([^\\"]+)\"\\>收获') { 
   		count = count + 1;
   		if(count>=2){	//不处理黄钻用户的一键收获链接
   			url = string.replace(s,"&amp;","&");
   			request(url); 
   		}
	}
	msg("收获了:" + (count>=2?count-1:0) + "块土地");	
}

/*偷好友的菜*/
var stealFriendCrop = function(){
	msg(" ");
	msg("★ 偷好友的菜");

	//获得好友列表
	request(urlOfFriendFarmList);
	urlOfMyFarm := string.match(response,'([^\\"]+)\\"\\>我的农场\\<\\/a\\>');
	var data = response;
	var page = string.match(response,"共(\d+)页");  //好友列表分页
	if(!page){
		page = string.match(response,"第1/(\d+)页");  //另一种好友列表分页形式
	}

	if(page){
		for(i=2;tonumber(page)){
			var url = urlOfFriendFarmList ++ "&pageNo=" ++ i;
			url = string.replace(url,"&amp;","&");
			request(url);
			data =string.str(data) + response;
		}	
	}

	var pattern = '\\d{1,2}\\.\\<a\\shref=\\"([^\\"]+)\\"\\>([^\\<]+)\\<\\/a\\>';
	var friendCount = 0;	//好友计数
	var gatheredFriendCount = 0;	//采摘的好友计数

	//检查每个好友的菜地
	for s,friend in string.gmatch(data,pattern) { 
		friendCount = friendCount + 1;

		var url = string.replace(s,"@index.jsp","more.jsp");
		url = string.replace(url,"&amp;","&");
		request(url);
		count = 0;  //当前好友采摘地数
		for ss in string.gmatch(response,'([^\\"]+)\\"\\>摘取\\<\\/a\\>') { 
   			ss = string.replace(ss,"&amp;","&");
   			request(ss);   //摘取
   			if(string.match(response,"你成功摘取好友的")){  //没摘取成功则不计数，防止QQ农场刷新问题导致误报
   				count = count + 1;
   			}
		} 
		if(count>0){
			gatheredFriendCount = gatheredFriendCount + 1;
			msg("光顾好友“" + friend + "”的农场，收获 " + count + " 块地");
		}
		else{
			msg("光顾好友“" + friend + "”的农场");
		}
	}
	msg(" ");
	msg("共有 " + friendCount + " 个好友，收获了 " + gatheredFriendCount + " 个好友的菜");		
}

/*进入我的牧场*/
var enterPasture = function(){
	msg(" ");
	msg("========== 正在进入QQ牧场 =========");
	var haveErr = false;	//进入牧场时是否发生错误
	if(sid){	//如果已经获得SessionID
		var url = (urlOfMyPasture)?urlOfMyPasture:"http://mc.z.qq.com/mc/main.jsp?sid=" ++ sid ++ "&B_UID=" ++ qq;
		request(url);
		try{
			urlOfFriendPastureList = string.replace(string.match(response,'([^\\"]+)\\"\\>好友牧场\\<\\/a\\>'),"op=1","op=0");
			urlOfFriendPastureList = string.replace(urlOfFriendPastureList,"&amp;","&");
			//成功进入牧场
			winform.txtQQ.disabled = 1;
			winform.txtPwd.disabled = 1;
			winform.btnLogin.disabled = 1;
			haveErr = false;
		}
		catch(e){
			haveErr = true;
		}
	}
	else {
		haveErr = true;	
	}
	return (!haveErr);
}

/*收获自己的产品*/
var gatherMyProduct = function(){
	msg(" ");
	msg("★ 收自己的产品");
	var count = 0;
	for s in string.gmatch( response,'([^\\"]+)\"\\>收获') { 
   		count = count + 1;
   		if(count>=2){
   			url = string.replace(s,"&amp;","&");
   			request(url); 
   		}
	}
	msg("收获了:" + (count>=2?count-1:0) + "类产品");	
}

/*偷好友的产品*/
var stealFriendProduct = function(){
	msg(" ");
	msg("★ 偷好友的产品");

	//获得好友列表
	request(urlOfFriendPastureList);
	urlOfMyPasture := string.replace(string.match(response,'([^\\"]+)\\"\\>我的牧场\\<\\/a\\>'),"&amp;","&");
	var data = response;
	var page = string.match(response,"共(\d+)页");  //好友列表分页
	if(!page){
		page = string.match(response,"第1/(\d+)页");  //另一种好友列表分页形式
	}

	if(page){
		for(i=2;tonumber(page)){
			var url = urlOfFriendPastureList ++ "&pageNo=" ++ i;
			url = string.replace(url,"&amp;","&");
			request(url);
			data =string.str(data) + response;
		}	
	}

	var pattern = '\\d{1,2}\\.\\<a\\shref=\\"([^\\"]+)\\"\\>([^\\<]+)\\<\\/a\\>';
	var friendCount = 0;	//好友计数
	var gatheredFriendCount = 0;	//收获的好友计数

	//检查每个好友的牧场
	for s,friend in string.gmatch(data,pattern) { 
		friendCount = friendCount + 1;

		var url = s + "&a=1";
		url = string.replace(url,"&amp;","&");
		request(url);
		count = 0;  //当前好友产品类数
		for ss in string.gmatch(response,'([^\\"]+)\\"\\>收获\\<\\/a\\>') { 
   			count = count + 1;
   			if(count>=2){
   				ss = string.replace(ss,"&amp;","&");
   				request(ss); 
   			}
		} 
		if(count>0){
			gatheredFriendCount = gatheredFriendCount + 1;
			msg("光顾好友“" + friend + "”的牧场，收获 " + (count-1) + " 类产品");
		}
		else{
			msg("光顾好友“" + friend + "”的牧场");
		}
	}
	msg(" ");
	msg("共有 " + friendCount + " 个好友，收获了 " + gatheredFriendCount + " 个好友的产品");
}

/*收获*/
var gather = function(){
	try{	//农场中的操作
		if(enterFarm()){ 	//如果进入农场成功则收自己的菜
			gatherMyCrop();
		}
	
		if(urlOfFriendFarmList){	//如果已经获得好友列表地址，则开始偷好友的菜
			stealFriendCrop();
		}
	}
	
	try{	//牧场中的操作
		if(enterPasture()){ 	//如果进入牧场成功则收自己的产品
			gatherMyProduct();
		}
	
		if(urlOfFriendPastureList){	//如果已经获得好友列表地址，则开始偷好友的产品
			stealFriendProduct();
		}
	}	

	//进入农场或牧场失败
	if(string.match(response,"@busy.jsp")){
		msg("目前摘菜的人过多，请稍后再试!");
	}
	elseif(string.match(response,"密码错误")){
		msg("QQ号码或密码错误!");	
	}
	elseif(string.match(response,"验证码不正确")){
		msg("验证码不正确!");
		getVerifyCode();
	}

	msg("------------- 本次任务结束 -------------");
	var url = "http://qzone.z.qq.com/logout.jsp?sid=" + tostring(sid);
	request(url);
	msg(" ");
	msg("退出QQ登录");
	msg("更多功能请下载源码自行修改:)");
	
	
	urlOfMyFarm = null;
	urlOfFriendFarm = null;
	
	urlOfMyPasture = null;
	urlOfFriendPastureList = null;

	
	winform.txtQQ.disabled = 0;
	winform.txtPwd.disabled = 0;
	winform.btnLogin.disabled = 0;
	winform.btnAutoLogin.disabled = 0;	
}

/*------------------------------ 窗体事件处理 --------------------------------*/
winform.btnVerifyOK.oncommand = function(id,event){
	winform.txtVerify.disabled = 1;
	winform.btnVerifyOK.disabled = 1;
	
	winform.txtVerify.hide = 1;
	winform.txtVerify.hide = 1;
	winform.btnVerifyOK.hide = 1;	
	winform.picVerify.hide = 1;
	winform.lstInfo.top = 44;
	winform.redraw();
	
	try{
		var verify = winform.txtVerify.text;
		var pattern = '\\<go href=\\"([^\\"]+)\\"[^\\<]+\\'
			+ '<postfield name=\\"qq\\" value=[^\\<]+'
			+ '\\<postfield name=\\"extend\\" value=\\"([^\\"]+)[^\\<]+'
			+ '\\<postfield name=\\"r_sid\\" value=\\"(\\d+)[^\\<]+'
			+ '\\<postfield name=\\"nb\\" value=\\"([^\\"]+)[^\\<]+'
			+ '\\<postfield name=\\"modifySKey\\" value=\\"([^\\"]+)[^\\<]+'
			+ '\\<postfield name=\\"verify\\"';
		var s,extend,r_sid,nb,modifySKey = string.match(response,pattern) ;
		extend = inet.url.encode(extend) ;
		extend = string.replace(extend,"@%2E",".");
		var postdata = "qq=" + qq + "&"
			+ "extend=" + extend + "&"
			+ "r_sid=" + r_sid + "&"
			+ "nb=" + nb + "&"
			+ "modifySKey=" + modifySKey + "&"
			+ "verify=" + verify;
		request(s,postdata);
	}
	gather();
}

winform.btnLogin.oncommand = function(id,event){
	winform.btnLogin.disabled = 1;
	winform.btnAutoLogin.disabled = 1;
	winform.lstInfo.clear();
	winform.lstInfo.redraw();
	qq = winform.txtQQ.text;
	password = winform.txtPwd.text;
	if(qq==""||password==""){
		win.msgbox("请输入QQ号码及密码!","提示");
		return;
	}
	sid = null;
	request("http://qzone.z.qq.com/login.jsp");
    var url,mkey = string.match(response,'([^\\"]+)\\" method=\\"post\\"\\>.+name=\\"mkey\\" value=\\"([^\\"]+)');
	var postdata = "qq=" ++ qq ++ "&pwd=" ++ password + "&mkey=" + mkey;
	
	request(url,postdata);

	if(string.match(response,"@需要进行安全验证")){
		getVerifyCode();
		return;
	}
	gather();
}//endproc

winform.btnAutoLogin.oncommand = function(id,event){
	qq = winform.txtQQ.text;
	password = winform.txtPwd.text;
	if(qq!=""&&password!=""){
		import string.xxtea;
		import string.base64;
		var encryptedPassword = string.base64.encode(string.xxtea.encrypt(password,qq));
		var file = io.open(io.fullpath("\AutoLogin.dat"),"w");
		file.write(qq,'\r\n',encryptedPassword);
		file.close();
		win.msgbox('下次运行将以当前登录信息自动开始操作!\r\n删除应用程序文件夹下的“AutoLogin.dat”文件将取消自动功能。',"提示");
	}
	else{
		win.msgbox("请输入QQ号码及密码!","提示");
		return;
	}
	
}//endproc

import win.cur; 
var hand = win.cur.load(32649/*_IDC_HAND*/ )
winform.lblLink.wndproc = function(hwnd,message,wparam,lparam){
	if( message = 0x200/*_WM_MOUSEMOVE*/ )
		win.cur.setCur(); 
}//endproc

winform.lblLink.oncommand = function(id,event){
	import process;
	process.execute("http://www.ecranesoft.com/");
}//endproc

//---------------------------------------------------------------------------------

var filename  = io.fullpath("\AutoLogin.dat");
if(io.exist(filename)){		//检查是否存在自动登录信息文件AutoLogin.dat
	var haveErr = false;
	var file = io.open(filename,"r");
	try{

		winform.txtQQ.text = string.trim(file.read());
		
		import string.xxtea;
		import string.base64;

		winform.txtPwd.text = string.xxtea.decrypt(string.base64.decode(string.trim(file.read())),winform.txtQQ.text);

		haveErr = false;
	}
	catch(e){
		win.msgbox("自动登录文件已经被破坏！请删除文件:“AutoLogin.dat”","警告");
		haveErr = true;
	}
	if(file){
		file.close();
	}
	if(!haveErr){	//自动登录
		autoLogin = true;
		
		import win.util.tray;
		tray = win.util.tray(winform.hwnd,130/*_IDI_MYICON*/);		//创建Tray图标
		
		winform.btnLogin.oncommand();	//调用“登录”按钮事件
		
		win.delay(5000);
		tray.delete();	//删除Tray图标
		return;  //退出应用程序
	}
}

//等待手工登录
winform.text = "QQ农牧场快手 V20101008 - by roking";
winform.show();
winform.lstInfo.top = 44;

win.loopMessage();
return winform;
