view src/protocols/gg/protocol.txt @ 9393:5667b1cdcb53

[gaim-migrate @ 10202] Make the firefox browser option with with firefox 0.9 when an instance of firefox is already running. Fixes bug 976056. This is backward compatible (with 0.8, at least). committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Fri, 25 Jun 2004 03:32:39 +0000 (2004-06-25)
parents 1ffac7cf4e94
children 40d04a6570de
line wrap: on
line source
---------------------------------------------------------------------------

                          Protok鶻 G*du-G*du 4.x

     (C) Copyright 2001 by Wojtek Kaniewski <wojtekka@irc.pl>,
                           Robert J. Wo�ny <speedy@atman.pl>,
                           Tomasz Jarzynka <tomee@cpi.pl>,
                           Adam Ludwikowski <adam.ludwikowski@wp.pl>,
                           Marek Kozina <klith@hybrid.art.pl>,
			   Rafa� Florek <raf@regionet.regionet.pl>,
			   Igor Popik <igipop@wsfiz.edu.pl>

--- 0) disclaimer ---------------------------------------------------------

opis protoko�u bazuj� na do�wiadczeniach przeprowadzonych na moim
domowym komputerze oraz informacjach przys�anych do mnie przez r鷽nych
ludzi. �aden klient g*du-g*du nie zosta� skrzywdzony podczas
przeprowadzania bada�, blabla.

--- 1) transmisja, format wszystkich pakiet�w -----------------------------

w przeciwie�stwie do zabawek typu icq, g*du-g*du korzysta z protoko�u tcp.
ka�dy pakiet zawiera dwa sta�e pola:

        struct gg_header {
		int type;		/* typ pakietu */
		int length;		/* d�ugo倶 reszty pakietu */
	};

dla u�atwienia przyjmuj� nast�puj�ce d�ugo�ci zmiennych: sizeof(char) = 1,
sizeof(short) = 2, sizeof(int) = 4. oczywi�cie wszystkie liczby s� zgodnie
z intelowym endianem. zak�adam te�, �e wszystkie zmienne s� bez znaku. nie
chce mi si� wsz�dzie pisa� `unsigned'.

pola, co do kt�rych znaczenia nie mam pewno�ci, lub w og�le nie mam poj�cia,
sk�d si� tam wzi螻y, oznaczam `dunno'.

--- 2) zanim si� po咳czymy -------------------------------------------------

�eby wiedzie�, z jakim serwerem mamy si� po咳czy�, nale�y poudawa� przez
chwil� Internet Explorera, po咳czy� si� z hostem `appmsg.gadu-gadu.pl'.

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

oryginalny klient mo�e wys�a� jeden z podanych identyfikator�w przegl�darki:

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

nowsze wersje klienta do zapytania dodaj� r�wnie� `version=...' opisuj�ce,
z jakim klientem serwer ma do czynienia. jednak ze wzgl�du na mo�liwe
r鷽nice w protokole, lepiej pomija� ten parametr i uwaga� GG 4.0. w ka�dym
razie na to zapytanie serwer powinien odpowiedzie�:

	HTTP/1.0 200 OK
	
	0 1 0 217.17.33.21:8074 217.17.33.21 217.17.33.21

co to oznacza? nie mam poj�cia ;) wygl�da na to, �e ca�y g*du-g*du jest
przemy�lany i w przysz�o�ci b�dzie mo�na u�ywa� r鷽nych serwer�w do r鷽nych
rzeczy, typu szukanie, obs�uga klient�w itd. p�ki co, 咳czy� si� trzeba na
pierwszy adres (tak, ten z portem).
Je�eli po咳czenie z portem 8074 nie wyjdzie z jaki� specyficznych powod�w -
mo�na si� 咳czy� na port 443. 

--- 3) logowanie si� -------------------------------------------------------

po po咳czeniu si� portem serwera g*du-g*du, dostajemy pakiet typu 0x0001,
kt�ry na potrzeby tego dokumentu nazwiemy:

	#define GG_WELCOME 0x0001

reszta pakietu zawiera liczb�, na podstawie kt�rej liczony jest hash z has�a
klienta:

	struct gg_welcome {
		int key;		/* klucz szyfrowania has�a */
	};
	
kiedy mamy ju� t� warto倶 mo�emy odes�a� pakiet logowania

	#define GG_LOGIN 0x000c

musimy poda� kilka informacji:

	struct gg_login {
		int uin;		/* tw�j numerek */
		int hash;		/* hash has�a */
		int status;		/* status na dzie� dobry */
		int version;		/* wersja klienta */
		int local_ip;		/* m�j adres ip */
		short local_port;	/* port, na kt�rym s�ucham */
	};

jak obliczy� hash has�a? hmm... nic prostszego. do ka�dej literki has�a
dodaje si� jedynk�, mno�y wszystko razem, a potem przez liczb� podan� przez
serwer. 

	for (hash = 1; *passwd; passwd++)
		hash *= (*passwd) + 1;

zrozumia�e, racja? liczba oznaczaj�ca wersj� mo�e by� jedn� z poni�szych:

	0x11 - 4.6.1
	0x10 - 4.5.22, 4.5.21, 4.5.19, 4.5.17, 4.5.15
	0x0f - 4.5.12
	0x0b - 4.0.30, 4.0.29, 4.0.28, 4.0.25

oczywi�cie nie s� to wszystkie mo�liwe wersje klient�w, lecz te, kt�re
uda�o si� sprawdzi�. najbezpieczniej b�dzie przedstawia� si� jako ta
wersja, kt�rej ficzer�w u�ywamy. wiadomo, �e 4.0.x nie obs�ugiwa�y trybu
ukrytego, ani tylko dla znajomych itd.

je�li wszystko si� powiedzie, dostaniemy w odpowiedzi pakiet typu

	#define GG_LOGIN_OK 0x0003

z polem header->length = 0, lub pakiet
	
	#define GG_LOGIN_FAILED 0x0009

--- 4) zmiana statusu -----------------------------------------------------

g*du-g*du przewiduje trzy stany klienta, kt�re zmieniamy pakietem

	#define GG_NEW_STATUS 0x0002

	#define GG_STATUS_NOT_AVAIL 0x0001	/* roz咳czony */
	#define GG_STATUS_AVAIL 0x0002		/* dost�pny */
	#define GG_STATUS_BUSY 0x0003		/* zaj�ty */
	#define GG_STATUS_INVISIBLE 0x0014	/* niewidoczny */

	#define GG_STATUS_FRIENDS_MASK 0x8000	/* tylko dla przyjaci鶻 */
	
	struct gg_new_status {
		int status;			/* na jaki zmieni�? */
	}

nale�y pami�ta�, �eby przed roz咳czeniem si� z serwerem nale�y zmieni�
stan na GG_STATUS_NOT_AVAIL. je�li ma by� widoczny tylko dla przyjaci鶻,
nale�y doda� GG_STATUS_FRIENDS do normalnej warto�ci stanu.

--- 5) ludzie przychodz�, ludzie odchodz� ---------------------------------

zaraz po zalogowaniu mo�emy wys�a� serwerowi list� ludzik�w w naszej li�cie
kontakt�w, �eby dowiedzie� si�, czy s� w tej chwili dost�pni. pakiet zawiera
dowoln� ilo倶 struktur gg_notify:

	#define GG_NOTIFY 0x0010
	
	struct gg_notify {
		int uin;		/* numerek danej osoby */
		char dunno1;		/* == 3 */
	};
	
je�li kto� jest, serwer odpowie pakietem zawieraj�cym jedn� lub wi�cej
struktur gg_notify_reply:

	#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 kt�rym s�ucha klient */
		int version;		/* wersja klienta */
		short dunno1;		/* znowu port? */
	};

je�li klient nie obs�uguje po咳cze� mi�dzy klientami (np. g*du-g*du 3.x)
zamiast adresu ip jest 0, zamiast portu mo�e by� 0, 1, 2... niewa�ne ;)
port mo�e przyjmowa� warto倶 1, je�li klient znajduje si� za jakim�
firewallem lub innym urz�dzeniem robi�cym NAT. w ka�dym razie, je�li kto�
si� pojawi w trakcie pracy, r�wnie� zostanie przys�any ten pakiet.
proste? proste :)

�eby doda� kogo� do listy w trakcie pracy, trzeba wys�a� ni�ej opisany
pakiet. jego format jest identyczny jak przy GG_NOTIFY.

	#define GG_ADD 0x000d
	
	struct gg_add {
		int uin;		/* numerek */
		char dunno1;		/* == 3 */
	};

je�li kto� opu�ci g*du-g*du lub zmieni stan, otrzymamy pakiet

	#define GG_STATUS 0x0002
	
	struct gg_status {
		int uin;		/* numerek */
		int status;		/* nowy stan */
	};

--- 6) wysy�anie wiadomo�ci ------------------------------------------------
	
przejd�my do sedna sprawy ;)

	#define GG_SEND_MSG 0x000b

	#define GG_CLASS_QUEUED 0x0001	/* tylko przy odbieraniu */
	#define GG_CLASS_MSG 0x0004
	#define GG_CLASS_CHAT 0x0008
	#define GG_CLASS_UNKNOWN_1 0x0020

	struct gg_send_msg {
		int recipient;
		int seq;
		int class;
		char message[];
	};

wiadomo, odbiorca. numer sekwencyjny, kt�ry wykorzystujemy potem do
potwierdzenia. nie wykluczone, �e w jakis spos�b odr鷽nia si� r鷽ne
rozmowy za pomoc� cz蟠ci bajt�w, ale raczej nie ma znaczenia. klasa
wiadomo�ci pozwala odr鷽ni�, czy wiadomo倶 ma si� pokaza� w osobym
okienku czy jako kolejna linijka w okienku rozmowy. wygl�da na to,
�e to jaka� bitmapa, wi�c najlepiej ola� inne bity ni� 0x0e. (czasem
klienty wysy�aj� 0x04, czasem 0x24 -- widocznie 0x20 to te� jaka�
flaga). je�li odbiorca by� niedost�pny podczas wysy�ania wiadomo�ci,
zostanie zaznaczony bit 0x01.

oryginalny klient wysy�aj�c wiadomo倶 do kilku u�ytkownik�w, wysy�a po
prostu kilka takich samych pakiet�w z r鷽nymi numerkami odbiorc�w. nie
ma osobnego pakietu do tego. natomiast je�li chodzi o ,,konferencyjn�''
do pakietu doklejana jest za ,,char message[];'' nast�puj�ca struktura:

	struct gg_send_recipients {
		char flag;		/* == 1 */
		int count;		/* ilo倶 odbiorc�w */
		int recipients[];	/* tablica odbiorc�w */
	};

na przyk�ad, by wys�a� do trzech ludzi, nale�y wys�a� pakiet:

	- -- --- --+--+--+--+--+--+--+-----------+-----------+
          tre倶    |\0|\1|    0x02   |    uin1   |   uin2    |
	- -- -- ---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

serwer po otrzymaniu wiadomo�ci odsy�a informacj� o tym. przy okazji
m�wi, czy wiadomo倶 dotar�a do odbiorcy (status == GG_ACK_DELIVERED),
czy mo�e jest offline i zosta�a zakolejkowana (GG_ACK_QUEUED):

	#define GG_SEND_MSG_ACK 0x0005
	
	#define GG_ACK_DELIVERED 0x0002
	#define GG_ACK_QUEUED 0x0003

	struct gg_send_msg_ack {
		int status;
		int recipient;
		int seq;
	};

numer sekwencyjny i adresat ten sam, co przy wysy�aniu.

--- 7) otrzymywanie wiadomo�ci ---------------------------------------------

zbyt wiele wyja�nie� chyba nie trzeba. wiadomo od kogo. drugie pole to
najprawdopodobniej jaki� numerek sekwencyjny. trzecie oznacza czas nadania
wiadomo�ci. klasa wiadomo�ci taka sama jak przy wysy�aniu:

	#define GG_RECV_MSG 0x000a
	
	struct gg_recv_msg {
		int sender;
		int seq;
		int time;
		int class;
		char message[];
	};

w przypadku pakiet�w ,,konferencyjnych'' na koncu pakietu doklejona jest
struktura identyczna ze struct gg_send_recipients zawieraj�ca pozosta�ych
rozm�wc�w.

--- 8) ping/pong -----------------------------------------------------------

od czasu do czasu klient wysy�a pakiet a'la ping do serwera i dostaje pust�
odpowied�. o ile dobrze pami�tam, serwer roz咳cza si� po up�ywie 5 minut od
otrzymania ostatniej informacji.

	#define GG_PING 0x0008
	
	/* nie ma niczego */
	
	#define GG_PONG 0x0007
	
	/* nie ma niczego */

--- 9) podzi�kowania -------------------------------------------------------

sw�j wk�ad w poznanie protoko�u mieli:
 - Robert J. Wo�ny <speedy@atman.pl>:
   opis nowo�ci w protokole GG 4.6,
 - Tomasz Jarzynka <tomee@cpi.pl>:
   badanie timeout�w,
 - Adam Ludwikowski <adam.ludwikowski@wp.pl>:
   wiele r鷽nych poprawek do tekstu, badanie wersji,
 - Marek Kozina <klith@hybrid.art.pl>:
   czas otrzymania wiadomo�ci,
 - Rafa� Florek <raf@regionet.regionet.pl>:
   konferencje,
 - Igor Popik <igipop@wsfiz.edu.pl>:
   klasy wiadomo�ci przy odbieraniu zakolejkowanej.

----------------------------------------------------------------------------

$Id: protocol.txt 2819 2001-11-27 22:54:32Z warmenhoven $