Mercurial > pidgin
comparison libpurple/protocols/qq/qq_base.c @ 24140:619ac2303c46
2009.10.02 - ccpaging <ccpaging(at)gmail.com>
* Added 'Captcha Display' function
* Most functions from patch written by Emil Alexiev merged into trunk,
except 'buddy operations'
* 'online buddy status' and 'qun buddies' still have problems
author | SHiNE CsyFeK <csyfek@gmail.com> |
---|---|
date | Wed, 22 Oct 2008 14:43:46 +0000 |
parents | 832178d951ca |
children | c2253c485728 |
comparison
equal
deleted
inserted
replaced
24139:832178d951ca | 24140:619ac2303c46 |
---|---|
458 | 458 |
459 /* In fact, we can send whatever we like to server | 459 /* In fact, we can send whatever we like to server |
460 * with this command, server return the same result including | 460 * with this command, server return the same result including |
461 * the amount of online QQ users, my ip and port */ | 461 * the amount of online QQ users, my ip and port */ |
462 bytes += qq_put32(raw_data + bytes, qd->uid); | 462 bytes += qq_put32(raw_data + bytes, qd->uid); |
463 | 463 qq_send_cmd(gc, QQ_CMD_KEEP_ALIVE, raw_data, bytes); |
464 qq_send_cmd(gc, QQ_CMD_KEEP_ALIVE, raw_data, 4); | 464 } |
465 } | 465 |
466 | 466 /* parse the return ofqq_process_keep_alive keep-alive packet, it includes some system information */ |
467 /* parse the return of keep-alive packet, it includes some system information */ | |
468 gboolean qq_process_keep_alive(guint8 *data, gint data_len, PurpleConnection *gc) | 467 gboolean qq_process_keep_alive(guint8 *data, gint data_len, PurpleConnection *gc) |
469 { | 468 { |
470 qq_data *qd; | 469 qq_data *qd; |
471 gchar **segments; | 470 gchar **segments; |
472 | 471 |
492 | 491 |
493 purple_debug_info("QQ", "keep alive, %s:%d\n", | 492 purple_debug_info("QQ", "keep alive, %s:%d\n", |
494 inet_ntoa(qd->my_ip), qd->my_port); | 493 inet_ntoa(qd->my_ip), qd->my_port); |
495 | 494 |
496 g_strfreev(segments); | 495 g_strfreev(segments); |
496 return TRUE; | |
497 } | |
498 | |
499 void qq_request_keep_alive_2007(PurpleConnection *gc) | |
500 { | |
501 qq_data *qd; | |
502 guint8 raw_data[32] = {0}; | |
503 gint bytes= 0; | |
504 gchar *uid_str; | |
505 | |
506 qd = (qq_data *) gc->proto_data; | |
507 | |
508 /* In fact, we can send whatever we like to server | |
509 * with this command, server return the same result including | |
510 * the amount of online QQ users, my ip and port */ | |
511 uid_str = g_strdup_printf("%u", qd->uid); | |
512 bytes += qq_putdata(raw_data + bytes, (guint8 *)uid_str, strlen(uid_str)); | |
513 qq_send_cmd(gc, QQ_CMD_KEEP_ALIVE, raw_data, bytes); | |
514 | |
515 g_free(uid_str); | |
516 } | |
517 | |
518 gboolean qq_process_keep_alive_2007(guint8 *data, gint data_len, PurpleConnection *gc) | |
519 { | |
520 qq_data *qd; | |
521 gint bytes= 0; | |
522 guint8 ret; | |
523 | |
524 g_return_val_if_fail(data != NULL && data_len != 0, FALSE); | |
525 | |
526 qd = (qq_data *) gc->proto_data; | |
527 | |
528 /* qq_show_packet("Keep alive reply packet", data, len); */ | |
529 | |
530 bytes = 0; | |
531 bytes += qq_get8(&ret, data + bytes); | |
532 bytes += qq_get32(&qd->online_total, data + bytes); | |
533 if(0 == qd->online_total) { | |
534 purple_connection_error_reason(gc, | |
535 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
536 _("Keep alive error")); | |
537 } | |
538 | |
539 bytes += qq_getIP(&qd->my_ip, data + bytes); | |
540 bytes += qq_get16(&qd->my_port, data + bytes); | |
541 return TRUE; | |
542 } | |
543 | |
544 void qq_request_keep_alive_2008(PurpleConnection *gc) | |
545 { | |
546 qq_data *qd; | |
547 guint8 raw_data[16] = {0}; | |
548 gint bytes= 0; | |
549 | |
550 qd = (qq_data *) gc->proto_data; | |
551 | |
552 /* In fact, we can send whatever we like to server | |
553 * with this command, server return the same result including | |
554 * the amount of online QQ users, my ip and port */ | |
555 bytes += qq_put32(raw_data + bytes, qd->uid); | |
556 bytes += qq_putime(raw_data + bytes, &qd->login_time); | |
557 qq_send_cmd(gc, QQ_CMD_KEEP_ALIVE, raw_data, bytes); | |
558 } | |
559 | |
560 gboolean qq_process_keep_alive_2008(guint8 *data, gint data_len, PurpleConnection *gc) | |
561 { | |
562 qq_data *qd; | |
563 gint bytes= 0; | |
564 guint8 ret; | |
565 time_t server_time; | |
566 struct tm *tm_local; | |
567 | |
568 g_return_val_if_fail(data != NULL && data_len != 0, FALSE); | |
569 | |
570 qd = (qq_data *) gc->proto_data; | |
571 | |
572 /* qq_show_packet("Keep alive reply packet", data, len); */ | |
573 | |
574 bytes = 0; | |
575 bytes += qq_get8(&ret, data + bytes); | |
576 bytes += qq_get32(&qd->online_total, data + bytes); | |
577 if(0 == qd->online_total) { | |
578 purple_connection_error_reason(gc, | |
579 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
580 _("Keep alive error")); | |
581 } | |
582 | |
583 bytes += qq_getIP(&qd->my_ip, data + bytes); | |
584 bytes += qq_get16(&qd->my_port, data + bytes); | |
585 /* skip 2 byytes, 0x(00 3c) */ | |
586 bytes += 2; | |
587 bytes += qq_getime(&server_time, data + bytes); | |
588 /* skip 5 bytes, all are 0 */ | |
589 | |
590 purple_debug_info("QQ", "keep alive, %s:%d\n", | |
591 inet_ntoa(qd->my_ip), qd->my_port); | |
592 | |
593 tm_local = localtime(&server_time); | |
594 purple_debug_info("QQ", "Server time: %d-%d-%d, %d:%d:%d\n", | |
595 (1900 +tm_local->tm_year), (1 + tm_local->tm_mon), tm_local->tm_mday, | |
596 tm_local->tm_hour, tm_local->tm_min, tm_local->tm_sec); | |
497 return TRUE; | 597 return TRUE; |
498 } | 598 } |
499 | 599 |
500 /* For QQ2007/2008 */ | 600 /* For QQ2007/2008 */ |
501 void qq_request_get_server(PurpleConnection *gc) | 601 void qq_request_get_server(PurpleConnection *gc) |
679 bytes += qq_put8(raw_data + bytes, 4); /* Subcommand */ | 779 bytes += qq_put8(raw_data + bytes, 4); /* Subcommand */ |
680 bytes += qq_put16(raw_data + bytes, 5); | 780 bytes += qq_put16(raw_data + bytes, 5); |
681 bytes += qq_put32(raw_data + bytes, 0); | 781 bytes += qq_put32(raw_data + bytes, 0); |
682 bytes += qq_put16(raw_data + bytes, code_len); | 782 bytes += qq_put16(raw_data + bytes, code_len); |
683 bytes += qq_putdata(raw_data + bytes, code, code_len); | 783 bytes += qq_putdata(raw_data + bytes, code, code_len); |
684 bytes += qq_put16(raw_data + bytes, qd->captcha.token_len); /* captcha token */ | 784 bytes += qq_put16(raw_data + bytes, qd->ld.token_ex_len); /* login token ex */ |
685 bytes += qq_putdata(raw_data + bytes, qd->captcha.token, qd->captcha.token_len); | 785 bytes += qq_putdata(raw_data + bytes, qd->ld.token_ex, qd->ld.token_ex_len); |
686 | 786 |
687 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key); | 787 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key); |
688 | 788 |
689 buf = g_newa(guint8, MAX_PACKET_SIZE); | 789 buf = g_newa(guint8, MAX_PACKET_SIZE); |
690 memset(buf, 0, MAX_PACKET_SIZE); | 790 memset(buf, 0, MAX_PACKET_SIZE); |
809 bytes += 2; /* 0x(00 05) */ | 909 bytes += 2; /* 0x(00 05) */ |
810 bytes += qq_get8(&reply, data + bytes); | 910 bytes += qq_get8(&reply, data + bytes); |
811 | 911 |
812 bytes += qq_get16(&(qd->ld.token_ex_len), data + bytes); | 912 bytes += qq_get16(&(qd->ld.token_ex_len), data + bytes); |
813 qd->ld.token_ex = g_realloc(qd->ld.token_ex, qd->ld.token_ex_len); | 913 qd->ld.token_ex = g_realloc(qd->ld.token_ex, qd->ld.token_ex_len); |
814 bytes += qq_getdata(qd->ld.token_ex, qd->ld.token_ex_len , data + bytes); | 914 bytes += qq_getdata(qd->ld.token_ex, qd->ld.token_ex_len, data + bytes); |
915 qq_show_packet("Get token ex", qd->ld.token_ex, qd->ld.token_ex_len); | |
916 | |
815 if(reply != 1) | 917 if(reply != 1) |
816 { | 918 { |
817 purple_debug_info("QQ", "Captcha verified, result %d\n", reply); | 919 purple_debug_info("QQ", "Captcha verified, result %d\n", reply); |
818 return QQ_LOGIN_REPLY_OK; | 920 return QQ_LOGIN_REPLY_OK; |
819 } | 921 } |
826 | 928 |
827 bytes += qq_get8(&curr_index, data + bytes); | 929 bytes += qq_get8(&curr_index, data + bytes); |
828 bytes += qq_get8(&qd->captcha.next_index, data + bytes); | 930 bytes += qq_get8(&qd->captcha.next_index, data + bytes); |
829 | 931 |
830 bytes += qq_get16(&qd->captcha.token_len, data + bytes); | 932 bytes += qq_get16(&qd->captcha.token_len, data + bytes); |
831 qd->captcha.token = g_new0(guint8, qd->captcha.token_len); | 933 qd->captcha.token = g_realloc(qd->captcha.token, qd->captcha.token_len); |
832 bytes += qq_getdata(qd->captcha.token, qd->captcha.token_len, data + bytes); | 934 bytes += qq_getdata(qd->captcha.token, qd->captcha.token_len, data + bytes); |
833 | 935 qq_show_packet("Get captcha token", qd->captcha.token, qd->captcha.token_len); |
936 | |
937 purple_debug_info("QQ", "Request next captcha %d, new %d, total %d\n", | |
938 qd->captcha.next_index, captcha_len, qd->captcha.data_len); | |
834 if(qd->captcha.next_index > 0) | 939 if(qd->captcha.next_index > 0) |
835 { | 940 { |
836 return QQ_LOGIN_REPLY_NEXT_TOKEN_EX; | 941 return QQ_LOGIN_REPLY_NEXT_TOKEN_EX; |
837 } | 942 } |
838 | 943 |
892 }; | 997 }; |
893 | 998 |
894 g_return_if_fail(gc != NULL && gc->proto_data != NULL); | 999 g_return_if_fail(gc != NULL && gc->proto_data != NULL); |
895 qd = (qq_data *) gc->proto_data; | 1000 qd = (qq_data *) gc->proto_data; |
896 | 1001 |
897 g_return_if_fail(qd->ld.token != NULL && qd->ld.token_len > 0); | 1002 g_return_if_fail(qd->ld.token_ex != NULL && qd->ld.token_ex_len > 0); |
898 | 1003 |
899 raw_data = g_newa(guint8, MAX_PACKET_SIZE - 16); | 1004 raw_data = g_newa(guint8, MAX_PACKET_SIZE - 16); |
900 memset(raw_data, 0, MAX_PACKET_SIZE - 16); | 1005 memset(raw_data, 0, MAX_PACKET_SIZE - 16); |
901 | 1006 |
902 encrypted = g_newa(guint8, MAX_PACKET_SIZE); /* 16 bytes more */ | 1007 encrypted = g_newa(guint8, MAX_PACKET_SIZE); /* 16 bytes more */ |
911 | 1016 |
912 /* create packet */ | 1017 /* create packet */ |
913 bytes = 0; | 1018 bytes = 0; |
914 bytes += qq_putdata(raw_data + bytes, header, sizeof(header)); | 1019 bytes += qq_putdata(raw_data + bytes, header, sizeof(header)); |
915 /* token get from qq_request_token_ex */ | 1020 /* token get from qq_request_token_ex */ |
916 bytes += qq_put8(raw_data + bytes, qd->ld.token_ex_len); | 1021 bytes += qq_put8(raw_data + bytes, (guint8)(qd->ld.token_ex_len & 0xff)); |
917 bytes += qq_putdata(raw_data + bytes, qd->ld.token_ex, qd->ld.token_ex_len); | 1022 bytes += qq_putdata(raw_data + bytes, qd->ld.token_ex, qd->ld.token_ex_len); |
918 /* password encrypted */ | 1023 /* password encrypted */ |
919 bytes += qq_put16(raw_data + bytes, encrypted_len); | 1024 bytes += qq_put16(raw_data + bytes, encrypted_len); |
920 bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len); | 1025 bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len); |
921 /* len of unknown + len of CRC32 */ | 1026 /* len of unknown + len of CRC32 */ |
922 bytes += qq_put16(raw_data + bytes, sizeof(unknown) + 4); | 1027 bytes += qq_put16(raw_data + bytes, sizeof(unknown) + 4); |
923 bytes += qq_putdata(raw_data + bytes, unknown, sizeof(unknown)); | 1028 bytes += qq_putdata(raw_data + bytes, unknown, sizeof(unknown)); |
924 bytes += qq_put32( | 1029 bytes += qq_put32( |
925 raw_data + bytes, crc32(0xFFFFFFFF, unknown, sizeof(unknown))); | 1030 raw_data + bytes, crc32(0xFFFFFFFF, unknown, sizeof(unknown))); |
926 | 1031 |
927 /* put length into first 2 bytes */ | 1032 /* put length into first 2 bytes */ |
928 qq_put8(raw_data + 1, bytes - 2); | 1033 qq_put8(raw_data + 1, bytes - 2); |
929 | 1034 |
930 /* tail */ | 1035 /* tail */ |
931 bytes += qq_put16(raw_data + bytes, 0x0003); | 1036 bytes += qq_put16(raw_data + bytes, 0x0003); |
932 bytes += qq_put8(raw_data + bytes, 0); | 1037 bytes += qq_put8(raw_data + bytes, 0); |
933 bytes += qq_put8(raw_data + bytes, qd->ld.pwd_md5[1]); | 1038 bytes += qq_put8(raw_data + bytes, qd->ld.pwd_md5[1]); |
934 bytes += qq_put8(raw_data + bytes, qd->ld.pwd_md5[2]); | 1039 bytes += qq_put8(raw_data + bytes, qd->ld.pwd_md5[2]); |
935 | 1040 |
936 /* qq_show_packet("Check password", raw_data, bytes); */ | 1041 qq_show_packet("Check password", raw_data, bytes); |
937 /* Encrypted by random key*/ | 1042 /* Encrypted by random key*/ |
938 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key); | 1043 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key); |
939 | 1044 |
940 buf = g_newa(guint8, MAX_PACKET_SIZE); | 1045 buf = g_newa(guint8, MAX_PACKET_SIZE); |
941 memset(buf, 0, MAX_PACKET_SIZE); | 1046 memset(buf, 0, MAX_PACKET_SIZE); |
961 g_return_val_if_fail(data != NULL && data_len != 0, QQ_LOGIN_REPLY_ERR); | 1066 g_return_val_if_fail(data != NULL && data_len != 0, QQ_LOGIN_REPLY_ERR); |
962 | 1067 |
963 g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, QQ_LOGIN_REPLY_ERR); | 1068 g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, QQ_LOGIN_REPLY_ERR); |
964 qd = (qq_data *) gc->proto_data; | 1069 qd = (qq_data *) gc->proto_data; |
965 | 1070 |
966 /* qq_show_packet("Check password reply", data, data_len); */ | 1071 qq_show_packet("Check password reply", data, data_len); |
967 | 1072 |
968 bytes = 0; | 1073 bytes = 0; |
969 bytes += qq_get16(&unknow_token_len, data + bytes); /* maybe total length */ | 1074 bytes += qq_get16(&unknow_token_len, data + bytes); /* maybe total length */ |
970 bytes += qq_get8(&ret, data + bytes); | 1075 bytes += qq_get8(&ret, data + bytes); |
971 bytes += 4; /* 0x(00 00 6d b9) */ | 1076 bytes += 4; /* 0x(00 00 6d b9) */ |
1095 bytes += qq_put8(raw_data + bytes, qd->login_mode); | 1200 bytes += qq_put8(raw_data + bytes, qd->login_mode); |
1096 /* unknow 10 bytes zero filled*/ | 1201 /* unknow 10 bytes zero filled*/ |
1097 memset(raw_data + bytes, 0, 10); | 1202 memset(raw_data + bytes, 0, 10); |
1098 bytes += 10; | 1203 bytes += 10; |
1099 /* redirect data, 15 bytes */ | 1204 /* redirect data, 15 bytes */ |
1205 qq_show_packet("Redirect", qd->redirect, qd->redirect_len); | |
1100 bytes += qq_putdata(raw_data + bytes, qd->redirect, qd->redirect_len); | 1206 bytes += qq_putdata(raw_data + bytes, qd->redirect, qd->redirect_len); |
1101 /* unknow fill */ | 1207 /* unknow fill */ |
1102 bytes += qq_putdata(raw_data + bytes, login_2_16, sizeof(login_2_16)); | 1208 bytes += qq_putdata(raw_data + bytes, login_2_16, sizeof(login_2_16)); |
1103 /* captcha token get from qq_process_token_ex */ | 1209 /* captcha token get from qq_process_token_ex */ |
1104 bytes += qq_put8(raw_data + bytes, qd->ld.token_ex_len); | 1210 bytes += qq_put8(raw_data + bytes, (guint8)(qd->ld.token_ex_len & 0xff)); |
1105 bytes += qq_putdata(raw_data + bytes, qd->ld.token_ex, qd->ld.token_ex_len); | 1211 bytes += qq_putdata(raw_data + bytes, qd->ld.token_ex, qd->ld.token_ex_len); |
1106 /* unknow fill */ | 1212 /* unknow fill */ |
1107 bytes += qq_putdata(raw_data + bytes, login_3_83, sizeof(login_3_83)); | 1213 bytes += qq_putdata(raw_data + bytes, login_3_83, sizeof(login_3_83)); |
1108 memset(raw_data + bytes, 0, 332 - sizeof(login_3_83)); | 1214 memset(raw_data + bytes, 0, 332 - sizeof(login_3_83)); |
1109 bytes += 332 - sizeof(login_3_83); | 1215 bytes += 332 - sizeof(login_3_83); |
1128 guint8 qq_process_login_2007( PurpleConnection *gc, guint8 *data, gint data_len) | 1234 guint8 qq_process_login_2007( PurpleConnection *gc, guint8 *data, gint data_len) |
1129 { | 1235 { |
1130 qq_data *qd; | 1236 qq_data *qd; |
1131 gint bytes; | 1237 gint bytes; |
1132 guint8 ret; | 1238 guint8 ret; |
1239 guint32 uid; | |
1133 gchar *error; | 1240 gchar *error; |
1134 guint32 uid; | 1241 gchar *msg; |
1242 gchar *msg_utf8; | |
1135 | 1243 |
1136 g_return_val_if_fail(data != NULL && data_len != 0, QQ_LOGIN_REPLY_ERR); | 1244 g_return_val_if_fail(data != NULL && data_len != 0, QQ_LOGIN_REPLY_ERR); |
1137 | 1245 |
1138 qd = (qq_data *) gc->proto_data; | 1246 qd = (qq_data *) gc->proto_data; |
1139 | 1247 |
1140 bytes = 0; | 1248 bytes = 0; |
1141 bytes += qq_get8(&ret, data + bytes); | 1249 bytes += qq_get8(&ret, data + bytes); |
1142 if (ret != 0) { | 1250 if (ret != 0) { |
1143 qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ", data, data_len, | 1251 msg = g_strndup((gchar *)data + bytes, data_len - bytes); |
1144 ">>> [default] decrypt and dump"); | 1252 msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); |
1145 error = g_strdup_printf( | 1253 |
1146 _("Unknow reply code when login (0x%02X)"), | 1254 switch (ret) { |
1147 ret ); | 1255 case 0x05: |
1256 error = g_strdup_printf( | |
1257 _("Server is busy now, Please try later\n%s"), | |
1258 ret, msg_utf8); | |
1259 break; | |
1260 case 0x0A: | |
1261 /* 0a 2d 9a 4b 9a 01 01 00 00 00 05 00 00 00 00 79 0e 5f fd */ | |
1262 default: | |
1263 error = g_strdup_printf( | |
1264 _("Unknow reply code when login (0x%02X):\n%s"), | |
1265 ret, msg_utf8); | |
1266 break; | |
1267 } | |
1268 | |
1269 purple_debug_error("QQ", "%s\n", error); | |
1148 purple_connection_error_reason(gc, | 1270 purple_connection_error_reason(gc, |
1149 PURPLE_CONNECTION_ERROR_OTHER_ERROR, | 1271 PURPLE_CONNECTION_ERROR_OTHER_ERROR, |
1150 error); | 1272 error); |
1273 | |
1274 qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ", data, data_len, error); | |
1275 | |
1151 g_free(error); | 1276 g_free(error); |
1277 g_free(msg_utf8); | |
1278 g_free(msg); | |
1152 return QQ_LOGIN_REPLY_ERR; | 1279 return QQ_LOGIN_REPLY_ERR; |
1153 } | 1280 } |
1154 | 1281 |
1155 bytes += qq_getdata(qd->session_key, sizeof(qd->session_key), data + bytes); | 1282 bytes += qq_getdata(qd->session_key, sizeof(qd->session_key), data + bytes); |
1156 purple_debug_info("QQ", "Got session_key\n"); | 1283 purple_debug_info("QQ", "Got session_key\n"); |
1260 /* redirect data, 15 bytes */ | 1387 /* redirect data, 15 bytes */ |
1261 bytes += qq_putdata(raw_data + bytes, qd->redirect, qd->redirect_len); | 1388 bytes += qq_putdata(raw_data + bytes, qd->redirect, qd->redirect_len); |
1262 /* unknow fill */ | 1389 /* unknow fill */ |
1263 bytes += qq_putdata(raw_data + bytes, login_2_16, sizeof(login_2_16)); | 1390 bytes += qq_putdata(raw_data + bytes, login_2_16, sizeof(login_2_16)); |
1264 /* captcha token get from qq_process_token_ex */ | 1391 /* captcha token get from qq_process_token_ex */ |
1265 bytes += qq_put8(raw_data + bytes, qd->ld.token_ex_len); | 1392 bytes += qq_put8(raw_data + bytes, (guint8)(qd->ld.token_ex_len & 0xff)); |
1266 bytes += qq_putdata(raw_data + bytes, qd->ld.token_ex, qd->ld.token_ex_len); | 1393 bytes += qq_putdata(raw_data + bytes, qd->ld.token_ex, qd->ld.token_ex_len); |
1267 /* unknow fill */ | 1394 /* unknow fill */ |
1268 bytes += qq_putdata(raw_data + bytes, login_3_18, sizeof(login_3_18)); | 1395 bytes += qq_putdata(raw_data + bytes, login_3_18, sizeof(login_3_18)); |
1269 bytes += qq_put8(raw_data + bytes , sizeof(login_4_16)); | 1396 bytes += qq_put8(raw_data + bytes , sizeof(login_4_16)); |
1270 bytes += qq_putdata(raw_data + bytes, login_4_16, sizeof(login_4_16)); | 1397 bytes += qq_putdata(raw_data + bytes, login_4_16, sizeof(login_4_16)); |
1299 guint8 qq_process_login_2008( PurpleConnection *gc, guint8 *data, gint data_len) | 1426 guint8 qq_process_login_2008( PurpleConnection *gc, guint8 *data, gint data_len) |
1300 { | 1427 { |
1301 qq_data *qd; | 1428 qq_data *qd; |
1302 gint bytes; | 1429 gint bytes; |
1303 guint8 ret; | 1430 guint8 ret; |
1431 guint32 uid; | |
1304 gchar *error; | 1432 gchar *error; |
1305 guint32 uid; | 1433 gchar *msg; |
1434 gchar *msg_utf8; | |
1306 | 1435 |
1307 g_return_val_if_fail(data != NULL && data_len != 0, QQ_LOGIN_REPLY_ERR); | 1436 g_return_val_if_fail(data != NULL && data_len != 0, QQ_LOGIN_REPLY_ERR); |
1308 | 1437 |
1309 qd = (qq_data *) gc->proto_data; | 1438 qd = (qq_data *) gc->proto_data; |
1310 | 1439 |
1311 bytes = 0; | 1440 bytes = 0; |
1312 bytes += qq_get8(&ret, data + bytes); | 1441 bytes += qq_get8(&ret, data + bytes); |
1313 if (ret != 0) { | 1442 if (ret != 0) { |
1314 qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ", data, data_len, | 1443 msg = g_strndup((gchar *)data + bytes, data_len - bytes); |
1315 ">>> [default] decrypt and dump"); | 1444 msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); |
1316 error = g_strdup_printf( | 1445 |
1317 _("Unknow reply code when login (0x%02X)"), | 1446 switch (ret) { |
1318 ret ); | 1447 case 0x05: |
1448 error = g_strdup_printf( | |
1449 _("Server is busy now, Please try later\n%s"), | |
1450 ret, msg_utf8); | |
1451 break; | |
1452 default: | |
1453 error = g_strdup_printf( | |
1454 _("Unknow reply code when login (0x%02X):\n%s"), | |
1455 ret, msg_utf8); | |
1456 break; | |
1457 } | |
1458 | |
1459 purple_debug_error("QQ", "%s\n", error); | |
1319 purple_connection_error_reason(gc, | 1460 purple_connection_error_reason(gc, |
1320 PURPLE_CONNECTION_ERROR_OTHER_ERROR, | 1461 PURPLE_CONNECTION_ERROR_OTHER_ERROR, |
1321 error); | 1462 error); |
1463 | |
1464 qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ", data, data_len, error); | |
1465 | |
1322 g_free(error); | 1466 g_free(error); |
1467 g_free(msg_utf8); | |
1468 g_free(msg); | |
1323 return QQ_LOGIN_REPLY_ERR; | 1469 return QQ_LOGIN_REPLY_ERR; |
1324 } | 1470 } |
1325 | 1471 |
1326 bytes += qq_getdata(qd->session_key, sizeof(qd->session_key), data + bytes); | 1472 bytes += qq_getdata(qd->session_key, sizeof(qd->session_key), data + bytes); |
1327 purple_debug_info("QQ", "Got session_key\n"); | 1473 purple_debug_info("QQ", "Got session_key\n"); |