| 282 |
282 |
| 283 g_return_if_fail(uid != 0); |
283 g_return_if_fail(uid != 0); |
| 284 |
284 |
| 285 qd = (qq_data *) gc->proto_data; |
285 qd = (qq_data *) gc->proto_data; |
| 286 g_snprintf(uid_str, sizeof(uid_str), "%d", uid); |
286 g_snprintf(uid_str, sizeof(uid_str), "%d", uid); |
| 287 qq_send_cmd(gc, QQ_CMD_GET_USER_INFO, (guint8 *) uid_str, strlen(uid_str)); |
287 qq_send_cmd(qd, QQ_CMD_GET_USER_INFO, (guint8 *) uid_str, strlen(uid_str)); |
| 288 |
288 |
| 289 query = g_new0(qq_info_query, 1); |
289 query = g_new0(qq_info_query, 1); |
| 290 query->uid = uid; |
290 query->uid = uid; |
| 291 query->show_window = show_window; |
291 query->show_window = show_window; |
| 292 query->modify_info = FALSE; |
292 query->modify_info = FALSE; |
| 293 qd->info_query = g_list_append(qd->info_query, query); |
293 qd->info_query = g_list_append(qd->info_query, query); |
| 294 } |
|
| 295 |
|
| 296 void qq_request_buddy_info(PurpleConnection *gc, guint32 uid, |
|
| 297 gint update_class, guint32 ship32) |
|
| 298 { |
|
| 299 qq_data *qd; |
|
| 300 gchar raw_data[16] = {0}; |
|
| 301 |
|
| 302 g_return_if_fail(uid != 0); |
|
| 303 |
|
| 304 qd = (qq_data *) gc->proto_data; |
|
| 305 g_snprintf(raw_data, sizeof(raw_data), "%d", uid); |
|
| 306 qq_send_cmd_mess(gc, QQ_CMD_GET_USER_INFO, (guint8 *) raw_data, strlen(raw_data), |
|
| 307 update_class, ship32); |
|
| 308 } |
294 } |
| 309 |
295 |
| 310 /* set up the fields requesting personal information and send a get_info packet |
296 /* set up the fields requesting personal information and send a get_info packet |
| 311 * for myself */ |
297 * for myself */ |
| 312 void qq_prepare_modify_info(PurpleConnection *gc) |
298 void qq_prepare_modify_info(PurpleConnection *gc) |
| 457 bytes += qq_put8(raw_data + bytes, bar); |
444 bytes += qq_put8(raw_data + bytes, bar); |
| 458 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->unknown6, strlen(info->unknown6)); |
445 bytes += qq_putdata(raw_data + bytes, (guint8 *)info->unknown6, strlen(info->unknown6)); |
| 459 |
446 |
| 460 bytes += qq_put8(raw_data + bytes, bar); |
447 bytes += qq_put8(raw_data + bytes, bar); |
| 461 |
448 |
| 462 qq_send_cmd(gc, QQ_CMD_UPDATE_INFO, raw_data, bytes); |
449 qq_send_cmd(qd, QQ_CMD_UPDATE_INFO, raw_data, bytes); |
| 463 |
450 |
| 464 } |
451 } |
| 465 |
452 |
| 466 static void modify_info_cancel_cb(modify_info_data *mid) |
453 static void modify_info_cancel_cb(modify_info_data *mid) |
| 467 { |
454 { |
| 708 |
695 |
| 709 qd = (qq_data *) gc->proto_data; |
696 qd = (qq_data *) gc->proto_data; |
| 710 |
697 |
| 711 data[data_len] = '\0'; |
698 data[data_len] = '\0'; |
| 712 if (qd->uid == atoi((gchar *) data)) { /* return should be my uid */ |
699 if (qd->uid == atoi((gchar *) data)) { /* return should be my uid */ |
| 713 purple_debug_info("QQ", "Update info ACK OK\n"); |
700 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Update info ACK OK\n"); |
| 714 purple_notify_info(gc, NULL, _("My information has been updated"), NULL); |
701 purple_notify_info(gc, NULL, _("Your information has been updated"), NULL); |
| 715 } |
702 } |
| 716 } |
703 } |
| 717 |
704 |
| 718 static void _qq_send_packet_modify_face(PurpleConnection *gc, gint face_num) |
705 static void _qq_send_packet_modify_face(PurpleConnection *gc, gint face_num) |
| 719 { |
706 { |
| 757 PurpleAccount *account = purple_connection_get_account(gc); |
744 PurpleAccount *account = purple_connection_get_account(gc); |
| 758 const gchar *icon_path = purple_account_get_buddy_icon_path(account); |
745 const gchar *icon_path = purple_account_get_buddy_icon_path(account); |
| 759 const gchar *buddy_icon_dir = qq_buddy_icon_dir(); |
746 const gchar *buddy_icon_dir = qq_buddy_icon_dir(); |
| 760 gint prefix_len = strlen(QQ_ICON_PREFIX); |
747 gint prefix_len = strlen(QQ_ICON_PREFIX); |
| 761 gint suffix_len = strlen(QQ_ICON_SUFFIX); |
748 gint suffix_len = strlen(QQ_ICON_SUFFIX); |
| 762 gint dir_len = strlen(buddy_icon_dir); |
749 gint dir_len = buddy_icon_dir ? strlen(buddy_icon_dir) : 0; |
| 763 gchar *errmsg = g_strdup_printf(_("Setting custom faces is not currently supported. Please choose an image from %s."), buddy_icon_dir); |
750 gchar *errmsg = g_strdup_printf(_("Setting custom faces is not currently supported. Please choose an image from %s."), buddy_icon_dir ? buddy_icon_dir : "(null)"); |
| 764 gboolean icon_global = purple_account_get_bool(gc->account, "use-global-buddyicon", TRUE); |
751 gboolean icon_global = purple_account_get_bool(gc->account, "use-global-buddyicon", TRUE); |
| 765 |
752 |
| 766 if (!icon_path) |
753 if (!icon_path) |
| 767 icon_path = ""; |
754 icon_path = ""; |
| 768 |
755 |
| 769 icon_len = strlen(icon_path) - dir_len - 1 - prefix_len - suffix_len; |
756 icon_len = strlen(icon_path) - dir_len - 1 - prefix_len - suffix_len; |
| 770 |
757 |
| 771 /* make sure we're using an appropriate icon */ |
758 /* make sure we're using an appropriate icon */ |
| 772 if (!(g_ascii_strncasecmp(icon_path, buddy_icon_dir, dir_len) == 0 |
759 if (buddy_icon_dir && !(g_ascii_strncasecmp(icon_path, buddy_icon_dir, dir_len) == 0 |
| 773 && icon_path[dir_len] == G_DIR_SEPARATOR |
760 && icon_path[dir_len] == G_DIR_SEPARATOR |
| 774 && g_ascii_strncasecmp(icon_path + dir_len + 1, QQ_ICON_PREFIX, prefix_len) == 0 |
761 && g_ascii_strncasecmp(icon_path + dir_len + 1, QQ_ICON_PREFIX, prefix_len) == 0 |
| 775 && g_ascii_strncasecmp(icon_path + dir_len + 1 + prefix_len + icon_len, QQ_ICON_SUFFIX, suffix_len) == 0 |
762 && g_ascii_strncasecmp(icon_path + dir_len + 1 + prefix_len + icon_len, QQ_ICON_SUFFIX, suffix_len) == 0 |
| 776 && icon_len <= 3)) { |
763 && icon_len <= 3)) { |
| 777 if (icon_global) |
764 if (icon_global) |
| 778 purple_debug_error("QQ", "%s\n", errmsg); |
765 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "%s\n", errmsg); |
| 779 else |
766 else |
| 780 purple_notify_error(gc, _("Invalid QQ Face"), errmsg, NULL); |
767 purple_notify_error(gc, _("Invalid QQ Face"), errmsg, NULL); |
| 781 g_free(errmsg); |
768 g_free(errmsg); |
| 782 return; |
769 return; |
| 783 } |
770 } |
| 786 icon_num = strtol(icon, NULL, 10); |
773 icon_num = strtol(icon, NULL, 10); |
| 787 g_free(icon); |
774 g_free(icon); |
| 788 /* ensure face number in proper range */ |
775 /* ensure face number in proper range */ |
| 789 if (icon_num > QQ_FACES) { |
776 if (icon_num > QQ_FACES) { |
| 790 if (icon_global) |
777 if (icon_global) |
| 791 purple_debug_error("QQ", "%s\n", errmsg); |
778 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "%s\n", errmsg); |
| 792 else |
779 else |
| 793 purple_notify_error(gc, _("Invalid QQ Face"), errmsg, NULL); |
780 purple_notify_error(gc, _("Invalid QQ Face"), errmsg, NULL); |
| 794 g_free(errmsg); |
781 g_free(errmsg); |
| 795 return; |
782 return; |
| 796 } |
783 } |
| 809 const gchar *old_icon_num = NULL; |
796 const gchar *old_icon_num = NULL; |
| 810 |
797 |
| 811 if ((buddy = purple_find_buddy(account, name))) |
798 if ((buddy = purple_find_buddy(account, name))) |
| 812 old_icon_num = purple_buddy_icons_get_checksum_for_user(buddy); |
799 old_icon_num = purple_buddy_icons_get_checksum_for_user(buddy); |
| 813 |
800 |
| 814 if (old_icon_num == NULL || |
801 if ((old_icon_num == NULL || |
| 815 strcmp(icon_num_str, old_icon_num)) |
802 strcmp(icon_num_str, old_icon_num)) && (qq_buddy_icon_dir() != NULL)) |
| 816 { |
803 { |
| 817 gchar *icon_path; |
804 gchar *icon_path; |
| 818 |
805 |
| 819 icon_path = g_strconcat(qq_buddy_icon_dir(), G_DIR_SEPARATOR_S, |
806 icon_path = g_strconcat(qq_buddy_icon_dir(), G_DIR_SEPARATOR_S, |
| 820 QQ_ICON_PREFIX, icon_num_str, |
807 QQ_ICON_PREFIX, icon_num_str, |
| 913 g_strfreev(segments); |
900 g_strfreev(segments); |
| 914 } |
901 } |
| 915 |
902 |
| 916 void qq_info_query_free(qq_data *qd) |
903 void qq_info_query_free(qq_data *qd) |
| 917 { |
904 { |
| 918 gint count; |
905 gint i; |
| 919 qq_info_query *p; |
906 qq_info_query *p; |
| 920 |
907 |
| 921 g_return_if_fail(qd != NULL); |
908 g_return_if_fail(qd != NULL); |
| 922 |
909 |
| 923 count = 0; |
910 i = 0; |
| 924 while (qd->info_query != NULL) { |
911 while (qd->info_query != NULL) { |
| 925 p = (qq_info_query *) (qd->info_query->data); |
912 p = (qq_info_query *) (qd->info_query->data); |
| 926 qd->info_query = g_list_remove(qd->info_query, p); |
913 qd->info_query = g_list_remove(qd->info_query, p); |
| 927 g_free(p); |
914 g_free(p); |
| 928 count++; |
915 i++; |
| 929 } |
916 } |
| 930 if (count > 0) { |
917 purple_debug(PURPLE_DEBUG_INFO, "QQ", "%d info queries are freed!\n", i); |
| 931 purple_debug_info("QQ", "%d info queries are freed!\n", count); |
|
| 932 } |
|
| 933 } |
918 } |
| 934 |
919 |
| 935 void qq_send_packet_get_level(PurpleConnection *gc, guint32 uid) |
920 void qq_send_packet_get_level(PurpleConnection *gc, guint32 uid) |
| 936 { |
921 { |
| 937 qq_data *qd = (qq_data *) gc->proto_data; |
922 qq_data *qd = (qq_data *) gc->proto_data; |
| 940 |
925 |
| 941 bytes += qq_put8(buf + bytes, 0x00); |
926 bytes += qq_put8(buf + bytes, 0x00); |
| 942 bytes += qq_put32(buf + bytes, uid); |
927 bytes += qq_put32(buf + bytes, uid); |
| 943 |
928 |
| 944 qd = (qq_data *) gc->proto_data; |
929 qd = (qq_data *) gc->proto_data; |
| 945 qq_send_cmd(gc, QQ_CMD_GET_LEVEL, buf, bytes); |
930 qq_send_cmd(qd, QQ_CMD_GET_LEVEL, buf, bytes); |
| 946 } |
931 } |
| 947 |
932 |
| 948 void qq_request_get_buddies_levels(PurpleConnection *gc, gint update_class) |
933 void qq_send_packet_get_buddies_levels(PurpleConnection *gc) |
| 949 { |
934 { |
| 950 guint8 *buf; |
935 guint8 *buf; |
| 951 guint16 size; |
936 guint16 size; |
| 952 qq_buddy *q_bud; |
937 qq_buddy *q_bud; |
| 953 qq_data *qd = (qq_data *) gc->proto_data; |
938 qq_data *qd = (qq_data *) gc->proto_data; |
| 955 gint bytes = 0; |
940 gint bytes = 0; |
| 956 |
941 |
| 957 if ( qd->buddies == NULL) { |
942 if ( qd->buddies == NULL) { |
| 958 return; |
943 return; |
| 959 } |
944 } |
| 960 /* server only reply levels for online buddies */ |
945 /* server only sends back levels for online buddies, no point |
| 961 size = 4 * g_list_length(qd->buddies) + 1 + 4; |
946 * in asking for anyone else */ |
| |
947 size = 4 * g_list_length(qd->buddies) + 1; |
| 962 buf = g_newa(guint8, size); |
948 buf = g_newa(guint8, size); |
| 963 bytes += qq_put8(buf + bytes, 0x00); |
949 bytes += qq_put8(buf + bytes, 0x00); |
| 964 |
950 |
| 965 while (NULL != node) { |
951 while (NULL != node) { |
| 966 q_bud = (qq_buddy *) node->data; |
952 q_bud = (qq_buddy *) node->data; |
| 967 if (NULL != q_bud) { |
953 if (NULL != q_bud) { |
| 968 bytes += qq_put32(buf + bytes, q_bud->uid); |
954 bytes += qq_put32(buf + bytes, q_bud->uid); |
| 969 } |
955 } |
| 970 node = node->next; |
956 node = node->next; |
| 971 } |
957 } |
| 972 |
958 qq_send_cmd(qd, QQ_CMD_GET_LEVEL, buf, size); |
| 973 /* my id should be the end if included */ |
|
| 974 bytes += qq_put32(buf + bytes, qd->uid); |
|
| 975 qq_send_cmd_mess(gc, QQ_CMD_GET_LEVEL, buf, size, update_class, 0); |
|
| 976 } |
959 } |
| 977 |
960 |
| 978 void qq_process_get_level_reply(guint8 *decr_buf, gint decr_len, PurpleConnection *gc) |
961 void qq_process_get_level_reply(guint8 *decr_buf, gint decr_len, PurpleConnection *gc) |
| 979 { |
962 { |
| 980 guint32 uid, onlineTime; |
963 guint32 uid, onlineTime; |
| 985 gint i; |
968 gint i; |
| 986 PurpleAccount *account = purple_connection_get_account(gc); |
969 PurpleAccount *account = purple_connection_get_account(gc); |
| 987 qq_data *qd = (qq_data *) gc->proto_data; |
970 qq_data *qd = (qq_data *) gc->proto_data; |
| 988 gint bytes = 0; |
971 gint bytes = 0; |
| 989 |
972 |
| 990 decr_len--; |
973 decr_len--; |
| 991 if (decr_len % 12 != 0) { |
974 if (decr_len % 12 != 0) { |
| 992 purple_debug_error("QQ", |
975 purple_debug(PURPLE_DEBUG_ERROR, "QQ", |
| 993 "Get levels list of abnormal length. Truncating last %d bytes.\n", decr_len % 12); |
976 "Get levels list of abnormal length. Truncating last %d bytes.\n", decr_len % 12); |
| 994 decr_len -= (decr_len % 12); |
977 decr_len -= (decr_len % 12); |
| 995 } |
978 } |
| 996 |
979 |
| 997 bytes += 1; |
980 bytes += 1; |
| 998 /* this byte seems random */ |
981 /* this byte seems random */ |
| 999 /* |
982 /* |
| 1000 purple_debug_info("QQ", "Byte one of get_level packet: %d\n", buf[0]); |
983 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Byte one of get_level packet: %d\n", buf[0]); |
| 1001 */ |
984 */ |
| 1002 for (i = 0; i < decr_len; i += 12) { |
985 for (i = 0; i < decr_len; i += 12) { |
| 1003 bytes += qq_get32(&uid, decr_buf + bytes); |
986 bytes += qq_get32(&uid, decr_buf + bytes); |
| 1004 bytes += qq_get32(&onlineTime, decr_buf + bytes); |
987 bytes += qq_get32(&onlineTime, decr_buf + bytes); |
| 1005 bytes += qq_get16(&level, decr_buf + bytes); |
988 bytes += qq_get16(&level, decr_buf + bytes); |
| 1006 bytes += qq_get16(&timeRemainder, decr_buf + bytes); |
989 bytes += qq_get16(&timeRemainder, decr_buf + bytes); |
| 1007 purple_debug_info("QQ_LEVEL", "%d, tmOnline: %d, level: %d, tmRemainder: %d\n", |
990 purple_debug(PURPLE_DEBUG_INFO, "QQ_LEVEL", |
| |
991 "%d, tmOnline: %d, level: %d, tmRemainder: %d\n", |
| 1008 uid, onlineTime, level, timeRemainder); |
992 uid, onlineTime, level, timeRemainder); |
| 1009 if (uid == qd->uid) { |
993 if (uid == qd->uid) { |
| 1010 qd->my_level = level; |
994 qd->my_level = level; |
| 1011 purple_debug_warning("QQ", "Got my levels as %d\n", qd->my_level); |
995 purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Got my levels as %d\n", qd->my_level); |
| 1012 continue; |
996 continue; |
| 1013 } |
997 } |
| 1014 |
998 |
| 1015 purple_name = uid_to_purple_name(uid); |
999 purple_name = uid_to_purple_name(uid); |
| 1016 if (purple_name == NULL) { |
1000 if (purple_name == NULL) { |
| 1017 continue; |
1001 continue; |
| 1018 } |
1002 } |
| 1019 |
1003 |
| 1020 b = purple_find_buddy(account, purple_name); |
1004 b = purple_find_buddy(account, purple_name); |
| 1021 g_free(purple_name); |
1005 g_free(purple_name); |
| 1022 |
1006 |
| 1023 q_bud = NULL; |
1007 q_bud = NULL; |
| 1024 if (b != NULL) { |
1008 if (b != NULL) { |
| 1025 q_bud = (qq_buddy *) b->proto_data; |
1009 q_bud = (qq_buddy *) b->proto_data; |
| 1026 } |
1010 } |
| 1027 |
1011 |
| 1028 if (q_bud == NULL) { |
1012 if (q_bud == NULL) { |
| 1029 purple_debug_error("QQ", "Got levels of %d not in my buddy list\n", uid); |
1013 purple_debug(PURPLE_DEBUG_ERROR, "QQ", |
| |
1014 "Got levels of %d not in my buddy list\n", uid); |
| 1030 continue; |
1015 continue; |
| 1031 } |
1016 } |
| 1032 |
1017 |
| 1033 q_bud->onlineTime = onlineTime; |
1018 q_bud->onlineTime = onlineTime; |
| 1034 q_bud->level = level; |
1019 q_bud->level = level; |