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 }