Вход Регистрация
Файл: WebIcqLite.class.php
Строк: 301
<?php
/*
* WebIcqLite: ICQ messages sender. v3.0b
* (C) 2006 Sergey Akudovich, http://intrigue.ru/
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* See http://www.gnu.org/copyleft/lesser.html
*
*/

class WebIcqLite_TLV {
    var 
$type;
    var 
$size;
    var 
$error;
    
    var 
$types = array
    (
        
'UIN'                 =>  1// 0x01
        
'DATA'                =>  2// 0x02
        
'CLIENT'            =>  3// 0x03
        
'ERROR_URL'            =>  4// 0x04
        
'RECONECT_HERE'        =>  5// 0x05
        
'COOKIE'            =>  6// 0x06
        
'SNAC_VERSION'        =>  7// 0x07
        
'ERROR_SUBCODE'        =>  8// 0x08
        
'DISCONECT_REASON'    =>  9// 0x09
        
'RECONECT_HOST'        => 10// 0x0A
        
'URL'                => 11// 0x0B
        
'DEBUG_DATA'        => 12// 0x0C
        
'SERVICE'            => 13// 0x0D
        
'CLIENT_COUNTRY'    => 14// 0x0E
        
'CLIENT_LNG'        => 15// 0x0F
        
'SCRIPT'            => 16// 0x10
        
'USER_EMAIL'        => 17// 0x11
        
'OLD_PASSWORD'        => 18// 0x12
        
'REG_STATUS'        => 19// 0x13
        
'DISTRIB_NUMBER'    => 20// 0x14
        
'PERSONAL_TEXT'        => 21// 0x15
        
'CLIENT_ID'            => 22// 0x16
        
'CLI_MAJOR_VER'     => 23// 0x17
        
'CLI_MINOR_VER'     => 24// 0x18
        
'CLI_LESSER_VER'     => 25// 0x19
        
'CLI_BUILD_NUMBER'    => 26// 0x1A
        
'PASSWORD'            => 37
    
);
    
    function 
setTLV($type$value$length false)
    {
        switch (
$length
        {
            case 
1:
                
$format 'c';
                break;
            case 
2:
                
$format 'n';
                break;
            case 
4:
                
$format 'N';
                break;
            default:
                
$format 'a*';
                break;
        }
        if (
$length === false
        {
            
$length strlen($value);
        }
        return 
pack('nn'.$format$this->types[$type], $length$value);
    }
    
    function 
getTLV($data)
    {
        
$arr unpack('n2'substr($data04));
        
$this->type $arr[1];
        
$this->size $arr[2];
        return 
substr($data4$this->size);
    }

    function 
getTLVFragment($data)
    {
        
$frg unpack('cid/cversion/nsize'substr($data04));
        
$frg['data'] = substr($data4$frg['size']);
        return 
$frg;
    }
}

class 
WebIcqLite_SNAC extends WebIcqLite_TLV {
    
    var 
$request_id 0;
    var 
$uin;
    
    function 
setSNAC0102()
    {
        
$this->request_id++;
        
$out pack('nnnN'120$this->request_id);
        
$out .= pack('n*'13272650);
        
$out .= pack('n*'21272650);
        
$out .= pack('n*'31272650);
        
$out .= pack('n*'211272650);
        
$out .= pack('n*'41272650);
        
$out .= pack('n*'61272650);
        
$out .= pack('n*'91272650);
        
$out .= pack('n*'101272650);
        
        return 
$out;
    }
    
    function 
setSNAC0406($uin$message)
    {
        
$this->request_id++;
        
$cookie microtime();
        
$out pack('nnnNdnca*'460$this->request_id$cookie2strlen($uin), $uin);
        
        
$capabilities pack('H*''094613494C7F11D18222444553540000'); // utf-8 support
        // '97B12751243C4334AD22D6ABF73F1492' rtf support
        
        
$data pack('nd'0$cookie).$capabilities;
        
$data .= pack('nnn'1021);
        
$data .= pack('nn'150);
        
$data .= pack('nnvvddnVn'10001strlen($message)+622780003$this->request_id);
        
$data .= pack('nndnn'14$this->request_id000); //45
        
$data .= pack('ncvnva*'1001, (strlen($message)+1), $message);
        
$data .= pack('H*''0000000000FFFFFF00');
        
$out .= $this->setTLV('RECONECT_HERE'$data);
        
$out .= $this->setTLV('CLIENT''');
        return 
$out;
    }
    
    function 
setSNAC0406offline($uin$message)
    {
        
$this->request_id++;
        
$cookie microtime();
        
$out pack('nnnNdnca*'460$this->request_id$cookie1strlen($uin), $uin);
        
        
$data pack('ccnc'5111);
        
$data .= pack('ccnnna*'11strlen($message)+430$message);
        
$out .= $this->setTLV('DATA'$data);
        
$out .= $this->setTLV('CLIENT''');
        
$out .= $this->setTLV('COOKIE''');
        return 
$out;
    }
    
    function 
getSNAC0407($body)
    {
        if (
strlen($body)) 
        {
            
$msg unpack('nfamily/nsubtype/nflags/Nrequestid/N2msgid/nchannel/cnamesize'$body);
            if (
$msg['family'] == && $msg['subtype'] == 7
            {
                
$body substr($body21);
                
$from substr($body0$msg['namesize']);
                
$channel $msg['channel'];
                
$body substr($body$msg['namesize']);
                
$msg unpack('nwarnlevel/nTLVnumber'$body);
                
$body substr($body4);
                for (
$i 0$i <= $msg['TLVnumber']; $i++)
                {
                    
$part $this->getTLV($body);
                    
$body substr($body$this->size);
                    if (
$channel == && $this->type == 2
                    {
                        while (
strlen($part)) 
                        {
                            
$frg $this->getTLVFragment($part);
                            if (
$frg['id'] == && $frg['version'] == 1
                            {
                                return array(
'from' => $from'message' => substr($frg['data'], 4));
                            }
                            
$part substr($part4+$frg['size']);
                        }
                        return 
false;
                    }
                }
            }
        }
        return 
false;
    }
    function 
dump($str)
    {
        
$f fopen('dump''a');
        
fwrite($f$str);
        
fclose($f);
    }
    
}

class 
WebIcqLite_FLAP extends WebIcqLite_SNAC{
    
    var 
$socet;
    var 
$command 0x2A;
    var 
$channel;
    var 
$sequence;
    var 
$body;
    var 
$info = array();

    function 
WebIcqLite_FLAP() {
        
$this->sequence rand(130000);
    }
    
    function 
getFLAP()
    {
        if(
$this->socet)
        {
            
$header socket_read($this->socet6);
            if (
$header
            {
                
$header unpack('c2channel/n2size'$header);
                
$this->channel $header['channel2'];
                
$this->body socket_read($this->socet$header['size2']);
                return 
true;
            }
            else 
            {
                return 
false;
            }
        }
    }
    
    function 
parseCookieFLAP()
    {
        
$this->getFLAP();
        
$this->info = array();
        while(
$this->body != '')
        {
            
$info $this->getTLV($this->body);
            
$key array_search($this->type$this->types);
            if(
$key)
            {
                
$this->info[$key] = $info;
            }
            
$this->body substr($this->body, ($this->size+4));
        }
    }
    
    function 
parseAnswerFLAP()
    {
        
$this->getFLAP();
        
$array unpack('n3int/Nint'$this->body);
        while (
$array['int'] != $this->request_id
        {
            
$this->getFLAP();
            
$array unpack('n3int/Nint'$this->body);
        }

        
$this->error '1'//Неизвестный ответ сервера
        
$this->oshibka='Неизвестная ошибка при проверке номера';
        if (
$array['int1'] == 4
        {
            switch (
$array['int2']) 
            {
                case 
1:
                        
$this->error '2';//Сообщение не отправлено
                        
$this->oshibka='Невозможно проверить пароль';
                        return 
false;
                    break;
                case 
0x0c:
                        return 
true;
                    break;
            }
        }

        
$this->error '3';//Неизвестный ответ сервера
        
$this->oshibka='Неизвестная ошибка при проверке номера';
        return 
false;
    }
    
    function 
prepare()
    {
        
$this->sequence++;
        
$out pack('ccnn'$this->command$this->channel$this->sequencestrlen($this->body)).$this->body;
        return 
$out;
    }
    
    function 
login($uin$password)
    {
        
$this->getFLAP();
        
$this->uin $uin;
        
$this->body .= $this->setTLV('UIN',                 "$uin");
        
$this->body .= $this->setTLV('DATA',                 $this->xorpass($password));
        
$this->body .= $this->setTLV('CLIENT',                 'ICQBasic');
        
$this->body .= $this->setTLV('CLIENT_ID',             2662);
        
$this->body .= $this->setTLV('CLI_MAJOR_VER',         202);
        
$this->body .= $this->setTLV('CLI_MINOR_VER',         342);
        
$this->body .= $this->setTLV('CLI_LESSER_VER',         02);
        
$this->body .= $this->setTLV('CLI_BUILD_NUMBER',     23212);
        
$this->body .= $this->setTLV('DISTRIB_NUMBER',         10854);
        
$this->body .= $this->setTLV('CLIENT_LNG',             'en');
        
$this->body .= $this->setTLV('CLIENT_COUNTRY',         'us');
        
        
        
$this->channel 1;
        
$pack $this->prepare();
        
socket_write($this->socet$packstrlen($pack));
        
$this->parseCookieFLAP();
        
        
$this->body 0x0000;
        
$pack $this->prepare();
        
socket_write($this->socet$packstrlen($pack));
        
$this->close();
        
        if(isset(
$this->info['RECONECT_HERE']))
        {
            
$url explode(':'$this->info['RECONECT_HERE']);
            if(!
$this->open($url))
            {
                
$this->error = isset($this->info['DISCONECT_REASON']) ? $this->info['DISCONECT_REASON'] : '4';//Не удается восстановить соеденение
                
$this->oshibka='Неудаетса востановить соединение';
                return 
false;
            }
        }
        else
        {
            
$this->error = isset($this->info['DISCONECT_REASON']) ? $this->info['DISCONECT_REASON'] : '5';//UIN заблокирован. Пожалуйста, попробуйте через 20 минут
            
$this->oshibka='Пароль неверный или UIN заблокирован';
            return 
false;
        }

        
$this->getFLAP();
        
$this->body .= $this->setTLV('COOKIE'$this->info['COOKIE']);
        
$pack $this->prepare();
        if (!
socket_write($this->socet$packstrlen($pack)))
        {
            
$this->error '6';//Cookie не отправлены, соединение закрыто сервером
            
$this->oshibka='Cookie не отправлены';
            return 
false;
        }
        
$this->getFLAP();
        
$this->body $this->setSNAC0102();
        
$pack $this->prepare();
        if (!
socket_write($this->socet$packstrlen($pack)))
        {
            
$this->error '7';//Сигнал не отправлен, соединение закрыто сервером
            
$this->oshibka='Сигнал не отправлен';
            return 
false;
        }
        return 
true;
    }
    
    function 
write_message($uin$message)
    {
        
$this->body $this->setSNAC0406($uin$message);
        
$pack $this->prepare();
        if (!
socket_write($this->socet$packstrlen($pack)))
        {
            
$this->error '8';//Сообщение не отправлено, соединение закрыто сервером
            
$this->oshibka='Сообщение не отправлено';
            return 
false;
        }
        if (! 
$this->parseAnswerFLAP()) {
            
// try to send offline message
            
            
$this->body $this->setSNAC0406offline($uin$message);
            
$pack $this->prepare();
            if (!
socket_write($this->socet$packstrlen($pack)))
            {
                
$this->error '9';//Невозможно отправить сообщение в offline, соединение закрыто сервером
                
$this->oshibka='Невозможно отправить сообщение в offline';
                return 
false;
            }
            if (! 
$this->parseAnswerFLAP()) 
            {
                return 
false;
            }
            else
            {
                
$this->error '10';//Пользователь offline. Сообщение отправлено на сервер
                
return false;
            }
        }
        
        return 
true;
    }
    
    function 
read_message()
    {
        while(
$this->getFLAP())
        {
            
$message $this->getSNAC0407($this->body);
            if(
$message){
                return 
$message;
            }
        }
        return 
false;
    }

    function 
xorpass($pass)
    {
        
$roast = array(0xF30x260x810xC40x390x860xDB0x920x710xA30xB90xE60x530x7A0x950x7c);
        
$roasting_pass '';
        for (
$i=0$i<strlen($pass); $i++) 
        {
            
$roasting_pass .= chr($roast[$i] ^ ord($pass{$i}));
        }
        return(
$roasting_pass);
    }
    
    function 
open($url = array('login.icq.com'5190))
    {
        
$this->socet socket_create(AF_INETSOCK_STREAMSOL_TCP);
        if (
$this->socet 0
        {
            
$this->error "socket_create() failed: reason: " socket_strerror($this->socet);
            return 
false;
        }
        
$result socket_connect($this->socetgethostbyname($url[0]), $url[1]);
        if (
$result 0
        {
            
$this->error "socket_connect() failed.nReason: ($result) " socket_strerror($result);
            return 
false;
        }
        return 
true;
    }

    function 
close()
    {
        return 
socket_close($this->socet);
    }
}

class 
WebIcqLite extends WebIcqLite_FLAP {

    function 
WebIcqLite ()
    {
        
$this->WebIcqLite_FLAP();
    }
    
    function 
connect($uin$pass)
    {
        if (!
$this->open()) 
        {
            return 
false;
        }
        
        return 
$this->login($uin$pass);
    }

    function 
disconnect()
    {
        return 
$this->close();
    }

    function 
get_message()
    {
        return 
$this->read_message();
    }
    
    function 
send_message($uin$message)
    {
        return 
$this->write_message($uin$message);
    }
    function 
send_sms($phpne$message)
    {
        return 
$this->write_sms($phpne$message);
    }
}
?>
Онлайн: 0
Реклама