Mercurial > pidgin.yaz
comparison libpurple/protocols/qq/buddy_list.c @ 24080:818ab62006f5
2008.10.07 - ccpaging <ccpaging(at)gmail.com>
* Update qq_buddy
author | SHiNE CsyFeK <csyfek@gmail.com> |
---|---|
date | Wed, 22 Oct 2008 14:59:55 +0000 |
parents | 1bdf7b602684 |
children | 237e5a94e11c |
comparison
equal
deleted
inserted
replaced
24079:1bdf7b602684 | 24080:818ab62006f5 |
---|---|
162 { | 162 { |
163 qq_data *qd; | 163 qq_data *qd; |
164 gint bytes, bytes_start; | 164 gint bytes, bytes_start; |
165 gint count; | 165 gint count; |
166 guint8 position; | 166 guint8 position; |
167 qq_buddy *buddy; | 167 qq_buddy_data *bd; |
168 int entry_len = 38; | 168 int entry_len = 38; |
169 | 169 |
170 qq_buddy_status bs; | 170 qq_buddy_status bs; |
171 struct { | 171 struct { |
172 guint16 unknown1; | 172 guint16 unknown1; |
223 if (bs.uid == qd->uid) { | 223 if (bs.uid == qd->uid) { |
224 purple_debug_warning("QQ", "I am in online list %d\n", bs.uid); | 224 purple_debug_warning("QQ", "I am in online list %d\n", bs.uid); |
225 } | 225 } |
226 | 226 |
227 /* update buddy information */ | 227 /* update buddy information */ |
228 buddy = qq_buddy_find(gc, bs.uid); | 228 bd = qq_buddy_data_find(gc, bs.uid); |
229 if (buddy == NULL) { | 229 if (bd == NULL) { |
230 purple_debug_error("QQ", | 230 purple_debug_error("QQ", |
231 "Got an online buddy %d, but not in my buddy list\n", bs.uid); | 231 "Got an online buddy %d, but not in my buddy list\n", bs.uid); |
232 continue; | 232 continue; |
233 } | 233 } |
234 /* we find one and update qq_buddy */ | 234 /* we find one and update qq_buddy_data */ |
235 /* | 235 /* |
236 if(0 != fe->s->client_tag) | 236 if(0 != fe->s->client_tag) |
237 q_bud->client_tag = fe->s->client_tag; | 237 q_bud->client_tag = fe->s->client_tag; |
238 */ | 238 */ |
239 buddy->ip.s_addr = bs.ip.s_addr; | 239 bd->ip.s_addr = bs.ip.s_addr; |
240 buddy->port = bs.port; | 240 bd->port = bs.port; |
241 buddy->status = bs.status; | 241 bd->status = bs.status; |
242 buddy->ext_flag = packet.ext_flag; | 242 bd->ext_flag = packet.ext_flag; |
243 buddy->comm_flag = packet.comm_flag; | 243 bd->comm_flag = packet.comm_flag; |
244 qq_update_buddy_status(gc, bs.uid, bs.status, packet.comm_flag); | 244 bd->last_update = time(NULL); |
245 qq_update_buddy_status(gc, bd->uid, bd->status, bd->comm_flag); | |
245 count++; | 246 count++; |
246 } | 247 } |
247 | 248 |
248 if(bytes > data_len) { | 249 if(bytes > data_len) { |
249 purple_debug_error("QQ", | 250 purple_debug_error("QQ", |
258 | 259 |
259 /* process reply for get_buddies_list */ | 260 /* process reply for get_buddies_list */ |
260 guint16 qq_process_get_buddies(guint8 *data, gint data_len, PurpleConnection *gc) | 261 guint16 qq_process_get_buddies(guint8 *data, gint data_len, PurpleConnection *gc) |
261 { | 262 { |
262 qq_data *qd; | 263 qq_data *qd; |
263 qq_buddy bd; | 264 qq_buddy_data bd; |
264 gint bytes_expected, count; | 265 gint bytes_expected, count; |
265 gint bytes, buddy_bytes; | 266 gint bytes, buddy_bytes; |
266 gint nickname_len; | 267 gint nickname_len; |
267 guint16 position, unknown; | 268 guint16 position, unknown; |
268 PurpleBuddy *buddy; | 269 PurpleBuddy *buddy; |
326 buddy = qq_buddy_find_or_new(gc, bd.uid); | 327 buddy = qq_buddy_find_or_new(gc, bd.uid); |
327 if (buddy == NULL || buddy->proto_data == NULL) { | 328 if (buddy == NULL || buddy->proto_data == NULL) { |
328 g_free(bd.nickname); | 329 g_free(bd.nickname); |
329 continue; | 330 continue; |
330 } | 331 } |
332 purple_blist_server_alias_buddy(buddy, bd.nickname); | |
331 bd.last_update = time(NULL); | 333 bd.last_update = time(NULL); |
332 purple_blist_server_alias_buddy(buddy, bd.nickname); | |
333 qq_update_buddy_status(gc, bd.uid, bd.status, bd.comm_flag); | 334 qq_update_buddy_status(gc, bd.uid, bd.status, bd.comm_flag); |
334 | 335 |
335 g_memmove(buddy->proto_data, &bd, sizeof(qq_buddy)); | 336 g_memmove(buddy->proto_data, &bd, sizeof(qq_buddy_data)); |
336 /* nickname has been copy to buddy_data do not free | 337 /* nickname has been copy to buddy_data do not free |
337 g_free(bd.nickname); | 338 g_free(bd.nickname); |
338 */ | 339 */ |
339 } | 340 } |
340 | 341 |
341 if(bytes > data_len) { | 342 if(bytes > data_len) { |
342 purple_debug_error("QQ", | 343 purple_debug_error("QQ", |
448 } else { | 449 } else { |
449 return 0; | 450 return 0; |
450 } | 451 } |
451 } | 452 } |
452 | 453 |
454 static guint8 get_status_from_purple(PurpleConnection *gc) | |
455 { | |
456 qq_data *qd; | |
457 PurpleAccount *account; | |
458 PurplePresence *presence; | |
459 guint8 ret; | |
460 | |
461 qd = (qq_data *) gc->proto_data; | |
462 account = purple_connection_get_account(gc); | |
463 presence = purple_account_get_presence(account); | |
464 | |
465 if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_INVISIBLE)) { | |
466 ret = QQ_BUDDY_ONLINE_INVISIBLE; | |
467 } else if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_UNAVAILABLE)) | |
468 { | |
469 if (qd->client_version >= 2007) { | |
470 ret = QQ_BUDDY_ONLINE_BUSY; | |
471 } else { | |
472 ret = QQ_BUDDY_ONLINE_INVISIBLE; | |
473 } | |
474 } else if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_AWAY) | |
475 || purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_EXTENDED_AWAY) | |
476 || purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_UNAVAILABLE)) { | |
477 ret = QQ_BUDDY_ONLINE_AWAY; | |
478 } else { | |
479 ret = QQ_BUDDY_ONLINE_NORMAL; | |
480 } | |
481 return ret; | |
482 } | |
483 | |
453 /* send a packet to change my online status */ | 484 /* send a packet to change my online status */ |
454 void qq_request_change_status(PurpleConnection *gc, gint update_class) | 485 void qq_request_change_status(PurpleConnection *gc, gint update_class) |
455 { | 486 { |
456 qq_data *qd; | 487 qq_data *qd; |
457 guint8 raw_data[16] = {0}; | 488 guint8 raw_data[16] = {0}; |
467 | 498 |
468 qd = (qq_data *) gc->proto_data; | 499 qd = (qq_data *) gc->proto_data; |
469 if (!qd->is_login) | 500 if (!qd->is_login) |
470 return; | 501 return; |
471 | 502 |
472 if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_INVISIBLE)) { | 503 away_cmd = get_status_from_purple(gc); |
473 away_cmd = QQ_BUDDY_ONLINE_INVISIBLE; | |
474 } else if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_UNAVAILABLE)) | |
475 { | |
476 if (qd->client_version >= 2007) { | |
477 away_cmd = QQ_BUDDY_ONLINE_BUSY; | |
478 } else { | |
479 away_cmd = QQ_BUDDY_ONLINE_INVISIBLE; | |
480 } | |
481 } else if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_AWAY) | |
482 || purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_EXTENDED_AWAY) | |
483 || purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_UNAVAILABLE)) { | |
484 away_cmd = QQ_BUDDY_ONLINE_AWAY; | |
485 } else { | |
486 away_cmd = QQ_BUDDY_ONLINE_NORMAL; | |
487 } | |
488 | 504 |
489 misc_status = 0x00000000; | 505 misc_status = 0x00000000; |
490 fake_video = purple_prefs_get_bool("/plugins/prpl/qq/show_fake_video"); | 506 fake_video = purple_prefs_get_bool("/plugins/prpl/qq/show_fake_video"); |
491 if (fake_video) | 507 if (fake_video) |
492 misc_status |= QQ_MISC_STATUS_HAVING_VIIDEO; | 508 misc_status |= QQ_MISC_STATUS_HAVING_VIIDEO; |
512 void qq_process_change_status(guint8 *data, gint data_len, PurpleConnection *gc) | 528 void qq_process_change_status(guint8 *data, gint data_len, PurpleConnection *gc) |
513 { | 529 { |
514 qq_data *qd; | 530 qq_data *qd; |
515 gint bytes; | 531 gint bytes; |
516 guint8 reply; | 532 guint8 reply; |
517 qq_buddy *buddy; | 533 qq_buddy_data *bd; |
518 | 534 |
519 g_return_if_fail(data != NULL && data_len != 0); | 535 g_return_if_fail(data != NULL && data_len != 0); |
520 | 536 |
521 qd = (qq_data *) gc->proto_data; | 537 qd = (qq_data *) gc->proto_data; |
522 | 538 |
526 purple_debug_warning("QQ", "Change status fail 0x%02X\n", reply); | 542 purple_debug_warning("QQ", "Change status fail 0x%02X\n", reply); |
527 return; | 543 return; |
528 } | 544 } |
529 | 545 |
530 /* purple_debug_info("QQ", "Change status OK\n"); */ | 546 /* purple_debug_info("QQ", "Change status OK\n"); */ |
531 buddy = qq_buddy_find(gc, qd->uid); | 547 bd = qq_buddy_data_find(gc, qd->uid); |
532 if (buddy != NULL) { | 548 if (bd != NULL) { |
533 qq_update_buddy_contact(gc, buddy); | 549 bd->status = get_status_from_purple(gc); |
550 bd->last_update = time(NULL); | |
551 qq_update_buddy_status(gc, bd->uid, bd->status, bd->comm_flag); | |
534 } | 552 } |
535 } | 553 } |
536 | 554 |
537 /* it is a server message indicating that one of my buddies has changed its status */ | 555 /* it is a server message indicating that one of my buddies has changed its status */ |
538 void qq_process_buddy_change_status(guint8 *data, gint data_len, PurpleConnection *gc) | 556 void qq_process_buddy_change_status(guint8 *data, gint data_len, PurpleConnection *gc) |
539 { | 557 { |
540 qq_data *qd; | 558 qq_data *qd; |
541 gint bytes; | 559 gint bytes; |
542 guint32 my_uid; | 560 guint32 my_uid; |
543 qq_buddy *buddy; | 561 qq_buddy_data *bd; |
544 qq_buddy_status bs; | 562 qq_buddy_status bs; |
545 | 563 |
546 g_return_if_fail(data != NULL && data_len != 0); | 564 g_return_if_fail(data != NULL && data_len != 0); |
547 | 565 |
548 qd = (qq_data *) gc->proto_data; | 566 qd = (qq_data *) gc->proto_data; |
559 /* 031-034: Unknow, maybe my uid */ | 577 /* 031-034: Unknow, maybe my uid */ |
560 /* This has a value of 0 when we've changed our status to | 578 /* This has a value of 0 when we've changed our status to |
561 * QQ_BUDDY_ONLINE_INVISIBLE */ | 579 * QQ_BUDDY_ONLINE_INVISIBLE */ |
562 bytes += qq_get32(&my_uid, data + bytes); | 580 bytes += qq_get32(&my_uid, data + bytes); |
563 | 581 |
564 buddy = qq_buddy_find(gc, bs.uid); | 582 bd = qq_buddy_data_find(gc, bs.uid); |
565 if (buddy == NULL) { | 583 if (bd == NULL) { |
566 purple_debug_warning("QQ", "Get status of unknown buddy %d\n", bs.uid); | 584 purple_debug_warning("QQ", "Get status of unknown buddy %d\n", bs.uid); |
567 return; | 585 return; |
568 } | 586 } |
569 | 587 |
570 if(bs.ip.s_addr != 0) { | 588 if(bs.ip.s_addr != 0) { |
571 buddy->ip.s_addr = bs.ip.s_addr; | 589 bd->ip.s_addr = bs.ip.s_addr; |
572 buddy->port = bs.port; | 590 bd->port = bs.port; |
573 } | 591 } |
574 buddy->status =bs.status; | 592 bd->status =bs.status; |
575 | 593 |
576 if (buddy->status == QQ_BUDDY_ONLINE_NORMAL && buddy->level <= 0) { | 594 bd->last_update = time(NULL); |
595 qq_update_buddy_status(gc, bd->uid, bd->status, bd->comm_flag); | |
596 | |
597 if (bd->status == QQ_BUDDY_ONLINE_NORMAL && bd->level <= 0) { | |
577 if (qd->client_version >= 2007) { | 598 if (qd->client_version >= 2007) { |
578 qq_request_get_level_2007(gc, buddy->uid); | 599 qq_request_get_level_2007(gc, bd->uid); |
579 } else { | 600 } else { |
580 qq_request_get_level(gc, buddy->uid); | 601 qq_request_get_level(gc, bd->uid); |
581 } | 602 } |
582 } | 603 } |
583 qq_update_buddy_contact(gc, buddy); | |
584 } | 604 } |
585 | 605 |
586 /*TODO: maybe this should be qq_update_buddy_status() ?*/ | 606 /*TODO: maybe this should be qq_update_buddy_status() ?*/ |
587 void qq_update_buddy_status(PurpleConnection *gc, guint32 uid, guint8 status, guint8 flag) | 607 void qq_update_buddy_status(PurpleConnection *gc, guint32 uid, guint8 status, guint8 flag) |
588 { | 608 { |
590 gchar *status_id; | 610 gchar *status_id; |
591 | 611 |
592 g_return_if_fail(uid != 0); | 612 g_return_if_fail(uid != 0); |
593 | 613 |
594 who = uid_to_purple_name(uid); | 614 who = uid_to_purple_name(uid); |
595 | 615 |
596 /* purple supports signon and idle time | 616 /* purple supports signon and idle time |
597 * but it is not much use for QQ, I do not use them */ | 617 * but it is not much use for QQ, I do not use them */ |
598 /* serv_got_update(gc, name, online, 0, q_bud->signon, q_bud->idle, bud->uc); */ | 618 /* serv_got_update(gc, name, online, 0, q_bud->signon, q_bud->idle, bud->uc); */ |
599 status_id = "available"; | 619 status_id = "available"; |
600 switch(status) { | 620 switch(status) { |
626 | 646 |
627 if (flag & QQ_COMM_FLAG_MOBILE && status != QQ_BUDDY_OFFLINE) | 647 if (flag & QQ_COMM_FLAG_MOBILE && status != QQ_BUDDY_OFFLINE) |
628 purple_prpl_got_user_status(gc->account, who, "mobile", NULL); | 648 purple_prpl_got_user_status(gc->account, who, "mobile", NULL); |
629 else | 649 else |
630 purple_prpl_got_user_status_deactive(gc->account, who, "mobile"); | 650 purple_prpl_got_user_status_deactive(gc->account, who, "mobile"); |
631 | 651 |
632 g_free(who); | 652 g_free(who); |
633 } | |
634 | |
635 /*TODO: maybe this should be qq_update_buddy_status() ?*/ | |
636 void qq_update_buddy_contact(PurpleConnection *gc, qq_buddy *buddy) | |
637 { | |
638 gchar *purple_name; | |
639 PurpleBuddy *purple_buddy; | |
640 gchar *status_id; | |
641 | |
642 g_return_if_fail(buddy != NULL); | |
643 | |
644 purple_name = uid_to_purple_name(buddy->uid); | |
645 if (purple_name == NULL) { | |
646 purple_debug_error("QQ", "Not find purple name: %d\n", buddy->uid); | |
647 return; | |
648 } | |
649 | |
650 purple_buddy = purple_find_buddy(gc->account, purple_name); | |
651 if (purple_buddy == NULL) { | |
652 purple_debug_error("QQ", "Not find buddy: %d\n", buddy->uid); | |
653 g_free(purple_name); | |
654 return; | |
655 } | |
656 | |
657 purple_blist_server_alias_buddy(purple_buddy, buddy->nickname); /* server */ | |
658 buddy->last_update = time(NULL); | |
659 | |
660 /* purple supports signon and idle time | |
661 * but it is not much use for QQ, I do not use them */ | |
662 /* serv_got_update(gc, name, online, 0, q_bud->signon, q_bud->idle, bud->uc); */ | |
663 status_id = "available"; | |
664 switch(buddy->status) { | |
665 case QQ_BUDDY_OFFLINE: | |
666 status_id = "offline"; | |
667 break; | |
668 case QQ_BUDDY_ONLINE_NORMAL: | |
669 status_id = "available"; | |
670 break; | |
671 case QQ_BUDDY_CHANGE_TO_OFFLINE: | |
672 status_id = "offline"; | |
673 break; | |
674 case QQ_BUDDY_ONLINE_AWAY: | |
675 status_id = "away"; | |
676 break; | |
677 case QQ_BUDDY_ONLINE_INVISIBLE: | |
678 status_id = "invisible"; | |
679 break; | |
680 case QQ_BUDDY_ONLINE_BUSY: | |
681 status_id = "busy"; | |
682 break; | |
683 default: | |
684 status_id = "invisible"; | |
685 purple_debug_error("QQ", "unknown status: %x\n", buddy->status); | |
686 break; | |
687 } | |
688 purple_debug_info("QQ", "buddy %d %s\n", buddy->uid, status_id); | |
689 purple_prpl_got_user_status(gc->account, purple_name, status_id, NULL); | |
690 | |
691 if (buddy->comm_flag & QQ_COMM_FLAG_MOBILE && buddy->status != QQ_BUDDY_OFFLINE) | |
692 purple_prpl_got_user_status(gc->account, purple_name, "mobile", NULL); | |
693 else | |
694 purple_prpl_got_user_status_deactive(gc->account, purple_name, "mobile"); | |
695 | |
696 g_free(purple_name); | |
697 } | 653 } |
698 | 654 |
699 /* refresh all buddies online/offline, | 655 /* refresh all buddies online/offline, |
700 * after receiving reply for get_buddies_online packet */ | 656 * after receiving reply for get_buddies_online packet */ |
701 void qq_update_buddyies_status(PurpleConnection *gc) | 657 void qq_update_buddyies_status(PurpleConnection *gc) |
702 { | 658 { |
703 qq_data *qd; | 659 qq_data *qd; |
704 PurpleBuddy *buddy; | 660 PurpleBuddy *buddy; |
705 qq_buddy *bd; | 661 qq_buddy_data *bd; |
706 GSList *buddies, *it; | 662 GSList *buddies, *it; |
707 time_t tm_limit = time(NULL); | 663 time_t tm_limit = time(NULL); |
708 | 664 |
709 qd = (qq_data *) (gc->proto_data); | 665 qd = (qq_data *) (gc->proto_data); |
710 | 666 |
711 tm_limit -= QQ_UPDATE_ONLINE_INTERVAL; | 667 tm_limit -= QQ_UPDATE_ONLINE_INTERVAL; |
712 | 668 |
713 buddies = purple_find_buddies(purple_connection_get_account(gc), NULL); | 669 buddies = purple_find_buddies(purple_connection_get_account(gc), NULL); |
714 for (it = buddies; it; it = it->next) { | 670 for (it = buddies; it; it = it->next) { |
715 buddy = it->data; | 671 buddy = it->data; |
716 if (buddy == NULL) continue; | 672 if (buddy == NULL) continue; |
717 if (buddy->proto_data == NULL) continue; | 673 if (buddy->proto_data == NULL) continue; |
718 | 674 |
719 bd = (qq_buddy *)buddy->proto_data; | 675 bd = (qq_buddy_data *)buddy->proto_data; |
720 if (bd->uid == 0) continue; | 676 if (bd->uid == 0) continue; |
721 if (bd->uid == qd->uid) continue; /* my status is always online in my buddy list */ | 677 if (bd->uid == qd->uid) continue; /* my status is always online in my buddy list */ |
722 if (tm_limit < bd->last_update) continue; | 678 if (tm_limit < bd->last_update) continue; |
723 if (bd->status == QQ_BUDDY_ONLINE_INVISIBLE) continue; | 679 if (bd->status == QQ_BUDDY_ONLINE_INVISIBLE) continue; |
724 | 680 |
725 bd->status = QQ_BUDDY_CHANGE_TO_OFFLINE; | 681 bd->status = QQ_BUDDY_CHANGE_TO_OFFLINE; |
682 bd->last_update = time(NULL); | |
726 qq_update_buddy_status(gc, bd->uid, bd->status, bd->comm_flag); | 683 qq_update_buddy_status(gc, bd->uid, bd->status, bd->comm_flag); |
727 } | 684 } |
728 } | 685 } |
729 | 686 |
730 void qq_buddy_data_free_all(PurpleConnection *gc) | 687 void qq_buddy_data_free_all(PurpleConnection *gc) |
733 PurpleBuddy *buddy; | 690 PurpleBuddy *buddy; |
734 GSList *buddies, *it; | 691 GSList *buddies, *it; |
735 gint count = 0; | 692 gint count = 0; |
736 | 693 |
737 qd = (qq_data *) (gc->proto_data); | 694 qd = (qq_data *) (gc->proto_data); |
738 | 695 |
739 buddies = purple_find_buddies(purple_connection_get_account(gc), NULL); | 696 buddies = purple_find_buddies(purple_connection_get_account(gc), NULL); |
740 for (it = buddies; it; it = it->next) { | 697 for (it = buddies; it; it = it->next) { |
741 buddy = it->data; | 698 buddy = it->data; |
742 if (buddy == NULL) continue; | 699 if (buddy == NULL) continue; |
743 if (buddy->proto_data == NULL) continue; | 700 if (buddy->proto_data == NULL) continue; |
744 | 701 |
745 qq_buddy_data_free(buddy->proto_data); | 702 qq_buddy_data_free(buddy->proto_data); |
746 buddy->proto_data = NULL; | 703 buddy->proto_data = NULL; |
747 | 704 |
748 count++; | 705 count++; |
749 } | 706 } |
750 | 707 |
751 if (count > 0) { | 708 if (count > 0) { |
752 purple_debug_info("QQ", "%d buddies' data are freed\n", count); | 709 purple_debug_info("QQ", "%d buddies' data are freed\n", count); |