Mercurial > pidgin.yaz
comparison libpurple/protocols/qq/buddy_opt.c @ 24048:d57928c9dd8f
2008.09.19 - ccpaging <ccpaging(at)gmail.com>
* Rewrite buddy modify info, there is a ticket for this problem
* Use ship32 to trans action code between request packet and reply packet process
author | SHiNE CsyFeK <csyfek@gmail.com> |
---|---|
date | Fri, 19 Sep 2008 14:46:41 +0000 |
parents | bcfc98c7a55f |
children | bdfcfd71449c |
comparison
equal
deleted
inserted
replaced
24047:b72816d1a131 | 24048:d57928c9dd8f |
---|---|
24 | 24 |
25 #include "debug.h" | 25 #include "debug.h" |
26 #include "internal.h" | 26 #include "internal.h" |
27 #include "notify.h" | 27 #include "notify.h" |
28 #include "request.h" | 28 #include "request.h" |
29 #include "privacy.h" | |
29 | 30 |
30 #include "buddy_info.h" | 31 #include "buddy_info.h" |
31 #include "buddy_list.h" | 32 #include "buddy_list.h" |
32 #include "buddy_opt.h" | 33 #include "buddy_opt.h" |
33 #include "char_conv.h" | 34 #include "char_conv.h" |
50 QQ_MY_AUTH_APPROVE = 0x30, /* ASCII value of "0" */ | 51 QQ_MY_AUTH_APPROVE = 0x30, /* ASCII value of "0" */ |
51 QQ_MY_AUTH_REJECT = 0x31, /* ASCII value of "1" */ | 52 QQ_MY_AUTH_REJECT = 0x31, /* ASCII value of "1" */ |
52 QQ_MY_AUTH_REQUEST = 0x32, /* ASCII value of "2" */ | 53 QQ_MY_AUTH_REQUEST = 0x32, /* ASCII value of "2" */ |
53 }; | 54 }; |
54 | 55 |
55 typedef struct _qq_add_buddy_request { | |
56 guint32 uid; | |
57 guint16 seq; | |
58 } qq_add_buddy_request; | |
59 | |
60 /* send packet to remove a buddy from my buddy list */ | 56 /* send packet to remove a buddy from my buddy list */ |
61 static void _qq_send_packet_remove_buddy(PurpleConnection *gc, guint32 uid) | 57 static void request_buddy_remove(PurpleConnection *gc, guint32 uid) |
62 { | 58 { |
63 gchar uid_str[11]; | 59 gchar uid_str[11]; |
64 | 60 |
65 g_return_if_fail(uid > 0); | 61 g_return_if_fail(uid > 0); |
66 | 62 |
67 g_snprintf(uid_str, sizeof(uid_str), "%d", uid); | 63 g_snprintf(uid_str, sizeof(uid_str), "%d", uid); |
68 qq_send_cmd(gc, QQ_CMD_DEL_BUDDY, (guint8 *) uid_str, strlen(uid_str)); | 64 qq_send_cmd(gc, QQ_CMD_BUDDY_REMOVE, (guint8 *) uid_str, strlen(uid_str)); |
69 } | 65 } |
70 | 66 |
71 /* try to remove myself from someone's buddy list */ | 67 /* try to remove myself from someone's buddy list */ |
72 static void _qq_send_packet_remove_self_from(PurpleConnection *gc, guint32 uid) | 68 static void request_buddy_remove_me(PurpleConnection *gc, guint32 uid) |
73 { | 69 { |
74 guint8 raw_data[16] = {0}; | 70 guint8 raw_data[16] = {0}; |
75 gint bytes = 0; | 71 gint bytes = 0; |
76 | 72 |
77 g_return_if_fail(uid > 0); | 73 g_return_if_fail(uid > 0); |
78 | 74 |
79 bytes += qq_put32(raw_data + bytes, uid); | 75 bytes += qq_put32(raw_data + bytes, uid); |
80 | 76 |
81 qq_send_cmd(gc, QQ_CMD_REMOVE_SELF, raw_data, bytes); | 77 qq_send_cmd(gc, QQ_CMD_REMOVE_ME, raw_data, bytes); |
82 } | 78 } |
83 | 79 |
84 /* try to add a buddy without authentication */ | 80 /* try to add a buddy without authentication */ |
85 static void _qq_send_packet_add_buddy(PurpleConnection *gc, guint32 uid) | 81 static void request_buddy_add_no_auth(PurpleConnection *gc, guint32 uid) |
86 { | 82 { |
87 qq_data *qd = (qq_data *) gc->proto_data; | |
88 qq_add_buddy_request *req; | |
89 gchar uid_str[11]; | 83 gchar uid_str[11]; |
90 | 84 |
91 g_return_if_fail(uid > 0); | 85 g_return_if_fail(uid > 0); |
92 | 86 |
93 /* we need to send the ascii code of this uid to qq server */ | 87 /* we need to send the ascii code of this uid to qq server */ |
94 g_snprintf(uid_str, sizeof(uid_str), "%d", uid); | 88 g_snprintf(uid_str, sizeof(uid_str), "%d", uid); |
95 qq_send_cmd(gc, QQ_CMD_ADD_BUDDY_WO_AUTH, (guint8 *) uid_str, strlen(uid_str)); | 89 qq_send_cmd_mess(gc, QQ_CMD_BUDDY_ADD_NO_AUTH, |
96 | 90 (guint8 *) uid_str, strlen(uid_str), 0, uid); |
97 /* must be set after sending packet to get the correct send_seq */ | |
98 req = g_new0(qq_add_buddy_request, 1); | |
99 req->seq = qd->send_seq; | |
100 req->uid = uid; | |
101 qd->add_buddy_request = g_list_append(qd->add_buddy_request, req); | |
102 } | 91 } |
103 | 92 |
104 /* this buddy needs authentication, text conversion is done at lowest level */ | 93 /* this buddy needs authentication, text conversion is done at lowest level */ |
105 static void _qq_send_packet_buddy_auth(PurpleConnection *gc, guint32 uid, const gchar response, const gchar *text) | 94 static void request_buddy_auth(PurpleConnection *gc, guint32 uid, const gchar response, const gchar *text) |
106 { | 95 { |
107 gchar *text_qq, uid_str[11]; | 96 gchar *text_qq, uid_str[11]; |
108 guint8 bar, *raw_data; | 97 guint8 bar, *raw_data; |
109 gint bytes = 0; | 98 gint bytes = 0; |
110 | 99 |
123 bytes += qq_put8(raw_data + bytes, bar); | 112 bytes += qq_put8(raw_data + bytes, bar); |
124 bytes += qq_putdata(raw_data + bytes, (guint8 *) text_qq, strlen(text_qq)); | 113 bytes += qq_putdata(raw_data + bytes, (guint8 *) text_qq, strlen(text_qq)); |
125 g_free(text_qq); | 114 g_free(text_qq); |
126 } | 115 } |
127 | 116 |
128 qq_send_cmd(gc, QQ_CMD_BUDDY_AUTH, raw_data, bytes); | 117 qq_send_cmd(gc, QQ_CMD_BUDDY_ADD_AUTH, raw_data, bytes); |
129 } | 118 } |
130 | 119 |
131 static void _qq_send_packet_add_buddy_auth_with_gc_and_uid(gc_and_uid *g, const gchar *text) | 120 static void request_buddy_add_auth_cb(qq_add_request *add_req, const gchar *text) |
132 { | 121 { |
133 PurpleConnection *gc; | 122 g_return_if_fail(add_req != NULL); |
134 guint32 uid; | 123 if (add_req->gc == NULL || add_req->uid == 0) { |
135 g_return_if_fail(g != NULL); | 124 g_free(add_req); |
136 | 125 return; |
137 gc = g->gc; | 126 } |
138 uid = g->uid; | 127 |
139 g_return_if_fail(uid != 0); | 128 request_buddy_auth(add_req->gc, add_req->uid, QQ_MY_AUTH_REQUEST, text); |
140 | 129 g_free(add_req); |
141 _qq_send_packet_buddy_auth(gc, uid, QQ_MY_AUTH_REQUEST, text); | |
142 g_free(g); | |
143 } | 130 } |
144 | 131 |
145 /* the real packet to reject and request is sent from here */ | 132 /* the real packet to reject and request is sent from here */ |
146 static void _qq_reject_add_request_real(gc_and_uid *g, const gchar *reason) | 133 static void buddy_add_deny_reason_cb(qq_add_request *add_req, const gchar *reason) |
147 { | 134 { |
148 gint uid; | 135 g_return_if_fail(add_req != NULL); |
149 PurpleConnection *gc; | 136 if (add_req->gc == NULL || add_req->uid == 0) { |
150 | 137 g_free(add_req); |
151 g_return_if_fail(g != NULL); | 138 return; |
152 | 139 } |
153 gc = g->gc; | 140 |
154 uid = g->uid; | 141 request_buddy_auth(add_req->gc, add_req->uid, QQ_MY_AUTH_REJECT, reason); |
155 g_return_if_fail(uid != 0); | 142 g_free(add_req); |
156 | |
157 _qq_send_packet_buddy_auth(gc, uid, QQ_MY_AUTH_REJECT, reason); | |
158 g_free(g); | |
159 } | 143 } |
160 | 144 |
161 /* we approve other's request of adding me as friend */ | 145 /* we approve other's request of adding me as friend */ |
162 void qq_approve_add_request_with_gc_and_uid(gc_and_uid *g) | 146 static void buddy_add_authorize_cb(qq_add_request *add_req) |
163 { | 147 { |
164 gint uid; | 148 g_return_if_fail(add_req != NULL); |
165 PurpleConnection *gc; | 149 if (add_req->gc == NULL || add_req->uid != 0) { |
166 | 150 g_free(add_req); |
167 g_return_if_fail(g != NULL); | 151 return; |
168 | 152 } |
169 gc = g->gc; | 153 |
170 uid = g->uid; | 154 request_buddy_auth(add_req->gc, add_req->uid, QQ_MY_AUTH_APPROVE, NULL); |
171 g_return_if_fail(uid != 0); | 155 g_free(add_req); |
172 | |
173 _qq_send_packet_buddy_auth(gc, uid, QQ_MY_AUTH_APPROVE, NULL); | |
174 g_free(g); | |
175 } | |
176 | |
177 void qq_do_nothing_with_gc_and_uid(gc_and_uid *g, const gchar *msg) | |
178 { | |
179 g_free(g); | |
180 } | 156 } |
181 | 157 |
182 /* we reject other's request of adding me as friend */ | 158 /* we reject other's request of adding me as friend */ |
183 void qq_reject_add_request_with_gc_and_uid(gc_and_uid *g) | 159 static void buddy_add_deny_cb(qq_add_request *add_req) |
184 { | 160 { |
185 gint uid; | 161 gint uid; |
186 gchar *msg1, *msg2; | 162 gchar *msg1, *msg2; |
187 PurpleConnection *gc; | 163 PurpleConnection *gc; |
188 gc_and_uid *g2; | 164 gchar *purple_name; |
189 gchar *nombre; | 165 |
190 | 166 g_return_if_fail(add_req != NULL); |
191 g_return_if_fail(g != NULL); | 167 if (add_req->gc == NULL || add_req->uid == 0) { |
192 | 168 g_free(add_req); |
193 gc = g->gc; | 169 return; |
194 uid = g->uid; | 170 } |
195 g_return_if_fail(uid != 0); | 171 |
196 | 172 gc = add_req->gc; |
197 g_free(g); | 173 uid = add_req->uid; |
198 | |
199 g2 = g_new0(gc_and_uid, 1); | |
200 g2->gc = gc; | |
201 g2->uid = uid; | |
202 | 174 |
203 msg1 = g_strdup_printf(_("You rejected %d's request"), uid); | 175 msg1 = g_strdup_printf(_("You rejected %d's request"), uid); |
204 msg2 = g_strdup(_("Message:")); | 176 msg2 = g_strdup(_("Message:")); |
205 | 177 |
206 nombre = uid_to_purple_name(uid); | 178 purple_name = uid_to_purple_name(uid); |
207 purple_request_input(gc, _("Reject request"), msg1, msg2, | 179 purple_request_input(gc, _("Reject request"), msg1, msg2, |
208 _("Sorry, you are not my style..."), TRUE, FALSE, | 180 _("Sorry, you are not my style..."), TRUE, FALSE, |
209 NULL, _("Reject"), G_CALLBACK(_qq_reject_add_request_real), _("Cancel"), NULL, | 181 NULL, _("Reject"), G_CALLBACK(buddy_add_deny_reason_cb), _("Cancel"), NULL, |
210 purple_connection_get_account(gc), nombre, NULL, | 182 purple_connection_get_account(gc), purple_name, NULL, |
211 g2); | 183 add_req); |
212 g_free(nombre); | 184 g_free(purple_name); |
213 } | 185 } |
214 | 186 |
215 void qq_add_buddy_with_gc_and_uid(gc_and_uid *g) | 187 /* suggested by rakescar@linuxsir, can still approve after search */ |
188 static void buddy_add_check_info_cb(qq_add_request *add_req) | |
189 { | |
190 PurpleConnection *gc; | |
191 guint32 uid; | |
192 gchar *purple_name; | |
193 | |
194 g_return_if_fail(add_req != NULL); | |
195 if (add_req->gc == NULL || add_req->uid == 0) { | |
196 g_free(add_req); | |
197 return; | |
198 } | |
199 | |
200 gc = add_req->gc; | |
201 uid = add_req->uid; | |
202 | |
203 qq_request_buddy_info(gc, uid, 0, QQ_BUDDY_INFO_DISPLAY); | |
204 | |
205 purple_name = uid_to_purple_name(uid); | |
206 purple_request_action | |
207 (gc, NULL, _("Do you approve the requestion?"), "", | |
208 PURPLE_DEFAULT_ACTION_NONE, | |
209 purple_connection_get_account(gc), purple_name, NULL, | |
210 add_req, 2, | |
211 _("Reject"), G_CALLBACK(buddy_add_deny_cb), | |
212 _("Approve"), G_CALLBACK(buddy_add_authorize_cb)); | |
213 g_free(purple_name); | |
214 } | |
215 | |
216 /* add a buddy and send packet to QQ server | |
217 * note that when purple load local cached buddy list into its blist | |
218 * it also calls this funtion, so we have to | |
219 * define qd->is_login=TRUE AFTER serv_finish_login(gc) */ | |
220 void qq_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) | |
221 { | |
222 qq_data *qd; | |
223 guint32 uid; | |
224 PurpleBuddy *b; | |
225 | |
226 qd = (qq_data *) gc->proto_data; | |
227 if (!qd->is_login) | |
228 return; /* IMPORTANT ! */ | |
229 | |
230 uid = purple_name_to_uid(buddy->name); | |
231 if (uid > 0) { | |
232 request_buddy_add_no_auth(gc, uid); | |
233 return; | |
234 } | |
235 | |
236 b = purple_find_buddy(gc->account, buddy->name); | |
237 if (b != NULL) { | |
238 purple_blist_remove_buddy(b); | |
239 } | |
240 purple_notify_error(gc, NULL, _("QQ Number Error"), _("Invalid QQ Number")); | |
241 } | |
242 | |
243 void qq_change_buddys_group(PurpleConnection *gc, const char *who, | |
244 const char *old_group, const char *new_group) | |
216 { | 245 { |
217 gint uid; | 246 gint uid; |
247 g_return_if_fail(who != NULL); | |
248 | |
249 if (strcmp(new_group, PURPLE_GROUP_QQ_UNKNOWN) == 0) { | |
250 if (purple_privacy_check(gc->account, who)) { | |
251 purple_privacy_deny(gc->account, who, TRUE, FALSE); | |
252 } else { | |
253 purple_privacy_deny_add(gc->account, who, TRUE); | |
254 } | |
255 return; | |
256 } | |
257 | |
258 if (strcmp(old_group, PURPLE_GROUP_QQ_UNKNOWN) != 0) { | |
259 return; | |
260 } | |
261 | |
262 uid = purple_name_to_uid(who); | |
263 g_return_if_fail(uid != 0); | |
264 | |
265 purple_privacy_deny_remove(gc->account, who, TRUE); | |
266 | |
267 purple_debug_info("QQ", "Add unknow buddy %d\n", uid); | |
268 request_buddy_add_no_auth(gc, uid); | |
269 } | |
270 | |
271 static void buddy_cancel_cb(qq_add_request *add_req, const gchar *msg) | |
272 { | |
273 g_return_if_fail(add_req != NULL); | |
274 g_free(add_req); | |
275 } | |
276 | |
277 static void buddy_add_no_auth_cb(qq_add_request *add_req) | |
278 { | |
279 g_return_if_fail(add_req != NULL); | |
280 if (add_req->gc == NULL || add_req->uid == 0) { | |
281 g_free(add_req); | |
282 return; | |
283 } | |
284 | |
285 request_buddy_add_no_auth(add_req->gc, add_req->uid); | |
286 g_free(add_req); | |
287 } | |
288 | |
289 static void buddy_remove_both_cb(qq_add_request *add_req) | |
290 { | |
218 PurpleConnection *gc; | 291 PurpleConnection *gc; |
219 | 292 qq_data *qd; |
220 g_return_if_fail(g != NULL); | 293 gchar *purple_name; |
221 | 294 PurpleBuddy *buddy; |
222 gc = g->gc; | 295 qq_buddy *q_buddy; |
223 uid = g->uid; | 296 |
224 g_return_if_fail(uid != 0); | 297 g_return_if_fail(add_req != NULL); |
225 | 298 if (add_req->gc == NULL || add_req->uid == 0) { |
226 _qq_send_packet_add_buddy(gc, uid); | 299 g_free(add_req); |
227 g_free(g); | 300 return; |
228 } | 301 } |
229 | 302 |
230 void qq_block_buddy_with_gc_and_uid(gc_and_uid *g) | 303 gc = add_req->gc; |
231 { | 304 qd = (qq_data *) gc->proto_data; |
305 | |
306 request_buddy_remove(gc, add_req->uid); | |
307 request_buddy_remove_me(gc, add_req->uid); | |
308 | |
309 purple_name = uid_to_purple_name(add_req->uid); | |
310 buddy = purple_find_buddy(gc->account, purple_name); | |
311 if (buddy == NULL) { | |
312 g_free(add_req); | |
313 return; | |
314 } | |
315 | |
316 q_buddy = (qq_buddy *) buddy->proto_data; | |
317 if (q_buddy != NULL) | |
318 qd->buddies = g_list_remove(qd->buddies, q_buddy); | |
319 else | |
320 purple_debug_warning("QQ", "We have no qq_buddy record for %s\n", buddy->name); | |
321 | |
322 purple_blist_remove_buddy(buddy); | |
323 g_free(add_req); | |
324 } | |
325 | |
326 /* remove a buddy from my list and remove myself from his list */ | |
327 /* TODO: re-enable this */ | |
328 void qq_remove_buddy_and_me(PurpleBlistNode * node) | |
329 { | |
330 PurpleConnection *gc; | |
331 qq_data *qd; | |
232 guint32 uid; | 332 guint32 uid; |
233 PurpleConnection *gc; | 333 qq_add_request *add_req; |
234 PurpleBuddy buddy; | 334 PurpleBuddy *buddy; |
235 PurpleGroup group; | 335 const gchar *who; |
236 | 336 |
237 g_return_if_fail(g != NULL); | 337 g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); |
238 | 338 |
239 gc = g->gc; | 339 buddy = (PurpleBuddy *) node; |
240 uid = g->uid; | 340 gc = purple_account_get_connection(buddy->account); |
341 qd = (qq_data *) gc->proto_data; | |
342 if (!qd->is_login) | |
343 return; | |
344 | |
345 who = buddy->name; | |
346 g_return_if_fail(who != NULL); | |
347 | |
348 uid = purple_name_to_uid(who); | |
241 g_return_if_fail(uid > 0); | 349 g_return_if_fail(uid > 0); |
242 | 350 |
243 buddy.name = uid_to_purple_name(uid); | 351 add_req = g_new0(qq_add_request, 1); |
244 group.name = PURPLE_GROUP_QQ_BLOCKED; | 352 add_req->gc = gc; |
245 | 353 add_req->uid = uid; |
246 qq_remove_buddy(gc, &buddy, &group); | 354 |
247 _qq_send_packet_remove_self_from(gc, uid); | 355 purple_request_action(gc, _("Block Buddy"), |
356 "Are you sure you want to block this buddy?", | |
357 NULL, | |
358 1, | |
359 purple_connection_get_account(gc), NULL, NULL, | |
360 add_req, 2, | |
361 _("Cancel"), G_CALLBACK(buddy_cancel_cb), | |
362 _("Block"), G_CALLBACK(buddy_remove_both_cb)); | |
248 } | 363 } |
249 | 364 |
250 /* process reply to add_buddy_auth request */ | 365 /* process reply to add_buddy_auth request */ |
251 void qq_process_add_buddy_auth_reply(guint8 *data, gint data_len, PurpleConnection *gc) | 366 void qq_process_buddy_add_auth(guint8 *data, gint data_len, PurpleConnection *gc) |
252 { | 367 { |
253 qq_data *qd; | 368 qq_data *qd; |
254 gchar **segments, *msg_utf8; | 369 gchar **segments, *msg_utf8; |
255 | 370 |
256 g_return_if_fail(data != NULL && data_len != 0); | 371 g_return_if_fail(data != NULL && data_len != 0); |
269 purple_debug_info("QQ", "Add buddy with auth request OK\n"); | 384 purple_debug_info("QQ", "Add buddy with auth request OK\n"); |
270 } | 385 } |
271 } | 386 } |
272 | 387 |
273 /* process the server reply for my request to remove a buddy */ | 388 /* process the server reply for my request to remove a buddy */ |
274 void qq_process_remove_buddy_reply(guint8 *data, gint data_len, PurpleConnection *gc) | 389 void qq_process_buddy_remove(guint8 *data, gint data_len, PurpleConnection *gc) |
275 { | 390 { |
276 qq_data *qd; | 391 qq_data *qd; |
277 | 392 |
278 g_return_if_fail(data != NULL && data_len != 0); | 393 g_return_if_fail(data != NULL && data_len != 0); |
279 | 394 |
289 purple_notify_info(gc, _("QQ Buddy"), _("Successed:"), _("Remove buddy")); | 404 purple_notify_info(gc, _("QQ Buddy"), _("Successed:"), _("Remove buddy")); |
290 } | 405 } |
291 } | 406 } |
292 | 407 |
293 /* process the server reply for my request to remove myself from a buddy */ | 408 /* process the server reply for my request to remove myself from a buddy */ |
294 void qq_process_remove_self_reply(guint8 *data, gint data_len, PurpleConnection *gc) | 409 void qq_process_buddy_remove_me(guint8 *data, gint data_len, PurpleConnection *gc) |
295 { | 410 { |
296 qq_data *qd; | 411 qq_data *qd; |
297 | 412 |
298 g_return_if_fail(data != NULL && data_len != 0); | 413 g_return_if_fail(data != NULL && data_len != 0); |
299 | 414 |
300 qd = (qq_data *) gc->proto_data; | 415 qd = (qq_data *) gc->proto_data; |
301 | 416 |
302 if (data[0] != QQ_REMOVE_SELF_REPLY_OK) { | 417 if (data[0] != QQ_REMOVE_SELF_REPLY_OK) { |
303 /* there is no reason return from server */ | 418 /* there is no reason return from server */ |
304 purple_debug_warning("QQ", "Remove self fails\n"); | 419 purple_debug_warning("QQ", "Remove self fails\n"); |
305 purple_notify_info(gc, _("QQ Buddy"), _("Failed:"), _("Remove from other's buddy list")); | 420 purple_notify_info(gc, _("QQ Buddy"), _("Failed:"), _("Remove me from other's buddy list")); |
306 } else { /* if reply */ | 421 } else { /* if reply */ |
307 purple_debug_info("QQ", "Remove from a buddy OK\n"); | 422 purple_debug_info("QQ", "Remove from a buddy OK\n"); |
308 /* TODO: Does the user really need to be notified about this? */ | 423 #if 0 |
309 purple_notify_info(gc, _("QQ Buddy"), _("Successed:"), _("Remove from other's buddy list")); | 424 purple_notify_info(gc, _("QQ Buddy"), _("Successed:"), _("Remove from other's buddy list")); |
310 } | 425 #endif |
311 } | 426 } |
312 | 427 } |
313 void qq_process_add_buddy_reply(guint8 *data, gint data_len, guint16 seq, PurpleConnection *gc) | 428 |
314 { | 429 void qq_process_buddy_add_no_auth(guint8 *data, gint data_len, guint32 uid, PurpleConnection *gc) |
315 qq_data *qd; | 430 { |
316 gint for_uid; | 431 qq_data *qd; |
317 gchar *msg, **segments, *uid, *reply; | 432 gchar *msg, **segments, *dest_uid, *reply; |
318 GList *list; | |
319 PurpleBuddy *b; | 433 PurpleBuddy *b; |
320 gc_and_uid *g; | 434 qq_add_request *add_req; |
321 qq_add_buddy_request *req; | |
322 gchar *nombre; | 435 gchar *nombre; |
323 | 436 |
324 g_return_if_fail(data != NULL && data_len != 0); | 437 g_return_if_fail(data != NULL && data_len != 0); |
325 | 438 |
326 for_uid = 0; | 439 qd = (qq_data *) gc->proto_data; |
327 qd = (qq_data *) gc->proto_data; | 440 |
328 | 441 if (uid == 0) { /* we have no record for this */ |
329 list = qd->add_buddy_request; | 442 purple_debug_error("QQ", "Process buddy add, unknow id\n"); |
330 while (list != NULL) { | |
331 req = (qq_add_buddy_request *) list->data; | |
332 if (req->seq == seq) { /* reply to this */ | |
333 for_uid = req->uid; | |
334 qd->add_buddy_request = g_list_remove(qd->add_buddy_request, qd->add_buddy_request->data); | |
335 g_free(req); | |
336 break; | |
337 } | |
338 list = list->next; | |
339 } | |
340 | |
341 if (for_uid == 0) { /* we have no record for this */ | |
342 purple_debug_error("QQ", "We have no record for add buddy reply [%d], discard\n", seq); | |
343 return; | 443 return; |
344 } else { | 444 } else { |
345 purple_debug_info("QQ", "Add buddy reply [%d] is for id [%d]\n", seq, for_uid); | 445 purple_debug_info("QQ", "Process buddy add for id [%d]\n", uid); |
346 } | 446 } |
347 | 447 |
348 if (NULL == (segments = split_data(data, data_len, "\x1f", 2))) | 448 if (NULL == (segments = split_data(data, data_len, "\x1f", 2))) |
349 return; | 449 return; |
350 | 450 |
351 uid = segments[0]; | 451 dest_uid = segments[0]; |
352 reply = segments[1]; | 452 reply = segments[1]; |
353 if (strtol(uid, NULL, 10) != qd->uid) { /* should not happen */ | 453 if (strtol(dest_uid, NULL, 10) != qd->uid) { /* should not happen */ |
354 purple_debug_error("QQ", "Add buddy reply is to [%s], not me!", uid); | 454 purple_debug_error("QQ", "Add buddy reply is to [%s], not me!", dest_uid); |
355 g_strfreev(segments); | 455 g_strfreev(segments); |
356 return; | 456 return; |
357 } | 457 } |
358 | 458 |
359 if (strtol(reply, NULL, 10) > 0) { /* need auth */ | 459 if (strtol(reply, NULL, 10) > 0) { /* need auth */ |
360 purple_debug_warning("QQ", "Add buddy attempt fails, need authentication\n"); | 460 purple_debug_warning("QQ", "Add buddy attempt fails, need authentication\n"); |
361 nombre = uid_to_purple_name(for_uid); | 461 nombre = uid_to_purple_name(uid); |
362 b = purple_find_buddy(gc->account, nombre); | 462 b = purple_find_buddy(gc->account, nombre); |
363 if (b != NULL) | 463 if (b != NULL) |
364 purple_blist_remove_buddy(b); | 464 purple_blist_remove_buddy(b); |
365 g = g_new0(gc_and_uid, 1); | 465 add_req = g_new0(qq_add_request, 1); |
366 g->gc = gc; | 466 add_req->gc = gc; |
367 g->uid = for_uid; | 467 add_req->uid = uid; |
368 msg = g_strdup_printf(_("%d needs authentication"), for_uid); | 468 msg = g_strdup_printf(_("%d needs authentication"), uid); |
369 purple_request_input(gc, NULL, msg, | 469 purple_request_input(gc, NULL, msg, |
370 _("Input request here"), /* TODO: Awkward string to fix post string freeze - standardize auth dialogues? -evands */ | 470 _("Input request here"), /* TODO: Awkward string to fix post string freeze - standardize auth dialogues? -evands */ |
371 _("Would you be my friend?"), | 471 _("Would you be my friend?"), |
372 TRUE, FALSE, NULL, _("Send"), | 472 TRUE, FALSE, NULL, _("Send"), |
373 G_CALLBACK | 473 G_CALLBACK(request_buddy_add_auth_cb), |
374 (_qq_send_packet_add_buddy_auth_with_gc_and_uid), | 474 _("Cancel"), G_CALLBACK(buddy_cancel_cb), |
375 _("Cancel"), G_CALLBACK(qq_do_nothing_with_gc_and_uid), | |
376 purple_connection_get_account(gc), nombre, NULL, | 475 purple_connection_get_account(gc), nombre, NULL, |
377 g); | 476 add_req); |
378 g_free(msg); | 477 g_free(msg); |
379 g_free(nombre); | 478 g_free(nombre); |
380 } else { /* add OK */ | 479 } else { /* add OK */ |
381 qq_add_buddy_by_recv_packet(gc, for_uid, TRUE, TRUE); | 480 qq_create_buddy(gc, uid, TRUE, TRUE); |
382 msg = g_strdup_printf(_("Add into %d's buddy list"), for_uid); | 481 msg = g_strdup_printf(_("Add into %d's buddy list"), uid); |
383 purple_notify_info(gc, _("QQ Buddy"), _("Successed:"), msg); | 482 purple_notify_info(gc, _("QQ Buddy"), _("Successed:"), msg); |
384 g_free(msg); | 483 g_free(msg); |
385 } | 484 } |
386 g_strfreev(segments); | 485 g_strfreev(segments); |
387 } | 486 } |
388 | 487 |
389 PurpleGroup *qq_get_purple_group(const gchar *group_name) | 488 PurpleGroup *qq_create_group(const gchar *group_name) |
390 { | 489 { |
391 PurpleGroup *g; | 490 PurpleGroup *g; |
392 | 491 |
393 g_return_val_if_fail(group_name != NULL, NULL); | 492 g_return_val_if_fail(group_name != NULL, NULL); |
394 | 493 |
402 return g; | 501 return g; |
403 } | 502 } |
404 | 503 |
405 /* we add new buddy, if the received packet is from someone not in my list | 504 /* we add new buddy, if the received packet is from someone not in my list |
406 * return the PurpleBuddy that is just created */ | 505 * return the PurpleBuddy that is just created */ |
407 PurpleBuddy *qq_add_buddy_by_recv_packet(PurpleConnection *gc, guint32 uid, gboolean is_known, gboolean create) | 506 PurpleBuddy *qq_create_buddy(PurpleConnection *gc, guint32 uid, gboolean is_known, gboolean create) |
408 { | 507 { |
409 PurpleAccount *a; | 508 PurpleBuddy *buddy; |
410 PurpleBuddy *b; | 509 PurpleGroup *group; |
411 PurpleGroup *g; | |
412 qq_data *qd; | 510 qq_data *qd; |
413 qq_buddy *q_bud; | 511 qq_buddy *q_bud; |
414 gchar *name, *group_name; | 512 gchar *buddy_name, *group_name; |
415 | 513 |
416 a = gc->account; | 514 g_return_val_if_fail(gc->account != NULL && uid != 0, NULL); |
417 qd = (qq_data *) gc->proto_data; | 515 qd = (qq_data *) gc->proto_data; |
418 g_return_val_if_fail(a != NULL && uid != 0, NULL); | 516 |
419 | 517 if (is_known) { |
420 group_name = is_known ? | 518 group_name = g_strdup_printf(PURPLE_GROUP_QQ_FORMAT, |
421 g_strdup_printf(PURPLE_GROUP_QQ_FORMAT, purple_account_get_username(a)) : g_strdup(PURPLE_GROUP_QQ_UNKNOWN); | 519 purple_account_get_username(gc->account)); |
422 | 520 } else { |
423 g = qq_get_purple_group(group_name); | 521 group_name = g_strdup(PURPLE_GROUP_QQ_UNKNOWN); |
424 | 522 } |
425 name = uid_to_purple_name(uid); | 523 |
426 b = purple_find_buddy(gc->account, name); | 524 group = qq_create_group(group_name); |
525 | |
526 buddy_name = uid_to_purple_name(uid); | |
527 buddy = purple_find_buddy(gc->account, buddy_name); | |
427 /* remove old, we can not simply return here | 528 /* remove old, we can not simply return here |
428 * because there might be old local copy of this buddy */ | 529 * because there might be old local copy of this buddy */ |
429 if (b != NULL) | 530 if (buddy != NULL) |
430 purple_blist_remove_buddy(b); | 531 purple_blist_remove_buddy(buddy); |
431 | 532 |
432 b = purple_buddy_new(a, name, NULL); | 533 buddy = purple_buddy_new(gc->account, buddy_name, NULL); |
534 if ( !is_known ) { | |
535 if (purple_privacy_check(gc->account, buddy_name)) { | |
536 purple_privacy_deny(gc->account, buddy_name, TRUE, FALSE); | |
537 } else { | |
538 purple_privacy_deny_add(gc->account, buddy_name, TRUE); | |
539 } | |
540 } | |
433 | 541 |
434 if (!create) | 542 if (!create) |
435 b->proto_data = NULL; | 543 buddy->proto_data = NULL; |
436 else { | 544 else { |
437 q_bud = g_new0(qq_buddy, 1); | 545 q_bud = g_new0(qq_buddy, 1); |
438 q_bud->uid = uid; | 546 q_bud->uid = uid; |
439 b->proto_data = q_bud; | 547 buddy->proto_data = q_bud; |
440 qd->buddies = g_list_append(qd->buddies, q_bud); | 548 qd->buddies = g_list_append(qd->buddies, q_bud); |
441 qq_send_packet_get_info(gc, q_bud->uid, FALSE); | 549 qq_request_buddy_info(gc, qd->uid, 0, 0); |
442 qq_request_get_buddies_online(gc, 0, 0); | 550 qq_request_get_buddies_online(gc, 0, 0); |
443 } | 551 qq_request_get_level(gc, qd->uid); |
444 | 552 } |
445 purple_blist_add_buddy(b, NULL, g, NULL); | 553 |
446 purple_debug_warning("QQ", "Add new buddy: [%s]\n", name); | 554 purple_blist_add_buddy(buddy, NULL, group, NULL); |
447 | 555 purple_debug_warning("QQ", "Add new buddy: [%s]\n", buddy_name); |
448 g_free(name); | 556 |
557 g_free(buddy_name); | |
449 g_free(group_name); | 558 g_free(group_name); |
450 | 559 |
451 return b; | 560 return buddy; |
452 } | |
453 | |
454 /* add a buddy and send packet to QQ server | |
455 * note that when purple load local cached buddy list into its blist | |
456 * it also calls this funtion, so we have to | |
457 * define qd->is_login=TRUE AFTER serv_finish_login(gc) */ | |
458 void qq_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) | |
459 { | |
460 qq_data *qd; | |
461 guint32 uid; | |
462 PurpleBuddy *b; | |
463 | |
464 qd = (qq_data *) gc->proto_data; | |
465 if (!qd->is_login) | |
466 return; /* IMPORTANT ! */ | |
467 | |
468 uid = purple_name_to_uid(buddy->name); | |
469 if (uid > 0) | |
470 _qq_send_packet_add_buddy(gc, uid); | |
471 else { | |
472 b = purple_find_buddy(gc->account, buddy->name); | |
473 if (b != NULL) | |
474 purple_blist_remove_buddy(b); | |
475 purple_notify_error(gc, NULL, | |
476 _("QQ Number Error"), | |
477 _("Invalid QQ Number")); | |
478 } | |
479 } | 561 } |
480 | 562 |
481 /* remove a buddy and send packet to QQ server accordingly */ | 563 /* remove a buddy and send packet to QQ server accordingly */ |
482 void qq_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) | 564 void qq_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) |
483 { | 565 { |
484 qq_data *qd; | 566 qq_data *qd; |
485 PurpleBuddy *b; | |
486 qq_buddy *q_bud; | 567 qq_buddy *q_bud; |
487 guint32 uid; | 568 guint32 uid; |
488 | 569 |
489 qd = (qq_data *) gc->proto_data; | 570 g_return_if_fail(gc != NULL && gc->proto_data != NULL); |
571 g_return_if_fail(buddy != NULL); | |
572 qd = (qq_data *) gc->proto_data; | |
573 | |
490 uid = purple_name_to_uid(buddy->name); | 574 uid = purple_name_to_uid(buddy->name); |
491 | |
492 if (!qd->is_login) | 575 if (!qd->is_login) |
493 return; | 576 return; |
494 | 577 |
495 if (uid > 0) | 578 if (uid > 0) { |
496 _qq_send_packet_remove_buddy(gc, uid); | 579 request_buddy_remove(gc, uid); |
497 | 580 } |
498 b = purple_find_buddy(gc->account, buddy->name); | 581 |
499 if (b != NULL) { | 582 q_bud = (qq_buddy *) buddy->proto_data; |
500 q_bud = (qq_buddy *) b->proto_data; | 583 if (q_bud != NULL) |
501 if (q_bud != NULL) | 584 qd->buddies = g_list_remove(qd->buddies, q_bud); |
502 qd->buddies = g_list_remove(qd->buddies, q_bud); | 585 else |
503 else | 586 purple_debug_warning("QQ", "We have no qq_buddy record for %s\n", buddy->name); |
504 purple_debug_warning("QQ", "We have no qq_buddy record for %s\n", buddy->name); | 587 |
505 /* remove buddy on blist, this does not trigger qq_remove_buddy again | 588 /* Do not call purple_blist_remove_buddy, |
506 * do this only if the request comes from block request, | 589 * otherwise purple segmentation fault */ |
507 * otherwise purple segmentation fault */ | 590 } |
508 if (g_ascii_strcasecmp(group->name, PURPLE_GROUP_QQ_BLOCKED) == 0) | 591 |
509 purple_blist_remove_buddy(b); | 592 /* free all qq_buddy */ |
510 } | |
511 } | |
512 | |
513 /* free add buddy request queue */ | |
514 void qq_add_buddy_request_free(qq_data *qd) | |
515 { | |
516 gint count; | |
517 qq_add_buddy_request *p; | |
518 | |
519 count = 0; | |
520 while (qd->add_buddy_request != NULL) { | |
521 p = (qq_add_buddy_request *) (qd->add_buddy_request->data); | |
522 qd->add_buddy_request = g_list_remove(qd->add_buddy_request, p); | |
523 g_free(p); | |
524 count++; | |
525 } | |
526 if (count > 0) { | |
527 purple_debug_info("QQ", "%d add buddy requests are freed!\n", count); | |
528 } | |
529 } | |
530 | |
531 /* free up all qq_buddy */ | |
532 void qq_buddies_list_free(PurpleAccount *account, qq_data *qd) | 593 void qq_buddies_list_free(PurpleAccount *account, qq_data *qd) |
533 { | 594 { |
534 gint count; | 595 gint count; |
535 qq_buddy *p; | 596 qq_buddy *p; |
536 gchar *name; | 597 gchar *name; |
553 } | 614 } |
554 if (count > 0) { | 615 if (count > 0) { |
555 purple_debug_info("QQ", "%d qq_buddy structures are freed!\n", count); | 616 purple_debug_info("QQ", "%d qq_buddy structures are freed!\n", count); |
556 } | 617 } |
557 } | 618 } |
619 | |
620 /* someone wants to add you to his buddy list */ | |
621 static void server_buddy_add_request(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8) | |
622 { | |
623 gchar *message, *reason; | |
624 guint32 uid; | |
625 qq_add_request *g, *g2; | |
626 PurpleBuddy *b; | |
627 gchar *name; | |
628 | |
629 g_return_if_fail(from != NULL && to != NULL); | |
630 | |
631 uid = strtol(from, NULL, 10); | |
632 g = g_new0(qq_add_request, 1); | |
633 g->gc = gc; | |
634 g->uid = uid; | |
635 | |
636 name = uid_to_purple_name(uid); | |
637 | |
638 /* TODO: this should go through purple_account_request_authorization() */ | |
639 message = g_strdup_printf(_("%s wants to add you [%s] as a friend"), from, to); | |
640 reason = g_strdup_printf(_("Message: %s"), msg_utf8); | |
641 | |
642 purple_request_action | |
643 (gc, NULL, message, reason, PURPLE_DEFAULT_ACTION_NONE, | |
644 purple_connection_get_account(gc), name, NULL, | |
645 g, 3, | |
646 _("Reject"), | |
647 G_CALLBACK(buddy_add_deny_cb), | |
648 _("Approve"), | |
649 G_CALLBACK(buddy_add_authorize_cb), | |
650 _("Search"), G_CALLBACK(buddy_add_check_info_cb)); | |
651 | |
652 g_free(message); | |
653 g_free(reason); | |
654 | |
655 /* XXX: Is this needed once the above goes through purple_account_request_authorization()? */ | |
656 b = purple_find_buddy(gc->account, name); | |
657 if (b == NULL) { /* the person is not in my list */ | |
658 g2 = g_new0(qq_add_request, 1); | |
659 g2->gc = gc; | |
660 g2->uid = strtol(from, NULL, 10); | |
661 message = g_strdup_printf(_("%s is not in buddy list"), from); | |
662 purple_request_action(gc, NULL, message, | |
663 _("Would you add?"), PURPLE_DEFAULT_ACTION_NONE, | |
664 purple_connection_get_account(gc), name, NULL, | |
665 g2, 3, | |
666 _("Cancel"), NULL, | |
667 _("Add"), G_CALLBACK(buddy_add_no_auth_cb), | |
668 _("Search"), G_CALLBACK(buddy_add_check_info_cb)); | |
669 g_free(message); | |
670 } | |
671 | |
672 g_free(name); | |
673 } | |
674 | |
675 /* when you are added by a person, QQ server will send sys message */ | |
676 static void server_buddy_added(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8) | |
677 { | |
678 gchar *message; | |
679 PurpleBuddy *b; | |
680 guint32 uid; | |
681 qq_add_request *add_req; | |
682 gchar *name; | |
683 | |
684 g_return_if_fail(from != NULL && to != NULL); | |
685 | |
686 uid = strtol(from, NULL, 10); | |
687 name = uid_to_purple_name(uid); | |
688 b = purple_find_buddy(gc->account, name); | |
689 | |
690 if (b == NULL) { /* the person is not in my list */ | |
691 add_req = g_new0(qq_add_request, 1); | |
692 add_req->gc = gc; | |
693 add_req->uid = uid; /* only need to get value */ | |
694 message = g_strdup_printf(_("You have been added by %s"), from); | |
695 purple_request_action(gc, NULL, message, | |
696 _("Would you like to add him?"), | |
697 PURPLE_DEFAULT_ACTION_NONE, | |
698 purple_connection_get_account(gc), name, NULL, | |
699 add_req, 3, | |
700 _("Cancel"), G_CALLBACK(buddy_cancel_cb), | |
701 _("Add"), G_CALLBACK(buddy_add_no_auth_cb), | |
702 _("Search"), G_CALLBACK(buddy_add_check_info_cb)); | |
703 } else { | |
704 message = g_strdup_printf(_("%s added you [%s] to buddy list"), from, to); | |
705 purple_notify_info(gc, _("QQ Budy"), _("Successed:"), message); | |
706 } | |
707 | |
708 g_free(name); | |
709 g_free(message); | |
710 } | |
711 | |
712 /* the buddy approves your request of adding him/her as your friend */ | |
713 static void server_buddy_added_me(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8) | |
714 { | |
715 gchar *message; | |
716 qq_data *qd; | |
717 | |
718 g_return_if_fail(from != NULL && to != NULL); | |
719 | |
720 qd = (qq_data *) gc->proto_data; | |
721 qq_create_buddy(gc, strtol(from, NULL, 10), TRUE, TRUE); | |
722 | |
723 message = g_strdup_printf(_("Requestion approved by %s"), from); | |
724 purple_notify_info(gc, _("QQ Buddy"), _("Notice:"), message); | |
725 | |
726 g_free(message); | |
727 } | |
728 | |
729 /* you are rejected by the person */ | |
730 static void server_buddy_rejected_me(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8) | |
731 { | |
732 gchar *message, *reason; | |
733 | |
734 g_return_if_fail(from != NULL && to != NULL); | |
735 | |
736 message = g_strdup_printf(_("Requestion rejected by %s"), from); | |
737 reason = g_strdup_printf(_("Message: %s"), msg_utf8); | |
738 | |
739 purple_notify_info(gc, _("QQ Buddy"), message, reason); | |
740 g_free(message); | |
741 g_free(reason); | |
742 } | |
743 | |
744 void qq_process_buddy_from_server(PurpleConnection *gc, int funct, | |
745 gchar *from, gchar *to, gchar *msg_utf8) | |
746 { | |
747 switch (funct) { | |
748 case QQ_SERVER_BUDDY_ADDED: | |
749 server_buddy_added(gc, from, to, msg_utf8); | |
750 break; | |
751 case QQ_SERVER_BUDDY_ADD_REQUEST: | |
752 server_buddy_add_request(gc, from, to, msg_utf8); | |
753 break; | |
754 case QQ_SERVER_BUDDY_ADDED_ME: | |
755 server_buddy_added_me(gc, from, to, msg_utf8); | |
756 break; | |
757 case QQ_SERVER_BUDDY_REJECTED_ME: | |
758 server_buddy_rejected_me(gc, from, to, msg_utf8); | |
759 break; | |
760 default: | |
761 purple_debug_warning("QQ", "Unknow buddy operate (%d) from server\n", funct); | |
762 break; | |
763 } | |
764 } |