00001
00023
00024
00025 #include "internal.h"
00026 #include "debug.h"
00027 #include "notify.h"
00028
00029 #include "utils.h"
00030 #include "packet_parse.h"
00031 #include "buddy_info.h"
00032 #include "char_conv.h"
00033 #include "crypt.h"
00034 #include "header_info.h"
00035 #include "infodlg.h"
00036 #include "keep_alive.h"
00037 #include "send_core.h"
00038
00039
00040 #define QQ_CONTACT_FIELDS 37
00041
00042
00043
00044 typedef struct _qq_info_query {
00045 guint32 uid;
00046 gboolean show_window;
00047 contact_info *ret_info;
00048 } qq_info_query;
00049
00050
00051
00052
00053 void qq_send_packet_get_info(GaimConnection * gc, guint32 uid, gboolean show_window)
00054 {
00055 qq_data *qd;
00056 gchar *uid_str;
00057 GList *list;
00058 qq_info_query *query;
00059 gboolean is_exist;
00060 contact_info_window *info_window;
00061
00062 g_return_if_fail(gc != NULL && gc->proto_data != NULL && uid != 0);
00063
00064 qd = (qq_data *) gc->proto_data;
00065 uid_str = g_strdup_printf("%d", uid);
00066 qq_send_cmd(gc, QQ_CMD_GET_USER_INFO, TRUE, 0, TRUE, uid_str, strlen(uid_str));
00067
00068 if (show_window) {
00069 is_exist = FALSE;
00070 list = qd->contact_info_window;
00071 while (list != NULL) {
00072 info_window = (contact_info_window *) list->data;
00073 if (uid == info_window->uid) {
00074 is_exist = TRUE;
00075 break;
00076 } else
00077 list = list->next;
00078 }
00079 if (!is_exist) {
00080 info_window = g_new0(contact_info_window, 1);
00081 info_window->uid = uid;
00082 qd->contact_info_window = g_list_append(qd->contact_info_window, info_window);
00083 }
00084 }
00085
00086 query = g_new0(qq_info_query, 1);
00087 query->uid = uid;
00088 query->show_window = show_window;
00089 qd->info_query = g_list_append(qd->info_query, query);
00090
00091 g_free(uid_str);
00092 }
00093
00094
00095
00096 void qq_send_packet_modify_info(GaimConnection * gc, contact_info * info, gchar * new_passwd)
00097 {
00098 GaimAccount *a;
00099 gchar *old_passwd, *info_field[QQ_CONTACT_FIELDS];
00100 gint i;
00101 guint8 *raw_data, *cursor, bar;
00102
00103 g_return_if_fail(gc != NULL && info != NULL);
00104
00105 a = gc->account;
00106 old_passwd = a->password;
00107 bar = 0x1f;
00108 raw_data = g_newa(guint8, MAX_PACKET_SIZE - 128);
00109 cursor = raw_data;
00110
00111 g_memmove(info_field, info, sizeof(gchar *) * QQ_CONTACT_FIELDS);
00112
00113 if (new_passwd == NULL || strlen(new_passwd) == 0)
00114 create_packet_b(raw_data, &cursor, bar);
00115 else {
00116 create_packet_data(raw_data, &cursor, old_passwd, strlen(old_passwd));
00117 create_packet_b(raw_data, &cursor, bar);
00118 create_packet_data(raw_data, &cursor, new_passwd, strlen(new_passwd));
00119 }
00120
00121
00122 for (i = 1; i < QQ_CONTACT_FIELDS; i++) {
00123 create_packet_b(raw_data, &cursor, bar);
00124 create_packet_data(raw_data, &cursor, info_field[i], strlen(info_field[i]));
00125 }
00126 create_packet_b(raw_data, &cursor, bar);
00127
00128 qq_send_cmd(gc, QQ_CMD_UPDATE_INFO, TRUE, 0, TRUE, raw_data, cursor - raw_data);
00129
00130 }
00131
00132
00133
00134 void qq_process_modify_info_reply(guint8 * buf, gint buf_len, GaimConnection * gc)
00135 {
00136 qq_data *qd;
00137 gint len;
00138 guint8 *data;
00139
00140 g_return_if_fail(gc != NULL && gc->proto_data != NULL);
00141 g_return_if_fail(buf != NULL && buf_len != 0);
00142
00143 qd = (qq_data *) gc->proto_data;
00144 len = buf_len;
00145 data = g_newa(guint8, len);
00146
00147 if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) {
00148 if (qd->uid == atoi(data)) {
00149 gaim_debug(GAIM_DEBUG_INFO, "QQ", "Update info ACK OK\n");
00150 gaim_notify_info(gc, NULL, _("You information have been updated"), NULL);
00151 }
00152 } else
00153 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Error decrypt modify info reply\n");
00154
00155 }
00156
00157
00158
00159 void qq_refresh_buddy_and_myself(contact_info * info, GaimConnection * gc)
00160 {
00161 GaimBuddy *b;
00162 qq_data *qd;
00163 qq_buddy *q_bud;
00164 gchar *alias_utf8;
00165
00166 g_return_if_fail(gc != NULL && gc->proto_data != NULL);
00167 qd = (qq_data *) gc->proto_data;
00168
00169 alias_utf8 = qq_to_utf8(info->nick, QQ_CHARSET_DEFAULT);
00170 if (qd->uid == strtol(info->uid, NULL, 10)) {
00171 qd->my_icon = strtol(info->face, NULL, 10);
00172 if (alias_utf8 != NULL)
00173 gaim_account_set_alias(gc->account, alias_utf8);
00174 }
00175
00176 b = gaim_find_buddy(gc->account, uid_to_gaim_name(strtol(info->uid, NULL, 10)));
00177 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;
00178 if (q_bud != NULL) {
00179 q_bud->age = strtol(info->age, NULL, 10);
00180 q_bud->gender = strtol(info->gender, NULL, 10);
00181 q_bud->icon = strtol(info->face, NULL, 10);
00182 if (alias_utf8 != NULL)
00183 q_bud->nickname = g_strdup(alias_utf8);
00184 qq_update_buddy_contact(gc, q_bud);
00185 }
00186 g_free(alias_utf8);
00187 }
00188
00189
00190
00191 void qq_process_get_info_reply(guint8 * buf, gint buf_len, GaimConnection * gc)
00192 {
00193 gint len;
00194 guint8 *data;
00195 gchar **segments;
00196 qq_info_query *query;
00197 qq_data *qd;
00198 contact_info *info;
00199 contact_info_window *info_window;
00200 gboolean show_window;
00201 GList *list, *query_list;
00202
00203 g_return_if_fail(gc != NULL && gc->proto_data != NULL);
00204 g_return_if_fail(buf != NULL && buf_len != 0);
00205
00206 qd = (qq_data *) gc->proto_data;
00207 list = query_list = NULL;
00208 len = buf_len;
00209 data = g_newa(guint8, len);
00210 info = NULL;
00211
00212 if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) {
00213 if (NULL == (segments = split_data(data, len, "\x1e", QQ_CONTACT_FIELDS)))
00214 return;
00215
00216 info = (contact_info *) segments;
00217 qq_refresh_buddy_and_myself(info, gc);
00218
00219 query_list = qd->info_query;
00220 show_window = FALSE;
00221 while (query_list != NULL) {
00222 query = (qq_info_query *) query_list->data;
00223 if (query->uid == atoi(info->uid)) {
00224 show_window = query->show_window;
00225 qd->info_query = g_list_remove(qd->info_query, qd->info_query->data);
00226 g_free(query);
00227 break;
00228 }
00229 query_list = query_list->next;
00230 }
00231
00232 if (!show_window) {
00233 g_strfreev(segments);
00234 return;
00235 }
00236
00237 list = qd->contact_info_window;
00238 while (list != NULL) {
00239 info_window = (contact_info_window *) (list->data);
00240 if (info_window->uid == atoi(info->uid)) {
00241 if (info_window->window)
00242 qq_refresh_contact_info_dialog(info, gc, info_window);
00243 else
00244 qq_show_contact_info_dialog(info, gc, info_window);
00245 break;
00246 } else
00247 list = list->next;
00248 }
00249 g_strfreev(segments);
00250 } else
00251 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Error decrypt get info reply\n");
00252
00253 }
00254
00255
00256 void qq_info_query_free(qq_data * qd)
00257 {
00258 gint i;
00259 qq_info_query *p;
00260
00261 g_return_if_fail(qd != NULL);
00262
00263 i = 0;
00264 while (qd->info_query != NULL) {
00265 p = (qq_info_query *) (qd->info_query->data);
00266 qd->info_query = g_list_remove(qd->info_query, p);
00267 g_free(p);
00268 i++;
00269 }
00270 gaim_debug(GAIM_DEBUG_INFO, "QQ", "%d info queries are freed!\n", i);
00271 }
00272
00273
00274