diff src/protocols/gg/protocol.txt @ 2393:a7ecfd3f7714

[gaim-migrate @ 2406] Arkadiusz Miskiewicz\'s Gadu-Gadu plugin. I was able to figure out enough polish to be able to download Gadu-Gadu, create an account, and test the plugin. Imagine my shock when I got my info and it said I was a woman. Whoops. Also splitting plugins.c so that non-gtk stuff is in modules.c. gaim-core is almost ready for protocol implantaion. Also fixing an IRC bug. Also patiently waiting for anoncvs_gaim's lock in /cvsroot/gaim/gaim/pixmaps committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Sat, 29 Sep 2001 23:06:30 +0000
parents
children 1ffac7cf4e94
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/gg/protocol.txt	Sat Sep 29 23:06:30 2001 +0000
@@ -0,0 +1,248 @@
+---------------------------------------------------------------------------
+
+                         protokół g*du-g*du 4.x
+        (c) copyright 2001 by wojtek kaniewski <wojtekka@irc.pl>
+
+--- 0) disclaimer ---------------------------------------------------------
+
+wszystkie informacje bazują na doświadczeniach przeprowadzonych na moim
+domowym komputerze. ż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
+
+na co powinniśmy dostać odpowiedź w stylu:
+
+	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).
+
+--- 3) logowanie się -------------------------------------------------------
+
+po połączeniu się portem 8074 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 dunno1;		/* == 0x0b */
+		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? 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 dunno1;		/* == 0x0b */
+		short dunno2;		/* 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 jest 2. nieważne ;) 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_MSG 0x0004
+	#define GG_CLASS_CHAT 0x0008
+
+	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ż 0x0f. (czasem
+klienty wysyłają 0x04, czasem 0x24)
+
+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. nieznane pola to
+coś a'la numer sekwencyjny albo identyfikator okienka z rozmową albo nowe
+dane dla setiathome. klasa wiadomości taka sama jak przy wysyłaniu:
+
+	#define GG_RECV_MSG 0x000a
+	
+	struct gg_recv_msg {
+		int sender;
+		int dunno1;
+		int dunno2;
+		int class;
+		char message[];
+	};
+
+--- 8) otrzymywanie wiadomości ---------------------------------------------
+
+od czasu do czasu klient wysyła pakiet a'la ping do serwera i dostaje pustą
+odpowiedź. ciężko stwierdzić, czy serwer wywala, jeśli nie dostanie pinga
+przez jakiś czas, czy klient się rozłącza, jeśli serwer mu nie odpowie.
+jakoś nie chce mi się sprawdzać ;)
+
+	#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 miał Robert Woźny, który opisał nowości
+w GG 4.6.
+
+----------------------------------------------------------------------------
+
+$Id: protocol.txt 2406 2001-09-29 23:06:30Z warmenhoven $
+