<commit_before><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=iso-8859-2" />
<style type="text/css">
BODY { font-family: tahoma, verdana, arial, helvetica, sans-serif; }
.tab { background-color: #a0a0a0; }
.tabh { background-color: #d0d0d0; }
.tabf { background-color: white; }
.c { font-family: monospace; padding: 0.7em; background-color: #e0e0e0; border: 1px solid #a0a0a0; }
.http { font-family: monospace; padding: 0.7em; background-color: #c0f0c0; border: 1px solid #80a080; }
.example { font-family: monospace; padding: 0.7em; background-color: #c0f0f0; border: 1px solid #80a0a0; }
</style>
<title>Protok Gadu-Gadu</title>
</head>

<body bgcolor="white" text="black">

<center>
<table width="600" border="0"><tr><td>

<center>
<h1>Protok Gadu-Gadu</h1>
<h3>&copy; Copyright 2001 - 2003 <a href="#ch4">Autorzy</a></h3>
</center>

<hr />

<h2>0. Informacje wstpne</h2>

<p>
Opis protokou uywanego przez Gadu-Gadu bazuje na dowiadczeniach
przeprowadzonych przez autorw oraz informacjach nadsyanych przez 
uytkownikw. aden klient Gadu-Gadu nie zosta skrzywdzony podczas
bada. Reverse-engineering opiera si gwnie na analizie pakietw
wysyanych midzy klientem a serwerem.
</p>

<hr />

<h2>1. Protok Gadu-Gadu</h2>

<h3>1.1. Format pakietw</h3>

<p>
Podobnie jak coraz wiksza ilo komunikatorw, Gadu-Gadu korzysta z
protokou TCP/IP. Kady pakiet zawiera na pocztku dwa stae pola:
</p>

<div class="c">
<pre>struct gg_header {
	int type;	<i>/* typ pakietu */</i>
	int length;	<i>/* dugo reszty pakietu */</i>
};</pre>
</div>

<p>
Wszystkie zmienne liczbowe s zgodne z kolejnoci bajtw maszyn Intela,
czyli Little-Endian.
</p>

<p>
Przy opisie struktur, zaoono, e <tt>char</tt> ma rozmiar 1 bajtu,
<tt>short</tt> 2 bajtw, <tt>int</tt> 4 bajtw. Uywajc innych
architektur ni i386 naley zwrci szczegln uwag na rozmiar typw
zmiennych i kolejno znakw.
</p>

<p>
Pola, ktry znaczenie jest nieznane, lub nie do koca jasne, oznaczono
przedrostkiem <tt>unknown</tt>.
</p>

<hr />

<h3>1.2. Zanim si poczymy</h3>

<p>
eby wiedzie, z jakim serwerem mamy si poczy, naley poudawa przez
chwil przegldark WWW i poczy si z hostem <tt>appmsg.gadu-gadu.pl</tt>.
</p>

<div class="http">
<pre>GET /appsvc/appmsg.asp?fmnumber=<b>NUMER</b> HTTP/1.0
Host: appmsg.gadu-gadu.pl
User-Agent: Mozilla/4.7 [en] (Win98; I)
Pragma: no-cache</pre>
</div>

<p>
Oryginalny klient moe wysa jeden z podanych identyfikatorw przegldarki:
</p>

<ul>
<li><tt>Mozilla/4.04 [en] (Win95; I ;Nav)</tt></li>
<li><tt>Mozilla/4.7 [en] (Win98; I)</tt></li>
<li><tt>Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)</tt></li>
<li><tt>Mozilla/4.0 (compatible; MSIE 5.0; Windows NT)</tt></li>
<li><tt>Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt)</tt></li>
<li><tt>Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)</tt></li>
</ul>

<p>
Nowsze wersje (od 4.6.2) korzystaj z innego skryptu:
</p>

<div class="http">
<pre>GET /appsvc/appmsg2.asp?fmnumber=<b>NUMER</b>&amp;version=<b>WERSJA</b>&amp;fmt=<b>FORMAT</b>&amp;lastmsg=<b>WIADOMO</b>
Host: appmsg.gadu-gadu.pl
User-Agent: <b>PRZEGLDARKA</b>
Pragma: no-cache</pre>
</div>

<p>
Gdzie <b>NUMER</b> jest numerem klienta, <b>WERSJA</b> jest wersj klienta,
<b>FORMAT</b> okrela czy wiadomo systemowa bdzie przesyana czystym
tekstem (brak zmiennej "fmt") czy w HTMLu (jakakolwiek jej warto), a
<b>WIADOMO</b> jest numerem ostatnio otrzymanej wiadomoci systemowej.
Na postawione w ten sposb zapytanie, serwer powinien odpowiedzie
na przykad tak:
</p>

<div class="http">
<pre>HTTP/1.0 200 OK

0 192.168.127.12:8074 192.168.127.12</pre>
</div>

<p>
Pierwsze pole jest numerem wiadomoci systemowej, a drugie i trzecie
podaj nam namiary na waciwy serwer. Jeli serwer jest niedostpny,
zamiast adresu IP jest zwracany tekst ,,<tt>notoperating</tt>''.
Jeeli poczenie z portem 8074 nie powiedzie si z jakich powodw,
mona si czy na port 443. 
</p>

<p>
Jeli pierwsza liczba nie jest rwna zero, zaraz po nagwku znajduje si
wiadomo systemowa, lub jeli linia zaczyna si od znaku ,,<tt>@</tt>'',
adres strony, ktr naley otworzy w przegldarce.
</p>

<hr />

<h3>1.3. Logowanie si</h3>

<p>
Po poczeniu si portem 8074 lub 443 serwera Gadu-Gadu, dostajemy pakiet
typu <tt>0x0001</tt>, ktry na potrzeby tego dokumentu nazwiemy:
</p>

<div class="c">
<pre>#define GG_WELCOME 0x0001</pre>
</div>

<p>
Reszta pakietu zawiera liczb, na podstawie ktrej liczony jest hash z hasa
klienta:
</p>

<div class="c">
<pre>struct gg_welcome {
	int seed;	<i>/* klucz szyfrowania hasa */</i>
};</pre>
</div>

<p>
Kiedy mamy ju t warto moemy odesa pakiet logowania
</p>

<div class="c">
<pre>#define GG_LOGIN 0x000c</pre>
</div>

<p>
Musimy poda kilka informacji:
</p>

<div class="c">
<pre>struct gg_login {
	int uin;		<i>/* numer klienta */</i>
	int hash;		<i>/* hash hasa */</i>
	int status;		<i>/* pocztkowy stan */</i>
	int version;		<i>/* wersja klienta */</i>
	int local_ip;		<i>/* mj adres ip */</i>
	short local_port;	<i>/* port, na ktrym sucham */</i>
	char description[];	<i>/* opis, nie musi wystpi */</i>
	int time;		<i>/* czas, nie musi wystpi */</i>
};</pre>
</div>

<p>
Hash hasa w pierwszych wersjach by liczony w do prosty sposb, ale
niestety z ktr zmian protokou wprowadzono nowy algorytm:
</p>

<div class="example">
<pre>int gg_login_hash(char *password, int seed)
{
	unsigned int x, y, z;

	y = seed;

	for (x = 0; *password; password++) {
		x = (x &amp; 0xffffff00) | *password;
		y ^= x;
		y += x;
		x &lt;&lt;= 8;
		y ^= x;
		x &lt;&lt;= 8;
		y -= x;
		x &lt;&lt;= 8;
		y ^= x;

		z = y &amp; 0x1f;
		y = (y &lt;&lt; z) | (y &gt;&gt; (32 - z));
	}

	return y;
}</pre>
</div>

<p>
Liczba oznaczajca wersj moe by jedn z poniszych:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Warto</b></td><td><b>Wersje klientw</b></td></tr>
<tr class="tabf"><td><tt>0x19</tt></td><td>5.0.3</td></tr>
<tr class="tabf"><td><tt>0x18</tt></td><td>5.0.1, 5.0.0, 4.9.3</td></tr>
<tr class="tabf"><td><tt>0x17</tt></td><td>4.9.2</td></tr>
<tr class="tabf"><td><tt>0x16</tt></td><td>4.9.1</td></tr>
<tr class="tabf"><td><tt>0x15</tt></td><td>4.8.9</td></tr>
<tr class="tabf"><td><tt>0x14</tt></td><td>4.8.3, 4.8.1</td></tr>
<tr class="tabf"><td><tt>0x11</tt></td><td>4.6.10, 4.6.1</td></tr>
<tr class="tabf"><td><tt>0x10</tt></td><td>4.5.22, 4.5.21, 4.5.19, 4.5.17, 4.5.15</td></tr>
<tr class="tabf"><td><tt>0x0f</tt></td><td>4.5.12</td></tr>
<tr class="tabf"><td><tt>0x0b</tt></td><td>4.0.30, 4.0.29, 4.0.28, 4.0.25</td></tr>
</table>

<p>
Oczywicie nie s to wszystkie moliwe wersje klientw, lecz te, ktre
udao si zapa na wolnoci. Najbezpieczniej bdzie przedstawia si jako
ta wersja, ktrej wasnoci uywamy. Wiadomo, e wersje 4.0 nie obsugiway
trybu ukrytego, tylko dla znajomych itd.
</p>

<p>
W najnowszej wersji protokou jest dodatkowa maska na wersj:
</p>

<div class="c">
<pre>#define GG_HAS_AUDIO_MASK 0x40000000</pre>
</div>

<p>
ktra mwi nam, e dany klient moe prowadzi rozmowy gosowe.
</p>

<p>
Jeli wszystko si powiedzie, dostaniemy w odpowiedzi pakiet typu:
</p>

<div class="c">
<pre>#define GG_LOGIN_OK 0x0003</pre>
</div>

<p>
o zerowej dugoci, lub w przypadku bdu pakiet:
</p>

<div class="c">
<pre>#define GG_LOGIN_FAILED 0x0009</pre>
</div>

<p>
Od wersji 4.9.3 (protok 0x18), moliwe jest rwnie wykorzystanie
przekierowania portw. Jeli chcemy wykorzysta, naley zamiast
pakietu GG_LOGIN wysa nastpujcy:
</p>

<div class="c">
<pre>#define GG_LOGIN_EXT 0x0013

struct gg_login_ext {
	int uin;		<i>/* numer klienta */</i>
	int hash;		<i>/* hash hasa */</i>
	int status;		<i>/* pocztkowy stan */</i>
	int version;		<i>/* wersja klienta */</i>
	int local_ip;		<i>/* mj adres ip */</i>
	short local_port;	<i>/* port, na ktrym sucham */</i>
	int external_ip;	<i>/* zewntrzny adres ip */</i>
	short external_port;	<i>/* zewntrzny port */</i>
	char description[];	<i>/* opis, nie musi wystpi */</i>
	int time;		<i>/* czas, nie musi wystpi */</i>
};</pre>
</div>

<hr />

<h3>1.4. Zmiana stanu</h3>

<p>
Gadu-Gadu przewiduje kilka stanw klienta, ktre zmieniamy pakietem typu:
</p>

<div class="c">
<pre>#define GG_NEW_STATUS 0x0002
	
struct gg_new_status {
	int status;		<i>/* na jaki zmieni? */</i>
	char description[];	<i>/* opis, nie musi wystpi */</i>
	int time;		<i>/* czas, nie musi wystpi */</i>
}</pre>
</div>

<p>
Moliwe stany to:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Etykieta</b></td><td><b>Warto</b></td><td><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>GG_STATUS_NOT_AVAIL</tt></td><td><tt>0x0001</tt></td><td>Niedostpny</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_NOT_AVAIL_DESCR</tt></td><td><tt>0x0015</tt></td><td>Niedostpny (z opisem)</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_AVAIL</tt></td><td><tt>0x0002</tt></td><td>Dostpny</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_AVAIL_DESCR</tt></td><td><tt>0x0004</tt></td><td>Dostpny (z opisem)</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_BUSY</tt></td><td><tt>0x0003</tt></td><td>Zajty</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_BUSY_DESCR</tt></td><td><tt>0x0005</tt></td><td>Zajty (z opisem)</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_INVISIBLE</tt></td><td><tt>0x0014</tt></td><td>Niewidoczny</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_INVISIBLE_DESCR</tt></td><td><tt>0x0016</tt></td><td>Niewidoczny z opisem</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_BLOCKED</tt></td><td><tt>0x0006</tt></td><td>Zablokowany</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_FRIENDS_MASK</tt></td><td><tt>0x8000</tt></td><td>Maska bitowa oznaczajca tryb tylko dla przyjaci</td></tr>
</table>

<p>
Naley pamita, eby przed rozczeniem si z serwerem naley zmieni
stan na <tt>GG_STATUS_NOT_AVAIL</tt> lub <tt>GG_STATUS_NOT_AVAIL_DESCR</tt>.
Jeli ma by widoczny tylko dla przyjaci, naley doda
<tt>GG_STATUS_FRIENDS_MASK</tt> do normalnej wartoci stanu.
</p>

<p>
Jeli wybieramy stan opisowy, naley doczy cig znakw zakoczony
zerem oraz ewentualny czas powrotu w postaci iloci sekund od 1 stycznia
1970r (UTC). Maksymalna dugo opisu wynosi 40 znakw plus zero plus
4 bajty na godzin powrotu, co razem daje 45 bajtw.
</p>

<hr />

<h3>1.5. Ludzie przychodz, ludzie odchodz</h3>

<p>
Zaraz po zalogowaniu moemy wysa serwerowi nasz list kontaktw, eby
dowiedzie si, czy s w danej chwili dostpni. Pakiet zawiera maksymalnie
409 struktur <tt>gg_notify</tt>:
</p>

<div class="c">
<pre>#define GG_NOTIFY 0x0010
	
struct gg_notify {
	int uin;	<i>/* numerek danej osoby */</i>
	char type;	<i>/* rodzaj uytkownika */</i>
};</pre>	
</div>

<p>
Gdzie pole <tt>type</tt> przyjmuje nastpujce wartoci:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Etykieta</b></td><td><b>Warto</b></td><td><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>GG_USER_OFFLINE</tt></td><td><tt>0x01</tt></td><td>Uytkownik, dla ktrego bdziemy niedostpni</td></tr>
<tr class="tabf"><td><tt>GG_USER_NORMAL</tt></td><td><tt>0x03</tt></td><td>Zwyky uytkownik dodany do listy kontkatw</td></tr>
<tr class="tabf"><td><tt>GG_USER_BLOCKED</tt></td><td><tt>0x04</tt></td><td>Uytkownik, ktrego wiadomoci nie chcemy otrzymywa</td></tr>
</table>

<!-- Adam pisa, e jest to bitmapa, w ktrej 0x01 znaczy otwarte okienko
rozmowy z dan osob, ale wygldaoby to co najmniej dziwnie, wic
uprociem troch ca spraw. -->

<p>
Jeli nie mamy nikogo na licie wysyamy pakiet:
</p>

<div class="c">
<pre>#define GG_LIST_EMPTY 0x0012</pre>
</div>

<p>	
o zerowej dugoci.
</p>

<p>
Jeli kto jest, serwer odpowie pakietem zawierajcym jedn lub wicej
struktur <tt>gg_notify_reply</tt>:
</p>

<div class="c">
<pre>#define GG_NOTIFY_REPLY 0x000c	/* tak, to samo co GG_LOGIN */
	
struct gg_notify_reply {
	int uin;		/* numerek */
	int status;		/* status danej osoby */
	int remote_ip;		/* adres ip delikwenta */
	short remote_port;	/* port, na ktrym sucha klient */
	int version;		/* wersja klienta */
	short unknown1;		/* znowu port? */
	char description[];	/* opis, nie musi wystpi */
	int time;		/* czas, nie musi wystpi */
};</pre>
</div>

<p>
Wikszo pl powinna by zrozumiaa. <tt>remote_port</tt> poza zwykym
portem moe przyjmowa rwnie ponisze wartoci:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Warto</b></td><td><b>Znaczenie</b></td></tr>
<tr class="tabf"><td>0</td><td>Klient nie obsuguje bezporednich pocze</td></tr>
<tr class="tabf"><td>1</td><td>Klient czy si zza NAT lub innej formy maskarady</td></tr>
<tr class="tabf"><td>2</td><td>Klient nie ma nas w swojej licie kontaktw</td></tr>
</table>

<p>
Zdarzaj si te inne ,,nietypowe'' wartoci, ale ich znaczenie nie jest
jeszcze do koca znane.
</p>

<p>
Jeli dany klient jest w stanie z podanym opisem, najpierw dostaniemy
informacj osobnym pakietem o nim, pniej paczk struktur
<tt>gg_notify_reply</tt> z ludmi, ktrzy nie maj ustawionych opisw.
</p>

<p>
Moliwe jest rwnie otrzymanie pakietu <tt>gg_notify_reply</tt> ze swoim wasnym numerem, ktr najlepiej zignorowa.
</p>

<p>
eby doda kogo do listy w trakcie pracy, trzeba wysa niej opisany
pakiet. Jego format jest identyczny jak przy <tt>GG_NOTIFY</tt>.
</p>

<div class="c">
<pre>#define GG_ADD_NOTIFY 0x000d
	
struct gg_add {
	int uin;	<i>/* numerek */</i>
	char type;	<i>/* rodzaj uytkownika */</i>
};</pre>
</div>

<p>
By usun z listy kontaktw, wysya si podobny pakiet:
</p>

<div class="c">
<pre>#define GG_REMOVE_NOTIFY 0x000e
	
struct gg_add {
	int uin;	<i>/* numerek */</i>
	char type;	<i>/* rodzaj uytkownika */</i>
};</pre>
</div>

<p>
Jeli kto opuci Gadu-Gadu lub zmieni stan na niedostpny lub niewidoczny, otrzymamy pakiet:
</p>

<div class="c">
<pre>#define GG_STATUS 0x0002
	
struct gg_status {
	int uin;	        <i>/* numerek */</i>
	int status;	        <i>/* nowy stan */</i>
	char description[];	<i>/* opis, nie musi wystpi */</i>
	int time;		<i>/* czas, nie musi wystpi */</i>
};</pre>
</div>

<p>
Natomiast jeli kto zmieni status na inny ni niedostpny lub niewidoczny, otrzymamy pakiet <tt>gg_notify_reply</tt>.
</p>

<hr />

<h3>1.6. Wysyanie wiadomoci</h3>

<p>
Wiadomoci wysya si nastpujcym typem pakietu:
</p>

<div class="c">
<pre>#define GG_SEND_MSG 0x000b

struct gg_send_msg {
	int recipient;		<i>/* numer odbiorcy */</i>
	int seq;		<i>/* numer sekwencyjny */</i>
	int class;		<i>/* klasa wiadomoci */</i>
	char message[];		<i>/* tre */</i>
};</pre>
</div>

<p>
Numer sekwencyjny jest wykorzystywany przy potwierdzeniu dostarczenia
lub zakolejkowania pakietu. Nie jest wykluczone, e w jakis sposb odrnia
si rne rozmowy za pomoc czci bajtw, ale raczej nie powinno mie to
ma znaczenia. Klasa wiadomoci pozwala odrni, czy wiadomo ma si
pojawi w osobnym okienku czy jako kolejna linijka w okienku rozmowy. Jest
to mapa bitowa, wic najlepiej ignorowa te bity, ktrych znaczenia nie
znamy:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Etykieta</b></td><td><b>Warto</b></td><td><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>GG_CLASS_QUEUED</tt></td><td><tt>0x0001</tt></td><td>Bit ustawiany wycznie przy odbiorze wiadomoci, gdy wiadomo zostaa wczeniej zakolejkowania z powodu nieobecnoci</td></tr>
<tr class="tabf"><td><tt>GG_CLASS_MSG</tt></td><td><tt>0x0004</tt></td><td>Wiadomo ma si pojawi w osobnym okienku</td></tr>
<tr class="tabf"><td><tt>GG_CLASS_CHAT</tt></td><td><tt>0x0008</tt></td><td>Wiadomo jest czci toczcej si rozmowy i zostanie wywietlona w istniejcym okienku</td></tr>
<tr class="tabf"><td><tt>GG_CLASS_CTCP</tt></td><td><tt>0x0010</tt></td><td>Wiadomo jest przeznaczona dla klienta Gadu-Gadu i nie powinna by wywietlona uytkownikowi.</td></tr>
<tr class="tabf"><td><tt>GG_CLASS_ACK</tt></td><td><tt>0x0020</tt></td><td>Klient nie yczy sobie potwierdzenia wiadomoci.</td></tr>
</table>

<p>
Dugo treci wiadomoci nie powinna przekracza 2000 znakw. Oryginalny
klient zezwala na wysanie do 1989 znakw.
</p>

<p>
Oryginalny klient wysyajc wiadomo do kilku uytkownikw, wysya po
kilka takich samych pakietw z rnymi numerkami odbiorcw. Nie ma osobnego
pakietu do tego. Natomiast jeli chodzi o <i>poczenia konferencyjne</i>
do pakietu doklejana jest nastpujca struktura:
</p>

<div class="c">
<pre>struct gg_msg_recipients {
	char flag;		<i>/* == 1 */</i>
	int count;		<i>/* ilo odbiorcw */</i>
	int recipients[];	<i>/* tablica odbiorcw */</i>
};</pre>
</div>

<p>
Na przykad, by wysa do dwch osb, naley wysa pakiet:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Offset</b></td><td><b>Warto</b></td></tr>
<tr class="tabf"><td><i>n</i></td><td>Tre wiadomoci</td></tr>
<tr class="tabf"><td><i>m</i></td><td><tt>0x01</tt> (wiadomo konferencyjna)</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;1</td><td rowspan="4"><tt>0x02</tt> (ilo adresatw)</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;2</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;3</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;4</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;5</td><td rowspan="4">Numer pierwszego adresata</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;6</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;7</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;8</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;9</td><td rowspan="4">Numer drugiego adresata</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;10</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;11</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;12</td></tr>
</table>

<p>
Od wersji 4.8.1 moliwe jest rwnie dodawanie do wiadomoci rnych
atrybutw tekstu jak pogrubienie czy kolory. Niezbdne jest doczenie
nastpnujcej struktury:
</p>

<div class="c">
<pre>struct gg_msg_richtext {
	char flag;	<i>/* == 2 */</i>
	short length;	<i>/* dugo dalszej czci */</i>
};</pre>
</div>

<p>
Dalsza cz pakietu zawiera odpowiedni ilo struktur o czej dugoci
okrelonej polem <tt>length</tt>:
</p>

<div class="c">
<pre>struct gg_msg_richtext_format {
	short position;	<i>/* pozycja atrybutu w tekcie */</i>
	char font;	<i>/* atrybuty czcionki */</i>
	char rgb[3];	<i>/* kolor czcionki, nie musi wystpi */</i>
};</pre>
</div>

<p>
Kada z tych struktur okrela kawaek tekstu poczwszy od znaku okrelonego
przez pole <tt>position</tt> (liczone od zera) a do nastpnego wpisu lub
koca tekstu. Pole <tt>font</tt> jest map bitow i kolejne bity maj
nastpujce znaczenie:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Etykieta</b></td><td><b>Warto</b></td><td><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>GG_FONT_BOLD</tt></td><td><tt>0x01</tt></td><td>Pogrubiony tekst</td></tr>
<tr class="tabf"><td><tt>GG_FONT_ITALIC</tt></td><td><tt>0x02</tt></td><td>Kursywa</td></tr>
<tr class="tabf"><td><tt>GG_FONT_UNDERLINE</tt></td><td><tt>0x04</tt></td><td>Podkrelenie</td></tr>
<tr class="tabf"><td><tt>GG_FONT_COLOR</tt></td><td><tt>0x08</tt></td><td>Kolorowy tekst. Tylko w tym wypadku struktura <tt>gg_msg_richtext_format</tt> zawiera pole <tt>rgb[]</tt> bdce opisem trzech skadowych koloru, kolejno czerwonej, zielonej i niebieskiej.</td></tr>
</table>

<p>
Dla przykadu, by przesa tekst ,,ala <b>ma</b> kota'', naley doczy do
wiadomoci nastpujc sekwencj bajtw:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Offset</b></td><td><b>Warto</b></td><td><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><i>n</i></td><td><tt>0x02</tt></td><td>Opis atrybutw tekstu...</td></tr>
<tr class="tabf"><td><i>n</i> + 1</td><td rowspan="2"><tt>0x0006</tt></td><td rowspan="2">...majcy 6 bajtw dugoci</td></tr>
<tr class="tabf"><td><i>n</i> + 2</td></tr>
<tr class="tabf"><td><i>n</i> + 3</td><td rowspan="2"><tt>0x0004</tt></td><td rowspan="2">Atrybut zaczyna si od pozycji 4...</td></tr>
<tr class="tabf"><td><i>n</i> + 4</td></tr>
<tr class="tabf"><td><i>n</i> + 5</td><td><tt>0x01</tt></td><td>...i jest to pogrubiony tekst</td></tr>
<tr class="tabf"><td><i>n</i> + 6</td><td rowspan="2"><tt>0x0006</tt></td><td rowspan="2">Atrybut zaczyna si od pozycji 6...</td></tr>
<tr class="tabf"><td><i>n</i> + 7</td></tr>
<tr class="tabf"><td><i>n</i> + 8</td><td><tt>0x00</tt></td><td>...i jest to zwyky tekst</td></tr>
</table>

<p>
Serwer po otrzymaniu wiadomoci odsya potwierdzenie, ktre przy okazji
mwi nam, czy wiadomo dotara do odbiorcy czy zostaa zakolejkowana
z powodu nieobecnoci. Otrzymujemy je w postaci pakietu:
</p>

<div class="c">
<pre>#define GG_SEND_MSG_ACK 0x0005
	
struct gg_send_msg_ack {
	int status;	<i>/* stan wiadomoci */</i>
	int recipient;	<i>/* numer odbiorcy */</i>
	int seq;	<i>/* numer sekwencyjny */</i>
};</pre>
</div>

<p>
Numer sekwencyjny i numer adresata s takie same jak podczas wysyania,
a stan wiadomoci moe by jednym z nastpujcych:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Etykieta</b></td><td><b>Warto</b></td><td><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>GG_ACK_DELIVERED</tt></td><td><tt>0x0002</tt></td><td>Wiadomo dostarczono</td></tr>
<tr class="tabf"><td><tt>GG_ACK_QUEUED</tt></td><td><tt>0x0003</tt></td><td>Wiadomo zakolejkowano</td></tr>
<tr class="tabf"><td><tt>GG_ACK_MBOXFULL</tt></td><td><tt>0x0004</tt></td><td>Wiadomoci nie dostarczono. Skrzynka odbiorcza na serwerze jest pena (20 wiadomoci maks). Wystpuje tylko w trybie offline</td></tr>
<tr class="tabf"><td><tt>GG_ACK_NOT_DELIVERED</tt></td><td><tt>0x0006</tt></td><td>Wiadomoci nie dostarczono. Odpowied ta wystpuje tylko w przypadku wiadomoci klasy <tt>GG_CLASS_CTCP</tt></td></tr>
</table>

<hr />

<h3>1.7. Otrzymywanie wiadomoci</h3>

<p>
Wiadomoci serwer przysya za pomoc pakietu:
</p>

<div class="c">
<pre>#define GG_RECV_MSG 0x000a
	
struct gg_recv_msg {
	int sender;		<i>/* numer nadawcy */</i>
	int seq;		<i>/* numer sekwencyjny */</i>
	int time;		<i>/* czas nadania */</i>
	int class;		<i>/* klasa wiadomoci */</i>
	char message[];		<i>/* tre wiadomoci */</i>
};</pre>
</div>

<p>
Czas nadania jest zapisany w postaci UTC, jako iloci sekund od 1 stycznie
1970r.
</p>

<p>
W przypadku pakietw ,,konferencyjnych'' na kocu pakietu doklejona jest
struktura identyczna z <tt>gg_msg_recipients</tt> zawierajca pozostaych
rozmwcw.
</p>

<hr />

<h3>1.8. Ping, pong</h3>

<p>
Od czasu do czasu klient wysya pakiet do serwera, by oznajmi, e poczenie
jeszcze jest utrzymywane. Jeli serwer nie dostanie takiego pakietu w
przecigu 5 minut, zrywa poczenie. To, czy klient dostaje odpowied
zmienia si z wersji na wersj, wic najlepiej nie polega na tym.
</p>

<div class="c">
<pre>#define GG_PING 0x0008

#define GG_PONG 0x0007</pre>
</div>

<hr />

<h3>1.9. Rozczenie</h3>

<p>
Jeli serwer zechce nas rozczy, wyle wczeniej pusty pakiet:
</p>

<div class="c">
<pre>#define GG_DISCONNECTING 0x000b</pre>
</div>

<p>
Ma to miejsce, gdy prbowano zbyt wiele razy poczy si z nieprawidowym
hasem, lub gdy rwnoczenie poczy si drugi klient z tym samym numerem
(nowe poczenie ma wyszy priorytet).
</p>

<hr />

<h2>2. Usugi HTTP</h2>

<p>
Opis znajduje si w pliku <a href="http.txt">http.txt</a>.
</p>

<hr />

<h2>3. Bezporednie poczenie</h2>

<p>
Opis znajduje si w pliku <a href="dcc-protocol.txt">dcc-protocol.txt</a>.
</p>

<a name="ch4"></a>
	
<hr />

<h2>4. Autorzy</h2>

<p>
Autorami powyszego opisu s:
</p>

<ul>
	<li><b><NAME></b> (wojtekka%irc.pl): pierwsza wersja opisu, poprawki, utrzymanie wszystkiego w porzdku.</li>
	<li><b><NAME></b> (speedy%atman.pl): opis nowoci w protokole GG 4.6, poprawki.</li>
	<li><b><NAME></b> (tomee%cpi.pl): badanie timeoutw.</li>
	<li><b><NAME></b> (adam.ludwikowski%wp.pl): wiele poprawek, wersje klientw, rozszerzone wiadomoci, powody nieobecnoci.</li>
	<li><b><NAME></b> (klith%hybrid.art.pl): czas otrzymania wiadomoci.</li>
	<li><b><NAME></b> (raf%regionet.regionet.pl): opis pocze konferencyjnych.</li>
	<li><b><NAME></b> (igipop%wsfiz.edu.pl): klasy wiadomoci przy odbieraniu zakolejkowanej.</li>
	<li><b><NAME></b> (ajron%wp.pl): informacje o remote_port, rodzaje potwierdze przy ctcp, GG_LOGIN_EXT.</li>
	<li><b><NAME></b> (pm%gadu-gadu.com): ilo kontaktow, pena skrzynka, pusta lista, maska audio, usugi HTTP, GG_LOGIN_EXT.</li>
	<li><b><NAME></b> (acc%interia.pl): potwierdzenie wiadomoci GG_CLASS_ACK.</li>
	<li><b><NAME></b> (kdebski%kki.net.pl): czas w stanach opisowych.</li>
	<li><b><NAME></b> (alfapawel%go2.pl): format czasu.</li>
	<li><b><NAME></b> (chilek%chilan.com): nowoci w 5.0.2.</li>
	<li><b><NAME></b> (rano%ranosoft.com): uzupenienie statusu opisowego, wersja 5.0.3.</li>
</ul><commit_msg>- dodanie opisu usług http do docs/protocol.html (pm/w)<commit_after><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=iso-8859-2" />
<style type="text/css">
BODY { font-family: tahoma, verdana, arial, helvetica, sans-serif; }
.tab { background-color: #a0a0a0; }
.tabh { background-color: #d0d0d0; }
.tabf { background-color: white; }
.c { font-family: monospace; padding: 0.7em; background-color: #e0e0e0; border: 1px solid #a0a0a0; }
.http { font-family: monospace; padding: 0.7em; background-color: #c0f0c0; border: 1px solid #80a080; }
.example { font-family: monospace; padding: 0.7em; background-color: #c0f0f0; border: 1px solid #80a0a0; }
</style>
<title>Protok Gadu-Gadu</title>
</head>

<body bgcolor="white" text="black">

<center>
<table width="600" border="0"><tr><td>

<center>
<h1>Protok Gadu-Gadu</h1>
<h3>&copy; Copyright 2001 - 2003 <a href="#ch4">Autorzy</a></h3>
</center>

<hr />

<a name="index"></a>

<h2>Spis treci</h2>

<ol start="0">
	<li><a href="#ch0">Informacje wstpne</a></li>
	<li><a href="#ch1">Protok Gadu-Gadu</a><br>
		1.1.&nbsp;&nbsp;<a href="#ch11">Format pakietw</a><br>
		1.2.&nbsp;&nbsp;<a href="#ch12">Zanim si poczymy</a><br>
		1.3.&nbsp;&nbsp;<a href="#ch13">Logowanie si</a><br>
		1.4.&nbsp;&nbsp;<a href="#ch14">Zmiana stanu</a><br>
		1.5.&nbsp;&nbsp;<a href="#ch15">Ludzie przychodz, ludzie odchodz</a><br>
		1.6.&nbsp;&nbsp;<a href="#ch16">Wysyanie wiadomoci</a><br>
		1.7.&nbsp;&nbsp;<a href="#ch17">Otrzymywanie wiadomoci</a><br>
		1.8.&nbsp;&nbsp;<a href="#ch18">Ping, pong</a><br>
		1.9.&nbsp;&nbsp;<a href="#ch19">Rozczenie</a><br>
	</li>
	<li><a href="#ch2">Usugi HTTP</a><br>
		2.1.&nbsp;&nbsp;<a href="#ch21">Format danych</a><br>
		2.2.&nbsp;&nbsp;<a href="#ch22">Rejestracja konta</a><br>
		2.3.&nbsp;&nbsp;<a href="#ch23">Usunicie konta</a><br>
		2.4.&nbsp;&nbsp;<a href="#ch24">Zmiana hasa</a><br>
		2.5.&nbsp;&nbsp;<a href="#ch25">Umieszczenie listy kontaktw na serwerze</a><br>
		2.6.&nbsp;&nbsp;<a href="#ch26">Pobranie listy kontaktw z serwera</a><br>
		2.7.&nbsp;&nbsp;<a href="#ch27">Usunicie listy kontaktw z serwera</a><br>
		2.8.&nbsp;&nbsp;<a href="#ch28">Przypomnienie hasa poczt</a><br>
	</li>
	<li><a href="#ch3">Bezporednie poczenia</a></li>
	<li><a href="#ch4">Autorzy</a></li>
</ol>

<hr />

<a name="ch0"></a>
<h2>0. Informacje wstpne</h2>

<p>
Opis protokou uywanego przez Gadu-Gadu bazuje na dowiadczeniach
przeprowadzonych przez autorw oraz informacjach nadsyanych przez 
uytkownikw. aden klient Gadu-Gadu nie zosta skrzywdzony podczas
bada. Reverse-engineering opiera si gwnie na analizie pakietw
wysyanych midzy klientem a serwerem.
</p>

<hr />

<a name="ch1"></a>
<h2>1. Protok Gadu-Gadu</h2>

<a name="ch11"></a>
<h3>1.1. Format pakietw</h3>

<p>
Podobnie jak coraz wiksza ilo komunikatorw, Gadu-Gadu korzysta z
protokou TCP/IP. Kady pakiet zawiera na pocztku dwa stae pola:
</p>

<div class="c">
<pre>struct gg_header {
	int type;	<i>/* typ pakietu */</i>
	int length;	<i>/* dugo reszty pakietu */</i>
};</pre>
</div>

<p>
Wszystkie zmienne liczbowe s zgodne z kolejnoci bajtw maszyn Intela,
czyli Little-Endian.
</p>

<p>
Przy opisie struktur, zaoono, e <tt>char</tt> ma rozmiar 1 bajtu,
<tt>short</tt> 2 bajtw, <tt>int</tt> 4 bajtw. Uywajc innych
architektur ni i386 naley zwrci szczegln uwag na rozmiar typw
zmiennych i kolejno znakw.
</p>

<p>
Pola, ktry znaczenie jest nieznane, lub nie do koca jasne, oznaczono
przedrostkiem <tt>unknown</tt>.
</p>

<hr />

<a name="ch12"></a>
<h3>1.2. Zanim si poczymy</h3>

<p>
eby wiedzie, z jakim serwerem mamy si poczy, naley poudawa przez
chwil przegldark WWW i poczy si z hostem <tt>appmsg.gadu-gadu.pl</tt>.
</p>

<div class="http">
<pre>GET /appsvc/appmsg.asp?fmnumber=<b>NUMER</b> HTTP/1.0
Host: appmsg.gadu-gadu.pl
User-Agent: Mozilla/4.7 [en] (Win98; I)
Pragma: no-cache</pre>
</div>

<p>
Oryginalny klient moe wysa jeden z podanych identyfikatorw przegldarki:
</p>

<ul>
<li><tt>Mozilla/4.04 [en] (Win95; I ;Nav)</tt></li>
<li><tt>Mozilla/4.7 [en] (Win98; I)</tt></li>
<li><tt>Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)</tt></li>
<li><tt>Mozilla/4.0 (compatible; MSIE 5.0; Windows NT)</tt></li>
<li><tt>Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt)</tt></li>
<li><tt>Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)</tt></li>
</ul>

<p>
Nowsze wersje (od 4.6.2) korzystaj z innego skryptu:
</p>

<div class="http">
<pre>GET /appsvc/appmsg2.asp?fmnumber=<b>NUMER</b>&amp;version=<b>WERSJA</b>&amp;fmt=<b>FORMAT</b>&amp;lastmsg=<b>WIADOMO</b>
Host: appmsg.gadu-gadu.pl
User-Agent: <b>PRZEGLDARKA</b>
Pragma: no-cache</pre>
</div>

<p>
Gdzie <b>NUMER</b> jest numerem klienta, <b>WERSJA</b> jest wersj klienta,
<b>FORMAT</b> okrela czy wiadomo systemowa bdzie przesyana czystym
tekstem (brak zmiennej "fmt") czy w HTMLu (jakakolwiek jej warto), a
<b>WIADOMO</b> jest numerem ostatnio otrzymanej wiadomoci systemowej.
Na postawione w ten sposb zapytanie, serwer powinien odpowiedzie
na przykad tak:
</p>

<div class="http">
<pre>HTTP/1.0 200 OK

0 192.168.127.12:8074 192.168.127.12</pre>
</div>

<p>
Pierwsze pole jest numerem wiadomoci systemowej, a drugie i trzecie
podaj nam namiary na waciwy serwer. Jeli serwer jest niedostpny,
zamiast adresu IP jest zwracany tekst ,,<tt>notoperating</tt>''.
Jeeli poczenie z portem 8074 nie powiedzie si z jakich powodw,
mona si czy na port 443. 
</p>

<p>
Jeli pierwsza liczba nie jest rwna zero, zaraz po nagwku znajduje si
wiadomo systemowa, lub jeli linia zaczyna si od znaku ,,<tt>@</tt>'',
adres strony, ktr naley otworzy w przegldarce.
</p>

<hr />

<a name="ch13"></a>
<h3>1.3. Logowanie si</h3>

<p>
Po poczeniu si portem 8074 lub 443 serwera Gadu-Gadu, dostajemy pakiet
typu <tt>0x0001</tt>, ktry na potrzeby tego dokumentu nazwiemy:
</p>

<div class="c">
<pre>#define GG_WELCOME 0x0001</pre>
</div>

<p>
Reszta pakietu zawiera liczb, na podstawie ktrej liczony jest hash z hasa
klienta:
</p>

<div class="c">
<pre>struct gg_welcome {
	int seed;	<i>/* klucz szyfrowania hasa */</i>
};</pre>
</div>

<p>
Kiedy mamy ju t warto moemy odesa pakiet logowania
</p>

<div class="c">
<pre>#define GG_LOGIN 0x000c</pre>
</div>

<p>
Musimy poda kilka informacji:
</p>

<div class="c">
<pre>struct gg_login {
	int uin;		<i>/* numer klienta */</i>
	int hash;		<i>/* hash hasa */</i>
	int status;		<i>/* pocztkowy stan */</i>
	int version;		<i>/* wersja klienta */</i>
	int local_ip;		<i>/* mj adres ip */</i>
	short local_port;	<i>/* port, na ktrym sucham */</i>
	char description[];	<i>/* opis, nie musi wystpi */</i>
	int time;		<i>/* czas, nie musi wystpi */</i>
};</pre>
</div>

<p>
Hash hasa w pierwszych wersjach by liczony w do prosty sposb, ale
niestety z ktr zmian protokou wprowadzono nowy algorytm:
</p>

<div class="example">
<pre>int gg_login_hash(char *password, int seed)
{
	unsigned int x, y, z;

	y = seed;

	for (x = 0; *password; password++) {
		x = (x &amp; 0xffffff00) | *password;
		y ^= x;
		y += x;
		x &lt;&lt;= 8;
		y ^= x;
		x &lt;&lt;= 8;
		y -= x;
		x &lt;&lt;= 8;
		y ^= x;

		z = y &amp; 0x1f;
		y = (y &lt;&lt; z) | (y &gt;&gt; (32 - z));
	}

	return y;
}</pre>
</div>

<p>
Liczba oznaczajca wersj moe by jedn z poniszych:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Warto</b></td><td><b>Wersje klientw</b></td></tr>
<tr class="tabf"><td><tt>0x19</tt></td><td>5.0.3</td></tr>
<tr class="tabf"><td><tt>0x18</tt></td><td>5.0.1, 5.0.0, 4.9.3</td></tr>
<tr class="tabf"><td><tt>0x17</tt></td><td>4.9.2</td></tr>
<tr class="tabf"><td><tt>0x16</tt></td><td>4.9.1</td></tr>
<tr class="tabf"><td><tt>0x15</tt></td><td>4.8.9</td></tr>
<tr class="tabf"><td><tt>0x14</tt></td><td>4.8.3, 4.8.1</td></tr>
<tr class="tabf"><td><tt>0x11</tt></td><td>4.6.10, 4.6.1</td></tr>
<tr class="tabf"><td><tt>0x10</tt></td><td>4.5.22, 4.5.21, 4.5.19, 4.5.17, 4.5.15</td></tr>
<tr class="tabf"><td><tt>0x0f</tt></td><td>4.5.12</td></tr>
<tr class="tabf"><td><tt>0x0b</tt></td><td>4.0.30, 4.0.29, 4.0.28, 4.0.25</td></tr>
</table>

<p>
Oczywicie nie s to wszystkie moliwe wersje klientw, lecz te, ktre
udao si zapa na wolnoci. Najbezpieczniej bdzie przedstawia si jako
ta wersja, ktrej wasnoci uywamy. Wiadomo, e wersje 4.0 nie obsugiway
trybu ukrytego, tylko dla znajomych itd.
</p>

<p>
W najnowszej wersji protokou jest dodatkowa maska na wersj:
</p>

<div class="c">
<pre>#define GG_HAS_AUDIO_MASK 0x40000000</pre>
</div>

<p>
ktra mwi nam, e dany klient moe prowadzi rozmowy gosowe.
</p>

<p>
Jeli wszystko si powiedzie, dostaniemy w odpowiedzi pakiet typu:
</p>

<div class="c">
<pre>#define GG_LOGIN_OK 0x0003</pre>
</div>

<p>
o zerowej dugoci, lub w przypadku bdu pakiet:
</p>

<div class="c">
<pre>#define GG_LOGIN_FAILED 0x0009</pre>
</div>

<p>
Od wersji 4.9.3 (protok 0x18), moliwe jest rwnie wykorzystanie
przekierowania portw. Jeli chcemy wykorzysta, naley zamiast
pakietu GG_LOGIN wysa nastpujcy:
</p>

<div class="c">
<pre>#define GG_LOGIN_EXT 0x0013

struct gg_login_ext {
	int uin;		<i>/* numer klienta */</i>
	int hash;		<i>/* hash hasa */</i>
	int status;		<i>/* pocztkowy stan */</i>
	int version;		<i>/* wersja klienta */</i>
	int local_ip;		<i>/* mj adres ip */</i>
	short local_port;	<i>/* port, na ktrym sucham */</i>
	int external_ip;	<i>/* zewntrzny adres ip */</i>
	short external_port;	<i>/* zewntrzny port */</i>
	char description[];	<i>/* opis, nie musi wystpi */</i>
	int time;		<i>/* czas, nie musi wystpi */</i>
};</pre>
</div>

<hr />

<a name="ch14"></a>
<h3>1.4. Zmiana stanu</h3>

<p>
Gadu-Gadu przewiduje kilka stanw klienta, ktre zmieniamy pakietem typu:
</p>

<div class="c">
<pre>#define GG_NEW_STATUS 0x0002
	
struct gg_new_status {
	int status;		<i>/* na jaki zmieni? */</i>
	char description[];	<i>/* opis, nie musi wystpi */</i>
	int time;		<i>/* czas, nie musi wystpi */</i>
}</pre>
</div>

<p>
Moliwe stany to:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Etykieta</b></td><td><b>Warto</b></td><td><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>GG_STATUS_NOT_AVAIL</tt></td><td><tt>0x0001</tt></td><td>Niedostpny</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_NOT_AVAIL_DESCR</tt></td><td><tt>0x0015</tt></td><td>Niedostpny (z opisem)</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_AVAIL</tt></td><td><tt>0x0002</tt></td><td>Dostpny</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_AVAIL_DESCR</tt></td><td><tt>0x0004</tt></td><td>Dostpny (z opisem)</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_BUSY</tt></td><td><tt>0x0003</tt></td><td>Zajty</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_BUSY_DESCR</tt></td><td><tt>0x0005</tt></td><td>Zajty (z opisem)</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_INVISIBLE</tt></td><td><tt>0x0014</tt></td><td>Niewidoczny</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_INVISIBLE_DESCR</tt></td><td><tt>0x0016</tt></td><td>Niewidoczny z opisem</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_BLOCKED</tt></td><td><tt>0x0006</tt></td><td>Zablokowany</td></tr>
<tr class="tabf"><td><tt>GG_STATUS_FRIENDS_MASK</tt></td><td><tt>0x8000</tt></td><td>Maska bitowa oznaczajca tryb tylko dla przyjaci</td></tr>
</table>

<p>
Naley pamita, eby przed rozczeniem si z serwerem naley zmieni
stan na <tt>GG_STATUS_NOT_AVAIL</tt> lub <tt>GG_STATUS_NOT_AVAIL_DESCR</tt>.
Jeli ma by widoczny tylko dla przyjaci, naley doda
<tt>GG_STATUS_FRIENDS_MASK</tt> do normalnej wartoci stanu.
</p>

<p>
Jeli wybieramy stan opisowy, naley doczy cig znakw zakoczony
zerem oraz ewentualny czas powrotu w postaci iloci sekund od 1 stycznia
1970r (UTC). Maksymalna dugo opisu wynosi 40 znakw plus zero plus
4 bajty na godzin powrotu, co razem daje 45 bajtw.
</p>

<hr />

<a name="ch15"></a>
<h3>1.5. Ludzie przychodz, ludzie odchodz</h3>

<p>
Zaraz po zalogowaniu moemy wysa serwerowi nasz list kontaktw, eby
dowiedzie si, czy s w danej chwili dostpni. Pakiet zawiera maksymalnie
409 struktur <tt>gg_notify</tt>:
</p>

<div class="c">
<pre>#define GG_NOTIFY 0x0010
	
struct gg_notify {
	int uin;	<i>/* numerek danej osoby */</i>
	char type;	<i>/* rodzaj uytkownika */</i>
};</pre>	
</div>

<p>
Gdzie pole <tt>type</tt> przyjmuje nastpujce wartoci:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Etykieta</b></td><td><b>Warto</b></td><td><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>GG_USER_OFFLINE</tt></td><td><tt>0x01</tt></td><td>Uytkownik, dla ktrego bdziemy niedostpni</td></tr>
<tr class="tabf"><td><tt>GG_USER_NORMAL</tt></td><td><tt>0x03</tt></td><td>Zwyky uytkownik dodany do listy kontkatw</td></tr>
<tr class="tabf"><td><tt>GG_USER_BLOCKED</tt></td><td><tt>0x04</tt></td><td>Uytkownik, ktrego wiadomoci nie chcemy otrzymywa</td></tr>
</table>

<!-- Adam pisa, e jest to bitmapa, w ktrej 0x01 znaczy otwarte okienko
rozmowy z dan osob, ale wygldaoby to co najmniej dziwnie, wic
uprociem troch ca spraw. -->

<p>
Jeli nie mamy nikogo na licie wysyamy pakiet:
</p>

<div class="c">
<pre>#define GG_LIST_EMPTY 0x0012</pre>
</div>

<p>	
o zerowej dugoci.
</p>

<p>
Jeli kto jest, serwer odpowie pakietem zawierajcym jedn lub wicej
struktur <tt>gg_notify_reply</tt>:
</p>

<div class="c">
<pre>#define GG_NOTIFY_REPLY 0x000c	/* tak, to samo co GG_LOGIN */
	
struct gg_notify_reply {
	int uin;		/* numerek */
	int status;		/* status danej osoby */
	int remote_ip;		/* adres ip delikwenta */
	short remote_port;	/* port, na ktrym sucha klient */
	int version;		/* wersja klienta */
	short unknown1;		/* znowu port? */
	char description[];	/* opis, nie musi wystpi */
	int time;		/* czas, nie musi wystpi */
};</pre>
</div>

<p>
Wikszo pl powinna by zrozumiaa. <tt>remote_port</tt> poza zwykym
portem moe przyjmowa rwnie ponisze wartoci:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Warto</b></td><td><b>Znaczenie</b></td></tr>
<tr class="tabf"><td>0</td><td>Klient nie obsuguje bezporednich pocze</td></tr>
<tr class="tabf"><td>1</td><td>Klient czy si zza NAT lub innej formy maskarady</td></tr>
<tr class="tabf"><td>2</td><td>Klient nie ma nas w swojej licie kontaktw</td></tr>
</table>

<p>
Zdarzaj si te inne ,,nietypowe'' wartoci, ale ich znaczenie nie jest
jeszcze do koca znane.
</p>

<p>
Jeli dany klient jest w stanie z podanym opisem, najpierw dostaniemy
informacj osobnym pakietem o nim, pniej paczk struktur
<tt>gg_notify_reply</tt> z ludmi, ktrzy nie maj ustawionych opisw.
</p>

<p>
Moliwe jest rwnie otrzymanie pakietu <tt>gg_notify_reply</tt> ze swoim wasnym numerem, ktr najlepiej zignorowa.
</p>

<p>
eby doda kogo do listy w trakcie pracy, trzeba wysa niej opisany
pakiet. Jego format jest identyczny jak przy <tt>GG_NOTIFY</tt>.
</p>

<div class="c">
<pre>#define GG_ADD_NOTIFY 0x000d
	
struct gg_add {
	int uin;	<i>/* numerek */</i>
	char type;	<i>/* rodzaj uytkownika */</i>
};</pre>
</div>

<p>
By usun z listy kontaktw, wysya si podobny pakiet:
</p>

<div class="c">
<pre>#define GG_REMOVE_NOTIFY 0x000e
	
struct gg_add {
	int uin;	<i>/* numerek */</i>
	char type;	<i>/* rodzaj uytkownika */</i>
};</pre>
</div>

<p>
Jeli kto opuci Gadu-Gadu lub zmieni stan na niedostpny lub niewidoczny, otrzymamy pakiet:
</p>

<div class="c">
<pre>#define GG_STATUS 0x0002
	
struct gg_status {
	int uin;	        <i>/* numerek */</i>
	int status;	        <i>/* nowy stan */</i>
	char description[];	<i>/* opis, nie musi wystpi */</i>
	int time;		<i>/* czas, nie musi wystpi */</i>
};</pre>
</div>

<p>
Natomiast jeli kto zmieni status na inny ni niedostpny lub niewidoczny, otrzymamy pakiet <tt>gg_notify_reply</tt>.
</p>

<hr />

<a name="ch16"></a>
<h3>1.6. Wysyanie wiadomoci</h3>

<p>
Wiadomoci wysya si nastpujcym typem pakietu:
</p>

<div class="c">
<pre>#define GG_SEND_MSG 0x000b

struct gg_send_msg {
	int recipient;		<i>/* numer odbiorcy */</i>
	int seq;		<i>/* numer sekwencyjny */</i>
	int class;		<i>/* klasa wiadomoci */</i>
	char message[];		<i>/* tre */</i>
};</pre>
</div>

<p>
Numer sekwencyjny jest wykorzystywany przy potwierdzeniu dostarczenia
lub zakolejkowania pakietu. Nie jest wykluczone, e w jakis sposb odrnia
si rne rozmowy za pomoc czci bajtw, ale raczej nie powinno mie to
ma znaczenia. Klasa wiadomoci pozwala odrni, czy wiadomo ma si
pojawi w osobnym okienku czy jako kolejna linijka w okienku rozmowy. Jest
to mapa bitowa, wic najlepiej ignorowa te bity, ktrych znaczenia nie
znamy:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Etykieta</b></td><td><b>Warto</b></td><td><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>GG_CLASS_QUEUED</tt></td><td><tt>0x0001</tt></td><td>Bit ustawiany wycznie przy odbiorze wiadomoci, gdy wiadomo zostaa wczeniej zakolejkowania z powodu nieobecnoci</td></tr>
<tr class="tabf"><td><tt>GG_CLASS_MSG</tt></td><td><tt>0x0004</tt></td><td>Wiadomo ma si pojawi w osobnym okienku</td></tr>
<tr class="tabf"><td><tt>GG_CLASS_CHAT</tt></td><td><tt>0x0008</tt></td><td>Wiadomo jest czci toczcej si rozmowy i zostanie wywietlona w istniejcym okienku</td></tr>
<tr class="tabf"><td><tt>GG_CLASS_CTCP</tt></td><td><tt>0x0010</tt></td><td>Wiadomo jest przeznaczona dla klienta Gadu-Gadu i nie powinna by wywietlona uytkownikowi.</td></tr>
<tr class="tabf"><td><tt>GG_CLASS_ACK</tt></td><td><tt>0x0020</tt></td><td>Klient nie yczy sobie potwierdzenia wiadomoci.</td></tr>
</table>

<p>
Dugo treci wiadomoci nie powinna przekracza 2000 znakw. Oryginalny
klient zezwala na wysanie do 1989 znakw.
</p>

<p>
Oryginalny klient wysyajc wiadomo do kilku uytkownikw, wysya po
kilka takich samych pakietw z rnymi numerkami odbiorcw. Nie ma osobnego
pakietu do tego. Natomiast jeli chodzi o <i>poczenia konferencyjne</i>
do pakietu doklejana jest nastpujca struktura:
</p>

<div class="c">
<pre>struct gg_msg_recipients {
	char flag;		<i>/* == 1 */</i>
	int count;		<i>/* ilo odbiorcw */</i>
	int recipients[];	<i>/* tablica odbiorcw */</i>
};</pre>
</div>

<p>
Na przykad, by wysa do dwch osb, naley wysa pakiet:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Offset</b></td><td><b>Warto</b></td></tr>
<tr class="tabf"><td><i>n</i></td><td>Tre wiadomoci</td></tr>
<tr class="tabf"><td><i>m</i></td><td><tt>0x01</tt> (wiadomo konferencyjna)</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;1</td><td rowspan="4"><tt>0x02</tt> (ilo adresatw)</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;2</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;3</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;4</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;5</td><td rowspan="4">Numer pierwszego adresata</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;6</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;7</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;8</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;9</td><td rowspan="4">Numer drugiego adresata</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;10</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;11</td></tr>
<tr class="tabf"><td><i>m</i>&nbsp;+&nbsp;12</td></tr>
</table>

<p>
Od wersji 4.8.1 moliwe jest rwnie dodawanie do wiadomoci rnych
atrybutw tekstu jak pogrubienie czy kolory. Niezbdne jest doczenie
nastpnujcej struktury:
</p>

<div class="c">
<pre>struct gg_msg_richtext {
	char flag;	<i>/* == 2 */</i>
	short length;	<i>/* dugo dalszej czci */</i>
};</pre>
</div>

<p>
Dalsza cz pakietu zawiera odpowiedni ilo struktur o czej dugoci
okrelonej polem <tt>length</tt>:
</p>

<div class="c">
<pre>struct gg_msg_richtext_format {
	short position;	<i>/* pozycja atrybutu w tekcie */</i>
	char font;	<i>/* atrybuty czcionki */</i>
	char rgb[3];	<i>/* kolor czcionki, nie musi wystpi */</i>
};</pre>
</div>

<p>
Kada z tych struktur okrela kawaek tekstu poczwszy od znaku okrelonego
przez pole <tt>position</tt> (liczone od zera) a do nastpnego wpisu lub
koca tekstu. Pole <tt>font</tt> jest map bitow i kolejne bity maj
nastpujce znaczenie:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Etykieta</b></td><td><b>Warto</b></td><td><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>GG_FONT_BOLD</tt></td><td><tt>0x01</tt></td><td>Pogrubiony tekst</td></tr>
<tr class="tabf"><td><tt>GG_FONT_ITALIC</tt></td><td><tt>0x02</tt></td><td>Kursywa</td></tr>
<tr class="tabf"><td><tt>GG_FONT_UNDERLINE</tt></td><td><tt>0x04</tt></td><td>Podkrelenie</td></tr>
<tr class="tabf"><td><tt>GG_FONT_COLOR</tt></td><td><tt>0x08</tt></td><td>Kolorowy tekst. Tylko w tym wypadku struktura <tt>gg_msg_richtext_format</tt> zawiera pole <tt>rgb[]</tt> bdce opisem trzech skadowych koloru, kolejno czerwonej, zielonej i niebieskiej.</td></tr>
</table>

<p>
Dla przykadu, by przesa tekst ,,ala <b>ma</b> kota'', naley doczy do
wiadomoci nastpujc sekwencj bajtw:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Offset</b></td><td><b>Warto</b></td><td><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><i>n</i></td><td><tt>0x02</tt></td><td>Opis atrybutw tekstu...</td></tr>
<tr class="tabf"><td><i>n</i> + 1</td><td rowspan="2"><tt>0x0006</tt></td><td rowspan="2">...majcy 6 bajtw dugoci</td></tr>
<tr class="tabf"><td><i>n</i> + 2</td></tr>
<tr class="tabf"><td><i>n</i> + 3</td><td rowspan="2"><tt>0x0004</tt></td><td rowspan="2">Atrybut zaczyna si od pozycji 4...</td></tr>
<tr class="tabf"><td><i>n</i> + 4</td></tr>
<tr class="tabf"><td><i>n</i> + 5</td><td><tt>0x01</tt></td><td>...i jest to pogrubiony tekst</td></tr>
<tr class="tabf"><td><i>n</i> + 6</td><td rowspan="2"><tt>0x0006</tt></td><td rowspan="2">Atrybut zaczyna si od pozycji 6...</td></tr>
<tr class="tabf"><td><i>n</i> + 7</td></tr>
<tr class="tabf"><td><i>n</i> + 8</td><td><tt>0x00</tt></td><td>...i jest to zwyky tekst</td></tr>
</table>

<p>
Serwer po otrzymaniu wiadomoci odsya potwierdzenie, ktre przy okazji
mwi nam, czy wiadomo dotara do odbiorcy czy zostaa zakolejkowana
z powodu nieobecnoci. Otrzymujemy je w postaci pakietu:
</p>

<div class="c">
<pre>#define GG_SEND_MSG_ACK 0x0005
	
struct gg_send_msg_ack {
	int status;	<i>/* stan wiadomoci */</i>
	int recipient;	<i>/* numer odbiorcy */</i>
	int seq;	<i>/* numer sekwencyjny */</i>
};</pre>
</div>

<p>
Numer sekwencyjny i numer adresata s takie same jak podczas wysyania,
a stan wiadomoci moe by jednym z nastpujcych:
</p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td><b>Etykieta</b></td><td><b>Warto</b></td><td><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>GG_ACK_DELIVERED</tt></td><td><tt>0x0002</tt></td><td>Wiadomo dostarczono</td></tr>
<tr class="tabf"><td><tt>GG_ACK_QUEUED</tt></td><td><tt>0x0003</tt></td><td>Wiadomo zakolejkowano</td></tr>
<tr class="tabf"><td><tt>GG_ACK_MBOXFULL</tt></td><td><tt>0x0004</tt></td><td>Wiadomoci nie dostarczono. Skrzynka odbiorcza na serwerze jest pena (20 wiadomoci maks). Wystpuje tylko w trybie offline</td></tr>
<tr class="tabf"><td><tt>GG_ACK_NOT_DELIVERED</tt></td><td><tt>0x0006</tt></td><td>Wiadomoci nie dostarczono. Odpowied ta wystpuje tylko w przypadku wiadomoci klasy <tt>GG_CLASS_CTCP</tt></td></tr>
</table>

<hr />

<a name="ch17"></a>
<h3>1.7. Otrzymywanie wiadomoci</h3>

<p>
Wiadomoci serwer przysya za pomoc pakietu:
</p>

<div class="c">
<pre>#define GG_RECV_MSG 0x000a
	
struct gg_recv_msg {
	int sender;		<i>/* numer nadawcy */</i>
	int seq;		<i>/* numer sekwencyjny */</i>
	int time;		<i>/* czas nadania */</i>
	int class;		<i>/* klasa wiadomoci */</i>
	char message[];		<i>/* tre wiadomoci */</i>
};</pre>
</div>

<p>
Czas nadania jest zapisany w postaci UTC, jako iloci sekund od 1 stycznie
1970r.
</p>

<p>
W przypadku pakietw ,,konferencyjnych'' na kocu pakietu doklejona jest
struktura identyczna z <tt>gg_msg_recipients</tt> zawierajca pozostaych
rozmwcw.
</p>

<hr />

<a name="ch18"></a>
<h3>1.8. Ping, pong</h3>

<p>
Od czasu do czasu klient wysya pakiet do serwera, by oznajmi, e poczenie
jeszcze jest utrzymywane. Jeli serwer nie dostanie takiego pakietu w
przecigu 5 minut, zrywa poczenie. To, czy klient dostaje odpowied
zmienia si z wersji na wersj, wic najlepiej nie polega na tym.
</p>

<div class="c">
<pre>#define GG_PING 0x0008

#define GG_PONG 0x0007</pre>
</div>

<hr />

<a name="ch19"></a>
<h3>1.9. Rozczenie</h3>

<p>
Jeli serwer zechce nas rozczy, wyle wczeniej pusty pakiet:
</p>

<div class="c">
<pre>#define GG_DISCONNECTING 0x000b</pre>
</div>

<p>
Ma to miejsce, gdy prbowano zbyt wiele razy poczy si z nieprawidowym
hasem, lub gdy rwnoczenie poczy si drugi klient z tym samym numerem
(nowe poczenie ma wyszy priorytet).
</p>

<hr />

<a name="ch2">
<h2>2. Usugi HTTP</h2>

<a name="ch21"></a>
<h3>2.1. Format danych</h3>

<p>
Komunikacja z <tt>appmsg.gadu-gadu.pl</tt> metod <tt>GET</tt> HTTP/1.0
zostaa opisana w poprzednim rozdziale, pozostae pakiety uywaj 
<tt>POST</tt> dla HTTP/1.0, a w odpowiedzi 1.1. Maj one posta:
</p>

<div class="http">
<pre>POST <b>CIEKA</b> HTTP/1.0
Host: <b>HOST</b>
Content-Type: application/x-www-form-urlencoded
User-Agent: <b>AGENT</b>
Content-Length: <b>DUGO</b>
Pragma: no-cache

<b>DANE</b></pre>
</div>

<p>
Gdzie <tt><b>AGENT</b></tt> to nazwa przegldarki (na przykad <tt>Mozilla/4.0
(compatible; MSIE 5.0; Windows 98)</tt> lub inne, wymienione w rozdziale
<a href="#ch12">1.2</a>), <tt><b>DUGO</b></tt> to dugo bloku
<tt><b>DANE</b></tt> w znakach.
</p>

<p>
Jeli bdzie mowa o wysyaniu danych do serwera, to chodzi o cay powyszy
pakiet, opisane zostan tylko: <tt><b>HOST</b></tt>, <tt><b>CIEKA</b></tt>
i <tt><b>DANE</b></tt>. Pakiet jest wysyany na port 80. Gdy mowa o wysyaniu
pl zapytania, mowa o <tt><b>DANE</b></tt> o wartoci:
</p>

<div class="http">
<pre>pole1=warto1&amp;pole2=warto2&amp;...</pre>
</div>

<p>
Pamitaj o zmianie kodowania na CP1250 i zakodowaniu danych do postaci URL
(na przykad funkcj typu <tt>urlencode</tt>).
</p>

<p>
Odpowiedzi serwera na powysze zapytania maj mniej wicej posta:
</p>

<div class="http">
<pre>HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Mon, 01 Jul 2002 22:30:31 GMT
Connection: Keep-Alive
Content-Length: <b>DUGO</b>
Content-Type: text/html
Set-Cookie: <b>COOKIE</b>
Cache-control: private

<b>ODPOWIED</b></pre>
</div>

<p>
Nagwki nie s dla nas wane. Mona zauway tylko to, e czasami serwer
ustawia <tt><b>COOKIE</b></tt> np. ,,<tt>ASPSESSIONIDQQGGGLJC=CAEKMBGDJCFBEOKCELEFCNKH; path=/</tt>''. Piszc dalej, e serwer ,,odpowie wartoci'' mona
tylko o polu <b>ODPOWIED</b>. Kodowanie znakw w odpowiedzi to CP1250.
</p>

<hr />

<a name="ch22"></a>

<h3>2.2. Rejestracja konta</h3>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td width="20%"><b>Pole nagwka</b></td><td width="80%"><b>Warto</b></td></tr>
<tr class="tabf"><td><tt>HOST</tt></td><td><tt>register.gadu-gadu.pl</tt></td></tr>
<tr class="tabf"><td><tt>CIEKA</tt></td><td><tt>/appsvc/fmregister.asp</tt></td></tr>
</table>

<p></p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td width="20%"><b>Wysyamy pole</b></td><td width="80%"><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>pwd</tt></td><td>haso dla nowego numeru</td></tr>
<tr class="tabf"><td><tt>email</tt></td><td>adres e-mail do przypomnienia hasa</td></tr>
<tr class="tabf"><td><tt>code</tt></td><td>hash liczony z pl <tt>email</tt> i <tt>pwd</tt>. Algorytmu szukaj w rdach libgadu w <tt>lib/common.c</tt></td></tr>
</table>

<p>
Przykad:
</p>

<div class="http">
<pre>POST /appsvc/fmregister.asp HTTP/1.0
Host: register.gadu-gadu.pl
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)
Content-Length: 51
Pragma: no-cache
		
pwd=<PASSWORD>&amp;email=<EMAIL>&amp;code=1104465363</pre>
</div>

<p>
Jeli wszystko przebiego poprawnie, serwer odpowie:
</p>

<div class="http">
<pre>reg_success:<b>UIN</b></pre>
</div>

<p>
Gdzie <tt><b>UIN</b></tt> to nowy numer, ktry wanie otrzymalimy.
</p>

<hr />

<a name="ch23"></a>
<h3>2.3. Usunicie konta</h3>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td width="20%"><b>Pole nagwka</b></td><td width="80%"><b>Warto</b></td></tr>
<tr class="tabf"><td><tt>HOST</tt></td><td><tt>register.gadu-gadu.pl</tt></td></tr>
<tr class="tabf"><td><tt>CIEKA</tt></td><td><tt>/appsvc/fmregister.asp</tt></td></tr>
</table>

<p></p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td width="20%"><b>Wysyamy pole</b></td><td width="80%"><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>fmnumber</tt></td><td>usuwany numer</td></tr>
<tr class="tabf"><td><tt>fmpwd</tt></td><td>haso</td></tr>
<tr class="tabf"><td><tt>delete</tt></td><td>warto ,,<tt>1</tt>''</td></tr>
<tr class="tabf"><td><tt>fmemail</tt></td><td>adres e-mail podany przy rejestracji</td></tr>
<tr class="tabf"><td><tt>email</tt></td><td>warto ,,<tt><EMAIL></tt>''</td></tr>
<tr class="tabf"><td><tt>code</tt></td><td>hash liczony z pl <tt>email</tt> i <tt>pwd</tt></td></tr>
</table>

<p>
Przykad:
</p>

<div class="http">
<pre>POST /appsvc/fmregister.asp HTTP/1.0
Host: register.gadu-gadu.pl
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)
Content-Length: 126
Pragma: no-cache
		
fmnumber=4617436&amp;fmpwd=haslo&amp;delete=1&amp;fmemail=<EMAIL>&amp;pwd=<PASSWORD>&amp;email=
deletedaccount@gadu%2Dgadu.pl&amp;code=477559883</pre>
</div>

<p>
Jeli wszystko przebiego poprawnie, serwer odpowie:
</p>

<div class="http">
<pre>reg_success:<b>UIN</b></pre>
</div>

<p>
Gdzie <tt><b>UIN</b></tt> to numer, ktry skasowalimy.
</p>

<hr />

<a name="ch24"></a>
<h3>2.4. <NAME></h3>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td width="20%"><b>Pole nagwka</b></td><td width="80%"><b>Warto</b></td></tr>
<tr class="tabf"><td><tt>HOST</tt></td><td><tt>register.gadu-gadu.pl</tt></td></tr>
<tr class="tabf"><td><tt>CIEKA</tt></td><td><tt>/appsvc/fmregister.asp</tt></td></tr>
</table>

<p></p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td width="20%"><b>Wysyamy pole</b></td><td width="80%"><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>fmnumber</tt></td><td>numer</td></tr>
<tr class="tabf"><td><tt>fmpwd</tt></td><td>stare haso</td></tr>
<tr class="tabf"><td><tt>pwd</tt></td><td>nowe haso</td></tr>
<tr class="tabf"><td><tt>fmemail</tt></td><td>adres e-mail podany przy rejestracji</td></tr>
<tr class="tabf"><td><tt>email</tt></td><td>nowy adres e-mail do przypomnienia hasa</td></tr>
<tr class="tabf"><td><tt>code</tt></td><td>hash liczony z pl <tt>email</tt> i <tt>pwd</tt></td></tr>
</table>

<p>
Jeli wszystko przebiego poprawnie, serwer odpowie:
</p>

<div class="http">
<pre>reg_success:<b>UIN</b></pre>
</div>

<p>
Jeli pole <tt>fmemail</tt> jest bdne, serwer odpowie:
</p>

<div class="http">
<pre>bademail</pre>
</div>

<hr />

<a name="ch25"></a>
<h3>2.5. Umieszczenie listy kontaktw na serwerze</h3>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td width="20%"><b>Pole nagwka</b></td><td width="80%"><b>Warto</b></td></tr>
<tr class="tabf"><td><tt>HOST</tt></td><td><tt>pubdir.gadu-gadu.pl</tt></td></tr>
<tr class="tabf"><td><tt>CIEKA</tt></td><td><tt>/appsvc/fmcontactsput.asp</tt></td></tr>
</table>

<p></p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td width="20%"><b>Wysyamy pole</b></td><td width="80%"><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>FmNum</tt></td><td>numer</td></tr>
<tr class="tabf"><td><tt>Pass</tt></td><td>haso</td></tr>
<tr class="tabf"><td><tt>Contacts</tt></td><td>dowolna ilo rekordw z kontaktami rozdzielone znakiem nowej linii ,,<tt>\r\n</tt>''</td></tr>
</table>

<p>
Format pojedynczego kontaktu:
</p>

<div class="c">
<pre>imie;nazwisko;pseudo;wyswietlane;telefon;grupa;uin;adres@email;0;;0;</pre>
</div>

<p>
Ostatnie 3 pola zostay dodane w wersji 4.9.3 i s zwizane z dwikami.
</p>

<p>
Przykad:
</p>

<div class="http">
<pre>POST /appsvc/fmcontactsput.asp HTTP/1.0
Host: pubdir.gadu-gadu.pl
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)
Content-Length: 110
Pragma: no-cache

FmNum=1000&amp;Pass=sekret&amp;Contacts=imie;nazwisko;pseudo;wyswietlane;+48123123123;grup
a1;1000;<EMAIL>;0;;0;</pre>
</div>

<p>
Jeli si udao, serwer odpowie:
</p>

<div class="http">
<pre>put_success:</pre>
</div>

<hr />

<a name="ch26"></a>
<h3>2.6. Pobranie listy kontaktw z serwera</h3>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td width="20%"><b>Pole nagwka</b></td><td width="80%"><b>Warto</b></td></tr>
<tr class="tabf"><td><tt>HOST</tt></td><td><tt>pubdir.gadu-gadu.pl</tt></td></tr>
<tr class="tabf"><td><tt>CIEKA</tt></td><td><tt>/appsvc/fmcontactsget.asp</tt></td></tr>
</table>

<p></p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td width="20%"><b>Wysyamy pole</b></td><td width="80%"><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>FmNum</tt></td><td>numer</td></tr>
<tr class="tabf"><td><tt>Pass</tt></td><td>haso</td></tr>
</table>

<p>
Przykad:
</p>

<div class="http">
<pre>POST /appsvc/fmcontactsget.asp HTTP/1.0
Host: pubdir.gadu-gadu.pl
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)
Content-Length: 22
Pragma: no-cache

FmNum=1000&amp;Pass=sekret</pre>
</div>

<p>
Jeli si udao, serwer odpowie:
</p>

<div class="http">
<pre>get_results:<b>rekord_1</b>
<b>rekord_2</b>
...
<b>rekord_N</b></pre>
</div>

<p>
Rekord ma taki sam format jak w <a href="ch26">2.6</a>.
</p>

<hr />

<a name="ch27"></a>
<h3>2.7. Usunicie listy kontaktw z serwera</h3>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td width="20%"><b>Pole nagwka</b></td><td width="80%"><b>Warto</b></td></tr>
<tr class="tabf"><td><tt>HOST</tt></td><td><tt>pubdir.gadu-gadu.pl</tt></td></tr>
<tr class="tabf"><td><tt>CIEKA</tt></td><td><tt>/appsvc/fmcontactsput.asp</tt></td></tr>
</table>

<p></p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td width="20%"><b>Wysyamy pole</b></td><td width="80%"><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>FmNum</tt></td><td>numer</td></tr>
<tr class="tabf"><td><tt>Pass</tt></td><td>haso</td></tr>
<tr class="tabf"><td><tt>Delete</tt></td><td>warto ,,<tt>1</tt>''</td></tr>
</table>

<p>
Przykad:
</p>

<div class="http">
<pre>POST /appsvc/fmcontactsput.asp HTTP/1.0
Host: pubdir.gadu-gadu.pl
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)
Content-Length: 31
Pragma: no-cache

FmNum=1000&amp;Pass=<PASSWORD>ret&amp;Delete=1</pre>
</div>

<p>
Jeli si udao, serwer odpowie:
</p>

<div class="http">
<pre>put_success:</pre>
</div>

<hr />

<a name="ch28"></a>
<h3>2.8. Przypomnienie hasa poczt</h3>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td width="20%"><b>Pole nagwka</b></td><td width="80%"><b>Warto</b></td></tr>
<tr class="tabf"><td><tt>HOST</tt></td><td><tt>retr.gadu-gadu.pl</tt></td></tr>
<tr class="tabf"><td><tt>CIEKA</tt></td><td><tt>/appsvc/fmsendpwd.asp</tt></td></tr>
</table>

<p></p>

<table class="tab" border="0" cellspacing="1" cellpadding="2" width="100%">
<tr class="tabh"><td width="20%"><b>Wysyamy pole</b></td><td width="80%"><b>Znaczenie</b></td></tr>
<tr class="tabf"><td><tt>userid</tt></td><td>numer</td></tr>
<tr class="tabf"><td><tt>code</tt></td><td>hash liczony z pola <tt>userid</tt></td></tr>
</table>

<p>
Jeli si udao, serwer odpowie:
</p>

<div class="http">
<pre>pwdsend_success</pre>
</div>

<hr />

<a name="ch3"></a>
<h2>3. Bezporednie poczenie</h2>

<p>
Opis znajduje si w pliku <a href="dcc-protocol.txt">dcc-protocol.txt</a>.
</p>

<hr />

<a name="ch4"></a>
<h2>4. Autorzy</h2>

<p>
Autorami powyszego opisu s:
</p>

<ul>
	<li><b><NAME></b> (wojtekka%irc.pl): pierwsza wersja opisu, poprawki, utrzymanie wszystkiego w porzdku.</li>
	<li><b><NAME></b> (speedy%atman.pl): opis nowoci w protokole GG 4.6, poprawki.</li>
	<li><b><NAME></b> (tomee%cpi.pl): badanie timeoutw.</li>
	<li><b><NAME></b> (adam.ludwikowski%wp.pl): wiele poprawek, wersje klientw, rozszerzone wiadomoci, powody nieobecnoci.</li>
	<li><b><NAME></b> (klith%hybrid.art.pl): czas otrzymania wiadomoci.</li>
	<li><b><NAME></b> (raf%regionet.regionet.pl): opis pocze konferencyjnych.</li>
	<li><b><NAME></b> (igipop%wsfiz.edu.pl): klasy wiadomoci przy odbieraniu zakolejkowanej.</li>
	<li><b><NAME></b> (ajron%wp.pl): informacje o remote_port, rodzaje potwierdze przy ctcp, GG_LOGIN_EXT.</li>
	<li><b><NAME></b> (pm%gadu-gadu.com): ilo kontaktow, pena skrzynka, pusta lista, maska audio, usugi HTTP, GG_LOGIN_EXT.</li>
	<li><b><NAME></b> (acc%interia.pl): potwierdzenie wiadomoci GG_CLASS_ACK.</li>
	<li><b><NAME></b> (kdebski%kki.net.pl): czas w stanach opisowych.</li>
	<li><b><NAME></b> (alfapawel%go2.pl): format czasu.</li>
	<li><b><NAME></b> (chilek%chilan.com): nowoci w 5.0.2.</li>
	<li><b><NAME></b> (rano%ranosoft.com): uzupenienie statusu opisowego, wersja 5.0.3.</li>
</ul>
{'fraction_non_alphanumeric': 0.21858020411782725, 'fraction_numerical': 0.03037582832175161, 'mean_word_length': 5.215452450145305, 'pattern_counts': {'":': 0, '<': 3529, '<?xml version=': 0, '>': 3529, 'https://': 0, 'lorem ipsum': 0, 'www.': 8, 'xml': 0}, 'pii_count': 4, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '187396', 'n_tokens_mistral': 29992, 'n_tokens_neox': 29384, 'n_words': 6171}