Mercurial > pidgin
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 $ +