Mercurial > pidgin
comparison libpurple/protocols/qq/group_im.c @ 24135:dbc7a9742f8d
2008.09.26 - ccpaging <ccpaging(at)gmail.com>
* Added 'Request/Add/Remove Buddy' functions
author | SHiNE CsyFeK <csyfek@gmail.com> |
---|---|
date | Wed, 22 Oct 2008 14:35:05 +0000 |
parents | bdfcfd71449c |
children | 619ac2303c46 |
comparison
equal
deleted
inserted
replaced
24134:bdfcfd71449c | 24135:dbc7a9742f8d |
---|---|
43 #include "packet_parse.h" | 43 #include "packet_parse.h" |
44 #include "qq_network.h" | 44 #include "qq_network.h" |
45 #include "qq_process.h" | 45 #include "qq_process.h" |
46 #include "utils.h" | 46 #include "utils.h" |
47 | 47 |
48 typedef struct _qq_recv_group_im { | |
49 guint32 ext_id; | |
50 guint8 type8; | |
51 guint32 member_uid; | |
52 guint16 msg_seq; | |
53 time_t send_time; | |
54 guint16 msg_len; | |
55 gchar *msg; | |
56 guint8 *font_attr; | |
57 gint font_attr_len; | |
58 } qq_recv_group_im; | |
59 | |
60 /* send IM to a group */ | 48 /* send IM to a group */ |
61 void qq_send_packet_group_im(PurpleConnection *gc, qq_group *group, const gchar *msg) | 49 void qq_send_packet_group_im(PurpleConnection *gc, qq_group *group, const gchar *msg) |
62 { | 50 { |
63 gint data_len, bytes; | 51 gint data_len, bytes; |
64 guint8 *raw_data, *send_im_tail; | 52 guint8 *raw_data, *send_im_tail; |
148 g_free(reason); | 136 g_free(reason); |
149 g_free(msg); | 137 g_free(msg); |
150 g_free(reason_utf8); | 138 g_free(reason_utf8); |
151 } | 139 } |
152 | 140 |
141 void qq_room_got_chat_in(PurpleConnection *gc, | |
142 qq_group *group, guint32 uid_from, const gchar *msg, time_t in_time) | |
143 { | |
144 PurpleAccount *account = purple_connection_get_account(gc); | |
145 PurpleConversation *conv; | |
146 qq_buddy *buddy; | |
147 gchar *from; | |
148 | |
149 g_return_if_fail(group != NULL); | |
150 | |
151 conv = purple_find_conversation_with_account( | |
152 PURPLE_CONV_TYPE_CHAT, group->title_utf8, account); | |
153 if (conv == NULL && purple_prefs_get_bool("/plugins/prpl/qq/show_room_when_newin")) { | |
154 conv = qq_room_conv_create(gc, group); | |
155 } | |
156 | |
157 if (conv == NULL) { | |
158 return; | |
159 } | |
160 | |
161 if (uid_from != 0) { | |
162 buddy = qq_group_find_member_by_uid(group, uid_from); | |
163 if (buddy == NULL || buddy->nickname == NULL) | |
164 from = uid_to_purple_name(uid_from); | |
165 else | |
166 from = g_strdup(buddy->nickname); | |
167 } else { | |
168 from = g_strdup(""); | |
169 } | |
170 serv_got_chat_in(gc, | |
171 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), | |
172 from, 0, msg, in_time); | |
173 g_free(from); | |
174 } | |
175 | |
153 /* the request to join a group is rejected */ | 176 /* the request to join a group is rejected */ |
154 void qq_process_room_msg_been_rejected(guint8 *data, gint len, guint32 id, PurpleConnection *gc) | 177 void qq_process_room_msg_been_rejected(guint8 *data, gint len, guint32 id, PurpleConnection *gc) |
155 { | 178 { |
156 guint32 ext_id, admin_uid; | 179 guint32 ext_id, admin_uid; |
157 guint8 type8; | 180 guint8 type8; |
158 gchar *reason_utf8, *msg, *reason; | 181 gchar *reason_utf8, *msg, *reason; |
159 qq_group *group; | 182 qq_group *group; |
160 gint bytes = 0; | 183 gint bytes; |
161 | 184 |
162 g_return_if_fail(data != NULL && len > 0); | 185 g_return_if_fail(data != NULL && len > 0); |
163 | 186 |
164 /* FIXME: check length here */ | 187 /* FIXME: check length here */ |
165 | 188 bytes = 0; |
166 bytes += qq_get32(&ext_id, data + bytes); | 189 bytes += qq_get32(&ext_id, data + bytes); |
167 bytes += qq_get8(&type8, data + bytes); | 190 bytes += qq_get8(&type8, data + bytes); |
168 bytes += qq_get32(&admin_uid, data + bytes); | 191 bytes += qq_get32(&admin_uid, data + bytes); |
169 | 192 |
170 g_return_if_fail(ext_id > 0 && admin_uid > 0); | 193 g_return_if_fail(ext_id > 0 && admin_uid > 0); |
181 if (group != NULL) { | 204 if (group != NULL) { |
182 group->my_role = QQ_ROOM_ROLE_NO; | 205 group->my_role = QQ_ROOM_ROLE_NO; |
183 qq_group_refresh(gc, group); | 206 qq_group_refresh(gc, group); |
184 } | 207 } |
185 | 208 |
209 g_free(msg); | |
186 g_free(reason); | 210 g_free(reason); |
187 g_free(msg); | |
188 g_free(reason_utf8); | 211 g_free(reason_utf8); |
189 } | 212 } |
190 | 213 |
191 /* the request to join a group is approved */ | 214 /* the request to join a group is approved */ |
192 void qq_process_room_msg_been_approved(guint8 *data, gint len, guint32 id, PurpleConnection *gc) | 215 void qq_process_room_msg_been_approved(guint8 *data, gint len, guint32 id, PurpleConnection *gc) |
193 { | 216 { |
194 guint32 ext_id, admin_uid; | 217 guint32 ext_id, admin_uid; |
195 guint8 type8; | 218 guint8 type8; |
196 gchar *reason_utf8, *msg; | 219 gchar *msg, *reason; |
197 qq_group *group; | 220 qq_group *group; |
198 gint bytes = 0; | 221 gint bytes; |
222 time_t now; | |
199 | 223 |
200 g_return_if_fail(data != NULL && len > 0); | 224 g_return_if_fail(data != NULL && len > 0); |
201 | 225 |
202 /* FIXME: check length here */ | 226 /* FIXME: check length here */ |
203 | 227 bytes = 0; |
204 bytes += qq_get32(&ext_id, data + bytes); | 228 bytes += qq_get32(&ext_id, data + bytes); |
205 bytes += qq_get8(&type8, data + bytes); | 229 bytes += qq_get8(&type8, data + bytes); |
206 bytes += qq_get32(&admin_uid, data + bytes); | 230 bytes += qq_get32(&admin_uid, data + bytes); |
207 | 231 |
208 g_return_if_fail(ext_id > 0 && admin_uid > 0); | 232 g_return_if_fail(ext_id > 0 && admin_uid > 0); |
209 /* it is also a "无" here, so do not display */ | 233 /* it is also a "无" here, so do not display */ |
210 bytes += convert_as_pascal_string(data + bytes, &reason_utf8, QQ_CHARSET_DEFAULT); | 234 bytes += convert_as_pascal_string(data + bytes, &reason, QQ_CHARSET_DEFAULT); |
211 | |
212 msg = g_strdup_printf | |
213 (_("Successed to join Qun %d, operated by admin %d"), ext_id, admin_uid); | |
214 | |
215 purple_notify_warning(gc, _("QQ Qun Operation"), msg, NULL); | |
216 | 235 |
217 group = qq_room_search_id(gc, id); | 236 group = qq_room_search_id(gc, id); |
218 if (group != NULL) { | 237 if (group != NULL) { |
219 group->my_role = QQ_ROOM_ROLE_YES; | 238 group->my_role = QQ_ROOM_ROLE_YES; |
220 qq_group_refresh(gc, group); | 239 qq_group_refresh(gc, group); |
221 } | 240 } |
222 | 241 |
242 msg = g_strdup_printf(_("<b>Joinning Qun %d is approved by Admin %d for %s</b>"), | |
243 ext_id, admin_uid, reason); | |
244 now = time(NULL); | |
245 qq_room_got_chat_in(gc, group, 0, msg, now); | |
246 | |
223 g_free(msg); | 247 g_free(msg); |
224 g_free(reason_utf8); | 248 g_free(reason); |
225 } | 249 } |
226 | 250 |
227 /* process the packet when removed from a group */ | 251 /* process the packet when removed from a group */ |
228 void qq_process_room_msg_been_removed(guint8 *data, gint len, guint32 id, PurpleConnection *gc) | 252 void qq_process_room_msg_been_removed(guint8 *data, gint len, guint32 id, PurpleConnection *gc) |
229 { | 253 { |
230 guint32 ext_id, uid; | 254 guint32 ext_id, uid; |
231 guint8 type8; | 255 guint8 type8; |
232 gchar *msg; | 256 gchar *msg; |
233 qq_group *group; | 257 qq_group *group; |
234 gint bytes = 0; | 258 gint bytes = 0; |
259 time_t now = time(NULL); | |
235 | 260 |
236 g_return_if_fail(data != NULL && len > 0); | 261 g_return_if_fail(data != NULL && len > 0); |
237 | 262 |
238 /* FIXME: check length here */ | 263 /* FIXME: check length here */ |
239 | 264 bytes = 0; |
240 bytes += qq_get32(&ext_id, data + bytes); | 265 bytes += qq_get32(&ext_id, data + bytes); |
241 bytes += qq_get8(&type8, data + bytes); | 266 bytes += qq_get8(&type8, data + bytes); |
242 bytes += qq_get32(&uid, data + bytes); | 267 bytes += qq_get32(&uid, data + bytes); |
243 | 268 |
244 g_return_if_fail(ext_id > 0 && uid > 0); | 269 g_return_if_fail(ext_id > 0 && uid > 0); |
245 | |
246 msg = g_strdup_printf(_("[%d] removed from Qun \"%d\""), uid, ext_id); | |
247 purple_notify_info(gc, _("QQ Qun Operation"), _("Notice:"), msg); | |
248 | 270 |
249 group = qq_room_search_id(gc, id); | 271 group = qq_room_search_id(gc, id); |
250 if (group != NULL) { | 272 if (group != NULL) { |
251 group->my_role = QQ_ROOM_ROLE_NO; | 273 group->my_role = QQ_ROOM_ROLE_NO; |
252 qq_group_refresh(gc, group); | 274 qq_group_refresh(gc, group); |
253 } | 275 } |
254 | 276 |
277 msg = g_strdup_printf(_("<b>Removed buddy %d.</b>"), uid); | |
278 qq_room_got_chat_in(gc, group, 0, msg, now); | |
255 g_free(msg); | 279 g_free(msg); |
256 } | 280 } |
257 | 281 |
258 /* process the packet when added to a group */ | 282 /* process the packet when added to a group */ |
259 void qq_process_room_msg_been_added(guint8 *data, gint len, guint32 id, PurpleConnection *gc) | 283 void qq_process_room_msg_been_added(guint8 *data, gint len, guint32 id, PurpleConnection *gc) |
260 { | 284 { |
261 guint32 ext_id, uid; | 285 guint32 ext_id, uid; |
262 guint8 type8; | 286 guint8 type8; |
263 qq_group *group; | 287 qq_group *group; |
264 gchar *msg; | 288 gchar *msg; |
265 gint bytes = 0; | 289 gint bytes; |
290 time_t now = time(NULL); | |
266 | 291 |
267 g_return_if_fail(data != NULL && len > 0); | 292 g_return_if_fail(data != NULL && len > 0); |
268 | 293 |
269 /* FIXME: check length here */ | 294 /* FIXME: check length here */ |
270 | 295 bytes = 0; |
271 bytes += qq_get32(&ext_id, data + bytes); | 296 bytes += qq_get32(&ext_id, data + bytes); |
272 bytes += qq_get8(&type8, data + bytes); | 297 bytes += qq_get8(&type8, data + bytes); |
273 bytes += qq_get32(&uid, data + bytes); | 298 bytes += qq_get32(&uid, data + bytes); |
274 | 299 |
275 g_return_if_fail(ext_id > 0 && uid > 0); | 300 g_return_if_fail(ext_id > 0 && uid > 0); |
276 | |
277 msg = g_strdup_printf(_("[%d] added to Qun \"%d\""), uid, ext_id); | |
278 purple_notify_info(gc, _("QQ Qun Operation"), _("Notice:"), msg); | |
279 | 301 |
280 group = qq_room_search_id(gc, id); | 302 group = qq_room_search_id(gc, id); |
281 if (group != NULL) { | 303 if (group != NULL) { |
282 group->my_role = QQ_ROOM_ROLE_YES; | 304 group->my_role = QQ_ROOM_ROLE_YES; |
283 qq_group_refresh(gc, group); | 305 qq_group_refresh(gc, group); |
287 qq_group_refresh(gc, group); | 309 qq_group_refresh(gc, group); |
288 qq_update_room(gc, 0, group->id); | 310 qq_update_room(gc, 0, group->id); |
289 /* the return of this cmd will automatically update the group in blist */ | 311 /* the return of this cmd will automatically update the group in blist */ |
290 } | 312 } |
291 | 313 |
314 msg = g_strdup_printf(_("<b>Added new buddy %d.</b>"), uid); | |
315 qq_room_got_chat_in(gc, group, 0, msg, now); | |
292 g_free(msg); | 316 g_free(msg); |
293 } | 317 } |
294 | 318 |
295 /* recv an IM from a group chat */ | 319 /* recv an IM from a group chat */ |
296 void qq_process_room_msg_normal(guint8 *data, gint data_len, guint32 id, PurpleConnection *gc, guint16 im_type) | 320 void qq_process_room_msg_normal(guint8 *data, gint data_len, guint32 id, PurpleConnection *gc, guint16 im_type) |
297 { | 321 { |
298 gchar *msg_with_purple_smiley, *msg_utf8_encoded, *im_src_name; | 322 gchar *msg_with_purple_smiley, *msg_utf8_encoded; |
299 guint16 unknown; | |
300 guint32 unknown4; | |
301 PurpleConversation *conv; | |
302 qq_data *qd; | 323 qq_data *qd; |
303 qq_buddy *member; | |
304 qq_group *group; | 324 qq_group *group; |
305 qq_recv_group_im *im_group; | |
306 gint skip_len; | 325 gint skip_len; |
307 gint bytes = 0; | 326 gint bytes ; |
327 struct { | |
328 guint32 ext_id; | |
329 guint8 type8; | |
330 guint32 member_uid; | |
331 guint16 unknown; | |
332 guint16 msg_seq; | |
333 time_t send_time; | |
334 guint32 unknown4; | |
335 guint16 msg_len; | |
336 gchar *msg; | |
337 guint8 *font_attr; | |
338 gint font_attr_len; | |
339 } packet; | |
340 | |
308 | 341 |
309 g_return_if_fail(data != NULL && data_len > 0); | 342 g_return_if_fail(data != NULL && data_len > 0); |
310 | 343 |
311 /* FIXME: check length here */ | 344 /* FIXME: check length here */ |
312 | 345 |
313 qd = (qq_data *) gc->proto_data; | 346 qd = (qq_data *) gc->proto_data; |
314 | 347 |
315 #if 0 | 348 #if 0 |
316 qq_hex_dump(PURPLE_DEBUG_INFO, "QQ", data, data_len, "group im hex dump"); | 349 qq_hex_dump(PURPLE_DEBUG_INFO, "QQ", data, data_len, "group im hex dump"); |
317 #endif | 350 #endif |
318 | 351 memset(&packet, 0, sizeof(packet)); |
319 im_group = g_newa(qq_recv_group_im, 1); | 352 bytes = 0; |
320 | 353 bytes += qq_get32(&(packet.ext_id), data + bytes); |
321 bytes += qq_get32(&(im_group->ext_id), data + bytes); | 354 bytes += qq_get8(&(packet.type8), data + bytes); |
322 bytes += qq_get8(&(im_group->type8), data + bytes); | |
323 | 355 |
324 if(QQ_RECV_IM_TEMP_QUN_IM == im_type) { | 356 if(QQ_RECV_IM_TEMP_QUN_IM == im_type) { |
325 bytes += qq_get32(&(id), data + bytes); | 357 bytes += qq_get32(&(id), data + bytes); |
326 } | 358 } |
327 | 359 |
328 bytes += qq_get32(&(im_group->member_uid), bytes + data); | 360 bytes += qq_get32(&(packet.member_uid), bytes + data); |
329 bytes += qq_get16(&unknown, data + bytes); /* 0x0001? */ | 361 bytes += qq_get16(&packet.unknown, data + bytes); /* 0x0001? */ |
330 bytes += qq_get16(&(im_group->msg_seq), data + bytes); | 362 bytes += qq_get16(&(packet.msg_seq), data + bytes); |
331 bytes += qq_getime(&im_group->send_time, data + bytes); | 363 bytes += qq_getime(&packet.send_time, data + bytes); |
332 bytes += qq_get32(&unknown4, data + bytes); /* versionID */ | 364 bytes += qq_get32(&packet.unknown4, data + bytes); /* versionID */ |
333 /* | 365 /* |
334 * length includes font_attr | 366 * length includes font_attr |
335 * this msg_len includes msg and font_attr | 367 * this msg_len includes msg and font_attr |
336 **** the format is **** | 368 **** the format is **** |
337 * length of all | 369 * length of all |
338 * 1. unknown 10 bytes | 370 * 1. unknown 10 bytes |
339 * 2. 0-ended string | 371 * 2. 0-ended string |
340 * 3. font_attr | 372 * 3. font_attr |
341 */ | 373 */ |
342 | 374 |
343 bytes += qq_get16(&(im_group->msg_len), data + bytes); | 375 bytes += qq_get16(&(packet.msg_len), data + bytes); |
344 g_return_if_fail(im_group->msg_len > 0); | 376 g_return_if_fail(packet.msg_len > 0); |
345 | 377 |
346 /* | 378 /* |
347 * 10 bytes from lumaqq | 379 * 10 bytes from lumaqq |
348 * contentType = buf.getChar(); | 380 * contentType = buf.getChar(); |
349 * totalFragments = buf.get() & 255; | 381 * totalFragments = buf.get() & 255; |
356 skip_len = 10; | 388 skip_len = 10; |
357 else | 389 else |
358 skip_len = 0; | 390 skip_len = 0; |
359 bytes += skip_len; | 391 bytes += skip_len; |
360 | 392 |
361 im_group->msg = g_strdup((gchar *) data + bytes); | 393 packet.msg = g_strdup((gchar *) data + bytes); |
362 bytes += strlen(im_group->msg) + 1; | 394 bytes += strlen(packet.msg) + 1; |
363 /* there might not be any font_attr, check it */ | 395 /* there might not be any font_attr, check it */ |
364 im_group->font_attr_len = im_group->msg_len - strlen(im_group->msg) - 1 - skip_len; | 396 packet.font_attr_len = packet.msg_len - strlen(packet.msg) - 1 - skip_len; |
365 if (im_group->font_attr_len > 0) | 397 if (packet.font_attr_len > 0) |
366 im_group->font_attr = g_memdup(data + bytes, im_group->font_attr_len); | 398 packet.font_attr = g_memdup(data + bytes, packet.font_attr_len); |
367 else | 399 else |
368 im_group->font_attr = NULL; | 400 packet.font_attr = NULL; |
369 | 401 |
370 /* group im_group has no flag to indicate whether it has font_attr or not */ | 402 /* group im_group has no flag to indicate whether it has font_attr or not */ |
371 msg_with_purple_smiley = qq_smiley_to_purple(im_group->msg); | 403 msg_with_purple_smiley = qq_smiley_to_purple(packet.msg); |
372 if (im_group->font_attr_len > 0) | 404 if (packet.font_attr_len > 0) |
373 msg_utf8_encoded = qq_encode_to_purple(im_group->font_attr, | 405 msg_utf8_encoded = qq_encode_to_purple(packet.font_attr, |
374 im_group->font_attr_len, msg_with_purple_smiley); | 406 packet.font_attr_len, msg_with_purple_smiley); |
375 else | 407 else |
376 msg_utf8_encoded = qq_to_utf8(msg_with_purple_smiley, QQ_CHARSET_DEFAULT); | 408 msg_utf8_encoded = qq_to_utf8(msg_with_purple_smiley, QQ_CHARSET_DEFAULT); |
377 | 409 |
378 group = qq_room_search_id(gc, id); | 410 group = qq_room_search_id(gc, id); |
379 g_return_if_fail(group != NULL); | 411 qq_room_got_chat_in(gc, group, packet.member_uid, msg_utf8_encoded, packet.send_time); |
380 | 412 |
381 conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, group->title_utf8, purple_connection_get_account(gc)); | |
382 if (conv == NULL && purple_prefs_get_bool("/plugins/prpl/qq/show_room_when_newin")) { | |
383 conv = qq_room_conv_create(gc, group); | |
384 } | |
385 | |
386 if (conv != NULL) { | |
387 member = qq_group_find_member_by_uid(group, im_group->member_uid); | |
388 if (member == NULL || member->nickname == NULL) | |
389 im_src_name = uid_to_purple_name(im_group->member_uid); | |
390 else | |
391 im_src_name = g_strdup(member->nickname); | |
392 serv_got_chat_in(gc, | |
393 purple_conv_chat_get_id(PURPLE_CONV_CHAT | |
394 (conv)), im_src_name, 0, msg_utf8_encoded, im_group->send_time); | |
395 g_free(im_src_name); | |
396 } | |
397 g_free(msg_with_purple_smiley); | 413 g_free(msg_with_purple_smiley); |
398 g_free(msg_utf8_encoded); | 414 g_free(msg_utf8_encoded); |
399 g_free(im_group->msg); | 415 g_free(packet.msg); |
400 g_free(im_group->font_attr); | 416 g_free(packet.font_attr); |
401 } | 417 } |