[PHP] Status opisowy GG w PHP i problem z fread()

0

Witam.
Chciałbym na swojej stronie umieścić status opisowy GG. Wiem że istnieją takie strony jak http://www.maro.dolsat.pl/gg/ ale chciałbym mieć coś szybszego i niezależnego.
Myślałem o tym aby skorzystać z projektu na stronie http://gg.wha.la/ lecz niestety nie przewiduje on pobierania statusu opisowego. Używałem też (a właściwie przede wszystkim) google ;-) i naprawdę ciężko jest cokolwiek gotowego (i niegotowego) znaleźć.
Może ktoś z Was słyszał o czymś takim w php i mógłby się podzielić swoimi informacjami na ten temat?
Pozdrawiam.

0

Tam niestety slesze psują kod, nieco go poprawilem. U mnie działa.

<?php
/* Skrypt napisany w oparciu o klasę www2gg (http://gg.wha.la/)
 * i opis protokołu GaduGadu z projektu EKG (http://dev.null.pl/ekg/docs/protocol.html)
 * Kod można dowolnie wykorzystać pod warunkiem pozostawienia niniejszego komentarza
 * Kod jest udostępniony na zasadach OpenSource.
 *
 * @author: Krzysztof Andrzej Błachut vel Bakus <[email protected]>
 * @copyright: 2004-2005 by Krzysztof Andrzej Błachut vel Bakus
 * @package: OpisGG
 * @version: 1.0
 */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    function oblicz_hash ($haslo, $klucz)
    {
        $x0=0; $x1=0; $y0=0; $y1=0; $z=0; $tmp=0;
        $y0 = ($klucz << 16) >> 16; $y1 = $klucz >> 16 ;
        for ($i=0; $i<strlen($haslo); $i++)
        {
            $x0 = ($x0 & 0xFF00) | ord($haslo[$i]); $x1 &= 0xFFFF;
            $y0 ^= $x0; $y1 ^= $x1;
            $y0 += $x0; $y1 += $x1;
            $x1 <<= 8; $x1 |= ($x0 >> 8); $x0 <<= 8;
            $y0 ^= $x0; $y1 ^= $x1;
            $x1 <<= 8; $x1 |= ($x0 >> 8); $x0 <<= 8;
            $y0 -= $x0; $y1 -= $x1;
            $x1 <<= 8; $x1 |= ($x0 >> 8); $x0 <<= 8;
            $y0 ^= $x0; $y1 ^= $x1;
            $z = $y0 & 0x1F;
            $y0 &= 0xFFFF; $y1 &= 0xFFFF;
            if ($z <= 16)
            {
                $tmp= ($y1 << $z) | ($y0 >> (16-$z));
                $y0 = ($y1 >> (16-$z)) | ($y0 << $z);
                $y1 = $tmp;    
            }else{
                $tmp= $y0 << ($z-16);
                $y0 = ($y0 >> (32-$z)) | ( (($y1 << $z) >> $z) << ($z-16) );
                $y1 = ($y1 >> (32-$z)) | $tmp;
            }
            $y0 &= 0xFFFF; $y1 &= 0xFFFF;
        }
        $hash = hexdec(sprintf("%04x%04x", $y1, $y0));
        settype($hash, 'integer');
        return $hash;
    }

    function get_gg_status($numer_gg, $haslo_gg, $szukany_numer, &$error)
    {
        // Ustawianie stałych na potrzeby protokołu
        define("GG_LOGIN60",        0x0015);
        define("GG_STATUS_AVAIL",   0x0002);
        define("GG_LOGIN_OK",        0x0003);
        define("GG_NOTIFY",         0x0010);
        define("GG_USER_NORMAL",    0x0003);

        $fp = fsockopen( "appmsg.gadu-gadu.pl", 80, $errno, $errmsg, 3 );
        if (!$fp)
        {
            $error = "BRAK POLACZENA Z APPMSG.GADU-GADU.PL, MOZE BYC PRZECIAZONY: " . $errno . " - " . $errstr . "\n";
            return false;
        }else{
            $get = "GET /appsvc/appmsg.asp?fmnumber=<$numer_gg> HTTP/1.0\r\n";
            $get.= "Host: appmsg.gadu-gadu.pl\r\n";
            $get.= "User-Agent: Mozilla/4.7 [en] (Win98; I)\r\n";
            $get.= "Pragma: no-cache\r\n\r\n";
            fputs($fp, $get);
            fgets($fp, 128);
            fgets($fp, 128);
            $buf = fgets($fp, 128);
            preg_match("/\s([\d\.]{8,16})\:([\d]{1,5})\s/", $buf, $adres);
            $host = $adres[1];
            $port = $adres[2];
            fclose($fp);
        }

        $fp = fsockopen($host, $port, $errno, $errstr, 10);
        if (!$fp)
        {
            $error = "PROBLEM Z POLACZENIEM: $errno - $errstr\n\n";
            return false;
        }
        if (!$data = fread($fp, 12))
        {
            $error = "Polaczenie nieoczekiwanie zamkniete\n\n";
            return false;
        }

        // Pobieranie danych z serwera - odbiór klucza do wygenerowania hasha hasła
        $tab = unpack("Vtyp/Vrozmiar/Vklucz", $data);
        // obliczanie hasha hasła
        $hash = oblicz_hash($haslo_gg, $tab['klucz']);
        $data = pack("VVVVVVvVvVvCCa".strlen(""), GG_LOGIN60, 0x20 + strlen(""),
        $numer_gg, $hash, GG_STATUS_AVAIL, 0x20, 0, 0, 0, 0, 0, 0x14, 0xbe , "");
        // wysłanie hasha hasła
        fwrite($fp, $data);
        if (!$data1 = fread($fp, 8))
        {
            $error = "Nie rozpoznany blad\n";
            return false;
        }
        $tab = unpack("Vlogin_status/Vrozmiar", $data1);
        if($tab['login_status'] != GG_LOGIN_OK)
        {
            $error = "Nie prawidłowe hasło...\n\n";
            return false;
        }

        // Wysłanie listy kontaktów z jednym numerem
        $data = pack ("VVVC",GG_NOTIFY, 5, $szukany_numer, GG_USER_NORMAL);
        if(!fwrite($fp,$data))
        {
            $error = "Blad wysylania listy kontaktow\n\n";
            return false;
        }
        // Odebranie pakietu ze specyfikacją następnego pakietu
        $data = fread($fp, 8);
        $tab = unpack("Vtyp/Vrozmiar", $data);
        // Pobranie pakietu opisu
        $data = fread($fp, $tab['rozmiar']);
        // Zamknięcie połączenia z serwerem
        fclose($fp);
        $tablica = unpack("Iuin/Cstatus/Iremoteip/Sremoteport/Cversion/Cimagesize/Cunknown/Cdescription_size/a*", $data);
        return $tablica[1];
    }
?>
<?php
    print get_gg_status("twojnumergg", "haslo", "i od kogo pobrac opis", $error);
?>

Nie wiem, ale u mnie jest troche powolny :( 30 sekund trzeba czekac na wynik

0

Odpaliłem skrypt u siebie i muszę powiedzieć że działa w miarę szybko ale tylko w przypadku gdy dany delikwent którego chcemy sprawdzić ma rzeczywiście swój opis ustawiony. Cały problem leży w tym kawałku kodu

        // Odebranie pakietu ze specyfikacją następnego pakietu
        $data = fread($fp, 8);

problem w tym, że jeśli ktoś nie ma ustawionego opisu w strumieniu nic się nie znajduje ale mimo to funkcja fread() próbuje go odczytać - z niepowodzeniem oczywiście i na odpowiedź musimy czekać tak długo, aż minie timeout ustawiony tu

        $fp = fsockopen($host, $port, $errno, $errstr, 10);

W przypadku gdy ktoś ma ustawiony opis to funkcja fread() wykonuje mi się w 0,06 sekundy więc można ten timeout z 10 spokojnie ustawić na np. 2 ale nie wiem jak to będzie sie sprawować przy większym obciążeniu serwera gg albo mojego poza tym nie lubię takich rozwiązań :)

Czy jest jakaś inna opcja?

PS. bordeux - wielkie dzięki :)

0

ja korzystam z tego samego skryptu i zrobiłem tak:

$data = pack("VVVC", 0x10, 0x05, $szukany_numer, 0x03);
	if(!fwrite($fp, $data)) return $error;
	stream_set_timeout($fp, parsetimeout($timeout), parsetimeout($timeout, true)); // 1,5 sekundy oczekiwania
	$data = fread($fp, 8);
	$info = stream_get_meta_data($fp);
	if($info['timed_out']) { return Array(1, '', false); }
	if (strlen($data) != 8) { return $error; }
	$tab = unpack("Vtyp/Vrozmiar", $data);
	$data = fread($fp, $tab['rozmiar']);
//	$opis = 'Przykladowy opis';
//	$opisL = strlen($opis);
//	$stat = pack("VVVa$opisL", 0x2, 0x4+$opisL, 0x15, $opis);
	$stat = pack("VVV", 0x2, 0x4, 0x1);
	fwrite($fp, $stat);
	fclose($fp);

	$def = Array(
		0x002 => 'Iid/Istatus/a*descr',
		0x00c => 'Iid/Cstatus/Iremoteip/Sremoteport/Cversion/Sunknown/a*descr',
		0x00f => 'Iid/Cstatus/Iremoteip/Sremoteport/Cversion/Cimagesize/Cunknown/a*descr',
		0x011 => 'Iid/Cstatus/Iremoteip/Sremoteport/Cversion/Cimagesize/Cunknown/Cdescrsize/a*descr'
		);

	if(!array_key_exists($typ = $tab['typ'], $def)) { return $error; }
	$t = unpack($def[$typ], "$data\0");
	$descr = explode("\0", $t['descr']);
	$t['descr'] = empty($descr[0]) ? '' : $descr[0];
	if (empty($descr[1])) { $t['powrot'] = false; } else
		{
		$temp = unpack("Vpowrot",$descr[1]);
		$t['powrot'] = $temp['powrot'];
		}
	return Array($t['status'],$t['descr'],$t['powrot']);

troche sam napisałem, troche z 4p, a troche z gogla

1 użytkowników online, w tym zalogowanych: 0, gości: 1