Mercurial > pidgin.yaz
comparison 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 |
comparison
equal
deleted
inserted
replaced
2392:9965c0bbdb7c | 2393:a7ecfd3f7714 |
---|---|
1 --------------------------------------------------------------------------- | |
2 | |
3 protokół g*du-g*du 4.x | |
4 (c) copyright 2001 by wojtek kaniewski <wojtekka@irc.pl> | |
5 | |
6 --- 0) disclaimer --------------------------------------------------------- | |
7 | |
8 wszystkie informacje bazują na doświadczeniach przeprowadzonych na moim | |
9 domowym komputerze. żaden klient g*du-g*du nie został skrzywdzony podczas | |
10 przeprowadzania badań, blabla. | |
11 | |
12 --- 1) transmisja, format wszystkich pakietów ----------------------------- | |
13 | |
14 w przeciwieństwie do zabawek typu icq, g*du-g*du korzysta z protokołu tcp. | |
15 każdy pakiet zawiera dwa stałe pola: | |
16 | |
17 struct gg_header { | |
18 int type; /* typ pakietu */ | |
19 int length; /* długość reszty pakietu */ | |
20 }; | |
21 | |
22 dla ułatwienia przyjmuję następujące długości zmiennych: sizeof(char) = 1, | |
23 sizeof(short) = 2, sizeof(int) = 4. oczywiście wszystkie liczby są zgodnie | |
24 z intelowym endianem. zakładam też, że wszystkie zmienne są bez znaku. nie | |
25 chce mi się wszędzie pisać `unsigned'. | |
26 | |
27 pola, co do których znaczenia nie mam pewności, lub w ogóle nie mam pojęcia, | |
28 skąd się tam wzięły, oznaczam `dunno'. | |
29 | |
30 --- 2) zanim się połączymy ------------------------------------------------- | |
31 | |
32 żeby wiedzieć, z jakim serwerem mamy się połączyć, należy poudawać przez | |
33 chwilę Internet Explorera, połączyć się z hostem `appmsg.gadu-gadu.pl'. | |
34 | |
35 GET /appsvc/appmsg.asp?fmnumber=<tutaj_numerek_gg> HTTP/1.0 | |
36 Host: appmsg.gadu-gadu.pl | |
37 User-Agent: Mozilla/4.7 [en] (Win98; I) | |
38 Pragma: no-cache | |
39 | |
40 na co powinniśmy dostać odpowiedź w stylu: | |
41 | |
42 HTTP/1.0 200 OK | |
43 | |
44 0 1 0 217.17.33.21:8074 217.17.33.21 217.17.33.21 | |
45 | |
46 co to oznacza? nie mam pojęcia ;) wygląda na to, że cały g*du-g*du jest | |
47 przemyślany i w przyszłości będzie można używać różnych serwerów do różnych | |
48 rzeczy, typu szukanie, obsługa klientów itd. póki co, łączyć się trzeba na | |
49 pierwszy adres (tak, ten z portem). | |
50 | |
51 --- 3) logowanie się ------------------------------------------------------- | |
52 | |
53 po połączeniu się portem 8074 serwera g*du-g*du, dostajemy pakiet typu 0x0001, | |
54 który na potrzeby tego dokumentu nazwiemy: | |
55 | |
56 #define GG_WELCOME 0x0001 | |
57 | |
58 reszta pakietu zawiera liczbę, na podstawie której liczony jest hash z hasła | |
59 klienta: | |
60 | |
61 struct gg_welcome { | |
62 int key; /* klucz szyfrowania hasła */ | |
63 }; | |
64 | |
65 kiedy mamy już tą wartość możemy odesłać pakiet logowania | |
66 | |
67 #define GG_LOGIN 0x000c | |
68 | |
69 musimy podać kilka informacji: | |
70 | |
71 struct gg_login { | |
72 int uin; /* twój numerek */ | |
73 int hash; /* hash hasła */ | |
74 int status; /* status na dzień dobry */ | |
75 int dunno1; /* == 0x0b */ | |
76 int local_ip; /* mój adres ip */ | |
77 short local_port; /* port, na którym słucham */ | |
78 }; | |
79 | |
80 jak obliczyć hash hasła? hmm... nic prostszego. do każdej literki hasła | |
81 dodaje się jedynkę, mnoży wszystko razem, a potem przez liczbę podaną przez | |
82 serwer. | |
83 | |
84 for (hash = 1; *passwd; passwd++) | |
85 hash *= (*passwd) + 1; | |
86 | |
87 zrozumiałe, racja? jeśli wszystko się powiedzie, dostaniemy w odpowiedzi | |
88 pakiet typu | |
89 | |
90 #define GG_LOGIN_OK 0x0003 | |
91 | |
92 z polem header->length = 0, lub pakiet | |
93 | |
94 #define GG_LOGIN_FAILED 0x0009 | |
95 | |
96 --- 4) zmiana statusu ----------------------------------------------------- | |
97 | |
98 g*du-g*du przewiduje trzy stany klienta, które zmieniamy pakietem | |
99 | |
100 #define GG_NEW_STATUS 0x0002 | |
101 | |
102 #define GG_STATUS_NOT_AVAIL 0x0001 /* rozłączony */ | |
103 #define GG_STATUS_AVAIL 0x0002 /* dostępny */ | |
104 #define GG_STATUS_BUSY 0x0003 /* zajęty */ | |
105 #define GG_STATUS_INVISIBLE 0x0014 /* niewidoczny */ | |
106 | |
107 #define GG_STATUS_FRIENDS_MASK 0x8000 /* tylko dla przyjaciół */ | |
108 | |
109 struct gg_new_status { | |
110 int status; /* na jaki zmienić? */ | |
111 } | |
112 | |
113 należy pamiętać, żeby przed rozłączeniem się z serwerem należy zmienić | |
114 stan na GG_STATUS_NOT_AVAIL. jeśli ma być widoczny tylko dla przyjaciół, | |
115 należy dodać GG_STATUS_FRIENDS do normalnej wartości stanu. | |
116 | |
117 --- 5) ludzie przychodzą, ludzie odchodzą --------------------------------- | |
118 | |
119 zaraz po zalogowaniu możemy wysłać serwerowi listę ludzików w naszej liście | |
120 kontaktów, żeby dowiedzieć się, czy są w tej chwili dostępni. pakiet zawiera | |
121 dowolną ilość struktur gg_notify: | |
122 | |
123 #define GG_NOTIFY 0x0010 | |
124 | |
125 struct gg_notify { | |
126 int uin; /* numerek danej osoby */ | |
127 char dunno1; /* == 3 */ | |
128 }; | |
129 | |
130 jeśli ktoś jest, serwer odpowie pakietem zawierającym jedną lub więcej | |
131 struktur gg_notify_reply: | |
132 | |
133 #define GG_NOTIFY_REPLY 0x000c /* tak, to samo co GG_LOGIN */ | |
134 | |
135 struct gg_notify_reply { | |
136 int uin; /* numerek */ | |
137 int status; /* status danej osoby */ | |
138 int remote_ip; /* adres ip delikwenta */ | |
139 short remote_port; /* port, na którym słucha klient */ | |
140 int dunno1; /* == 0x0b */ | |
141 short dunno2; /* znowu port? */ | |
142 }; | |
143 | |
144 jeśli klient nie obsługuje połączeń między klientami (np. g*du-g*du 3.x) | |
145 zamiast adresu ip jest 0, zamiast portu jest 2. nieważne ;) w każdym razie, | |
146 jeśli ktoś się pojawi w trakcie pracy, również zostanie przysłany ten | |
147 pakiet. proste? proste :) | |
148 | |
149 żeby dodać kogoś do listy w trakcie pracy, trzeba wysłać niżej opisany | |
150 pakiet. jego format jest identyczny jak przy GG_NOTIFY. | |
151 | |
152 #define GG_ADD 0x000d | |
153 | |
154 struct gg_add { | |
155 int uin; /* numerek */ | |
156 char dunno1; /* == 3 */ | |
157 }; | |
158 | |
159 jeśli ktoś opuści g*du-g*du lub zmieni stan, otrzymamy pakiet | |
160 | |
161 #define GG_STATUS 0x0002 | |
162 | |
163 struct gg_status { | |
164 int uin; /* numerek */ | |
165 int status; /* nowy stan */ | |
166 }; | |
167 | |
168 --- 6) wysyłanie wiadomości ------------------------------------------------ | |
169 | |
170 przejdźmy do sedna sprawy ;) | |
171 | |
172 #define GG_SEND_MSG 0x000b | |
173 | |
174 #define GG_CLASS_MSG 0x0004 | |
175 #define GG_CLASS_CHAT 0x0008 | |
176 | |
177 struct gg_send_msg { | |
178 int recipient; | |
179 int seq; | |
180 int class; | |
181 char message[]; | |
182 }; | |
183 | |
184 wiadomo, odbiorca. numer sekwencyjny, który wykorzystujemy potem do | |
185 potwierdzenia. nie wykluczone, że w jakis sposób odróżnia się różne | |
186 rozmowy za pomocą części bajtów, ale raczej nie ma znaczenia. klasa | |
187 wiadomości pozwala odróżnić, czy wiadomość ma się pokazać w osobym | |
188 okienku czy jako kolejna linijka w okienku rozmowy. wygląda na to, | |
189 że to jakaś bitmapa, więc najlepiej olać inne bity niż 0x0f. (czasem | |
190 klienty wysyłają 0x04, czasem 0x24) | |
191 | |
192 serwer po otrzymaniu wiadomości odsyła informację o tym. przy okazji | |
193 mówi, czy wiadomość dotarła do odbiorcy (status == GG_ACK_DELIVERED), | |
194 czy może jest offline i została zakolejkowana (GG_ACK_QUEUED): | |
195 | |
196 #define GG_SEND_MSG_ACK 0x0005 | |
197 | |
198 #define GG_ACK_DELIVERED 0x0002 | |
199 #define GG_ACK_QUEUED 0x0003 | |
200 | |
201 struct gg_send_msg_ack { | |
202 int status; | |
203 int recipient; | |
204 int seq; | |
205 }; | |
206 | |
207 numer sekwencyjny i adresat ten sam, co przy wysyłaniu. | |
208 | |
209 --- 7) otrzymywanie wiadomości --------------------------------------------- | |
210 | |
211 zbyt wiele wyjaśnień chyba nie trzeba. wiadomo od kogo. nieznane pola to | |
212 coś a'la numer sekwencyjny albo identyfikator okienka z rozmową albo nowe | |
213 dane dla setiathome. klasa wiadomości taka sama jak przy wysyłaniu: | |
214 | |
215 #define GG_RECV_MSG 0x000a | |
216 | |
217 struct gg_recv_msg { | |
218 int sender; | |
219 int dunno1; | |
220 int dunno2; | |
221 int class; | |
222 char message[]; | |
223 }; | |
224 | |
225 --- 8) otrzymywanie wiadomości --------------------------------------------- | |
226 | |
227 od czasu do czasu klient wysyła pakiet a'la ping do serwera i dostaje pustą | |
228 odpowiedź. ciężko stwierdzić, czy serwer wywala, jeśli nie dostanie pinga | |
229 przez jakiś czas, czy klient się rozłącza, jeśli serwer mu nie odpowie. | |
230 jakoś nie chce mi się sprawdzać ;) | |
231 | |
232 #define GG_PING 0x0008 | |
233 | |
234 /* nie ma niczego */ | |
235 | |
236 #define GG_PONG 0x0007 | |
237 | |
238 /* nie ma niczego */ | |
239 | |
240 --- 9) podziękowania ------------------------------------------------------- | |
241 | |
242 swój wkład w poznanie protokołu miał Robert Woźny, który opisał nowości | |
243 w GG 4.6. | |
244 | |
245 ---------------------------------------------------------------------------- | |
246 | |
247 $Id: protocol.txt 2406 2001-09-29 23:06:30Z warmenhoven $ | |
248 |