Mercurial > pidgin
comparison libpurple/protocols/qq/buddy_list.c @ 23048:9a5d140400f1
patch-02-fix-multiarch
author | SHiNE CsyFeK <csyfek@gmail.com> |
---|---|
date | Tue, 24 Jun 2008 11:58:57 +0000 |
parents | 217fffe3f46f |
children | 51dbe83ebbd3 |
comparison
equal
deleted
inserted
replaced
23046:13a9b56f83b0 | 23048:9a5d140400f1 |
---|---|
62 | 62 |
63 /* get a list of online_buddies */ | 63 /* get a list of online_buddies */ |
64 void qq_send_packet_get_buddies_online(PurpleConnection *gc, guint8 position) | 64 void qq_send_packet_get_buddies_online(PurpleConnection *gc, guint8 position) |
65 { | 65 { |
66 qq_data *qd; | 66 qq_data *qd; |
67 guint8 *raw_data, *cursor; | 67 guint8 *raw_data; |
68 gint bytes = 0; | |
68 | 69 |
69 qd = (qq_data *) gc->proto_data; | 70 qd = (qq_data *) gc->proto_data; |
70 raw_data = g_newa(guint8, 5); | 71 raw_data = g_newa(guint8, 5); |
71 cursor = raw_data; | |
72 | 72 |
73 /* 000-000 get online friends cmd | 73 /* 000-000 get online friends cmd |
74 * only 0x02 and 0x03 returns info from server, other valuse all return 0xff | 74 * only 0x02 and 0x03 returns info from server, other valuse all return 0xff |
75 * I can also only send the first byte (0x02, or 0x03) | 75 * I can also only send the first byte (0x02, or 0x03) |
76 * and the result is the same */ | 76 * and the result is the same */ |
77 create_packet_b(raw_data, &cursor, QQ_GET_ONLINE_BUDDY_02); | 77 bytes += qq_put8(raw_data + bytes, QQ_GET_ONLINE_BUDDY_02); |
78 /* 001-001 seems it supports 255 online buddies at most */ | 78 /* 001-001 seems it supports 255 online buddies at most */ |
79 create_packet_b(raw_data, &cursor, position); | 79 bytes += qq_put8(raw_data + bytes, position); |
80 /* 002-002 */ | 80 /* 002-002 */ |
81 create_packet_b(raw_data, &cursor, 0x00); | 81 bytes += qq_put8(raw_data + bytes, 0x00); |
82 /* 003-004 */ | 82 /* 003-004 */ |
83 create_packet_w(raw_data, &cursor, 0x0000); | 83 bytes += qq_put16(raw_data + bytes, 0x0000); |
84 | 84 |
85 qq_send_cmd(gc, QQ_CMD_GET_FRIENDS_ONLINE, TRUE, 0, TRUE, raw_data, 5); | 85 qq_send_cmd(gc, QQ_CMD_GET_FRIENDS_ONLINE, TRUE, 0, TRUE, raw_data, 5); |
86 qd->last_get_online = time(NULL); | 86 qd->last_get_online = time(NULL); |
87 } | 87 } |
88 | 88 |
89 /* position starts with 0x0000, | 89 /* position starts with 0x0000, |
90 * server may return a position tag if list is too long for one packet */ | 90 * server may return a position tag if list is too long for one packet */ |
91 void qq_send_packet_get_buddies_list(PurpleConnection *gc, guint16 position) | 91 void qq_send_packet_get_buddies_list(PurpleConnection *gc, guint16 position) |
92 { | 92 { |
93 guint8 *raw_data, *cursor; | 93 guint8 raw_data[16] = {0}; |
94 gint data_len; | 94 gint bytes = 0; |
95 | 95 |
96 data_len = 3; | |
97 raw_data = g_newa(guint8, data_len); | |
98 cursor = raw_data; | |
99 /* 000-001 starting position, can manually specify */ | 96 /* 000-001 starting position, can manually specify */ |
100 create_packet_w(raw_data, &cursor, position); | 97 bytes += qq_put16(raw_data + bytes, position); |
101 /* before Mar 18, 2004, any value can work, and we sent 00 | 98 /* before Mar 18, 2004, any value can work, and we sent 00 |
102 * I do not know what data QQ server is expecting, as QQ2003iii 0304 itself | 99 * I do not know what data QQ server is expecting, as QQ2003iii 0304 itself |
103 * even can sending packets 00 and get no response. | 100 * even can sending packets 00 and get no response. |
104 * Now I tested that 00,00,00,00,00,01 work perfectly | 101 * Now I tested that 00,00,00,00,00,01 work perfectly |
105 * March 22, found the 00,00,00 starts to work as well */ | 102 * March 22, found the 00,00,00 starts to work as well */ |
106 create_packet_b(raw_data, &cursor, 0x00); | 103 bytes += qq_put8(raw_data + bytes, 0x00); |
107 | 104 |
108 qq_send_cmd(gc, QQ_CMD_GET_FRIENDS_LIST, TRUE, 0, TRUE, raw_data, data_len); | 105 qq_send_cmd(gc, QQ_CMD_GET_FRIENDS_LIST, TRUE, 0, TRUE, raw_data, bytes); |
109 } | 106 } |
110 | 107 |
111 /* get all list, buddies & Quns with groupsid support */ | 108 /* get all list, buddies & Quns with groupsid support */ |
112 void qq_send_packet_get_all_list_with_group(PurpleConnection *gc, guint32 position) | 109 void qq_send_packet_get_all_list_with_group(PurpleConnection *gc, guint32 position) |
113 { | 110 { |
114 guint8 *raw_data, *cursor; | 111 guint8 raw_data[16] = {0}; |
115 gint data_len; | 112 gint bytes = 0; |
116 | 113 |
117 data_len = 10; | |
118 raw_data = g_newa(guint8, data_len); | |
119 cursor = raw_data; | |
120 /* 0x01 download, 0x02, upload */ | 114 /* 0x01 download, 0x02, upload */ |
121 create_packet_b(raw_data, &cursor, 0x01); | 115 bytes += qq_put8(raw_data + bytes, 0x01); |
122 /* unknown 0x02 */ | 116 /* unknown 0x02 */ |
123 create_packet_b(raw_data, &cursor, 0x02); | 117 bytes += qq_put8(raw_data + bytes, 0x02); |
124 /* unknown 00 00 00 00 */ | 118 /* unknown 00 00 00 00 */ |
125 create_packet_dw(raw_data, &cursor, 0x00000000); | 119 bytes += qq_put32(raw_data + bytes, 0x00000000); |
126 create_packet_dw(raw_data, &cursor, position); | 120 bytes += qq_put32(raw_data + bytes, position); |
127 | 121 |
128 qq_send_cmd(gc, QQ_CMD_GET_ALL_LIST_WITH_GROUP, TRUE, 0, TRUE, raw_data, data_len); | 122 qq_send_cmd(gc, QQ_CMD_GET_ALL_LIST_WITH_GROUP, TRUE, 0, TRUE, raw_data, bytes); |
129 } | 123 } |
130 | 124 |
131 static void _qq_buddies_online_reply_dump_unclear(qq_friends_online_entry *fe) | 125 static void _qq_buddies_online_reply_dump_unclear(qq_friends_online_entry *fe) |
132 { | 126 { |
133 GString *dump; | 127 GString *dump; |
149 | 143 |
150 /* process the reply packet for get_buddies_online packet */ | 144 /* process the reply packet for get_buddies_online packet */ |
151 void qq_process_get_buddies_online_reply(guint8 *buf, gint buf_len, PurpleConnection *gc) | 145 void qq_process_get_buddies_online_reply(guint8 *buf, gint buf_len, PurpleConnection *gc) |
152 { | 146 { |
153 qq_data *qd; | 147 qq_data *qd; |
154 gint len, bytes; | 148 gint len, bytes, bytes_buddy; |
155 guint8 *data, *cursor, position; | 149 guint8 *data, position; |
156 PurpleBuddy *b; | 150 PurpleBuddy *b; |
157 qq_buddy *q_bud; | 151 qq_buddy *q_bud; |
158 qq_friends_online_entry *fe; | 152 qq_friends_online_entry *fe; |
159 | 153 |
160 g_return_if_fail(buf != NULL && buf_len != 0); | 154 g_return_if_fail(buf != NULL && buf_len != 0); |
161 | 155 |
162 qd = (qq_data *) gc->proto_data; | 156 qd = (qq_data *) gc->proto_data; |
163 len = buf_len; | 157 len = buf_len; |
164 data = g_newa(guint8, len); | 158 data = g_newa(guint8, len); |
165 cursor = data; | |
166 | 159 |
167 purple_debug(PURPLE_DEBUG_INFO, "QQ", "processing get_buddies_online_reply\n"); | 160 purple_debug(PURPLE_DEBUG_INFO, "QQ", "processing get_buddies_online_reply\n"); |
168 | 161 |
169 if (qq_decrypt(buf, buf_len, qd->session_key, data, &len)) { | 162 if (!qq_decrypt(buf, buf_len, qd->session_key, data, &len)) { |
170 | 163 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Error decrypt buddies online"); |
171 _qq_show_packet("Get buddies online reply packet", data, len); | 164 return; |
172 | 165 } |
173 read_packet_b(data, &cursor, len, &position); | 166 |
174 | 167 _qq_show_packet("Get buddies online reply packet", data, len); |
175 fe = g_newa(qq_friends_online_entry, 1); | 168 |
176 fe->s = g_newa(qq_buddy_status, 1); | 169 bytes = 0; |
177 | 170 bytes += qq_get8(&position, data + bytes); |
178 while (cursor < (data + len)) { | 171 |
179 /* based on one online buddy entry */ | 172 fe = g_newa(qq_friends_online_entry, 1); |
180 bytes = 0; | 173 fe->s = g_newa(qq_buddy_status, 1); |
181 /* 000-030 qq_buddy_status */ | 174 |
182 bytes += qq_buddy_status_read(data, &cursor, len, fe->s); | 175 while (bytes < len) { |
183 /* 031-032: unknown4 */ | 176 /* set flag */ |
184 bytes += read_packet_w(data, &cursor, len, &fe->unknown1); | 177 bytes_buddy = bytes; |
185 /* 033-033: flag1 */ | 178 /* based on one online buddy entry */ |
186 bytes += read_packet_b(data, &cursor, len, &fe->flag1); | 179 /* ATTTENTION! NEWED in the sub function, but FREED here */ |
187 /* 034-034: comm_flag */ | 180 /* 000-030 qq_buddy_status */ |
188 bytes += read_packet_b(data, &cursor, len, &fe->comm_flag); | 181 bytes += qq_buddy_status_read(fe->s, data + bytes); |
189 /* 035-036: */ | 182 /* 031-032: unknown4 */ |
190 bytes += read_packet_w(data, &cursor, len, &fe->unknown2); | 183 bytes += qq_get16(&fe->unknown1, data + bytes); |
191 /* 037-037: */ | 184 /* 033-033: flag1 */ |
192 bytes += read_packet_b(data, &cursor, len, &fe->ending); /* 0x00 */ | 185 bytes += qq_get8(&fe->flag1, data + bytes); |
193 | 186 /* 034-034: comm_flag */ |
194 if (fe->s->uid == 0 || bytes != QQ_ONLINE_BUDDY_ENTRY_LEN) { | 187 bytes += qq_get8(&fe->comm_flag, data + bytes); |
195 purple_debug(PURPLE_DEBUG_ERROR, "QQ", | 188 /* 035-036: */ |
196 "uid=0 or entry complete len(%d) != %d", | 189 bytes += qq_get16(&fe->unknown2, data + bytes); |
197 bytes, QQ_ONLINE_BUDDY_ENTRY_LEN); | 190 /* 037-037: */ |
198 g_free(fe->s->ip); | 191 bytes += qq_get8(&fe->ending, data + bytes); /* 0x00 */ |
199 g_free(fe->s->unknown_key); | 192 |
200 continue; | 193 if (fe->s->uid == 0 || (bytes - bytes_buddy) != QQ_ONLINE_BUDDY_ENTRY_LEN) { |
201 } /* check if it is a valid entry */ | 194 purple_debug(PURPLE_DEBUG_ERROR, "QQ", |
202 | 195 "uid=0 or entry complete len(%d) != %d", |
203 if (QQ_DEBUG) | 196 (bytes - bytes_buddy), QQ_ONLINE_BUDDY_ENTRY_LEN); |
204 _qq_buddies_online_reply_dump_unclear(fe); | |
205 | |
206 /* update buddy information */ | |
207 b = purple_find_buddy(purple_connection_get_account(gc), uid_to_purple_name(fe->s->uid)); | |
208 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data; | |
209 | |
210 if (q_bud != NULL) { /* we find one and update qq_buddy */ | |
211 if(0 != fe->s->client_version) | |
212 q_bud->client_version = fe->s->client_version; | |
213 g_memmove(q_bud->ip, fe->s->ip, 4); | |
214 q_bud->port = fe->s->port; | |
215 q_bud->status = fe->s->status; | |
216 q_bud->flag1 = fe->flag1; | |
217 q_bud->comm_flag = fe->comm_flag; | |
218 qq_update_buddy_contact(gc, q_bud); | |
219 } else { | |
220 purple_debug(PURPLE_DEBUG_ERROR, "QQ", | |
221 "Got an online buddy %d, but not in my buddy list\n", fe->s->uid); | |
222 } | |
223 | |
224 g_free(fe->s->ip); | 197 g_free(fe->s->ip); |
225 g_free(fe->s->unknown_key); | 198 g_free(fe->s->unknown_key); |
226 } | 199 continue; |
227 | 200 } /* check if it is a valid entry */ |
228 if(cursor > (data + len)) { | 201 |
229 purple_debug(PURPLE_DEBUG_ERROR, "QQ", | 202 if (QQ_DEBUG) { |
230 "qq_process_get_buddies_online_reply: Dangerous error! maybe protocol changed, notify developers!\n"); | 203 _qq_buddies_online_reply_dump_unclear(fe); |
231 } | 204 } |
232 | 205 |
233 if (position != QQ_FRIENDS_ONLINE_POSITION_END) { | 206 /* update buddy information */ |
234 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Has more online buddies, position from %d\n", position); | 207 b = purple_find_buddy(purple_connection_get_account(gc), uid_to_purple_name(fe->s->uid)); |
235 | 208 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data; |
236 qq_send_packet_get_buddies_online(gc, position); | 209 |
210 if (q_bud != NULL) { /* we find one and update qq_buddy */ | |
211 if(0 != fe->s->client_version) | |
212 q_bud->client_version = fe->s->client_version; | |
213 g_memmove(q_bud->ip, fe->s->ip, 4); | |
214 q_bud->port = fe->s->port; | |
215 q_bud->status = fe->s->status; | |
216 q_bud->flag1 = fe->flag1; | |
217 q_bud->comm_flag = fe->comm_flag; | |
218 qq_update_buddy_contact(gc, q_bud); | |
237 } else { | 219 } else { |
238 qq_send_packet_get_buddies_levels(gc); | 220 purple_debug(PURPLE_DEBUG_ERROR, "QQ", |
239 qq_refresh_all_buddy_status(gc); | 221 "Got an online buddy %d, but not in my buddy list\n", fe->s->uid); |
240 } | 222 } |
241 | 223 |
224 g_free(fe->s->ip); | |
225 g_free(fe->s->unknown_key); | |
226 } | |
227 | |
228 if(bytes > len) { | |
229 purple_debug(PURPLE_DEBUG_ERROR, "QQ", | |
230 "qq_process_get_buddies_online_reply: Dangerous error! maybe protocol changed, notify developers!\n"); | |
231 } | |
232 | |
233 if (position != QQ_FRIENDS_ONLINE_POSITION_END) { | |
234 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Has more online buddies, position from %d\n", position); | |
235 | |
236 qq_send_packet_get_buddies_online(gc, position); | |
242 } else { | 237 } else { |
243 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Error decrypt buddies online"); | 238 qq_send_packet_get_buddies_levels(gc); |
244 } | 239 qq_refresh_all_buddy_status(gc); |
245 } | 240 } |
241 } | |
242 | |
246 | 243 |
247 /* process reply for get_buddies_list */ | 244 /* process reply for get_buddies_list */ |
248 void qq_process_get_buddies_list_reply(guint8 *buf, gint buf_len, PurpleConnection *gc) | 245 void qq_process_get_buddies_list_reply(guint8 *buf, gint buf_len, PurpleConnection *gc) |
249 { | 246 { |
250 qq_data *qd; | 247 qq_data *qd; |
251 qq_buddy *q_bud; | 248 qq_buddy *q_bud; |
252 gint len, bytes, bytes_expected, i; | 249 gint len, bytes_expected, i; |
250 gint bytes, buddy_bytes; | |
253 guint16 position, unknown; | 251 guint16 position, unknown; |
254 guint8 *data, *cursor, pascal_len; | 252 guint8 *data, pascal_len; |
255 gchar *name; | 253 gchar *name; |
256 PurpleBuddy *b; | 254 PurpleBuddy *b; |
257 | 255 |
258 g_return_if_fail(buf != NULL && buf_len != 0); | 256 g_return_if_fail(buf != NULL && buf_len != 0); |
259 | 257 |
260 qd = (qq_data *) gc->proto_data; | 258 qd = (qq_data *) gc->proto_data; |
261 len = buf_len; | 259 len = buf_len; |
262 data = g_newa(guint8, len); | 260 data = g_newa(guint8, len); |
263 cursor = data; | 261 |
264 | 262 if (!qq_decrypt(buf, buf_len, qd->session_key, data, &len)) { |
265 if (qq_decrypt(buf, buf_len, qd->session_key, data, &len)) { | 263 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Error decrypt buddies list"); |
266 read_packet_w(data, &cursor, len, &position); | 264 return; |
267 /* the following data is buddy list in this packet */ | 265 } |
268 i = 0; | 266 bytes = 0; |
269 while (cursor < (data + len)) { | 267 bytes += qq_get16(&position, data + bytes); |
270 q_bud = g_new0(qq_buddy, 1); | 268 /* the following data is buddy list in this packet */ |
271 bytes = 0; | 269 i = 0; |
272 /* 000-003: uid */ | 270 while (bytes < len) { |
273 bytes += read_packet_dw(data, &cursor, len, &q_bud->uid); | 271 q_bud = g_new0(qq_buddy, 1); |
274 /* 004-005: icon index (1-255) */ | 272 /* set flag */ |
275 bytes += read_packet_w(data, &cursor, len, &q_bud->face); | 273 buddy_bytes = bytes; |
276 /* 006-006: age */ | 274 /* 000-003: uid */ |
277 bytes += read_packet_b(data, &cursor, len, &q_bud->age); | 275 bytes += qq_get32(&q_bud->uid, data + bytes); |
278 /* 007-007: gender */ | 276 /* 004-005: icon index (1-255) */ |
279 bytes += read_packet_b(data, &cursor, len, &q_bud->gender); | 277 bytes += qq_get16(&q_bud->face, data + bytes); |
280 pascal_len = convert_as_pascal_string(cursor, &q_bud->nickname, QQ_CHARSET_DEFAULT); | 278 /* 006-006: age */ |
281 cursor += pascal_len; | 279 bytes += qq_get8(&q_bud->age, data + bytes); |
282 bytes += pascal_len; | 280 /* 007-007: gender */ |
283 bytes += read_packet_w(data, &cursor, len, &unknown); | 281 bytes += qq_get8(&q_bud->gender, data + bytes); |
284 /* flag1: (0-7) | 282 |
285 * bit1 => qq show | 283 pascal_len = convert_as_pascal_string(data + bytes, &q_bud->nickname, QQ_CHARSET_DEFAULT); |
286 * comm_flag: (0-7) | 284 bytes += pascal_len; |
287 * bit1 => member | 285 |
288 * bit4 => TCP mode | 286 bytes += qq_get16(&unknown, data + bytes); |
289 * bit5 => open mobile QQ | 287 /* flag1: (0-7) |
290 * bit6 => bind to mobile | 288 * bit1 => qq show |
291 * bit7 => whether having a video | 289 * comm_flag: (0-7) |
292 */ | 290 * bit1 => member |
293 bytes += read_packet_b(data, &cursor, len, &q_bud->flag1); | 291 * bit4 => TCP mode |
294 bytes += read_packet_b(data, &cursor, len, &q_bud->comm_flag); | 292 * bit5 => open mobile QQ |
295 | 293 * bit6 => bind to mobile |
296 bytes_expected = 12 + pascal_len; | 294 * bit7 => whether having a video |
297 | 295 */ |
298 if (q_bud->uid == 0 || bytes != bytes_expected) { | 296 bytes += qq_get8(&q_bud->flag1, data + bytes); |
299 purple_debug(PURPLE_DEBUG_INFO, "QQ", | 297 bytes += qq_get8(&q_bud->comm_flag, data + bytes); |
300 "Buddy entry, expect %d bytes, read %d bytes\n", bytes_expected, bytes); | 298 |
301 g_free(q_bud->nickname); | 299 bytes_expected = 12 + pascal_len; |
302 g_free(q_bud); | 300 |
303 continue; | 301 if (q_bud->uid == 0 || (bytes - buddy_bytes) != bytes_expected) { |
304 } else { | 302 purple_debug(PURPLE_DEBUG_INFO, "QQ", |
305 i++; | 303 "Buddy entry, expect %d bytes, read %d bytes\n", bytes_expected, bytes - buddy_bytes); |
306 } | 304 g_free(q_bud->nickname); |
307 | 305 g_free(q_bud); |
308 if (QQ_DEBUG) { | 306 continue; |
309 purple_debug(PURPLE_DEBUG_INFO, "QQ", | |
310 "buddy [%09d]: flag1=0x%02x, comm_flag=0x%02x\n", | |
311 q_bud->uid, q_bud->flag1, q_bud->comm_flag); | |
312 } | |
313 | |
314 name = uid_to_purple_name(q_bud->uid); | |
315 b = purple_find_buddy(gc->account, name); | |
316 g_free(name); | |
317 | |
318 if (b == NULL) | |
319 b = qq_add_buddy_by_recv_packet(gc, q_bud->uid, TRUE, FALSE); | |
320 | |
321 b->proto_data = q_bud; | |
322 qd->buddies = g_list_append(qd->buddies, q_bud); | |
323 qq_update_buddy_contact(gc, q_bud); | |
324 } | |
325 | |
326 if(cursor > (data + len)) { | |
327 purple_debug(PURPLE_DEBUG_ERROR, "QQ", | |
328 "qq_process_get_buddies_list_reply: Dangerous error! maybe protocol changed, notify developers!"); | |
329 } | |
330 if (position == QQ_FRIENDS_LIST_POSITION_END) { | |
331 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Get friends list done, %d buddies\n", i); | |
332 qq_send_packet_get_buddies_online(gc, QQ_FRIENDS_ONLINE_POSITION_START); | |
333 } else { | 307 } else { |
334 qq_send_packet_get_buddies_list(gc, position); | 308 i++; |
335 } | 309 } |
310 | |
311 if (QQ_DEBUG) { | |
312 purple_debug(PURPLE_DEBUG_INFO, "QQ", | |
313 "buddy [%09d]: flag1=0x%02x, comm_flag=0x%02x\n", | |
314 q_bud->uid, q_bud->flag1, q_bud->comm_flag); | |
315 } | |
316 | |
317 name = uid_to_purple_name(q_bud->uid); | |
318 b = purple_find_buddy(gc->account, name); | |
319 g_free(name); | |
320 | |
321 if (b == NULL) { | |
322 b = qq_add_buddy_by_recv_packet(gc, q_bud->uid, TRUE, FALSE); | |
323 } | |
324 | |
325 b->proto_data = q_bud; | |
326 qd->buddies = g_list_append(qd->buddies, q_bud); | |
327 qq_update_buddy_contact(gc, q_bud); | |
328 } | |
329 | |
330 if(bytes > len) { | |
331 purple_debug(PURPLE_DEBUG_ERROR, "QQ", | |
332 "qq_process_get_buddies_list_reply: Dangerous error! maybe protocol changed, notify developers!"); | |
333 } | |
334 if (position == QQ_FRIENDS_LIST_POSITION_END) { | |
335 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Get friends list done, %d buddies\n", i); | |
336 qq_send_packet_get_buddies_online(gc, QQ_FRIENDS_ONLINE_POSITION_START); | |
336 } else { | 337 } else { |
337 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Error decrypt buddies list"); | 338 qq_send_packet_get_buddies_list(gc, position); |
338 } | 339 } |
339 } | 340 } |
340 | 341 |
341 void qq_process_get_all_list_with_group_reply(guint8 *buf, gint buf_len, PurpleConnection *gc) | 342 void qq_process_get_all_list_with_group_reply(guint8 *buf, gint buf_len, PurpleConnection *gc) |
342 { | 343 { |
343 qq_data *qd; | 344 qq_data *qd; |
344 gint len, i, j; | 345 gint len, i, j; |
345 guint8 *data, *cursor; | 346 gint bytes = 0; |
347 guint8 *data; | |
346 guint8 sub_cmd, reply_code; | 348 guint8 sub_cmd, reply_code; |
347 guint32 unknown, position; | 349 guint32 unknown, position; |
348 guint32 uid; | 350 guint32 uid; |
349 guint8 type, groupid; | 351 guint8 type, groupid; |
350 qq_group *group; | 352 qq_group *group; |
352 g_return_if_fail(buf != NULL && buf_len != 0); | 354 g_return_if_fail(buf != NULL && buf_len != 0); |
353 | 355 |
354 qd = (qq_data *) gc->proto_data; | 356 qd = (qq_data *) gc->proto_data; |
355 len = buf_len; | 357 len = buf_len; |
356 data = g_newa(guint8, len); | 358 data = g_newa(guint8, len); |
357 cursor = data; | 359 |
358 | 360 if (!qq_decrypt(buf, buf_len, qd->session_key, data, &len)) { |
359 if (qq_decrypt(buf, buf_len, qd->session_key, data, &len)) { | 361 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Error decrypt all list with group"); |
360 read_packet_b(data, &cursor, len, &sub_cmd); | 362 return; |
361 g_return_if_fail(sub_cmd == 0x01); | 363 } |
362 read_packet_b(data, &cursor, len, &reply_code); | 364 |
363 if(0 != reply_code) { | 365 bytes += qq_get8(&sub_cmd, data + bytes); |
364 purple_debug(PURPLE_DEBUG_WARNING, "QQ", | 366 g_return_if_fail(sub_cmd == 0x01); |
365 "Get all list with group reply, reply_code(%d) is not zero", reply_code); | 367 |
366 } | 368 bytes += qq_get8(&reply_code, data + bytes); |
367 read_packet_dw(data, &cursor, len, &unknown); | 369 if(0 != reply_code) { |
368 read_packet_dw(data, &cursor, len, &position); | 370 purple_debug(PURPLE_DEBUG_WARNING, "QQ", |
369 /* the following data is all list in this packet */ | 371 "Get all list with group reply, reply_code(%d) is not zero", reply_code); |
370 i = 0; | 372 } |
371 j = 0; | 373 |
372 while (cursor < (data + len)) { | 374 bytes += qq_get32(&unknown, data + bytes); |
373 /* 00-03: uid */ | 375 bytes += qq_get32(&position, data + bytes); |
374 read_packet_dw(data, &cursor, len, &uid); | 376 /* the following data is all list in this packet */ |
375 /* 04: type 0x1:buddy 0x4:Qun */ | 377 i = 0; |
376 read_packet_b(data, &cursor, len, &type); | 378 j = 0; |
377 /* 05: groupid*4 */ /* seems to always be 0 */ | 379 while (bytes < len) { |
378 read_packet_b(data, &cursor, len, &groupid); | 380 /* 00-03: uid */ |
379 /* | 381 bytes += qq_get32(&uid, data + bytes); |
380 purple_debug(PURPLE_DEBUG_INFO, "QQ", "groupid: %i\n", groupid); | 382 /* 04: type 0x1:buddy 0x4:Qun */ |
381 groupid >>= 2; | 383 bytes += qq_get8(&type, data + bytes); |
382 */ | 384 /* 05: groupid*4 */ /* seems to always be 0 */ |
383 if (uid == 0 || (type != 0x1 && type != 0x4)) { | 385 bytes += qq_get8(&groupid, data + bytes); |
384 purple_debug(PURPLE_DEBUG_INFO, "QQ", | 386 /* |
385 "Buddy entry, uid=%d, type=%d", uid, type); | 387 purple_debug(PURPLE_DEBUG_INFO, "QQ", "groupid: %i\n", groupid); |
386 continue; | 388 groupid >>= 2; |
387 } | 389 */ |
388 if(0x1 == type) { /* a buddy */ | 390 if (uid == 0 || (type != 0x1 && type != 0x4)) { |
389 /* don't do anything but count - buddies are handled by | 391 purple_debug(PURPLE_DEBUG_INFO, "QQ", |
390 * qq_send_packet_get_buddies_list */ | 392 "Buddy entry, uid=%d, type=%d", uid, type); |
391 ++i; | 393 continue; |
392 } else { /* a group */ | 394 } |
393 group = qq_group_find_by_id(gc, uid, QQ_INTERNAL_ID); | 395 if(0x1 == type) { /* a buddy */ |
394 if(group == NULL) { | 396 /* don't do anything but count - buddies are handled by |
395 qq_set_pending_id(&qd->adding_groups_from_server, uid, TRUE); | 397 * qq_send_packet_get_buddies_list */ |
396 group = g_newa(qq_group, 1); | 398 ++i; |
397 group->internal_group_id = uid; | 399 } else { /* a group */ |
398 qq_send_cmd_group_get_group_info(gc, group); | 400 group = qq_group_find_by_id(gc, uid, QQ_INTERNAL_ID); |
399 } else { | 401 if(group == NULL) { |
400 group->my_status = QQ_GROUP_MEMBER_STATUS_IS_MEMBER; | 402 qq_set_pending_id(&qd->adding_groups_from_server, uid, TRUE); |
401 qq_group_refresh(gc, group); | 403 group = g_newa(qq_group, 1); |
402 qq_send_cmd_group_get_group_info(gc, group); | 404 group->internal_group_id = uid; |
403 } | 405 qq_send_cmd_group_get_group_info(gc, group); |
404 ++j; | 406 } else { |
407 group->my_status = QQ_GROUP_MEMBER_STATUS_IS_MEMBER; | |
408 qq_group_refresh(gc, group); | |
409 qq_send_cmd_group_get_group_info(gc, group); | |
405 } | 410 } |
406 } | 411 ++j; |
407 if(cursor > (data + len)) { | 412 } |
408 purple_debug(PURPLE_DEBUG_ERROR, "QQ", | 413 } |
409 "qq_process_get_all_list_with_group_reply: Dangerous error! maybe protocol changed, notify developers!"); | 414 |
410 } | 415 if(bytes > len) { |
411 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Get all list done, %d buddies and %d Quns\n", i, j); | 416 purple_debug(PURPLE_DEBUG_ERROR, "QQ", |
412 } else { | 417 "qq_process_get_all_list_with_group_reply: Dangerous error! maybe protocol changed, notify developers!"); |
413 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Error decrypt all list with group"); | 418 } |
414 } | 419 |
415 } | 420 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Get all list done, %d buddies and %d Quns\n", i, j); |
421 } |