comparison libpurple/protocols/qq/buddy_list.c @ 24019:147ada94a1d8

2008.08.16 - ccpaging <ecc_hy(at)hotmail.com> * Rename group to room. If you used pidginqq before, this may create a new room with same title, you may delete old one * Replace purple_debug with purple_debug_info, purple_debug_warning, purple_debug_error * Add server notice and server new, and two options to turn on/off * Minor modify for reducing transaction's debug infor * Minor modifies for system notice and QQ news. * Add 4 new strings need translate compare with p10.
author SHiNE CsyFeK <csyfek@gmail.com>
date Thu, 11 Sep 2008 13:25:07 +0000
parents 5f454b975a99
children 23cec4360d4a 25f62d21b3f8
comparison
equal deleted inserted replaced
24018:40a4e02027f4 24019:147ada94a1d8
54 guint16 unknown2; 54 guint16 unknown2;
55 guint8 ending; /* 0x00 */ 55 guint8 ending; /* 0x00 */
56 } qq_buddy_online; 56 } qq_buddy_online;
57 57
58 /* get a list of online_buddies */ 58 /* get a list of online_buddies */
59 void qq_send_packet_get_buddies_online(PurpleConnection *gc, guint8 position) 59 void qq_request_get_buddies_online(PurpleConnection *gc, guint8 position, gint update_class)
60 { 60 {
61 qq_data *qd; 61 qq_data *qd;
62 guint8 *raw_data; 62 guint8 *raw_data;
63 gint bytes = 0; 63 gint bytes = 0;
64 64
75 /* 002-002 */ 75 /* 002-002 */
76 bytes += qq_put8(raw_data + bytes, 0x00); 76 bytes += qq_put8(raw_data + bytes, 0x00);
77 /* 003-004 */ 77 /* 003-004 */
78 bytes += qq_put16(raw_data + bytes, 0x0000); 78 bytes += qq_put16(raw_data + bytes, 0x0000);
79 79
80 qq_send_cmd(qd, QQ_CMD_GET_BUDDIES_ONLINE, raw_data, 5); 80 qq_send_cmd_mess(gc, QQ_CMD_GET_BUDDIES_ONLINE, raw_data, 5, update_class, 0);
81 qd->last_get_online = time(NULL); 81 qd->last_get_online = time(NULL);
82 } 82 }
83 83
84 /* position starts with 0x0000, 84 /* position starts with 0x0000,
85 * server may return a position tag if list is too long for one packet */ 85 * server may return a position tag if list is too long for one packet */
86 void qq_send_packet_get_buddies_list(PurpleConnection *gc, guint16 position) 86 void qq_request_get_buddies_list(PurpleConnection *gc, guint16 position, gint update_class)
87 { 87 {
88 qq_data *qd = (qq_data *) gc->proto_data;
89 guint8 raw_data[16] = {0}; 88 guint8 raw_data[16] = {0};
90 gint bytes = 0; 89 gint bytes = 0;
91 90
92 /* 000-001 starting position, can manually specify */ 91 /* 000-001 starting position, can manually specify */
93 bytes += qq_put16(raw_data + bytes, position); 92 bytes += qq_put16(raw_data + bytes, position);
96 * even can sending packets 00 and get no response. 95 * even can sending packets 00 and get no response.
97 * Now I tested that 00,00,00,00,00,01 work perfectly 96 * Now I tested that 00,00,00,00,00,01 work perfectly
98 * March 22, found the 00,00,00 starts to work as well */ 97 * March 22, found the 00,00,00 starts to work as well */
99 bytes += qq_put8(raw_data + bytes, 0x00); 98 bytes += qq_put8(raw_data + bytes, 0x00);
100 99
101 qq_send_cmd(qd, QQ_CMD_GET_BUDDIES_LIST, raw_data, bytes); 100 qq_send_cmd_mess(gc, QQ_CMD_GET_BUDDIES_LIST, raw_data, bytes, update_class, 0);
102 } 101 }
103 102
104 /* get all list, buddies & Quns with groupsid support */ 103 /* get all list, buddies & Quns with groupsid support */
105 void qq_send_packet_get_buddies_and_rooms(PurpleConnection *gc, guint32 position) 104 void qq_request_get_buddies_and_rooms(PurpleConnection *gc, guint32 position, gint update_class)
106 { 105 {
107 qq_data *qd = (qq_data *) gc->proto_data;
108 guint8 raw_data[16] = {0}; 106 guint8 raw_data[16] = {0};
109 gint bytes = 0; 107 gint bytes = 0;
110 108
111 /* 0x01 download, 0x02, upload */ 109 /* 0x01 download, 0x02, upload */
112 bytes += qq_put8(raw_data + bytes, 0x01); 110 bytes += qq_put8(raw_data + bytes, 0x01);
114 bytes += qq_put8(raw_data + bytes, 0x02); 112 bytes += qq_put8(raw_data + bytes, 0x02);
115 /* unknown 00 00 00 00 */ 113 /* unknown 00 00 00 00 */
116 bytes += qq_put32(raw_data + bytes, 0x00000000); 114 bytes += qq_put32(raw_data + bytes, 0x00000000);
117 bytes += qq_put32(raw_data + bytes, position); 115 bytes += qq_put32(raw_data + bytes, position);
118 116
119 qq_send_cmd(qd, QQ_CMD_GET_BUDDIES_AND_ROOMS, raw_data, bytes); 117 qq_send_cmd_mess(gc, QQ_CMD_GET_BUDDIES_AND_ROOMS, raw_data, bytes, update_class, 0);
120 } 118 }
121 119
122 /* parse the data into qq_buddy_status */ 120 /* parse the data into qq_buddy_status */
123 static gint get_buddy_status(qq_buddy_status *bs, guint8 *data) 121 static gint get_buddy_status(qq_buddy_status *bs, guint8 *data)
124 { 122 {
144 /* 013-014: client_version */ 142 /* 013-014: client_version */
145 bytes += qq_get16(&bs->unknown3, data + bytes); 143 bytes += qq_get16(&bs->unknown3, data + bytes);
146 /* 015-030: unknown key */ 144 /* 015-030: unknown key */
147 bytes += qq_getdata(&(bs->unknown_key[0]), QQ_KEY_LENGTH, data + bytes); 145 bytes += qq_getdata(&(bs->unknown_key[0]), QQ_KEY_LENGTH, data + bytes);
148 146
149 purple_debug(PURPLE_DEBUG_INFO, "QQ_STATUS", 147 purple_debug_info("QQ_STATUS",
150 "uid: %d, U1: %d, ip: %s:%d, U2:%d, status:%d, U3:%04X\n", 148 "uid: %d, U1: %d, ip: %s:%d, U2:%d, status:%d, U3:%04X\n",
151 bs->uid, bs->unknown1, inet_ntoa(bs->ip), bs->port, 149 bs->uid, bs->unknown1, inet_ntoa(bs->ip), bs->port,
152 bs->unknown2, bs->status, bs->unknown3); 150 bs->unknown2, bs->status, bs->unknown3);
153 151
154 return bytes; 152 return bytes;
155 } 153 }
178 bytes += qq_get8(&position, data + bytes); 176 bytes += qq_get8(&position, data + bytes);
179 177
180 count = 0; 178 count = 0;
181 while (bytes < data_len) { 179 while (bytes < data_len) {
182 if (data_len - bytes < QQ_ONLINE_BUDDY_ENTRY_LEN) { 180 if (data_len - bytes < QQ_ONLINE_BUDDY_ENTRY_LEN) {
183 purple_debug(PURPLE_DEBUG_ERROR, "QQ", 181 purple_debug_error("QQ", "[buddies online] only %d, need %d",
184 "[buddies online] only %d, need %d",
185 (data_len - bytes), QQ_ONLINE_BUDDY_ENTRY_LEN); 182 (data_len - bytes), QQ_ONLINE_BUDDY_ENTRY_LEN);
186 break; 183 break;
187 } 184 }
188 memset(&bo, 0 ,sizeof(bo)); 185 memset(&bo, 0 ,sizeof(bo));
189 186
190 /* set flag */ 187 /* set flag */
191 bytes_buddy = bytes; 188 bytes_buddy = bytes;
192 /* based on one online buddy entry */ 189 /* based on one online buddy entry */
193 /* 000-030 qq_buddy_status */ 190 /* 000-030 qq_buddy_status */
194 bytes += get_buddy_status(&(bo.bs), data + bytes); 191 bytes += get_buddy_status(&(bo.bs), data + bytes);
202 bytes += qq_get16(&bo.unknown2, data + bytes); 199 bytes += qq_get16(&bo.unknown2, data + bytes);
203 /* 037-037: */ 200 /* 037-037: */
204 bytes += qq_get8(&bo.ending, data + bytes); /* 0x00 */ 201 bytes += qq_get8(&bo.ending, data + bytes); /* 0x00 */
205 202
206 if (bo.bs.uid == 0 || (bytes - bytes_buddy) != QQ_ONLINE_BUDDY_ENTRY_LEN) { 203 if (bo.bs.uid == 0 || (bytes - bytes_buddy) != QQ_ONLINE_BUDDY_ENTRY_LEN) {
207 purple_debug(PURPLE_DEBUG_ERROR, "QQ", 204 purple_debug_error("QQ", "uid=0 or entry complete len(%d) != %d",
208 "uid=0 or entry complete len(%d) != %d",
209 (bytes - bytes_buddy), QQ_ONLINE_BUDDY_ENTRY_LEN); 205 (bytes - bytes_buddy), QQ_ONLINE_BUDDY_ENTRY_LEN);
210 continue; 206 continue;
211 } /* check if it is a valid entry */ 207 } /* check if it is a valid entry */
212 208
213 if (bo.bs.uid == qd->uid) { 209 if (bo.bs.uid == qd->uid) {
214 purple_debug(PURPLE_DEBUG_WARNING, "QQ", 210 purple_debug_warning("QQ", "I am in online list %d\n", bo.bs.uid);
215 "I am in online list %d\n", bo.bs.uid);
216 continue; 211 continue;
217 } 212 }
218 213
219 /* update buddy information */ 214 /* update buddy information */
220 purple_name = uid_to_purple_name(bo.bs.uid); 215 purple_name = uid_to_purple_name(bo.bs.uid);
221 if (purple_name == NULL) { 216 if (purple_name == NULL) {
222 purple_debug(PURPLE_DEBUG_ERROR, "QQ", 217 purple_debug_error("QQ",
223 "Got an online buddy %d, but not find purple name\n", bo.bs.uid); 218 "Got an online buddy %d, but not find purple name\n", bo.bs.uid);
224 continue; 219 continue;
225 } 220 }
226 b = purple_find_buddy(purple_connection_get_account(gc), purple_name); 221 b = purple_find_buddy(purple_connection_get_account(gc), purple_name);
227 g_free(purple_name); 222 g_free(purple_name);
228 223
229 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data; 224 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;
230 if (q_bud == NULL) { 225 if (q_bud == NULL) {
231 purple_debug(PURPLE_DEBUG_ERROR, "QQ", 226 purple_debug_error("QQ",
232 "Got an online buddy %d, but not in my buddy list\n", bo.bs.uid); 227 "Got an online buddy %d, but not in my buddy list\n", bo.bs.uid);
233 continue; 228 continue;
234 } 229 }
235 /* we find one and update qq_buddy */ 230 /* we find one and update qq_buddy */
236 /* 231 /*
245 qq_update_buddy_contact(gc, q_bud); 240 qq_update_buddy_contact(gc, q_bud);
246 count++; 241 count++;
247 } 242 }
248 243
249 if(bytes > data_len) { 244 if(bytes > data_len) {
250 purple_debug(PURPLE_DEBUG_ERROR, "QQ", 245 purple_debug_error("QQ",
251 "qq_process_get_buddies_online_reply: Dangerous error! maybe protocol changed, notify developers!\n"); 246 "qq_process_get_buddies_online_reply: Dangerous error! maybe protocol changed, notify developers!\n");
252 } 247 }
253 248
254 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Received %d online buddies, nextposition=%u\n", 249 purple_debug_info("QQ", "Received %d online buddies, nextposition=%u\n",
255 count, (guint) position); 250 count, (guint) position);
256 return position; 251 return position;
257 } 252 }
258 253
259 254
272 g_return_val_if_fail(data != NULL && data_len != 0, -1); 267 g_return_val_if_fail(data != NULL && data_len != 0, -1);
273 268
274 qd = (qq_data *) gc->proto_data; 269 qd = (qq_data *) gc->proto_data;
275 270
276 if (data_len <= 2) { 271 if (data_len <= 2) {
277 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "empty buddies list"); 272 purple_debug_error("QQ", "empty buddies list");
278 return -1; 273 return -1;
279 } 274 }
280 /* qq_show_packet("QQ get buddies list", data, data_len); */ 275 /* qq_show_packet("QQ get buddies list", data, data_len); */
281 bytes = 0; 276 bytes = 0;
282 bytes += qq_get16(&position, data + bytes); 277 bytes += qq_get16(&position, data + bytes);
303 bytes += qq_get8(&q_bud->comm_flag, data + bytes); 298 bytes += qq_get8(&q_bud->comm_flag, data + bytes);
304 299
305 bytes_expected = 12 + pascal_len; 300 bytes_expected = 12 + pascal_len;
306 301
307 if (q_bud->uid == 0 || (bytes - buddy_bytes) != bytes_expected) { 302 if (q_bud->uid == 0 || (bytes - buddy_bytes) != bytes_expected) {
308 purple_debug(PURPLE_DEBUG_INFO, "QQ", 303 purple_debug_info("QQ",
309 "Buddy entry, expect %d bytes, read %d bytes\n", bytes_expected, bytes - buddy_bytes); 304 "Buddy entry, expect %d bytes, read %d bytes\n", bytes_expected, bytes - buddy_bytes);
310 g_free(q_bud->nickname); 305 g_free(q_bud->nickname);
311 g_free(q_bud); 306 g_free(q_bud);
312 continue; 307 continue;
313 } else { 308 } else {
314 count++; 309 count++;
315 } 310 }
316 311
317 #if 1 312 #if 1
318 purple_debug(PURPLE_DEBUG_INFO, "QQ", 313 purple_debug_info("QQ",
319 "buddy [%09d]: ext_flag=0x%02x, comm_flag=0x%02x, nick=%s\n", 314 "buddy [%09d]: ext_flag=0x%02x, comm_flag=0x%02x, nick=%s\n",
320 q_bud->uid, q_bud->ext_flag, q_bud->comm_flag, q_bud->nickname); 315 q_bud->uid, q_bud->ext_flag, q_bud->comm_flag, q_bud->nickname);
321 #endif 316 #endif
322 317
323 name = uid_to_purple_name(q_bud->uid); 318 name = uid_to_purple_name(q_bud->uid);
332 qd->buddies = g_list_append(qd->buddies, q_bud); 327 qd->buddies = g_list_append(qd->buddies, q_bud);
333 qq_update_buddy_contact(gc, q_bud); 328 qq_update_buddy_contact(gc, q_bud);
334 } 329 }
335 330
336 if(bytes > data_len) { 331 if(bytes > data_len) {
337 purple_debug(PURPLE_DEBUG_ERROR, "QQ", 332 purple_debug_error("QQ",
338 "qq_process_get_buddies_list_reply: Dangerous error! maybe protocol changed, notify developers!"); 333 "qq_process_get_buddies_list_reply: Dangerous error! maybe protocol changed, notify developers!");
339 } 334 }
340 335
341 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Received %d buddies, nextposition=%u\n", 336 purple_debug_info("QQ", "Received %d buddies, nextposition=%u\n",
342 count, (guint) position); 337 count, (guint) position);
343 return position; 338 return position;
344 } 339 }
345 340
346 guint32 qq_process_get_buddies_and_rooms(guint8 *data, gint data_len, PurpleConnection *gc) 341 guint32 qq_process_get_buddies_and_rooms(guint8 *data, gint data_len, PurpleConnection *gc)
362 bytes += qq_get8(&sub_cmd, data + bytes); 357 bytes += qq_get8(&sub_cmd, data + bytes);
363 g_return_val_if_fail(sub_cmd == 0x01, -1); 358 g_return_val_if_fail(sub_cmd == 0x01, -1);
364 359
365 bytes += qq_get8(&reply_code, data + bytes); 360 bytes += qq_get8(&reply_code, data + bytes);
366 if(0 != reply_code) { 361 if(0 != reply_code) {
367 purple_debug(PURPLE_DEBUG_WARNING, "QQ", 362 purple_debug_warning("QQ", "qq_process_get_buddies_and_rooms, %d", reply_code);
368 "qq_process_get_buddies_and_rooms, %d", reply_code);
369 } 363 }
370 364
371 bytes += qq_get32(&unknown, data + bytes); 365 bytes += qq_get32(&unknown, data + bytes);
372 bytes += qq_get32(&position, data + bytes); 366 bytes += qq_get32(&position, data + bytes);
373 /* the following data is all list in this packet */ 367 /* the following data is all list in this packet */
379 /* 04: type 0x1:buddy 0x4:Qun */ 373 /* 04: type 0x1:buddy 0x4:Qun */
380 bytes += qq_get8(&type, data + bytes); 374 bytes += qq_get8(&type, data + bytes);
381 /* 05: groupid*4 */ /* seems to always be 0 */ 375 /* 05: groupid*4 */ /* seems to always be 0 */
382 bytes += qq_get8(&groupid, data + bytes); 376 bytes += qq_get8(&groupid, data + bytes);
383 /* 377 /*
384 purple_debug(PURPLE_DEBUG_INFO, "QQ", "groupid: %i\n", groupid); 378 purple_debug_info("QQ", "groupid: %i\n", groupid);
385 groupid >>= 2; 379 groupid >>= 2;
386 */ 380 */
387 if (uid == 0 || (type != 0x1 && type != 0x4)) { 381 if (uid == 0 || (type != 0x1 && type != 0x4)) {
388 purple_debug(PURPLE_DEBUG_INFO, "QQ", 382 purple_debug_info("QQ", "Buddy entry, uid=%d, type=%d", uid, type);
389 "Buddy entry, uid=%d, type=%d", uid, type);
390 continue; 383 continue;
391 } 384 }
392 if(0x1 == type) { /* a buddy */ 385 if(0x1 == type) { /* a buddy */
393 /* don't do anything but count - buddies are handled by 386 /* don't do anything but count - buddies are handled by
394 * qq_send_packet_get_buddies_list */ 387 * qq_request_get_buddies_list */
395 ++i; 388 ++i;
396 } else { /* a group */ 389 } else { /* a group */
397 group = qq_room_search_id(gc, uid); 390 group = qq_room_search_id(gc, uid);
398 if(group == NULL) { 391 if(group == NULL) {
399 purple_debug(PURPLE_DEBUG_INFO, "QQ", 392 purple_debug_info("QQ",
400 "Not find room id %d in qq_process_get_buddies_and_rooms\n", uid); 393 "Not find room id %d in qq_process_get_buddies_and_rooms\n", uid);
401 qq_set_pending_id(&qd->adding_groups_from_server, uid, TRUE); 394 qq_set_pending_id(&qd->adding_groups_from_server, uid, TRUE);
402 qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_INFO, uid);
403 } else { 395 } else {
404 group->my_status = QQ_GROUP_MEMBER_STATUS_IS_MEMBER; 396 group->my_role = QQ_ROOM_ROLE_YES;
405 qq_group_refresh(gc, group); 397 qq_group_refresh(gc, group);
406 qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_INFO, group->id);
407 } 398 }
408 ++j; 399 ++j;
409 } 400 }
410 } 401 }
411 402
412 if(bytes > data_len) { 403 if(bytes > data_len) {
413 purple_debug(PURPLE_DEBUG_ERROR, "QQ", 404 purple_debug_error("QQ",
414 "qq_process_get_buddies_and_rooms: Dangerous error! maybe protocol changed, notify developers!"); 405 "qq_process_get_buddies_and_rooms: Dangerous error! maybe protocol changed, notify developers!");
415 } 406 }
416 407
417 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Received %d buddies and %d groups, nextposition=%u\n", i, j, (guint) position); 408 purple_debug_info("QQ", "Received %d buddies and %d groups, nextposition=%u\n", i, j, (guint) position);
418 return position; 409 return position;
419 } 410 }
420 411
421 #define QQ_MISC_STATUS_HAVING_VIIDEO 0x00000001 412 #define QQ_MISC_STATUS_HAVING_VIIDEO 0x00000001
422 #define QQ_CHANGE_ONLINE_STATUS_REPLY_OK 0x30 /* ASCII value of "0" */ 413 #define QQ_CHANGE_ONLINE_STATUS_REPLY_OK 0x30 /* ASCII value of "0" */
423 414
424 /* TODO: figure out what's going on with the IP region. Sometimes I get valid IP addresses, 415 /* TODO: figure out what's going on with the IP region. Sometimes I get valid IP addresses,
425 * but the port number's weird, other times I get 0s. I get these simultaneously on the same buddy, 416 * but the port number's weird, other times I get 0s. I get these simultaneously on the same buddy,
426 * using different accounts to get info. */ 417 * using different accounts to get info. */
427 418
428 /* check if status means online or offline */ 419 /* check if status means online or offline */
429 gboolean is_online(guint8 status) 420 gboolean is_online(guint8 status)
430 { 421 {
439 return FALSE; 430 return FALSE;
440 } 431 }
441 432
442 /* Help calculate the correct icon index to tell the server. */ 433 /* Help calculate the correct icon index to tell the server. */
443 gint get_icon_offset(PurpleConnection *gc) 434 gint get_icon_offset(PurpleConnection *gc)
444 { 435 {
445 PurpleAccount *account; 436 PurpleAccount *account;
446 PurplePresence *presence; 437 PurplePresence *presence;
447 438
448 account = purple_connection_get_account(gc); 439 account = purple_connection_get_account(gc);
449 presence = purple_account_get_presence(account); 440 presence = purple_account_get_presence(account);
450 441
451 if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_INVISIBLE)) { 442 if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_INVISIBLE)) {
458 return 0; 449 return 0;
459 } 450 }
460 } 451 }
461 452
462 /* send a packet to change my online status */ 453 /* send a packet to change my online status */
463 void qq_send_packet_change_status(PurpleConnection *gc) 454 void qq_request_change_status(PurpleConnection *gc, gint update_class)
464 { 455 {
465 qq_data *qd; 456 qq_data *qd;
466 guint8 raw_data[16] = {0}; 457 guint8 raw_data[16] = {0};
467 gint bytes = 0; 458 gint bytes = 0;
468 guint8 away_cmd; 459 guint8 away_cmd;
469 guint32 misc_status; 460 guint32 misc_status;
470 gboolean fake_video; 461 gboolean fake_video;
471 PurpleAccount *account; 462 PurpleAccount *account;
472 PurplePresence *presence; 463 PurplePresence *presence;
473 464
474 account = purple_connection_get_account(gc); 465 account = purple_connection_get_account(gc);
475 presence = purple_account_get_presence(account); 466 presence = purple_account_get_presence(account);
476 467
477 qd = (qq_data *) gc->proto_data; 468 qd = (qq_data *) gc->proto_data;
478 if (!qd->logged_in) 469 if (!qd->is_login)
479 return; 470 return;
480 471
481 if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_INVISIBLE)) { 472 if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_INVISIBLE)) {
482 away_cmd = QQ_BUDDY_ONLINE_INVISIBLE; 473 away_cmd = QQ_BUDDY_ONLINE_INVISIBLE;
483 } else if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_AWAY) 474 } else if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_AWAY)
495 486
496 bytes = 0; 487 bytes = 0;
497 bytes += qq_put8(raw_data + bytes, away_cmd); 488 bytes += qq_put8(raw_data + bytes, away_cmd);
498 bytes += qq_put32(raw_data + bytes, misc_status); 489 bytes += qq_put32(raw_data + bytes, misc_status);
499 490
500 qq_send_cmd(qd, QQ_CMD_CHANGE_ONLINE_STATUS, raw_data, bytes); 491 qq_send_cmd_mess(gc, QQ_CMD_CHANGE_STATUS, raw_data, bytes, update_class, 0);
501 } 492 }
502 493
503 /* parse the reply packet for change_status */ 494 /* parse the reply packet for change_status */
504 void qq_process_change_status_reply(guint8 *data, gint data_len, PurpleConnection *gc) 495 void qq_process_change_status_reply(guint8 *data, gint data_len, PurpleConnection *gc)
505 { 496 {
511 gchar *name; 502 gchar *name;
512 503
513 g_return_if_fail(data != NULL && data_len != 0); 504 g_return_if_fail(data != NULL && data_len != 0);
514 505
515 qd = (qq_data *) gc->proto_data; 506 qd = (qq_data *) gc->proto_data;
516 507
517 bytes = 0; 508 bytes = 0;
518 bytes = qq_get8(&reply, data + bytes); 509 bytes = qq_get8(&reply, data + bytes);
519 if (reply != QQ_CHANGE_ONLINE_STATUS_REPLY_OK) { 510 if (reply != QQ_CHANGE_ONLINE_STATUS_REPLY_OK) {
520 purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Change status fail 0x%02X\n", reply); 511 purple_debug_warning("QQ", "Change status fail 0x%02X\n", reply);
521 return; 512 return;
522 } 513 }
523 514
524 /* purple_debug(PURPLE_DEBUG_INFO, "QQ", "Change status OK\n"); */ 515 /* purple_debug_info("QQ", "Change status OK\n"); */
525 name = uid_to_purple_name(qd->uid); 516 name = uid_to_purple_name(qd->uid);
526 b = purple_find_buddy(gc->account, name); 517 b = purple_find_buddy(gc->account, name);
527 g_free(name); 518 g_free(name);
528 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data; 519 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;
529 if (q_bud != NULL) { 520 if (q_bud != NULL) {
530 qq_update_buddy_contact(gc, q_bud); 521 qq_update_buddy_contact(gc, q_bud);
531 } 522 }
532 } 523 }
533 524
534 /* it is a server message indicating that one of my buddies has changed its status */ 525 /* it is a server message indicating that one of my buddies has changed its status */
535 void qq_process_buddy_change_status(guint8 *data, gint data_len, PurpleConnection *gc) 526 void qq_process_buddy_change_status(guint8 *data, gint data_len, PurpleConnection *gc)
536 { 527 {
537 qq_data *qd; 528 qq_data *qd;
538 gint bytes; 529 gint bytes;
539 guint32 my_uid; 530 guint32 my_uid;
540 PurpleBuddy *b; 531 PurpleBuddy *b;
545 g_return_if_fail(data != NULL && data_len != 0); 536 g_return_if_fail(data != NULL && data_len != 0);
546 537
547 qd = (qq_data *) gc->proto_data; 538 qd = (qq_data *) gc->proto_data;
548 539
549 if (data_len < 35) { 540 if (data_len < 35) {
550 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "[buddy status change] only %d, need 35 bytes\n", data_len); 541 purple_debug_error("QQ", "[buddy status change] only %d, need 35 bytes\n", data_len);
551 return; 542 return;
552 } 543 }
553 544
554 memset(&bs, 0, sizeof(bs)); 545 memset(&bs, 0, sizeof(bs));
555 bytes = 0; 546 bytes = 0;
556 /* 000-030: qq_buddy_status */ 547 /* 000-030: qq_buddy_status */
557 bytes += get_buddy_status(&bs, data + bytes); 548 bytes += get_buddy_status(&bs, data + bytes);
558 /* 031-034: Unknow, maybe my uid */ 549 /* 031-034: Unknow, maybe my uid */
559 /* This has a value of 0 when we've changed our status to 550 /* This has a value of 0 when we've changed our status to
560 * QQ_BUDDY_ONLINE_INVISIBLE */ 551 * QQ_BUDDY_ONLINE_INVISIBLE */
561 bytes += qq_get32(&my_uid, data + bytes); 552 bytes += qq_get32(&my_uid, data + bytes);
562 553
563 name = uid_to_purple_name(bs.uid); 554 name = uid_to_purple_name(bs.uid);
564 b = purple_find_buddy(gc->account, name); 555 b = purple_find_buddy(gc->account, name);
565 g_free(name); 556 g_free(name);
566 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data; 557 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;
567 if (q_bud == NULL) { 558 if (q_bud == NULL) {
568 purple_debug(PURPLE_DEBUG_ERROR, "QQ", 559 purple_debug_error("QQ",
569 "got information of unknown buddy %d\n", bs.uid); 560 "got information of unknown buddy %d\n", bs.uid);
570 return; 561 return;
571 } 562 }
572 563
573 purple_debug(PURPLE_DEBUG_INFO, "QQ", "status:.uid = %d, q_bud->uid = %d\n", bs.uid , q_bud->uid); 564 purple_debug_info("QQ", "status:.uid = %d, q_bud->uid = %d\n", bs.uid , q_bud->uid);
574 if(bs.ip.s_addr != 0) { 565 if(bs.ip.s_addr != 0) {
575 q_bud->ip.s_addr = bs.ip.s_addr; 566 q_bud->ip.s_addr = bs.ip.s_addr;
576 q_bud->port = bs.port; 567 q_bud->port = bs.port;
577 } 568 }
578 q_bud->status =bs.status; 569 q_bud->status =bs.status;
579 570
587 void qq_update_buddy_contact(PurpleConnection *gc, qq_buddy *q_bud) 578 void qq_update_buddy_contact(PurpleConnection *gc, qq_buddy *q_bud)
588 { 579 {
589 gchar *purple_name; 580 gchar *purple_name;
590 PurpleBuddy *bud; 581 PurpleBuddy *bud;
591 gchar *status_id; 582 gchar *status_id;
592 583
593 g_return_if_fail(q_bud != NULL); 584 g_return_if_fail(q_bud != NULL);
594 585
595 purple_name = uid_to_purple_name(q_bud->uid); 586 purple_name = uid_to_purple_name(q_bud->uid);
596 if (purple_name == NULL) { 587 if (purple_name == NULL) {
597 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Not find purple name: %d\n", q_bud->uid); 588 purple_debug_error("QQ", "Not find purple name: %d\n", q_bud->uid);
598 return; 589 return;
599 } 590 }
600 591
601 bud = purple_find_buddy(gc->account, purple_name); 592 bud = purple_find_buddy(gc->account, purple_name);
602 if (bud == NULL) { 593 if (bud == NULL) {
603 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Not find buddy: %d\n", q_bud->uid); 594 purple_debug_error("QQ", "Not find buddy: %d\n", q_bud->uid);
604 g_free(purple_name); 595 g_free(purple_name);
605 return; 596 return;
606 } 597 }
607 598
608 purple_blist_server_alias_buddy(bud, q_bud->nickname); /* server */ 599 purple_blist_server_alias_buddy(bud, q_bud->nickname); /* server */
609 q_bud->last_refresh = time(NULL); 600 q_bud->last_update = time(NULL);
610 601
611 /* purple supports signon and idle time 602 /* purple supports signon and idle time
612 * but it is not much use for QQ, I do not use them */ 603 * but it is not much use for QQ, I do not use them */
613 /* serv_got_update(gc, name, online, 0, q_bud->signon, q_bud->idle, bud->uc); */ 604 /* serv_got_update(gc, name, online, 0, q_bud->signon, q_bud->idle, bud->uc); */
614 status_id = "available"; 605 status_id = "available";
628 case QQ_BUDDY_ONLINE_INVISIBLE: 619 case QQ_BUDDY_ONLINE_INVISIBLE:
629 status_id = "invisible"; 620 status_id = "invisible";
630 break; 621 break;
631 default: 622 default:
632 status_id = "invisible"; 623 status_id = "invisible";
633 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "unknown status: %x\n", q_bud->status); 624 purple_debug_error("QQ", "unknown status: %x\n", q_bud->status);
634 break; 625 break;
635 } 626 }
636 purple_debug(PURPLE_DEBUG_INFO, "QQ", "buddy %d %s\n", q_bud->uid, status_id); 627 purple_debug_info("QQ", "buddy %d %s\n", q_bud->uid, status_id);
637 purple_prpl_got_user_status(gc->account, purple_name, status_id, NULL); 628 purple_prpl_got_user_status(gc->account, purple_name, status_id, NULL);
638 629
639 if (q_bud->comm_flag & QQ_COMM_FLAG_MOBILE && q_bud->status != QQ_BUDDY_OFFLINE) 630 if (q_bud->comm_flag & QQ_COMM_FLAG_MOBILE && q_bud->status != QQ_BUDDY_OFFLINE)
640 purple_prpl_got_user_status(gc->account, purple_name, "mobile", NULL); 631 purple_prpl_got_user_status(gc->account, purple_name, "mobile", NULL);
641 else 632 else
662 now = time(NULL); 653 now = time(NULL);
663 list = qd->buddies; 654 list = qd->buddies;
664 655
665 while (list != NULL) { 656 while (list != NULL) {
666 q_bud = (qq_buddy *) list->data; 657 q_bud = (qq_buddy *) list->data;
667 if (q_bud != NULL && now > q_bud->last_refresh + QQ_UPDATE_ONLINE_INTERVAL 658 if (q_bud != NULL && now > q_bud->last_update + QQ_UPDATE_ONLINE_INTERVAL
668 && q_bud->status != QQ_BUDDY_ONLINE_INVISIBLE) { 659 && q_bud->status != QQ_BUDDY_ONLINE_INVISIBLE) {
669 q_bud->status = QQ_BUDDY_ONLINE_OFFLINE; 660 q_bud->status = QQ_BUDDY_ONLINE_OFFLINE;
670 qq_update_buddy_contact(gc, q_bud); 661 qq_update_buddy_contact(gc, q_bud);
671 } 662 }
672 list = list->next; 663 list = list->next;