comparison libpurple/protocols/qq/buddy_info.c @ 24076:ec3f7d3e0445

2008.10.04 - lonicerae <lonicerae(at)gmail.com> * fixed a bug in qq_base.c
author SHiNE CsyFeK <csyfek@gmail.com>
date Wed, 22 Oct 2008 14:49:38 +0000
parents a95c7e71064c
children ce94189f15ad
comparison
equal deleted inserted replaced
24075:a95c7e71064c 24076:ec3f7d3e0445
83 QQ_INFO_OCCU, QQ_INFO_HOME_PAGE, QQ_INFO_AUTH_TYPE, QQ_INFO_UNKNOW1, QQ_INFO_UNKNOW2, 83 QQ_INFO_OCCU, QQ_INFO_HOME_PAGE, QQ_INFO_AUTH_TYPE, QQ_INFO_UNKNOW1, QQ_INFO_UNKNOW2,
84 QQ_INFO_FACE, QQ_INFO_MOBILE, QQ_INFO_MOBILE_TYPE, QQ_INFO_INTRO, QQ_INFO_CITY, 84 QQ_INFO_FACE, QQ_INFO_MOBILE, QQ_INFO_MOBILE_TYPE, QQ_INFO_INTRO, QQ_INFO_CITY,
85 QQ_INFO_UNKNOW3, QQ_INFO_UNKNOW4, QQ_INFO_UNKNOW5, 85 QQ_INFO_UNKNOW3, QQ_INFO_UNKNOW4, QQ_INFO_UNKNOW5,
86 QQ_INFO_IS_PUB_MOBILE, QQ_INFO_IS_PUB_CONTACT, QQ_INFO_COLLEGE, QQ_INFO_HOROSCOPE, 86 QQ_INFO_IS_PUB_MOBILE, QQ_INFO_IS_PUB_CONTACT, QQ_INFO_COLLEGE, QQ_INFO_HOROSCOPE,
87 QQ_INFO_ZODIAC, QQ_INFO_BLOOD, QQ_INFO_SHOW, QQ_INFO_UNKNOW6, 87 QQ_INFO_ZODIAC, QQ_INFO_BLOOD, QQ_INFO_SHOW, QQ_INFO_UNKNOW6,
88 QQ_INFO_LAST_2007, QQ_INFO_LAST, 88 QQ_INFO_LAST,
89 }; 89 };
90 90
91 enum { 91 enum {
92 QQ_FIELD_UNUSED = 0, QQ_FIELD_BASE, QQ_FIELD_EXT, QQ_FIELD_CONTACT, QQ_FIELD_ADDR 92 QQ_FIELD_UNUSED = 0, QQ_FIELD_BASE, QQ_FIELD_EXT, QQ_FIELD_CONTACT, QQ_FIELD_ADDR
93 }; 93 };
140 { QQ_FIELD_EXT, QQ_FIELD_STRING, "college", N_("College"), NULL, 0 }, 140 { QQ_FIELD_EXT, QQ_FIELD_STRING, "college", N_("College"), NULL, 0 },
141 { QQ_FIELD_EXT, QQ_FIELD_CHOICE, "horoscope", N_("Horoscope"), horoscope_names, QQ_HOROSCOPE_SIZE }, 141 { QQ_FIELD_EXT, QQ_FIELD_CHOICE, "horoscope", N_("Horoscope"), horoscope_names, QQ_HOROSCOPE_SIZE },
142 { QQ_FIELD_EXT, QQ_FIELD_CHOICE, "zodiac", N_("Zodiac"), zodiac_names, QQ_ZODIAC_SIZE }, 142 { QQ_FIELD_EXT, QQ_FIELD_CHOICE, "zodiac", N_("Zodiac"), zodiac_names, QQ_ZODIAC_SIZE },
143 { QQ_FIELD_EXT, QQ_FIELD_CHOICE, "blood", N_("Blood"), blood_types, QQ_BLOOD_SIZE }, 143 { QQ_FIELD_EXT, QQ_FIELD_CHOICE, "blood", N_("Blood"), blood_types, QQ_BLOOD_SIZE },
144 { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "qq_show", "QQ Show", NULL, 0 }, 144 { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "qq_show", "QQ Show", NULL, 0 },
145 { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow6", "Unknow6", NULL, 0 }, 145 { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow6", "Unknow6", NULL, 0 }
146 { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "LAST_2005", "LAST_2005", NULL, 0 }
147 }; 146 };
148 147
149 typedef struct _modify_info_request { 148 typedef struct _modify_info_request {
150 PurpleConnection *gc; 149 PurpleConnection *gc;
151 int iclass; 150 int iclass;
567 } 566 }
568 g_free(icon_num_str); 567 g_free(icon_num_str);
569 } 568 }
570 569
571 /* after getting info or modify myself, refresh the buddy list accordingly */ 570 /* after getting info or modify myself, refresh the buddy list accordingly */
572 static void qq_set_buddy_info(gchar **segments, PurpleConnection *gc) 571 static void qq_refresh_buddy_and_myself(gchar **segments, PurpleConnection *gc)
573 { 572 {
574 PurpleBuddy *purple_buddy; 573 PurpleBuddy *b;
575 qq_data *qd; 574 qq_data *qd;
576 guint32 uid; 575 qq_buddy *q_bud;
577 qq_buddy *buddy;
578 gchar *alias_utf8; 576 gchar *alias_utf8;
579 gchar *purple_name; 577 gchar *purple_name;
580 PurpleAccount *account = purple_connection_get_account(gc); 578 PurpleAccount *account = purple_connection_get_account(gc);
581 579
582 qd = (qq_data *) gc->proto_data; 580 qd = (qq_data *) gc->proto_data;
583 581 purple_name = uid_to_purple_name(strtol(segments[QQ_INFO_UID], NULL, 10));
584 uid = strtol(segments[QQ_INFO_UID], NULL, 10);
585 purple_name = uid_to_purple_name(uid);
586 582
587 alias_utf8 = qq_to_utf8(segments[QQ_INFO_NICK], QQ_CHARSET_DEFAULT); 583 alias_utf8 = qq_to_utf8(segments[QQ_INFO_NICK], QQ_CHARSET_DEFAULT);
588 if (qd->uid == strtol(segments[QQ_INFO_UID], NULL, 10)) { /* it is me */ 584 if (qd->uid == strtol(segments[QQ_INFO_UID], NULL, 10)) { /* it is me */
589 purple_debug_info("QQ", "Got my info\n");
590 qd->my_icon = strtol(segments[QQ_INFO_FACE], NULL, 10); 585 qd->my_icon = strtol(segments[QQ_INFO_FACE], NULL, 10);
591 if (alias_utf8 != NULL) 586 if (alias_utf8 != NULL)
592 purple_account_set_alias(account, alias_utf8); 587 purple_account_set_alias(account, alias_utf8);
593 588 }
594 /* add me to buddy list */
595 purple_buddy = purple_find_buddy(gc->account, purple_name);
596 if ( purple_buddy == NULL) {
597 purple_buddy = qq_create_buddy(gc, uid, TRUE, FALSE);
598 }
599 buddy = g_new0(qq_buddy, 1);
600 buddy->uid = uid;
601 buddy->status = QQ_BUDDY_ONLINE_NORMAL;
602 purple_buddy->proto_data = buddy;
603 qd->buddies = g_list_append(qd->buddies, buddy);
604 }
605
606 /* update buddy list (including myself, if myself is the buddy) */ 589 /* update buddy list (including myself, if myself is the buddy) */
607 purple_buddy = purple_find_buddy(gc->account, purple_name); 590 b = purple_find_buddy(gc->account, purple_name);
608 buddy = (purple_buddy == NULL) ? NULL : (qq_buddy *) purple_buddy->proto_data; 591 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;
609 if (buddy != NULL) { /* I have this buddy */ 592 if (q_bud != NULL) { /* I have this buddy */
610 buddy->age = strtol(segments[QQ_INFO_AGE], NULL, 10); 593 q_bud->age = strtol(segments[QQ_INFO_AGE], NULL, 10);
611 buddy->gender = strtol(segments[QQ_INFO_GENDER], NULL, 10); 594 q_bud->gender = strtol(segments[QQ_INFO_GENDER], NULL, 10);
612 buddy->face = strtol(segments[QQ_INFO_FACE], NULL, 10); 595 q_bud->face = strtol(segments[QQ_INFO_FACE], NULL, 10);
613 if (alias_utf8 != NULL) 596 if (alias_utf8 != NULL)
614 buddy->nickname = g_strdup(alias_utf8); 597 q_bud->nickname = g_strdup(alias_utf8);
615 qq_update_buddy_contact(gc, buddy); 598 qq_update_buddy_contact(gc, q_bud);
616 buddy_local_icon_upate(gc->account, purple_name, buddy->face); 599 buddy_local_icon_upate(gc->account, purple_name, q_bud->face);
617 } else {
618 purple_debug_info("QQ", "Can not find buddy data of %s\n", purple_name);
619 } 600 }
620 g_free(purple_name); 601 g_free(purple_name);
621 g_free(alias_utf8); 602 g_free(alias_utf8);
622 } 603 }
623 604
624 /* process reply to get_info packet */ 605 /* process reply to get_info packet */
625 void qq_process_get_buddy_info(guint8 *data, gint data_len, guint32 action, PurpleConnection *gc) 606 void qq_process_get_buddy_info(guint8 *data, gint data_len, guint32 action, PurpleConnection *gc)
626 { 607 {
627 qq_data *qd; 608 qq_data *qd;
628 gchar **segments; 609 gchar **segments;
629 gint field_count;
630 610
631 g_return_if_fail(data != NULL && data_len != 0); 611 g_return_if_fail(data != NULL && data_len != 0);
632 612
633 qd = (qq_data *) gc->proto_data; 613 qd = (qq_data *) gc->proto_data;
634 614
635 if (qd->client_version >= 2008) { 615 if (NULL == (segments = split_data(data, data_len, "\x1e", QQ_INFO_LAST)))
636 field_count = QQ_INFO_LAST;
637 } else {
638 field_count = QQ_INFO_LAST_2007;
639 }
640 if (NULL == (segments = split_data(data, data_len, "\x1e", field_count)))
641 return; 616 return;
642 617
643 #ifdef DEBUG 618 #ifdef DEBUG
644 info_debug(segments); 619 info_debug(segments);
645 #endif 620 #endif
650 625
651 g_free(segments[QQ_INFO_FACE]); 626 g_free(segments[QQ_INFO_FACE]);
652 segments[QQ_INFO_FACE] = icon; 627 segments[QQ_INFO_FACE] = icon;
653 628
654 request_modify_info(gc, segments); 629 request_modify_info(gc, segments);
655 qq_set_buddy_info(segments, gc); 630 qq_refresh_buddy_and_myself(segments, gc);
656 } 631 }
657 g_strfreev(segments); 632 g_strfreev(segments);
658 return; 633 return;
659 } 634 }
660 635
661 qq_set_buddy_info(segments, gc); 636 qq_refresh_buddy_and_myself(segments, gc);
662 switch (action) { 637 switch (action) {
663 case QQ_BUDDY_INFO_DISPLAY: 638 case QQ_BUDDY_INFO_DISPLAY:
664 info_display_only(gc, segments); 639 info_display_only(gc, segments);
665 break; 640 break;
666 case QQ_BUDDY_INFO_SET_ICON: 641 case QQ_BUDDY_INFO_SET_ICON:
720 gint bytes = 0; 695 gint bytes = 0;
721 696
722 if ( qd->buddies == NULL) { 697 if ( qd->buddies == NULL) {
723 return; 698 return;
724 } 699 }
725 700
726 /* server only reply levels for online buddies */ 701 /* server only reply levels for online buddies */
727 size = 4 * g_list_length(qd->buddies) + 1 + 4; 702 size = 4 * g_list_length(qd->buddies) + 1 + 4;
728 buf = g_newa(guint8, size); 703 buf = g_newa(guint8, size);
729 bytes += qq_put8(buf + bytes, 0x00); 704 bytes += qq_put8(buf + bytes, 0x00);
730 while (NULL != node) { 705 while (NULL != node) {
744 qq_data *qd = (qq_data *) gc->proto_data; 719 qq_data *qd = (qq_data *) gc->proto_data;
745 gint bytes = 0; 720 gint bytes = 0;
746 guint32 uid, onlineTime; 721 guint32 uid, onlineTime;
747 guint16 level, timeRemainder; 722 guint16 level, timeRemainder;
748 qq_buddy *buddy; 723 qq_buddy *buddy;
749 724
750 while (data_len - bytes >= 12) { 725 while (data_len - bytes >= 12) {
751 bytes += qq_get32(&uid, data + bytes); 726 bytes += qq_get32(&uid, data + bytes);
752 bytes += qq_get32(&onlineTime, data + bytes); 727 bytes += qq_get32(&onlineTime, data + bytes);
753 bytes += qq_get16(&level, data + bytes); 728 bytes += qq_get16(&level, data + bytes);
754 bytes += qq_get16(&timeRemainder, data + bytes); 729 bytes += qq_get16(&timeRemainder, data + bytes);
807 } 782 }
808 783
809 buddy->onlineTime = onlineTime; 784 buddy->onlineTime = onlineTime;
810 buddy->level = level; 785 buddy->level = level;
811 buddy->timeRemainder = timeRemainder; 786 buddy->timeRemainder = timeRemainder;
812 787
813 /* extend bytes in qq2007*/ 788 /* extend bytes in qq2007*/
814 bytes += 4; /* skip 8 bytes */ 789 bytes += 4; /* skip 8 bytes */
815 /* qq_show_packet("Buddies level", data + bytes, data_len - bytes); */ 790 qq_show_packet("Buddies level", data + bytes, data_len - bytes);
816 791
817 do { 792 do {
818 bytes += qq_get16(&str_len, data + bytes); 793 bytes += qq_get16(&str_len, data + bytes);
819 if (str_len <= 0 || bytes + str_len > data_len) { 794 if (str_len <= 0 || bytes + str_len > data_len) {
820 purple_debug_error("QQ", 795 purple_debug_error("QQ",
821 "Wrong format of Get levels. Truncate %d bytes.\n", data_len - bytes); 796 "Wrong format of Get levels. Truncate %d bytes.\n", data_len - bytes);