| 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, |
88 QQ_INFO_LAST_2007, 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 } |
| 146 }; |
147 }; |
| 147 |
148 |
| 148 typedef struct _modify_info_request { |
149 typedef struct _modify_info_request { |
| 149 PurpleConnection *gc; |
150 PurpleConnection *gc; |
| 150 int iclass; |
151 int iclass; |
| 566 } |
567 } |
| 567 g_free(icon_num_str); |
568 g_free(icon_num_str); |
| 568 } |
569 } |
| 569 |
570 |
| 570 /* after getting info or modify myself, refresh the buddy list accordingly */ |
571 /* after getting info or modify myself, refresh the buddy list accordingly */ |
| 571 static void qq_refresh_buddy_and_myself(gchar **segments, PurpleConnection *gc) |
572 static void qq_set_buddy_info(gchar **segments, PurpleConnection *gc) |
| 572 { |
573 { |
| 573 PurpleBuddy *b; |
574 PurpleBuddy *purple_buddy; |
| 574 qq_data *qd; |
575 qq_data *qd; |
| 575 qq_buddy *q_bud; |
576 guint32 uid; |
| |
577 qq_buddy *buddy; |
| 576 gchar *alias_utf8; |
578 gchar *alias_utf8; |
| 577 gchar *purple_name; |
579 gchar *purple_name; |
| 578 PurpleAccount *account = purple_connection_get_account(gc); |
580 PurpleAccount *account = purple_connection_get_account(gc); |
| 579 |
581 |
| 580 qd = (qq_data *) gc->proto_data; |
582 qd = (qq_data *) gc->proto_data; |
| 581 purple_name = uid_to_purple_name(strtol(segments[QQ_INFO_UID], NULL, 10)); |
583 |
| |
584 uid = strtol(segments[QQ_INFO_UID], NULL, 10); |
| |
585 purple_name = uid_to_purple_name(uid); |
| 582 |
586 |
| 583 alias_utf8 = qq_to_utf8(segments[QQ_INFO_NICK], QQ_CHARSET_DEFAULT); |
587 alias_utf8 = qq_to_utf8(segments[QQ_INFO_NICK], QQ_CHARSET_DEFAULT); |
| 584 if (qd->uid == strtol(segments[QQ_INFO_UID], NULL, 10)) { /* it is me */ |
588 if (qd->uid == strtol(segments[QQ_INFO_UID], NULL, 10)) { /* it is me */ |
| |
589 purple_debug_info("QQ", "Got my info\n"); |
| 585 qd->my_icon = strtol(segments[QQ_INFO_FACE], NULL, 10); |
590 qd->my_icon = strtol(segments[QQ_INFO_FACE], NULL, 10); |
| 586 if (alias_utf8 != NULL) |
591 if (alias_utf8 != NULL) |
| 587 purple_account_set_alias(account, alias_utf8); |
592 purple_account_set_alias(account, alias_utf8); |
| 588 } |
593 |
| |
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 |
| 589 /* update buddy list (including myself, if myself is the buddy) */ |
606 /* update buddy list (including myself, if myself is the buddy) */ |
| 590 b = purple_find_buddy(gc->account, purple_name); |
607 purple_buddy = purple_find_buddy(gc->account, purple_name); |
| 591 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data; |
608 buddy = (purple_buddy == NULL) ? NULL : (qq_buddy *) purple_buddy->proto_data; |
| 592 if (q_bud != NULL) { /* I have this buddy */ |
609 if (buddy != NULL) { /* I have this buddy */ |
| 593 q_bud->age = strtol(segments[QQ_INFO_AGE], NULL, 10); |
610 buddy->age = strtol(segments[QQ_INFO_AGE], NULL, 10); |
| 594 q_bud->gender = strtol(segments[QQ_INFO_GENDER], NULL, 10); |
611 buddy->gender = strtol(segments[QQ_INFO_GENDER], NULL, 10); |
| 595 q_bud->face = strtol(segments[QQ_INFO_FACE], NULL, 10); |
612 buddy->face = strtol(segments[QQ_INFO_FACE], NULL, 10); |
| 596 if (alias_utf8 != NULL) |
613 if (alias_utf8 != NULL) |
| 597 q_bud->nickname = g_strdup(alias_utf8); |
614 buddy->nickname = g_strdup(alias_utf8); |
| 598 qq_update_buddy_contact(gc, q_bud); |
615 qq_update_buddy_contact(gc, buddy); |
| 599 buddy_local_icon_upate(gc->account, purple_name, q_bud->face); |
616 buddy_local_icon_upate(gc->account, purple_name, buddy->face); |
| |
617 } else { |
| |
618 purple_debug_info("QQ", "Can not find buddy data of %s\n", purple_name); |
| 600 } |
619 } |
| 601 g_free(purple_name); |
620 g_free(purple_name); |
| 602 g_free(alias_utf8); |
621 g_free(alias_utf8); |
| 603 } |
622 } |
| 604 |
623 |
| 605 /* process reply to get_info packet */ |
624 /* process reply to get_info packet */ |
| 606 void qq_process_get_buddy_info(guint8 *data, gint data_len, guint32 action, PurpleConnection *gc) |
625 void qq_process_get_buddy_info(guint8 *data, gint data_len, guint32 action, PurpleConnection *gc) |
| 607 { |
626 { |
| 608 qq_data *qd; |
627 qq_data *qd; |
| 609 gchar **segments; |
628 gchar **segments; |
| |
629 gint field_count; |
| 610 |
630 |
| 611 g_return_if_fail(data != NULL && data_len != 0); |
631 g_return_if_fail(data != NULL && data_len != 0); |
| 612 |
632 |
| 613 qd = (qq_data *) gc->proto_data; |
633 qd = (qq_data *) gc->proto_data; |
| 614 |
634 |
| 615 if (NULL == (segments = split_data(data, data_len, "\x1e", QQ_INFO_LAST))) |
635 if (qd->client_version >= 2008) { |
| |
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))) |
| 616 return; |
641 return; |
| 617 |
642 |
| 618 #ifdef DEBUG |
643 #ifdef DEBUG |
| 619 info_debug(segments); |
644 info_debug(segments); |
| 620 #endif |
645 #endif |
| 719 qq_data *qd = (qq_data *) gc->proto_data; |
744 qq_data *qd = (qq_data *) gc->proto_data; |
| 720 gint bytes = 0; |
745 gint bytes = 0; |
| 721 guint32 uid, onlineTime; |
746 guint32 uid, onlineTime; |
| 722 guint16 level, timeRemainder; |
747 guint16 level, timeRemainder; |
| 723 qq_buddy *buddy; |
748 qq_buddy *buddy; |
| 724 |
749 |
| 725 while (data_len - bytes >= 12) { |
750 while (data_len - bytes >= 12) { |
| 726 bytes += qq_get32(&uid, data + bytes); |
751 bytes += qq_get32(&uid, data + bytes); |
| 727 bytes += qq_get32(&onlineTime, data + bytes); |
752 bytes += qq_get32(&onlineTime, data + bytes); |
| 728 bytes += qq_get16(&level, data + bytes); |
753 bytes += qq_get16(&level, data + bytes); |
| 729 bytes += qq_get16(&timeRemainder, data + bytes); |
754 bytes += qq_get16(&timeRemainder, data + bytes); |
| 782 } |
807 } |
| 783 |
808 |
| 784 buddy->onlineTime = onlineTime; |
809 buddy->onlineTime = onlineTime; |
| 785 buddy->level = level; |
810 buddy->level = level; |
| 786 buddy->timeRemainder = timeRemainder; |
811 buddy->timeRemainder = timeRemainder; |
| 787 |
812 |
| 788 /* extend bytes in qq2007*/ |
813 /* extend bytes in qq2007*/ |
| 789 bytes += 4; /* skip 8 bytes */ |
814 bytes += 4; /* skip 8 bytes */ |
| 790 qq_show_packet("Buddies level", data + bytes, data_len - bytes); |
815 /* qq_show_packet("Buddies level", data + bytes, data_len - bytes); */ |
| 791 |
816 |
| 792 do { |
817 do { |
| 793 bytes += qq_get16(&str_len, data + bytes); |
818 bytes += qq_get16(&str_len, data + bytes); |
| 794 if (str_len <= 0 || bytes + str_len > data_len) { |
819 if (str_len <= 0 || bytes + str_len > data_len) { |
| 795 purple_debug_error("QQ", |
820 purple_debug_error("QQ", |
| 796 "Wrong format of Get levels. Truncate %d bytes.\n", data_len - bytes); |
821 "Wrong format of Get levels. Truncate %d bytes.\n", data_len - bytes); |