Funkcja łączy się z serwerem GG, loguje się na nim, pobiera opis dla podanego numeru i kończy połączenie. W przypadku powodzenia całości operacji funkcja zwraca opis. W przypadku niepowodzenia funkcja zwróci wartość "(bool) false" i w zmiennej podanej jako ostatni, czwaty argument umieści komunikat o błędzie jaki zaistniał.
Szczegóły parametrów do przekazania jak i wyniku działania funkcji znajdują się w jej komentarzu.
Funkcja wymaga zdefiniowania stałych wartości używanych w protokole GaduGadu. Nie są one umieszczone w funkcji, by uniknąć komunikatu o błędzie ponownego deklarowania stałych w przypadku, gdy funkcja zostanie wywołana wielokrotnie w jednym skrypcie.
Dwie uwagi końcowe:
- ilość znaków jaka jest wycinana ze zwracanego opisu (ostatnia linijka funkcji) jest dobrana eksperymentalnie i jak narazie nie znalazłem innego lepszego) rozwiązania na pozbycie się znaków znajdujących się na początku zwracanego przez serwer wyniku.
- Funkcja nie jest przystosowana do odbioru wielu statusów w jednym połączeniu. By ją do tego przystosować należy odpowiednio zmienić wywołanie funkcji (np. przekazać tablicę z numerami, a nie wartość INT i w linii 126 zmienić format pakietu zgodnie ze specyfikacją dostępną na stronie projektu EKG (
http://dev.null.pl/ekg/docs/protocol.html#ch1.11 )
(Kod wydzielony z tematu
Skrypty do generowania sygnaturek, na grafikach)
<?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 koment
rza
* Kod jest udostępniony na zasadach OpenSource.
*
* @author: Krzysztof Andrzej Błachut vel Bakus <bakus@idn.net.pl>
* @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;
}
return $hash;
}
/* Funkcja pobiera z serwera GaduGadu opis dla podanego numeru.
*
* @param int Numer GG \"bramki\"
* @param string Hasło GG \"bramki\"
* @param int Numer GG, którego opis funkcja ma pobrać
* @param var Zmienna w której umieszczony będzie ewentualny komunikat błęd
* @return mixed Zawiera Opis numeru GG, lub false w przypadku błędu
*/
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.0rn\";
$get.= \"Host: appmsg.gadu-gadu.plrn\";
$get.= \"User-Agent: Mozilla/4.7 [en] (Win98; I)rn\";
$get.= \"Pragma: no-cachernrn\";
preg_match(\"/s([d.]{8,16}):([d]{1,5})s/\", $buf, $adres); $host = $adres[1];
$port = $adres[2];
}
// Ustanawianie połączenia z serwerem GG
$fp = fsockopen($host, $port, $errno, $errstr, 10
); if (!$fp)
{
$error = \"PROBLEM Z POLACZENIEM: $errno - $errstrnn\";
return false;
}
if (!$data = fread($fp, 12
)) {
$error = \"Polaczenie nieoczekiwanie zamknietenn\";
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
if (!$data1 = fread($fp, 8
)) {
$error = \"Nie rozpoznany bladn\";
return false;
}
$tab = unpack(\"Vlogin_status/Vrozmiar\", $data1); if($tab['login_status'] != GG_LOGIN_OK)
{
$error = \"Nie prawidłowe hasło...nn\";
return false;
}
// Wysłanie listy kontaktów z jednym numerem
$data = pack (\"VVVC\",GG_NOTIFY, 5, $szukany_numer, GG_USER_NORMAL); {
$error = \"Blad wysylania listy kontaktownn\";
return false;
}
// Odebranie pakietu ze specyfikacją następnego pakietu
$tab = unpack(\"Vtyp/Vrozmiar\", $data); // Pobranie pakietu opisu
$data = fread($fp, $tab['rozmiar']); // Zamknięcie połączenia z serwerem
$tablica = unpack(\"Iuin/Cstatus/Iremoteip/Sremoteport/Cversion/Cimagesize/Cunknown/Cdescription_size/a*\", $data); return $tablica[1];
}
?>
UpDated (07.10.2004 01:07):
Zmieniłem "return substr($status_kontaktu, 15);" na nieco bardziej zaawansowany i skuteczny sposób wycinania niechcianych znaków...
Dzięki temu opisy nie są ucinane i nie zawierają śmieci...
UpDated (08.02.2005 14:45):
Coraz częściej dostaje PW o sposób użycia, więc...
Sposób użycia - wyświetlenie opisu numeru 1234567 (nasz numer to 2358764, a haslo to: zxcdews):
<?php
print get_gg_status
(\"2358764\", \"zxcdews\", \"1234567\", $error); ?>
UpDated (10.02.2005 04:31):
Status wyświetlany jest bez żadnych krzaków - zmianie uległ sposób wyciągania opisu z pakietu odbieranego z serwera...
UpDated (10.02.2005 05:16):
Zoptymalizowałem wyciąganie opisu z pakietu do 1 polecenia unpack...