Mercurial > pidgin.yaz
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 } |