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