Mercurial > pidgin.yaz
comparison libpurple/protocols/qq/buddy_opt.c @ 24091:d35672443baa
2008.10.10 - ccpaging <ccpaging(at)gmail.com>
* Support part of 'buddy' protocol of QQ2007/2008
author | SHiNE CsyFeK <csyfek@gmail.com> |
---|---|
date | Tue, 28 Oct 2008 16:42:46 +0000 |
parents | 9be95f0b9472 |
children | 7c0a56c5fea0 |
comparison
equal
deleted
inserted
replaced
24090:9be95f0b9472 | 24091:d35672443baa |
---|---|
38 #include "packet_parse.h" | 38 #include "packet_parse.h" |
39 #include "qq_network.h" | 39 #include "qq_network.h" |
40 #include "utils.h" | 40 #include "utils.h" |
41 | 41 |
42 #define PURPLE_GROUP_QQ_FORMAT "QQ (%s)" | 42 #define PURPLE_GROUP_QQ_FORMAT "QQ (%s)" |
43 #define PURPLE_GROUP_QQ_UNKNOWN "QQ Unknown" | 43 |
44 | |
45 #define QQ_REMOVE_BUDDY_REPLY_OK 0x00 | |
46 #define QQ_REMOVE_SELF_REPLY_OK 0x00 | 44 #define QQ_REMOVE_SELF_REPLY_OK 0x00 |
47 #define QQ_ADD_BUDDY_AUTH_REPLY_OK 0x30 /* ASCII value of "0" */ | 45 #define QQ_ADD_BUDDY_AUTH_REPLY_OK 0x30 /* ASCII value of "0" */ |
48 | 46 |
49 enum { | 47 enum { |
50 QQ_MY_AUTH_APPROVE = 0x30, /* ASCII value of "0" */ | 48 QQ_MY_AUTH_APPROVE = 0x30, /* ASCII value of "0" */ |
55 typedef struct _qq_buddy_req { | 53 typedef struct _qq_buddy_req { |
56 guint32 uid; | 54 guint32 uid; |
57 PurpleConnection *gc; | 55 PurpleConnection *gc; |
58 } qq_buddy_req; | 56 } qq_buddy_req; |
59 | 57 |
58 PurpleGroup *qq_group_find_or_new(const gchar *group_name) | |
59 { | |
60 PurpleGroup *g; | |
61 | |
62 g_return_val_if_fail(group_name != NULL, NULL); | |
63 | |
64 g = purple_find_group(group_name); | |
65 if (g == NULL) { | |
66 g = purple_group_new(group_name); | |
67 purple_blist_add_group(g, NULL); | |
68 purple_debug_warning("QQ", "Add new group: %s\n", group_name); | |
69 } | |
70 | |
71 return g; | |
72 } | |
73 | |
74 static qq_buddy_data *qq_buddy_data_new(guint32 uid) | |
75 { | |
76 qq_buddy_data *bd = g_new0(qq_buddy_data, 1); | |
77 memset(bd, 0, sizeof(qq_buddy_data)); | |
78 bd->uid = uid; | |
79 bd->status = QQ_BUDDY_OFFLINE; | |
80 return bd; | |
81 } | |
82 | |
83 qq_buddy_data *qq_buddy_data_find(PurpleConnection *gc, guint32 uid) | |
84 { | |
85 gchar *who; | |
86 PurpleBuddy *buddy; | |
87 | |
88 g_return_val_if_fail(gc != NULL, NULL); | |
89 | |
90 who = uid_to_purple_name(uid); | |
91 if (who == NULL) return NULL; | |
92 buddy = purple_find_buddy(purple_connection_get_account(gc), who); | |
93 g_free(who); | |
94 | |
95 if (buddy == NULL) { | |
96 purple_debug_error("QQ", "Can not find purple buddy of %d\n", uid); | |
97 return NULL; | |
98 } | |
99 if (buddy->proto_data == NULL) { | |
100 purple_debug_error("QQ", "Can not find buddy data of %d\n", uid); | |
101 return NULL; | |
102 } | |
103 return (qq_buddy_data *)buddy->proto_data; | |
104 } | |
105 | |
106 void qq_buddy_data_free(qq_buddy_data *bd) | |
107 { | |
108 g_return_if_fail(bd != NULL); | |
109 | |
110 if (bd->nickname) g_free(bd->nickname); | |
111 g_free(bd); | |
112 } | |
113 | |
114 /* create purple buddy without data and display with no-auth icon */ | |
115 PurpleBuddy *qq_buddy_new(PurpleConnection *gc, guint32 uid) | |
116 { | |
117 PurpleBuddy *buddy; | |
118 PurpleGroup *group; | |
119 gchar *who; | |
120 gchar *group_name; | |
121 | |
122 g_return_val_if_fail(gc->account != NULL && uid != 0, NULL); | |
123 | |
124 group_name = g_strdup_printf(PURPLE_GROUP_QQ_FORMAT, | |
125 purple_account_get_username(gc->account)); | |
126 group = qq_group_find_or_new(group_name); | |
127 if (group == NULL) { | |
128 purple_debug_error("QQ", "Failed creating group %s\n", group_name); | |
129 return NULL; | |
130 } | |
131 | |
132 who = uid_to_purple_name(uid); | |
133 | |
134 purple_debug_info("QQ", "Add new purple buddy: [%s]\n", who); | |
135 buddy = purple_buddy_new(gc->account, who, NULL); /* alias is NULL */ | |
136 buddy->proto_data = NULL; | |
137 | |
138 g_free(who); | |
139 | |
140 purple_blist_add_buddy(buddy, NULL, group, NULL); | |
141 | |
142 g_free(group_name); | |
143 | |
144 return buddy; | |
145 } | |
146 | |
147 static void qq_buddy_free(PurpleBuddy *buddy) | |
148 { | |
149 g_return_if_fail(buddy); | |
150 if (buddy->proto_data) { | |
151 qq_buddy_data_free(buddy->proto_data); | |
152 } | |
153 buddy->proto_data = NULL; | |
154 purple_blist_remove_buddy(buddy); | |
155 } | |
156 | |
157 PurpleBuddy *qq_buddy_find(PurpleConnection *gc, guint32 uid) | |
158 { | |
159 PurpleBuddy *buddy; | |
160 gchar *who; | |
161 | |
162 g_return_val_if_fail(gc->account != NULL && uid != 0, NULL); | |
163 | |
164 who = uid_to_purple_name(uid); | |
165 buddy = purple_find_buddy(gc->account, who); | |
166 g_free(who); | |
167 return buddy; | |
168 } | |
169 | |
170 PurpleBuddy *qq_buddy_find_or_new(PurpleConnection *gc, guint32 uid) | |
171 { | |
172 PurpleBuddy *buddy; | |
173 | |
174 g_return_val_if_fail(gc->account != NULL && uid != 0, NULL); | |
175 | |
176 buddy = qq_buddy_find(gc, uid); | |
177 if (buddy == NULL) { | |
178 buddy = qq_buddy_new(gc, uid); | |
179 if (buddy == NULL) { | |
180 return NULL; | |
181 } | |
182 } | |
183 | |
184 if (buddy->proto_data != NULL) { | |
185 return buddy; | |
186 } | |
187 | |
188 buddy->proto_data = qq_buddy_data_new(uid); | |
189 return buddy; | |
190 } | |
191 | |
60 /* send packet to remove a buddy from my buddy list */ | 192 /* send packet to remove a buddy from my buddy list */ |
61 static void request_buddy_remove(PurpleConnection *gc, guint32 uid) | 193 static void request_buddy_remove(PurpleConnection *gc, guint32 uid) |
62 { | 194 { |
63 gchar uid_str[11]; | 195 gchar uid_str[11]; |
196 gint bytes; | |
64 | 197 |
65 g_return_if_fail(uid > 0); | 198 g_return_if_fail(uid > 0); |
66 | 199 |
67 g_snprintf(uid_str, sizeof(uid_str), "%d", uid); | 200 g_snprintf(uid_str, sizeof(uid_str), "%d", uid); |
68 qq_send_cmd(gc, QQ_CMD_BUDDY_REMOVE, (guint8 *) uid_str, strlen(uid_str)); | 201 bytes = strlen(uid_str); |
202 qq_send_cmd_mess(gc, QQ_CMD_BUDDY_REMOVE, (guint8 *) uid_str, bytes, 0, uid); | |
69 } | 203 } |
70 | 204 |
71 /* try to remove myself from someone's buddy list */ | 205 /* try to remove myself from someone's buddy list */ |
72 static void request_buddy_remove_me(PurpleConnection *gc, guint32 uid) | 206 static void request_buddy_remove_me(PurpleConnection *gc, guint32 uid) |
73 { | 207 { |
76 | 210 |
77 g_return_if_fail(uid > 0); | 211 g_return_if_fail(uid > 0); |
78 | 212 |
79 bytes += qq_put32(raw_data + bytes, uid); | 213 bytes += qq_put32(raw_data + bytes, uid); |
80 | 214 |
81 qq_send_cmd(gc, QQ_CMD_REMOVE_ME, raw_data, bytes); | 215 qq_send_cmd_mess(gc, QQ_CMD_REMOVE_ME, raw_data, bytes, 0, uid); |
82 } | 216 } |
83 | 217 |
84 /* try to add a buddy without authentication */ | 218 /* try to add a buddy without authentication */ |
85 static void request_buddy_add_no_auth(PurpleConnection *gc, guint32 uid) | 219 static void request_buddy_add_no_auth(PurpleConnection *gc, guint32 uid) |
86 { | 220 { |
218 } | 352 } |
219 | 353 |
220 /* add a buddy and send packet to QQ server | 354 /* add a buddy and send packet to QQ server |
221 * note that when purple load local cached buddy list into its blist | 355 * note that when purple load local cached buddy list into its blist |
222 * it also calls this funtion, so we have to | 356 * it also calls this funtion, so we have to |
223 * define qd->is_login=TRUE AFTER serv_finish_login(gc) */ | 357 * define qd->is_login=TRUE AFTER LOGIN */ |
224 void qq_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) | 358 void qq_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) |
225 { | 359 { |
226 qq_data *qd; | 360 qq_data *qd; |
227 guint32 uid; | 361 guint32 uid; |
228 PurpleBuddy *b; | 362 |
363 g_return_if_fail(NULL != gc && NULL != gc->proto_data); | |
364 g_return_if_fail(buddy != NULL); | |
229 | 365 |
230 qd = (qq_data *) gc->proto_data; | 366 qd = (qq_data *) gc->proto_data; |
231 if (!qd->is_login) | 367 if (!qd->is_login) |
232 return; /* IMPORTANT ! */ | 368 return; /* IMPORTANT ! */ |
233 | 369 |
235 if (uid > 0) { | 371 if (uid > 0) { |
236 request_buddy_add_no_auth(gc, uid); | 372 request_buddy_add_no_auth(gc, uid); |
237 return; | 373 return; |
238 } | 374 } |
239 | 375 |
240 b = purple_find_buddy(gc->account, buddy->name); | 376 purple_notify_error(gc, _("QQ Buddy"), _("Add buddy"), _("Invalid QQ Number")); |
241 if (b != NULL) { | 377 if (buddy == NULL) { |
242 purple_blist_remove_buddy(b); | 378 return; |
243 } | 379 } |
244 purple_notify_error(gc, _("QQ Buddy"), _("QQ Number Error"), _("Invalid QQ Number")); | 380 |
245 } | 381 purple_debug_info("QQ", "Remove buddy with invalid QQ number %d\n", uid); |
246 | 382 qq_buddy_free(buddy); |
247 void qq_change_buddys_group(PurpleConnection *gc, const char *who, | |
248 const char *old_group, const char *new_group) | |
249 { | |
250 gint uid; | |
251 g_return_if_fail(who != NULL); | |
252 | |
253 if (strcmp(new_group, PURPLE_GROUP_QQ_UNKNOWN) == 0) { | |
254 if (purple_privacy_check(gc->account, who)) { | |
255 purple_privacy_deny(gc->account, who, TRUE, FALSE); | |
256 } else { | |
257 purple_privacy_deny_add(gc->account, who, TRUE); | |
258 } | |
259 return; | |
260 } | |
261 | |
262 if (strcmp(old_group, PURPLE_GROUP_QQ_UNKNOWN) != 0) { | |
263 return; | |
264 } | |
265 | |
266 uid = purple_name_to_uid(who); | |
267 g_return_if_fail(uid != 0); | |
268 | |
269 purple_privacy_deny_remove(gc->account, who, TRUE); | |
270 | |
271 purple_debug_info("QQ", "Add unknow buddy %d\n", uid); | |
272 request_buddy_add_no_auth(gc, uid); | |
273 } | 383 } |
274 | 384 |
275 static void buddy_cancel_cb(qq_buddy_req *add_req, const gchar *msg) | 385 static void buddy_cancel_cb(qq_buddy_req *add_req, const gchar *msg) |
276 { | 386 { |
277 g_return_if_fail(add_req != NULL); | 387 g_return_if_fail(add_req != NULL); |
288 | 398 |
289 request_buddy_add_no_auth(add_req->gc, add_req->uid); | 399 request_buddy_add_no_auth(add_req->gc, add_req->uid); |
290 g_free(add_req); | 400 g_free(add_req); |
291 } | 401 } |
292 | 402 |
293 static void buddy_remove_both_cb(qq_buddy_req *add_req) | |
294 { | |
295 PurpleConnection *gc; | |
296 qq_data *qd; | |
297 gchar *purple_name; | |
298 PurpleBuddy *buddy; | |
299 | |
300 g_return_if_fail(add_req != NULL); | |
301 if (add_req->gc == NULL || add_req->uid == 0) { | |
302 g_free(add_req); | |
303 return; | |
304 } | |
305 | |
306 gc = add_req->gc; | |
307 qd = (qq_data *) gc->proto_data; | |
308 | |
309 request_buddy_remove(gc, add_req->uid); | |
310 request_buddy_remove_me(gc, add_req->uid); | |
311 | |
312 purple_name = uid_to_purple_name(add_req->uid); | |
313 buddy = purple_find_buddy(gc->account, purple_name); | |
314 if (buddy == NULL) { | |
315 g_free(add_req); | |
316 return; | |
317 } | |
318 | |
319 if (buddy->proto_data != NULL) { | |
320 qq_buddy_data_free(buddy->proto_data); | |
321 buddy->proto_data = NULL; | |
322 } else { | |
323 purple_debug_warning("QQ", "We have no qq_buddy_data record for %s\n", buddy->name); | |
324 } | |
325 | |
326 purple_blist_remove_buddy(buddy); | |
327 g_free(add_req); | |
328 } | |
329 | |
330 /* remove a buddy from my list and remove myself from his list */ | |
331 /* TODO: re-enable this */ | |
332 void qq_remove_buddy_and_me(PurpleBlistNode * node) | |
333 { | |
334 PurpleConnection *gc; | |
335 qq_data *qd; | |
336 guint32 uid; | |
337 qq_buddy_req *add_req; | |
338 PurpleBuddy *buddy; | |
339 const gchar *who; | |
340 | |
341 g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); | |
342 | |
343 buddy = (PurpleBuddy *) node; | |
344 gc = purple_account_get_connection(buddy->account); | |
345 qd = (qq_data *) gc->proto_data; | |
346 if (!qd->is_login) | |
347 return; | |
348 | |
349 who = buddy->name; | |
350 g_return_if_fail(who != NULL); | |
351 | |
352 uid = purple_name_to_uid(who); | |
353 g_return_if_fail(uid > 0); | |
354 | |
355 if (uid == qd->uid) { | |
356 return; | |
357 } | |
358 | |
359 add_req = g_new0(qq_buddy_req, 1); | |
360 add_req->gc = gc; | |
361 add_req->uid = uid; | |
362 | |
363 purple_request_action(gc, _("Block Buddy"), | |
364 "Are you sure you want to block this buddy?", | |
365 NULL, | |
366 1, | |
367 purple_connection_get_account(gc), NULL, NULL, | |
368 add_req, 2, | |
369 _("Cancel"), G_CALLBACK(buddy_cancel_cb), | |
370 _("Block"), G_CALLBACK(buddy_remove_both_cb)); | |
371 } | |
372 | |
373 /* process reply to add_buddy_auth request */ | 403 /* process reply to add_buddy_auth request */ |
374 void qq_process_buddy_add_auth(guint8 *data, gint data_len, PurpleConnection *gc) | 404 void qq_process_buddy_add_auth(guint8 *data, gint data_len, PurpleConnection *gc) |
375 { | 405 { |
376 qq_data *qd; | 406 qq_data *qd; |
377 gchar **segments, *msg_utf8; | 407 gchar **segments, *msg_utf8; |
379 g_return_if_fail(data != NULL && data_len != 0); | 409 g_return_if_fail(data != NULL && data_len != 0); |
380 | 410 |
381 qd = (qq_data *) gc->proto_data; | 411 qd = (qq_data *) gc->proto_data; |
382 | 412 |
383 if (data[0] != QQ_ADD_BUDDY_AUTH_REPLY_OK) { | 413 if (data[0] != QQ_ADD_BUDDY_AUTH_REPLY_OK) { |
384 purple_debug_warning("QQ", "Failed authorizing of adding requestion\n"); | |
385 if (NULL == (segments = split_data(data, data_len, "\x1f", 2))) { | 414 if (NULL == (segments = split_data(data, data_len, "\x1f", 2))) { |
415 purple_notify_error(gc, _("QQ Buddy"), _("Failed sending authorize"), NULL); | |
386 return; | 416 return; |
387 } | 417 } |
388 msg_utf8 = qq_to_utf8(segments[1], QQ_CHARSET_DEFAULT); | 418 msg_utf8 = qq_to_utf8(segments[1], QQ_CHARSET_DEFAULT); |
389 purple_notify_error(gc, _("QQ Buddy"), _("Failed authorizing of adding requestion"), msg_utf8); | 419 purple_notify_error(gc, _("QQ Buddy"), _("Failed sending authorize"), msg_utf8); |
390 g_free(msg_utf8); | 420 g_free(msg_utf8); |
391 } else { | 421 } else { |
392 qq_got_attention(gc, _("Successed authorizing of adding requestion")); | 422 qq_got_attention(gc, _("Successed sending authorize")); |
393 } | 423 } |
394 } | 424 } |
395 | 425 |
396 /* process the server reply for my request to remove a buddy */ | 426 /* process the server reply for my request to remove a buddy */ |
397 void qq_process_buddy_remove(guint8 *data, gint data_len, PurpleConnection *gc) | 427 void qq_process_buddy_remove(PurpleConnection *gc, guint8 *data, gint data_len, guint32 uid) |
428 { | |
429 PurpleBuddy *buddy = NULL; | |
430 gchar *msg; | |
431 | |
432 g_return_if_fail(data != NULL && data_len != 0); | |
433 g_return_if_fail(uid != 0); | |
434 | |
435 buddy = qq_buddy_find(gc, uid); | |
436 if (data[0] != 0) { | |
437 msg = g_strdup_printf(_("Failed removing buddy %d"), uid); | |
438 purple_notify_info(gc, _("QQ Buddy"), msg, NULL); | |
439 if (buddy == NULL) { | |
440 /* Add buddy with no-auth */ | |
441 qq_buddy_new(gc, uid); | |
442 } | |
443 } else { | |
444 msg = g_strdup_printf(_("Successed removing buddy %d"), uid); | |
445 qq_got_attention(gc, _("Successed removing budy.")); | |
446 if (buddy != NULL) { | |
447 /* remove buddy again */ | |
448 qq_buddy_free(buddy); | |
449 } | |
450 } | |
451 g_free(msg); | |
452 } | |
453 | |
454 /* process the server reply for my request to remove myself from a buddy */ | |
455 void qq_process_buddy_remove_me(PurpleConnection *gc, guint8 *data, gint data_len, guint32 uid) | |
398 { | 456 { |
399 qq_data *qd; | 457 qq_data *qd; |
458 gchar *msg; | |
400 | 459 |
401 g_return_if_fail(data != NULL && data_len != 0); | 460 g_return_if_fail(data != NULL && data_len != 0); |
402 | |
403 qd = (qq_data *) gc->proto_data; | 461 qd = (qq_data *) gc->proto_data; |
404 | 462 |
405 if (data[0] != QQ_REMOVE_BUDDY_REPLY_OK) { | 463 if (data[0] != 0) { |
406 /* there is no reason return from server */ | 464 msg = g_strdup_printf(_("Failed removing me from %d's buddy list"), uid); |
407 purple_debug_warning("QQ", "Remove buddy fails\n"); | 465 purple_notify_info(gc, _("QQ Buddy"), msg, NULL); |
408 purple_notify_info(gc, _("QQ Buddy"), _("Failed:"), _("Remove buddy")); | 466 } else { |
409 } else { /* if reply */ | 467 msg = g_strdup_printf(_("Successed removing me from %d's buddy list"), uid); |
410 qq_got_attention(gc, _("Successed removing budy.")); | 468 qq_got_attention(gc, msg); |
411 } | 469 } |
412 } | 470 g_free(msg); |
413 | |
414 /* process the server reply for my request to remove myself from a buddy */ | |
415 void qq_process_buddy_remove_me(guint8 *data, gint data_len, PurpleConnection *gc) | |
416 { | |
417 qq_data *qd; | |
418 | |
419 g_return_if_fail(data != NULL && data_len != 0); | |
420 | |
421 qd = (qq_data *) gc->proto_data; | |
422 | |
423 if (data[0] != QQ_REMOVE_SELF_REPLY_OK) { | |
424 /* there is no reason return from server */ | |
425 purple_debug_warning("QQ", "Remove self fails\n"); | |
426 purple_notify_info(gc, _("QQ Buddy"), _("Failed:"), _("Remove me from other's buddy list")); | |
427 } else { /* if reply */ | |
428 qq_got_attention(gc, _("Successed removing me from other's budy list.")); | |
429 } | |
430 } | 471 } |
431 | 472 |
432 void qq_process_buddy_add_no_auth(guint8 *data, gint data_len, guint32 uid, PurpleConnection *gc) | 473 void qq_process_buddy_add_no_auth(guint8 *data, gint data_len, guint32 uid, PurpleConnection *gc) |
433 { | 474 { |
434 qq_data *qd; | 475 qq_data *qd; |
435 gchar *msg, **segments, *dest_uid, *reply; | 476 gchar *msg, **segments, *dest_uid, *reply; |
436 PurpleBuddy *b; | 477 PurpleBuddy *buddy; |
437 qq_buddy_req *add_req; | 478 qq_buddy_req *add_req; |
438 gchar *nombre; | 479 gchar *who; |
439 | 480 |
440 g_return_if_fail(data != NULL && data_len != 0); | 481 g_return_if_fail(data != NULL && data_len != 0); |
441 | 482 |
442 qd = (qq_data *) gc->proto_data; | 483 qd = (qq_data *) gc->proto_data; |
443 | 484 |
444 if (uid == 0) { /* we have no record for this */ | 485 if (uid == 0) { /* we have no record for this */ |
445 purple_debug_error("QQ", "Process buddy add, unknow id\n"); | 486 purple_debug_error("QQ", "Process buddy add, unknow id\n"); |
446 return; | 487 return; |
447 } else { | 488 } |
448 purple_debug_info("QQ", "Process buddy add for id [%d]\n", uid); | 489 purple_debug_info("QQ", "Process buddy add for id [%d]\n", uid); |
449 } | 490 qq_show_packet("buddy_add_no_auth", data, data_len); |
450 | 491 |
451 if (NULL == (segments = split_data(data, data_len, "\x1f", 2))) | 492 if (NULL == (segments = split_data(data, data_len, "\x1f", 2))) |
452 return; | 493 return; |
453 | 494 |
454 dest_uid = segments[0]; | 495 dest_uid = segments[0]; |
457 purple_debug_error("QQ", "Add buddy reply is to [%s], not me!", dest_uid); | 498 purple_debug_error("QQ", "Add buddy reply is to [%s], not me!", dest_uid); |
458 g_strfreev(segments); | 499 g_strfreev(segments); |
459 return; | 500 return; |
460 } | 501 } |
461 | 502 |
462 if (strtol(reply, NULL, 10) > 0) { /* need auth */ | 503 if (strtol(reply, NULL, 10) == 0) { |
463 purple_debug_warning("QQ", "Add buddy attempt fails, need authentication\n"); | 504 /* add OK */ |
464 nombre = uid_to_purple_name(uid); | |
465 b = purple_find_buddy(gc->account, nombre); | |
466 if (b != NULL) | |
467 purple_blist_remove_buddy(b); | |
468 add_req = g_new0(qq_buddy_req, 1); | |
469 add_req->gc = gc; | |
470 add_req->uid = uid; | |
471 msg = g_strdup_printf(_("%d needs authentication"), uid); | |
472 purple_request_input(gc, NULL, msg, | |
473 _("Input request here"), /* TODO: Awkward string to fix post string freeze - standardize auth dialogues? -evands */ | |
474 _("Would you be my friend?"), | |
475 TRUE, FALSE, NULL, _("Send"), | |
476 G_CALLBACK(request_buddy_add_auth_cb), | |
477 _("Cancel"), G_CALLBACK(buddy_cancel_cb), | |
478 purple_connection_get_account(gc), nombre, NULL, | |
479 add_req); | |
480 g_free(msg); | |
481 g_free(nombre); | |
482 } else { /* add OK */ | |
483 qq_buddy_find_or_new(gc, uid); | 505 qq_buddy_find_or_new(gc, uid); |
506 | |
484 qq_request_buddy_info(gc, uid, 0, 0); | 507 qq_request_buddy_info(gc, uid, 0, 0); |
485 qq_request_get_buddies_online(gc, 0, 0); | |
486 if (qd->client_version >= 2007) { | 508 if (qd->client_version >= 2007) { |
487 qq_request_get_level_2007(gc, uid); | 509 qq_request_get_level_2007(gc, uid); |
488 } else { | 510 } else { |
489 qq_request_get_level(gc, uid); | 511 qq_request_get_level(gc, uid); |
490 } | 512 } |
513 qq_request_get_buddies_online(gc, 0, 0); | |
491 | 514 |
492 msg = g_strdup_printf(_("Successed adding into %d's buddy list"), uid); | 515 msg = g_strdup_printf(_("Successed adding into %d's buddy list"), uid); |
493 qq_got_attention(gc, msg); | 516 qq_got_attention(gc, msg); |
494 g_free(msg); | 517 g_free(msg); |
495 } | 518 g_strfreev(segments); |
496 g_strfreev(segments); | 519 return; |
497 } | 520 } |
498 | 521 |
499 PurpleGroup *qq_group_find_or_new(const gchar *group_name) | 522 /* need auth */ |
500 { | 523 purple_debug_warning("QQ", "Failed adding buddy, need authorize\n"); |
501 PurpleGroup *g; | |
502 | |
503 g_return_val_if_fail(group_name != NULL, NULL); | |
504 | |
505 g = purple_find_group(group_name); | |
506 if (g == NULL) { | |
507 g = purple_group_new(group_name); | |
508 purple_blist_add_group(g, NULL); | |
509 purple_debug_warning("QQ", "Add new group: %s\n", group_name); | |
510 } | |
511 | |
512 return g; | |
513 } | |
514 | |
515 static qq_buddy_data *qq_buddy_data_new(guint32 uid) | |
516 { | |
517 qq_buddy_data *bd = g_new0(qq_buddy_data, 1); | |
518 memset(bd, 0, sizeof(qq_buddy_data)); | |
519 bd->uid = uid; | |
520 bd->status = QQ_BUDDY_ONLINE_NORMAL; | |
521 return bd; | |
522 } | |
523 | |
524 qq_buddy_data *qq_buddy_data_find(PurpleConnection *gc, guint32 uid) | |
525 { | |
526 gchar *who; | |
527 PurpleBuddy *buddy; | |
528 | |
529 g_return_val_if_fail(gc != NULL, NULL); | |
530 | |
531 who = uid_to_purple_name(uid); | |
532 if (who == NULL) return NULL; | |
533 buddy = purple_find_buddy(purple_connection_get_account(gc), who); | |
534 g_free(who); | |
535 | |
536 if (buddy == NULL) { | |
537 purple_debug_error("QQ", "Can not find purple buddy of %d\n", uid); | |
538 return NULL; | |
539 } | |
540 if (buddy->proto_data == NULL) { | |
541 purple_debug_error("QQ", "Can not find buddy data of %d\n", uid); | |
542 return NULL; | |
543 } | |
544 return (qq_buddy_data *)buddy->proto_data; | |
545 } | |
546 | |
547 void qq_buddy_data_free(qq_buddy_data *bd) | |
548 { | |
549 g_return_if_fail(bd != NULL); | |
550 | |
551 if (bd->nickname) g_free(bd->nickname); | |
552 g_free(bd); | |
553 } | |
554 | |
555 /* create purple buddy without data and display with no-auth icon */ | |
556 PurpleBuddy *qq_buddy_new(PurpleConnection *gc, guint32 uid) | |
557 { | |
558 PurpleBuddy *buddy; | |
559 PurpleGroup *group; | |
560 gchar *who; | |
561 gchar *group_name; | |
562 | |
563 g_return_val_if_fail(gc->account != NULL && uid != 0, NULL); | |
564 | |
565 group_name = g_strdup_printf(PURPLE_GROUP_QQ_FORMAT, | |
566 purple_account_get_username(gc->account)); | |
567 group = qq_group_find_or_new(group_name); | |
568 if (group == NULL) { | |
569 purple_debug_error("QQ", "Failed creating group %s\n", group_name); | |
570 return NULL; | |
571 } | |
572 | |
573 who = uid_to_purple_name(uid); | |
574 buddy = purple_buddy_new(gc->account, who, NULL); /* alias is NULL */ | |
575 g_free(who); | |
576 buddy->proto_data = NULL; | |
577 | |
578 purple_blist_add_buddy(buddy, NULL, group, NULL); | |
579 purple_debug_info("QQ", "Add new purple buddy: [%s]\n", who); | |
580 | |
581 g_free(group_name); | |
582 | |
583 return buddy; | |
584 } | |
585 | |
586 PurpleBuddy *qq_buddy_find(PurpleConnection *gc, guint32 uid) | |
587 { | |
588 PurpleBuddy *buddy; | |
589 gchar *who; | |
590 | |
591 g_return_val_if_fail(gc->account != NULL && uid != 0, NULL); | |
592 | |
593 who = uid_to_purple_name(uid); | |
594 buddy = purple_find_buddy(gc->account, who); | |
595 g_free(who); | |
596 return buddy; | |
597 } | |
598 | |
599 PurpleBuddy *qq_buddy_find_or_new(PurpleConnection *gc, guint32 uid) | |
600 { | |
601 PurpleBuddy *buddy; | |
602 | |
603 g_return_val_if_fail(gc->account != NULL && uid != 0, NULL); | |
604 | 524 |
605 buddy = qq_buddy_find(gc, uid); | 525 buddy = qq_buddy_find(gc, uid); |
606 if (buddy == NULL) { | 526 if (buddy == NULL) { |
607 buddy = qq_buddy_new(gc, uid); | 527 buddy = qq_buddy_new(gc, uid); |
608 if (buddy == NULL) { | 528 } |
609 return NULL; | 529 if (buddy != NULL && buddy->proto_data != NULL) { |
610 } | 530 /* Not authorized now, free buddy data */ |
611 } | 531 qq_buddy_data_free(buddy->proto_data); |
612 | 532 buddy->proto_data = NULL; |
613 if (buddy->proto_data != NULL) { | 533 } |
614 return buddy; | 534 |
615 } | 535 who = uid_to_purple_name(uid); |
616 | 536 add_req = g_new0(qq_buddy_req, 1); |
617 buddy->proto_data = qq_buddy_data_new(uid); | 537 add_req->gc = gc; |
618 return buddy; | 538 add_req->uid = uid; |
539 msg = g_strdup_printf(_("%d needs authentication"), uid); | |
540 purple_request_input(gc, _("Add buddy authorize"), msg, | |
541 _("Input request here"), /* TODO: Awkward string to fix post string freeze - standardize auth dialogues? -evands */ | |
542 _("Would you be my friend?"), | |
543 TRUE, FALSE, NULL, _("Send"), | |
544 G_CALLBACK(request_buddy_add_auth_cb), | |
545 _("Cancel"), G_CALLBACK(buddy_cancel_cb), | |
546 purple_connection_get_account(gc), who, NULL, | |
547 add_req); | |
548 | |
549 g_free(msg); | |
550 g_free(who); | |
551 g_strfreev(segments); | |
619 } | 552 } |
620 | 553 |
621 /* remove a buddy and send packet to QQ server accordingly */ | 554 /* remove a buddy and send packet to QQ server accordingly */ |
622 void qq_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) | 555 void qq_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) |
623 { | 556 { |
624 qq_data *qd; | 557 qq_data *qd; |
625 guint32 uid; | 558 guint32 uid; |
626 | 559 |
627 g_return_if_fail(gc != NULL && gc->proto_data != NULL); | 560 g_return_if_fail(gc != NULL && gc->proto_data != NULL); |
628 g_return_if_fail(buddy != NULL); | 561 g_return_if_fail(buddy != NULL); |
562 | |
629 qd = (qq_data *) gc->proto_data; | 563 qd = (qq_data *) gc->proto_data; |
564 if (!qd->is_login) | |
565 return; | |
630 | 566 |
631 uid = purple_name_to_uid(buddy->name); | 567 uid = purple_name_to_uid(buddy->name); |
632 if (!qd->is_login) | |
633 return; | |
634 | |
635 if (uid > 0) { | 568 if (uid > 0) { |
636 request_buddy_remove(gc, uid); | 569 request_buddy_remove(gc, uid); |
570 request_buddy_remove_me(gc, uid); | |
637 } | 571 } |
638 | 572 |
639 if (buddy->proto_data) { | 573 if (buddy->proto_data) { |
640 qq_buddy_data_free(buddy->proto_data); | 574 qq_buddy_data_free(buddy->proto_data); |
641 buddy->proto_data = NULL; | 575 buddy->proto_data = NULL; |
642 } else { | 576 } else { |
643 purple_debug_warning("QQ", "We have no qq_buddy_data record for %s\n", buddy->name); | 577 purple_debug_warning("QQ", "Empty buddy data of %s\n", buddy->name); |
644 } | 578 } |
645 | 579 |
646 /* Do not call purple_blist_remove_buddy, | 580 /* Do not call purple_blist_remove_buddy, |
647 * otherwise purple segmentation fault */ | 581 * otherwise purple segmentation fault */ |
648 } | 582 } |
767 | 701 |
768 /* you are rejected by the person */ | 702 /* you are rejected by the person */ |
769 static void server_buddy_rejected_me(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8) | 703 static void server_buddy_rejected_me(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8) |
770 { | 704 { |
771 gchar *message, *reason; | 705 gchar *message, *reason; |
706 guint32 uid; | |
707 PurpleBuddy *buddy; | |
772 | 708 |
773 g_return_if_fail(from != NULL && to != NULL); | 709 g_return_if_fail(from != NULL && to != NULL); |
774 | 710 |
775 message = g_strdup_printf(_("Requestion rejected by %s"), from); | 711 message = g_strdup_printf(_("Requestion rejected by %s"), from); |
776 reason = g_strdup_printf(_("Message: %s"), msg_utf8); | 712 reason = g_strdup_printf(_("Message: %s"), msg_utf8); |
777 | 713 |
778 purple_notify_info(gc, _("QQ Buddy"), message, reason); | 714 purple_notify_info(gc, _("QQ Buddy"), message, reason); |
779 g_free(message); | 715 g_free(message); |
780 g_free(reason); | 716 g_free(reason); |
717 | |
718 uid = strtol(from, NULL, 10); | |
719 g_return_if_fail(uid != 0); | |
720 | |
721 buddy = qq_buddy_find(gc, uid); | |
722 if (buddy != NULL && buddy->proto_data != NULL) { | |
723 /* Not authorized now, free buddy data */ | |
724 qq_buddy_data_free(buddy->proto_data); | |
725 buddy->proto_data = NULL; | |
726 } | |
781 } | 727 } |
782 | 728 |
783 void qq_process_buddy_from_server(PurpleConnection *gc, int funct, | 729 void qq_process_buddy_from_server(PurpleConnection *gc, int funct, |
784 gchar *from, gchar *to, gchar *msg_utf8) | 730 gchar *from, gchar *to, gchar *msg_utf8) |
785 { | 731 { |