WEBQQ的PHP版本实现

异步挂起实现:使用fsockopen访问启动qq在线的web地址,无需等待直接返回,qq在线的web地址就使用while来获取qq返回的聊天信息(qq.class.php  main 方法)

不用CURL,不需要额外开启PHP的组件非常方便。
qq.class.php

<?php

set_time_limit(0);

ignore_user_abort(true);

require_once('./common.php');

require_once('./db.class.php');

define('IN_QQ',true);



class qqclient{



private $setopt = array(

'port'=>80,

'host'=>'d.web2.qq.com',

'userAgent'=>'Mozilla/5.0 (Windows NT 6.1; rv:10.0) Gecko/20100101 Firefox/10.0',

'timeOut'=>16,

'useCookie'=>true,

'getmsg'=>'/channel/poll2',

'putmsg'=>'',

'uid'=>'',

'pwd'=>'',

'checkhost'=>'ptlogin2.qq.com',

'runTime'=>300,

);



public function __set($property,$value){

$this->$property = $value;

if($property == 'u')$this->setopt['uid'] = $this->u;

}

public function __get($property){

return $this->$property;

}



function __construct($setopt=array()){

$this->setopt = array_merge($this->setopt,$setopt);

if(@$setopt['uid'])$this->u = $setopt['uid'];

}



public function check($host = null , $url = null , $port = 80){

$host = isset($host) ? $host : $this->setopt['checkhost'];

$url = isset($url) ? $url : '/check?uin=' . $this->setopt['uid'] . '&appid=1003903&r='.rand();

$port = $port ? $port : $this->setopt['port'];

$this->check = $this->get( $host , $url , $port );

return $this;

}



public function verify(){

$out = $this->_parsmResult($this->body);

$this->verify = array();

$this->verify['state'] = $out[1][0];

$this->verify['code'] = $out[1][1];

return $this;

}



public function verifycode(){

$t = $this->get('captcha.qq.com','/getimage?aid=1003903&r='. rand() .'&uin='. $this->setopt['uid'] .'&vc_type='.$this->setopt['code']);

if($t){

header('Content-Type: image/jpeg');

echo $this->body;

}

}



public function login(){

$this->info = array();

if(getCache('live'.$this->u,time()+86400)){

$this->info['statusCode'] = '300';

$this->info['message'] = 'QQ已经登录了!请勿反复登录';

}else{

$url = "/login?u={$this->u}&p={$this->p}&verifycode={$this->v}&remember_uin=1&aid=1003903&u1=http%3A%2F%2Fweb2.qq.com%2";

$url .= "Floginproxy.html%3Fstrong%3Dtrue&h=1&ptredirect=0&ptlang=2052&from_ui=1&pttype=1&dumy=&fp=loginerroralert";

$this->setclientid()->get('Qq279495496.qq.com',$url);

$msg = $this->_parsmResult($this->body);

if($msg[1][0]==0){

$this->loginqq();

}else{

$this->info['statusCode'] = '300';

$this->info['message'] = $msg[1][count($msg[1])-1];

}

}

return $this->info;

}



public function progress($host,$url,$port = 80){

$this->get($host,$url,$port,'',true);

}



public function main(){

$clientid = $this->getclientid();

$psessionid = $this->getResult('psessionid');

$data = array(

'r'=>'{"clientid":"'.$clientid.'","psessionid":"'.$psessionid.'","key":0,"ids":[]}',

'clientid'=>$clientid,

'psessionid'=>$psessionid,

);

writeCache('live'.$this->u,time());

$this->msgid = $this->generateCode(7);

$this->rc = $this->generateCode(5);

$time = time();

while(true){

$this->flushmsg();

try{

if(!getCache('live'.$this->u,time()+86400))exit;

$msg = $this->post('d.web2.qq.com','/channel/poll2',80,$data);

if($msg){

$header = split("\r\n\r\n",$msg);$this->header = $header[0];unset($header[0]);$msg = join('',$header);

$msg = json_decode($msg);

if(@$msg->retcode == 0){

$this->putmsg($msg);

}elseif(@$msg->retcode == 103){

purgeCache('live'.$this->u);

exit;

}

}

}catch(Exception $e){



}

if( (time() - $time ) > $this->setopt['runTime'] ){

$this->progress($this->phost,$this->pmain,$this->pport);exit;}

}

}



private function putmsg($msg){

$clientid = $this->getclientid();

$psessionid = $this->getResult('psessionid');

foreach($msg->result as $value){

if($value->poll_type == 'message'){

$this->msgid += 1;

$from_uin = $value->value->from_uin;

unset($value->value->content[0]);

$sendmsg = $this->getKeyword(preg_replace("/\[.*?\]/si","",join('',$value->value->content)));

$tmp["to"] = $from_uin;

$tmp["face"] = 732;

$tmp["content"] = '["'.addslashes($sendmsg).'",["font",{"name":"微软雅黑","size":"10","style": [0,0,0],"color":"000000"}]]';

$tmp["msg_id"] = $this->msgid;

$tmp["clientid"] = $clientid;

$tmp["psessionid"] = $psessionid;



$data['r'] = json_encode($tmp);;

$data['clientid'] = $clientid;

$data['psessionid'] = $psessionid;



$e = $this->post('d.web2.qq.com','/channel/send_buddy_msg2',80,$data);

}elseif($value->poll_type == 'kick_message'){

purgeCache('live'.$this->u);

exit;

}

}

}



private function getKeyword($key){

$key = trim($key);

$db = new mysql();

$preg = array();



if($key){

if(preg_match_all("/^((\w+):?)([\w\W]*)/i",$key,$preg)){

$query = $db->findOne('qqrobot_key','files,stype,cotents',"qq='{$this->u}' and keyword='".$preg[2][0]."'");

}else{

$query = $db->findOne('qqrobot_key','files,stype,cotents',"qq='{$this->u}' and keyword='".addslashes($key)."'");

}

}



if(@$query){

if(@$query['stype'] == 'normal')

return $query['cotents'];

else{

if(is_file(dirname(__FILE__).'/plugin/'.$query['files'])){

try{

if(@$preg[1][0] == @$preg[2][0]){

return $query['cotents'];

}

require_once('./plugin/'.$query['files']);

}catch(Exception $e){



}

}

if($query['cotents']) return $query['cotents'];

}

}

$query = $db->findOne('qqrobot_key','files,stype,cotents',"qq='{$this->u}' and keyword='defalut'");

return @$query['cotents'] ? $query['cotents']:"完了完了...我什么都不知道,怎么办呀!! ~~~~(>_<)~~~~ ";

}



private function flushmsg(){

$this->rc += 1;

$this->get('web.qq.com','/get_msg_tip?uin=&tp=1&id=0&retype=1&rc='.$this->rc.'&lv=3&t='.time());

}



private function loginqq(){



$cookie = $this->_getCookies();

list($t,$ptwebqq) = split('=',$cookie['ptwebqq']);

$clientid = $this->getclientid();

$data= array(

'r' => '{"status":"callme","ptwebqq":"'.$ptwebqq.'","passwd_sig":"","clientid":"'.$clientid.'","psessionid":""}',

'clientid'=> $clientid,

'psessionid' => null,

);



$data2 = "";

$this->post('d.web2.qq.com','/channel/login2',80,$data);

$body = json_decode($this->body);

if($body->retcode == 0){

writeCache('result'.$this->u,$body);

$this->progress($this->phost,$this->pmain,$this->pport);

$this->info['statusCode'] = '200';

$this->info['message'] = '登录成功!';

$this->info['callbackType'] = 'sucessCurrent';

}else{

$this->info['statusCode'] = '300';

$this->info['message'] = '未知错误!';

}

return $this->info;

}



private function setclientid($uid = null){

$uid = $uid ? $uid : $this->setopt['uid'];

writeCache('clientid'.$uid,$this->generateCode(8));

return $this;

}



private function getclientid($uid = null){

$uid = $uid ? $uid : $this->setopt['uid'];

return getCache('clientid'.$uid,time()+86400);

}



private function getResult($key){

$data = getCache('result'.$this->u,time()+86400);

if($data && $data->result->$key){

return $data->result->$key;

}

return null;

}



private function _parsmResult($text){

if(!$text)return '';

preg_match_all("/\'(.*?)\'/",$text,$out);

return $out;

}



private function get($host,$url,$port = 80,$content=array(),$quick=false){

return $this->_request('get',$host,$url,$port,$content,$quick);

}



private function post($host,$url,$port = 80,$content=array(),$quick=false){

return $this->_request('post',$host,$url,$port,$content,$quick);

}



private function _request($type,$host,$url,$port = 80,$content=array(),$quick=false){

$type = $type == 'get' ? 'GET' : 'POST';

$port = $port ? $port : $this->setopt['port'];

$content = $this->_parsmEncode($content);

$i = $this->generateCode('20000');

$fp[$i] = fsockopen($host, $port, $errno, $errstr);

if(!$fp[$i]){

$this->errno = $errno ;

$this->errstr = $errstr ;

return false;

}

fputs($fp[$i], "$type $url HTTP/1.0\r\n");

fputs($fp[$i], "Host: $host\r\n");

if($type == 'POST'){

fputs($fp[$i], "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n");

fputs($fp[$i], "Content-length: " . strlen($content) . "\r\n");

}

fputs($fp[$i], "Referer: http://d.web2.qq.com/proxy.html?v=20110331002&callback=2\r\n");

fputs($fp[$i], "Accept-Language: zh-cn,zh;q=0.5\r\n");

fputs($fp[$i], "Cookie: ".$this->getCookies()."\r\n");

fputs($fp[$i], "User-Agent: " . $this->setopt['userAgent'] . "\r\n");

fputs($fp[$i], "Connection: keep-alive\r\n\r\n");

if($type == 'POST')fputs($fp[$i], "$content\\n");else fputs($fp[$i], "\\n");

if($type == 'POST')

stream_set_timeout($fp[$i],$this->setopt['timeOut']);

if(!$quick){

$res = '';

while (!feof($fp[$i]))

$res .= fgets($fp[$i], 128);



$info=stream_get_meta_data($fp[$i]);

fclose($fp[$i]);

if(!$info['timed_out'])

{

$header = split("\r\n\r\n",$res);

$this->header = $header[0];

unset($header[0]);

$this->body = join('',$header);

$this->parseCookies();

}else{

$this->header = null;

$this->body = null;

}

return $res;

}else{

fclose($fp[$i]);

return true;

}

}



private function parseCookies(){

$header = $this->header ? split("\r\n",$this->header) : array() ;

$cookie = array();

foreach($header as $val){

if(preg_match("/^Set-Cookie/",$val)){

$t = split('; ',str_replace("Set-Cookie: ","",$val));

parse_str($t[0],$t);

$t2 = array_keys($t);

$cookie[$t2[0]] = $t2[0].'='.$t[$t2[0]];

}

}

$cache = getCache($this->setopt['uid'],time()+850);

$cache = $cache ? array_merge($cache , $cookie) : $cookie ;

writeCache($this->setopt['uid'],$cache);

return true;

}



private function _getCookies(){

return getCache($this->setopt['uid'],time()+850);

}



private function getCookies(){

$cookie = $this->_getCookies();

return $this->cookies = $cookie ? join('; ',$cookie):'';

}



private function _parsmEncode($params,$isRetStr=true,$encode = false){

if(!is_array($params))return $params;

$result = $params;

if($encode){

foreach($params as $key=>$value){

$value = urlencode($value);

$result[$key] = $value;

}

}

return $isRetStr ? http_build_query($result) : $result;

}



private function generateCode($length=6) {

$chars = "0123456789";

$code = "";

while (strlen($code) < $length) {

$code .= $chars[rand(0,strlen($chars)-1)];

}

return $code;

}



}

?>

 

 剩余代码请到:http://www.qicq5.com/thread-279-1-1.html 查看

 

嘀咕cat

你可能感兴趣的:(PHP)