comparison libpurple/protocols/qq/qq_process.c @ 24092:7c0a56c5fea0

2008.10.14 - ccpaging <ccpaging(at)gmail.com> * 2007 remove buddy ok * Removed group_search.c/h
author SHiNE CsyFeK <csyfek@gmail.com>
date Tue, 28 Oct 2008 16:44:09 +0000
parents d35672443baa
children f4f29fac96c6
comparison
equal deleted inserted replaced
24091:d35672443baa 24092:7c0a56c5fea0
56 56
57 /* default process, decrypt and dump */ 57 /* default process, decrypt and dump */
58 static void process_unknow_cmd(PurpleConnection *gc,const gchar *title, guint8 *data, gint data_len, guint16 cmd, guint16 seq) 58 static void process_unknow_cmd(PurpleConnection *gc,const gchar *title, guint8 *data, gint data_len, guint16 cmd, guint16 seq)
59 { 59 {
60 qq_data *qd; 60 qq_data *qd;
61 gchar *msg_utf8 = NULL; 61 gchar *msg;
62 62
63 g_return_if_fail(data != NULL && data_len != 0); 63 g_return_if_fail(data != NULL && data_len != 0);
64 64
65 qq_show_packet(title, data, data_len); 65 qq_show_packet(title, data, data_len);
66 66
69 qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ", 69 qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ",
70 data, data_len, 70 data, data_len,
71 ">>> [%d] %s -> [default] decrypt and dump", 71 ">>> [%d] %s -> [default] decrypt and dump",
72 seq, qq_get_cmd_desc(cmd)); 72 seq, qq_get_cmd_desc(cmd));
73 73
74 msg_utf8 = try_dump_as_gbk(data, data_len); 74 msg = g_strdup_printf("Unknow command 0x%02X, %s", cmd, qq_get_cmd_desc(cmd));
75 if (msg_utf8 != NULL) { 75 purple_notify_info(gc, _("QQ Error"), title, msg);
76 purple_notify_info(gc, _("QQ Error"), title, msg_utf8); 76 g_free(msg);
77 g_free(msg_utf8);
78 }
79 } 77 }
80 78
81 /* parse the reply to send_im */ 79 /* parse the reply to send_im */
82 static void do_im_ack(guint8 *data, gint data_len, PurpleConnection *gc) 80 static void do_im_ack(guint8 *data, gint data_len, PurpleConnection *gc)
83 { 81 {
354 break; 352 break;
355 } 353 }
356 } 354 }
357 355
358 /* Send ACK if the sys message needs an ACK */ 356 /* Send ACK if the sys message needs an ACK */
359 static void request_server_ack(PurpleConnection *gc, guint8 code, guint32 from, guint16 seq) 357 static void request_server_ack(PurpleConnection *gc, gchar *funct_str, gchar *from, guint16 seq)
360 { 358 {
361 qq_data *qd; 359 qq_data *qd;
362 guint8 bar, *ack; 360 guint8 *raw_data;
363 gchar *str; 361 gint bytes;
364 gint ack_len, bytes; 362 guint8 bar;
365 363
366 qd = (qq_data *) gc->proto_data; 364 g_return_if_fail(funct_str != NULL && from != NULL);
367 365 qd = (qq_data *) gc->proto_data;
368 str = g_strdup_printf("%d", from); 366
367
369 bar = 0x1e; 368 bar = 0x1e;
370 ack_len = 1 + 1 + strlen(str) + 1 + 2; 369 raw_data = g_newa(guint8, strlen(funct_str) + strlen(from) + 16);
371 ack = g_newa(guint8, ack_len);
372 370
373 bytes = 0; 371 bytes = 0;
374 bytes += qq_put8(ack + bytes, code); 372 bytes += qq_putdata(raw_data + bytes, (guint8 *)funct_str, strlen(funct_str));
375 bytes += qq_put8(ack + bytes, bar); 373 bytes += qq_put8(raw_data + bytes, bar);
376 bytes += qq_putdata(ack + bytes, (guint8 *) str, strlen(str)); 374 bytes += qq_putdata(raw_data + bytes, (guint8 *)from, strlen(from));
377 bytes += qq_put8(ack + bytes, bar); 375 bytes += qq_put8(raw_data + bytes, bar);
378 bytes += qq_put16(ack + bytes, seq); 376 bytes += qq_put16(raw_data + bytes, seq);
379 377
380 g_free(str); 378 qq_send_server_reply(gc, QQ_CMD_ACK_SYS_MSG, 0, raw_data, bytes);
381 379 }
382 if (bytes == ack_len) /* creation OK */ 380
383 qq_send_server_reply(gc, QQ_CMD_ACK_SYS_MSG, 0, ack, ack_len); 381 static void do_server_notice(PurpleConnection *gc, gchar *from, gchar *to,
384 else 382 guint8 *data, gint data_len)
385 purple_debug_error("QQ",
386 "Fail creating sys msg ACK, expect %d bytes, build %d bytes\n", ack_len, bytes);
387 }
388
389 static void do_server_notice(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8)
390 { 383 {
391 qq_data *qd = (qq_data *) gc->proto_data; 384 qq_data *qd = (qq_data *) gc->proto_data;
385 gchar *msg, *msg_utf8;
392 gchar *title, *content; 386 gchar *title, *content;
393 387
394 g_return_if_fail(from != NULL && to != NULL); 388 g_return_if_fail(from != NULL && to != NULL && data_len > 0);
389
390 msg = g_strndup((gchar *)data, data_len);
391 msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT);
392 g_free(msg);
393 if (msg_utf8 == NULL) {
394 purple_debug_error("QQ", "Recv NULL sys msg from %s to %s, discard\n",
395 from, to);
396 return;
397 }
395 398
396 title = g_strdup_printf(_("From %s:"), from); 399 title = g_strdup_printf(_("From %s:"), from);
397 content = g_strdup_printf(_("Server notice From %s: \n%s"), from, msg_utf8); 400 content = g_strdup_printf(_("Server notice From %s: \n%s"), from, msg_utf8);
398 401
399 if (qd->is_show_notice) { 402 if (qd->is_show_notice) {
400 qq_got_attention(gc, content); 403 qq_got_attention(gc, content);
401 } else { 404 } else {
402 purple_debug_info("QQ", "QQ Server notice from %s:\n%s", from, msg_utf8); 405 purple_debug_info("QQ", "QQ Server notice from %s:\n%s", from, msg_utf8);
403 } 406 }
407 g_free(msg_utf8);
404 g_free(title); 408 g_free(title);
405 g_free(content); 409 g_free(content);
406 } 410 }
407 411
408 static void process_server_msg(guint8 *data, gint data_len, guint16 seq, PurpleConnection *gc) 412 static void process_server_msg(PurpleConnection *gc, guint8 *data, gint data_len, guint16 seq)
409 { 413 {
410 qq_data *qd; 414 qq_data *qd;
411 gchar **segments, *code, *from, *to, *msg, *msg_utf8; 415 guint8 *data_str;
412 int funct; 416 gchar **segments;
417 gchar *funct_str, *from, *to;
418 gint bytes, funct;
413 419
414 g_return_if_fail(data != NULL && data_len != 0); 420 g_return_if_fail(data != NULL && data_len != 0);
415 421
416 qd = (qq_data *) gc->proto_data; 422 qd = (qq_data *) gc->proto_data;
417 423
418 if (NULL == (segments = split_data(data, data_len, "\x1f", 4))) 424 data_str = g_newa(guint8, data_len + 1);
419 return; 425 g_memmove(data_str, data, data_len);
420 code = segments[0]; 426 data_str[data_len] = 0x00;
427
428 segments = g_strsplit_set((gchar *) data_str, "\x1f", 0);
429 g_return_if_fail(segments != NULL);
430 if (g_strv_length(segments) < 3) {
431 purple_debug_warning("QQ", "Server message segments is less than 3\n");
432 g_strfreev(segments);
433 return;
434 }
435
436 bytes = 0;
437 funct_str = segments[0];
438 bytes += strlen(funct_str) + 1;
421 from = segments[1]; 439 from = segments[1];
440 bytes += strlen(from) + 1;
422 to = segments[2]; 441 to = segments[2];
423 msg = segments[3]; 442 bytes += strlen(to) + 1;
424 443
425 request_server_ack(gc, code[0], strtol(from, NULL, 10), seq); 444 request_server_ack(gc, funct_str, from, seq);
426 445
446 qq_show_packet("Server MSG", data, data_len);
427 if (strtol(to, NULL, 10) != qd->uid) { /* not to me */ 447 if (strtol(to, NULL, 10) != qd->uid) { /* not to me */
428 purple_debug_error("QQ", "Recv sys msg to [%s], not me!, discard\n", to); 448 purple_debug_error("QQ", "Recv sys msg to [%s], not me!, discard\n", to);
429 g_strfreev(segments); 449 g_strfreev(segments);
430 return; 450 return;
431 } 451 }
432 452
433 msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); 453 funct = strtol(funct_str, NULL, 10);
434 if (from == NULL && msg_utf8) {
435 purple_debug_error("QQ", "Recv NULL sys msg to [%s], discard\n", to);
436 g_strfreev(segments);
437 g_free(msg_utf8);
438 return;
439 }
440
441 funct = strtol(code, NULL, 10);
442 switch (funct) { 454 switch (funct) {
443 case QQ_SERVER_BUDDY_ADDED: 455 case QQ_SERVER_BUDDY_ADDED:
444 case QQ_SERVER_BUDDY_ADD_REQUEST: 456 case QQ_SERVER_BUDDY_ADD_REQUEST:
445 case QQ_SERVER_BUDDY_ADDED_ME: 457 case QQ_SERVER_BUDDY_ADDED_ME:
446 case QQ_SERVER_BUDDY_REJECTED_ME: 458 case QQ_SERVER_BUDDY_REJECTED_ME:
447 qq_process_buddy_from_server(gc, funct, from, to, msg_utf8); 459 case QQ_MSG_SYS_ADD_FRIEND_REQUEST_EX:
460 qq_process_buddy_from_server(gc, funct, from, to, data + bytes, data_len - bytes);
448 break; 461 break;
449 case QQ_SERVER_NOTICE: 462 case QQ_SERVER_NOTICE:
450 do_server_notice(gc, from, to, msg_utf8); 463 do_server_notice(gc, from, to, data + bytes, data_len - bytes);
451 break; 464 break;
452 case QQ_SERVER_NEW_CLIENT: 465 case QQ_SERVER_NEW_CLIENT:
453 purple_debug_warning("QQ", "QQ Server has newer client version\n"); 466 purple_debug_warning("QQ", "QQ Server has newer client version\n");
454 break; 467 break;
455 default: 468 default:
456 purple_debug_warning("QQ", "Recv unknown sys msg code: %s\nMsg: %s\n", code, msg_utf8); 469 qq_show_packet("Recv unknown sys msg", data, data_len);
457 break; 470 purple_debug_warning("QQ", "Recv unknown sys msg code: %s\n", funct_str);
458 } 471 break;
459 g_free(msg_utf8); 472 }
460 g_strfreev(segments); 473 g_strfreev(segments);
461 } 474 }
462 475
463 void qq_proc_server_cmd(PurpleConnection *gc, guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len) 476 void qq_proc_server_cmd(PurpleConnection *gc, guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len)
464 { 477 {
491 switch (cmd) { 504 switch (cmd) {
492 case QQ_CMD_RECV_IM: 505 case QQ_CMD_RECV_IM:
493 process_private_msg(data, data_len, seq, gc); 506 process_private_msg(data, data_len, seq, gc);
494 break; 507 break;
495 case QQ_CMD_RECV_MSG_SYS: 508 case QQ_CMD_RECV_MSG_SYS:
496 process_server_msg(data, data_len, seq, gc); 509 process_server_msg(gc, data, data_len, seq);
497 break; 510 break;
498 case QQ_CMD_BUDDY_CHANGE_STATUS: 511 case QQ_CMD_BUDDY_CHANGE_STATUS:
499 qq_process_buddy_change_status(data, data_len, gc); 512 qq_process_buddy_change_status(data, data_len, gc);
500 break; 513 break;
501 default: 514 default:
944 } 957 }
945 break; 958 break;
946 case QQ_CMD_LOGIN: 959 case QQ_CMD_LOGIN:
947 if (qd->client_version == 2008) { 960 if (qd->client_version == 2008) {
948 ret_8 = qq_process_login_2008(gc, data, data_len); 961 ret_8 = qq_process_login_2008(gc, data, data_len);
962 if ( ret_8 == QQ_LOGIN_REPLY_REDIRECT) {
963 qq_request_get_server(gc);
964 return QQ_LOGIN_REPLY_OK;
965 }
949 } else if (qd->client_version == 2007) { 966 } else if (qd->client_version == 2007) {
950 ret_8 = qq_process_login_2007(gc, data, data_len); 967 ret_8 = qq_process_login_2007(gc, data, data_len);
968 if ( ret_8 == QQ_LOGIN_REPLY_REDIRECT) {
969 qq_request_get_server(gc);
970 return QQ_LOGIN_REPLY_OK;
971 }
951 } else { 972 } else {
952 ret_8 = qq_process_login(gc, data, data_len); 973 ret_8 = qq_process_login(gc, data, data_len);
953 } 974 }
954 if (ret_8 != QQ_LOGIN_REPLY_OK) { 975 if (ret_8 != QQ_LOGIN_REPLY_OK) {
955 return ret_8; 976 return ret_8;
1073 qq_request_get_buddies_and_rooms(gc, ret_32, update_class); 1094 qq_request_get_buddies_and_rooms(gc, ret_32, update_class);
1074 return; 1095 return;
1075 } 1096 }
1076 purple_debug_info("QQ", "All buddies and groups received\n"); 1097 purple_debug_info("QQ", "All buddies and groups received\n");
1077 break; 1098 break;
1099 case QQ_CMD_AUTH_INFO:
1100 qq_process_auth_info(gc, data, data_len, ship32);
1101 break;
1078 default: 1102 default:
1079 process_unknow_cmd(gc, _("Unknow CLIENT CMD"), data, data_len, cmd, seq); 1103 process_unknow_cmd(gc, _("Unknow CLIENT CMD"), data, data_len, cmd, seq);
1080 is_unknow = TRUE; 1104 is_unknow = TRUE;
1081 break; 1105 break;
1082 } 1106 }