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 }