comparison libpurple/protocols/qq/qq_network.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 87e61a85f5dd
comparison
equal deleted inserted replaced
24134:bdfcfd71449c 24135:dbc7a9742f8d
200 qd->connect_retry = QQ_CONNECT_MAX; 200 qd->connect_retry = QQ_CONNECT_MAX;
201 } 201 }
202 202
203 if (qd->curr_server == NULL || strlen (qd->curr_server) == 0 || qd->connect_retry <= 0) { 203 if (qd->curr_server == NULL || strlen (qd->curr_server) == 0 || qd->connect_retry <= 0) {
204 if ( set_new_server(qd) != TRUE) { 204 if ( set_new_server(qd) != TRUE) {
205 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 205 purple_connection_error_reason(gc,
206 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
206 _("Failed to connect all servers")); 207 _("Failed to connect all servers"));
207 return FALSE; 208 return FALSE;
208 } 209 }
209 qd->connect_retry = QQ_CONNECT_MAX; 210 qd->connect_retry = QQ_CONNECT_MAX;
210 } 211 }
218 } 219 }
219 g_strfreev(segments); 220 g_strfreev(segments);
220 221
221 qd->connect_retry--; 222 qd->connect_retry--;
222 if ( !connect_to_server(gc, server, port) ) { 223 if ( !connect_to_server(gc, server, port) ) {
223 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 224 purple_connection_error_reason(gc,
225 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
224 _("Unable to connect.")); 226 _("Unable to connect."));
225 } 227 }
226 228
227 qd->check_watcher = purple_timeout_add_seconds(QQ_CONNECT_CHECK, connect_check, gc); 229 qd->check_watcher = purple_timeout_add_seconds(QQ_CONNECT_CHECK, connect_check, gc);
228 return FALSE; /* timeout callback stops */ 230 return FALSE; /* timeout callback stops */
351 353
352 g_return_if_fail(gc != NULL && gc->proto_data != NULL); 354 g_return_if_fail(gc != NULL && gc->proto_data != NULL);
353 qd = (qq_data *) gc->proto_data; 355 qd = (qq_data *) gc->proto_data;
354 356
355 if(cond != PURPLE_INPUT_READ) { 357 if(cond != PURPLE_INPUT_READ) {
356 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 358 purple_connection_error_reason(gc,
359 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
357 _("Socket error")); 360 _("Socket error"));
358 return; 361 return;
359 } 362 }
360 363
361 conn = connection_find(qd, source); 364 conn = connection_find(qd, source);
375 if (errno == EAGAIN) 378 if (errno == EAGAIN)
376 /* No worries */ 379 /* No worries */
377 return; 380 return;
378 381
379 error_msg = g_strdup_printf(_("Lost connection with server:\n%d, %s"), errno, g_strerror(errno)); 382 error_msg = g_strdup_printf(_("Lost connection with server:\n%d, %s"), errno, g_strerror(errno));
380 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_msg); 383 purple_connection_error_reason(gc,
384 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
385 error_msg);
381 g_free(error_msg); 386 g_free(error_msg);
382 return; 387 return;
383 } else if (buf_len == 0) { 388 } else if (buf_len == 0) {
384 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 389 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
385 _("Server closed the connection.")); 390 _("Server closed the connection."));
477 gc = (PurpleConnection *) data; 482 gc = (PurpleConnection *) data;
478 g_return_if_fail(gc != NULL && gc->proto_data != NULL); 483 g_return_if_fail(gc != NULL && gc->proto_data != NULL);
479 qd = (qq_data *) gc->proto_data; 484 qd = (qq_data *) gc->proto_data;
480 485
481 if(cond != PURPLE_INPUT_READ) { 486 if(cond != PURPLE_INPUT_READ) {
482 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 487 purple_connection_error_reason(gc,
488 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
483 _("Socket error")); 489 _("Socket error"));
484 return; 490 return;
485 } 491 }
486 492
487 buf = g_newa(guint8, MAX_PACKET_SIZE); 493 buf = g_newa(guint8, MAX_PACKET_SIZE);
488 494
489 /* here we have UDP proxy suppport */ 495 /* here we have UDP proxy suppport */
490 buf_len = read(source, buf, MAX_PACKET_SIZE); 496 buf_len = read(source, buf, MAX_PACKET_SIZE);
491 if (buf_len <= 0) { 497 if (buf_len <= 0) {
492 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 498 purple_connection_error_reason(gc,
499 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
493 _("Unable to read from socket")); 500 _("Unable to read from socket"));
494 return; 501 return;
495 } 502 }
496 503
497 /* keep alive will be sent in 30 seconds since last_receive 504 /* keep alive will be sent in 30 seconds since last_receive
535 } 542 }
536 543
537 if (ret < 0) { 544 if (ret < 0) {
538 /* TODO: what to do here - do we really have to disconnect? */ 545 /* TODO: what to do here - do we really have to disconnect? */
539 purple_debug_error("UDP_SEND_OUT", "Send failed: %d, %s\n", errno, g_strerror(errno)); 546 purple_debug_error("UDP_SEND_OUT", "Send failed: %d, %s\n", errno, g_strerror(errno));
540 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, g_strerror(errno)); 547 purple_connection_error_reason(gc,
548 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
549 g_strerror(errno));
541 } 550 }
542 return ret; 551 return ret;
543 } 552 }
544 553
545 static void tcp_can_write(gpointer data, gint source, PurpleInputCondition cond) 554 static void tcp_can_write(gpointer data, gint source, PurpleInputCondition cond)
567 576
568 if (ret < 0 && errno == EAGAIN) 577 if (ret < 0 && errno == EAGAIN)
569 return; 578 return;
570 else if (ret < 0) { 579 else if (ret < 0) {
571 /* TODO: what to do here - do we really have to disconnect? */ 580 /* TODO: what to do here - do we really have to disconnect? */
572 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 581 purple_connection_error_reason(gc,
573 _("Write Error")); 582 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
583 _("Write Error"));
574 return; 584 return;
575 } 585 }
576 586
577 purple_circ_buffer_mark_read(conn->tcp_txbuf, ret); 587 purple_circ_buffer_mark_read(conn->tcp_txbuf, ret);
578 } 588 }
612 ret = 0; 622 ret = 0;
613 } else if (ret <= 0) { 623 } else if (ret <= 0) {
614 /* TODO: what to do here - do we really have to disconnect? */ 624 /* TODO: what to do here - do we really have to disconnect? */
615 purple_debug_error("TCP_SEND_OUT", 625 purple_debug_error("TCP_SEND_OUT",
616 "Send to socket %d failed: %d, %s\n", qd->fd, errno, g_strerror(errno)); 626 "Send to socket %d failed: %d, %s\n", qd->fd, errno, g_strerror(errno));
617 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, g_strerror(errno)); 627 purple_connection_error_reason(gc,
628 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
629 g_strerror(errno));
618 return ret; 630 return ret;
619 } 631 }
620 632
621 if (ret < data_len) { 633 if (ret < data_len) {
622 purple_debug_info("TCP_SEND_OUT", 634 purple_debug_info("TCP_SEND_OUT",
639 qd = (qq_data *) gc->proto_data; 651 qd = (qq_data *) gc->proto_data;
640 652
641 is_lost_conn = qq_trans_scan(gc); 653 is_lost_conn = qq_trans_scan(gc);
642 if (is_lost_conn) { 654 if (is_lost_conn) {
643 purple_connection_error_reason(gc, 655 purple_connection_error_reason(gc,
644 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Connection lost")); 656 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
657 _("Connection lost"));
645 return TRUE; 658 return TRUE;
646 } 659 }
647 660
648 if ( !qd->is_login ) { 661 if ( !qd->is_login ) {
649 return TRUE; 662 return TRUE;
672 685
673 static void set_all_keys(PurpleConnection *gc) 686 static void set_all_keys(PurpleConnection *gc)
674 { 687 {
675 qq_data *qd; 688 qq_data *qd;
676 const gchar *passwd; 689 const gchar *passwd;
690 guint8 *dest;
691 int dest_len = QQ_KEY_LENGTH;
677 692
678 /* _qq_show_socket("Got login socket", source); */ 693 /* _qq_show_socket("Got login socket", source); */
679 694
680 g_return_if_fail(gc != NULL && gc->proto_data != NULL); 695 g_return_if_fail(gc != NULL && gc->proto_data != NULL);
681 qd = (qq_data *) gc->proto_data; 696 qd = (qq_data *) gc->proto_data;
687 qd->is_login = FALSE; 702 qd->is_login = FALSE;
688 qd->channel = 1; 703 qd->channel = 1;
689 qd->uid = strtol(purple_account_get_username(purple_connection_get_account(gc)), NULL, 10); 704 qd->uid = strtol(purple_account_get_username(purple_connection_get_account(gc)), NULL, 10);
690 705
691 #ifdef DEBUG 706 #ifdef DEBUG
692 memset(qd->ld.init_key, 0x01, sizeof(qd->ld.init_key)); 707 memset(qd->ld.random_key, 0x01, sizeof(qd->ld.random_key));
693 memset(qd->ld.captcha_key, 0x02, sizeof(qd->ld.captcha_key));
694 #else 708 #else
695 for (bytes = 0; bytes < sizeof(qd->ld.init_key); bytes++) { 709 for (bytes = 0; bytes < sizeof(qd->ld.random_key); bytes++) {
696 qd->ld.init_key[bytes] = (guint8) (rand() & 0xff); 710 qd->ld.random_key[bytes] = (guint8) (rand() & 0xff);
697 }
698 for (bytes = 0; bytes < sizeof(qd->captcha_key); bytes++) {
699 qd->captcha_key[bytes] = (guint8) (rand() & 0xff);
700 } 711 }
701 #endif 712 #endif
702 713
703 /* now generate md5 processed passwd */ 714 /* now generate md5 processed passwd */
704 passwd = purple_account_get_password(purple_connection_get_account(gc)); 715 passwd = purple_account_get_password(purple_connection_get_account(gc));
705 716
706 /* use twice-md5 of user password as session key since QQ 2003iii */ 717 /* use twice-md5 of user password as session key since QQ 2003iii */
707 qq_get_md5(qd->ld.pwd_twice_md5, sizeof(qd->ld.pwd_twice_md5), 718 dest = qd->ld.pwd_2nd_md5;
708 (guint8 *)passwd, strlen(passwd)); 719 qq_get_md5(dest, dest_len, (guint8 *)passwd, strlen(passwd));
709 qq_get_md5(qd->ld.pwd_twice_md5, sizeof(qd->ld.pwd_twice_md5), 720 qq_get_md5(dest, dest_len, dest, dest_len);
710 qd->ld.pwd_twice_md5, sizeof(qd->ld.pwd_twice_md5)); 721
711 722 dest = qd->ld.pwd_4th_md5;
723 qq_get_md5(dest, dest_len, qd->ld.pwd_2nd_md5, dest_len);
724 qq_get_md5(dest, dest_len, dest, dest_len);
712 } 725 }
713 726
714 /* the callback function after socket is built 727 /* the callback function after socket is built
715 * we setup the qq protocol related configuration here */ 728 * we setup the qq protocol related configuration here */
716 static void connect_cb(gpointer data, gint source, const gchar *error_message) 729 static void connect_cb(gpointer data, gint source, const gchar *error_message)
756 g_return_if_fail(qd->network_watcher == 0); 769 g_return_if_fail(qd->network_watcher == 0);
757 qd->network_watcher = purple_timeout_add_seconds(qd->itv_config.resend, network_timeout, gc); 770 qd->network_watcher = purple_timeout_add_seconds(qd->itv_config.resend, network_timeout, gc);
758 771
759 set_all_keys( gc ); 772 set_all_keys( gc );
760 773
761 if (qd->is_above_2007) { 774 if (qd->client_version > 2005) {
762 purple_connection_update_progress(gc, _("Get server ..."), 2, QQ_CONNECT_STEPS); 775 purple_connection_update_progress(gc, _("Get server ..."), 2, QQ_CONNECT_STEPS);
763 qq_request_get_server(gc); 776 qq_request_get_server(gc);
764 return; 777 return;
765 } 778 }
766 779
834 * Otherwise purple_dnsquery_destroy in qq_disconnect cause glib double free error */ 847 * Otherwise purple_dnsquery_destroy in qq_disconnect cause glib double free error */
835 qd->udp_query_data = NULL; 848 qd->udp_query_data = NULL;
836 849
837 if (!hosts || !hosts->data) { 850 if (!hosts || !hosts->data) {
838 purple_connection_error_reason(gc, 851 purple_connection_error_reason(gc,
839 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 852 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
840 _("Couldn't resolve host")); 853 _("Couldn't resolve host"));
841 return; 854 return;
842 } 855 }
843 856
844 addr_size = GPOINTER_TO_INT(hosts->data); 857 addr_size = GPOINTER_TO_INT(hosts->data);
845 hosts = g_slist_remove(hosts, hosts->data); 858 hosts = g_slist_remove(hosts, hosts->data);
913 g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, FALSE); 926 g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, FALSE);
914 account = purple_connection_get_account(gc); 927 account = purple_connection_get_account(gc);
915 qd = (qq_data *) gc->proto_data; 928 qd = (qq_data *) gc->proto_data;
916 929
917 if (server == NULL || strlen(server) == 0 || port == 0) { 930 if (server == NULL || strlen(server) == 0 || port == 0) {
918 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 931 purple_connection_error_reason(gc,
932 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
919 _("Invalid server or port")); 933 _("Invalid server or port"));
920 return FALSE; 934 return FALSE;
921 } 935 }
922 936
923 purple_connection_update_progress(gc, _("Connecting server ..."), 1, QQ_CONNECT_STEPS); 937 purple_connection_update_progress(gc, _("Connecting server ..."), 1, QQ_CONNECT_STEPS);
1004 connection_free_all(qd); 1018 connection_free_all(qd);
1005 qd->fd = -1; 1019 qd->fd = -1;
1006 1020
1007 qq_trans_remove_all(gc); 1021 qq_trans_remove_all(gc);
1008 1022
1009 memset(qd->ld.init_key, 0, sizeof(qd->ld.init_key)); 1023 memset(qd->ld.random_key, 0, sizeof(qd->ld.random_key));
1010 memset(qd->ld.captcha_key, 0, sizeof(qd->ld.captcha_key)); 1024 memset(qd->ld.pwd_2nd_md5, 0, sizeof(qd->ld.pwd_2nd_md5));
1011 memset(qd->ld.pwd_twice_md5, 0, sizeof(qd->ld.pwd_twice_md5)); 1025 memset(qd->ld.pwd_4th_md5, 0, sizeof(qd->ld.pwd_4th_md5));
1026 memset(qd->ld.login_key, 0, sizeof(qd->ld.login_key));
1012 memset(qd->session_key, 0, sizeof(qd->session_key)); 1027 memset(qd->session_key, 0, sizeof(qd->session_key));
1013 memset(qd->session_md5, 0, sizeof(qd->session_md5)); 1028 memset(qd->session_md5, 0, sizeof(qd->session_md5));
1014 1029
1015 qd->my_ip.s_addr = 0; 1030 qd->my_ip.s_addr = 0;
1016 1031
1030 if (qd->use_tcp) { 1045 if (qd->use_tcp) {
1031 bytes += qq_put16(buf + bytes, 0x0000); 1046 bytes += qq_put16(buf + bytes, 0x0000);
1032 } 1047 }
1033 /* now comes the normal QQ packet as UDP */ 1048 /* now comes the normal QQ packet as UDP */
1034 bytes += qq_put8(buf + bytes, QQ_PACKET_TAG); 1049 bytes += qq_put8(buf + bytes, QQ_PACKET_TAG);
1035 bytes += qq_put16(buf + bytes, qd->client_version); 1050 bytes += qq_put16(buf + bytes, qd->client_tag);
1036 bytes += qq_put16(buf + bytes, cmd); 1051 bytes += qq_put16(buf + bytes, cmd);
1037 1052
1038 bytes += qq_put16(buf + bytes, seq); 1053 bytes += qq_put16(buf + bytes, seq);
1039 1054
1040 bytes += qq_put32(buf + bytes, qd->uid); 1055 bytes += qq_put32(buf + bytes, qd->uid);
1077 1092
1078 return bytes_sent; 1093 return bytes_sent;
1079 } 1094 }
1080 1095
1081 gint qq_send_cmd_encrypted(PurpleConnection *gc, guint16 cmd, guint16 seq, 1096 gint qq_send_cmd_encrypted(PurpleConnection *gc, guint16 cmd, guint16 seq,
1082 guint8 *encrypted_data, gint encrypted_len, gboolean is_save2trans) 1097 guint8 *encrypted, gint encrypted_len, gboolean is_save2trans)
1083 { 1098 {
1084 gint sent_len; 1099 gint sent_len;
1085 1100
1086 #if 1 1101 #if 1
1087 /* qq_show_packet("qq_send_cmd_encrypted", data, data_len); */ 1102 /* qq_show_packet("qq_send_cmd_encrypted", data, data_len); */
1088 purple_debug_info("QQ", "<== [%05d], %s(0x%04X), datalen %d\n", 1103 purple_debug_info("QQ", "<== [%05d], %s(0x%04X), datalen %d\n",
1089 seq, qq_get_cmd_desc(cmd), cmd, encrypted_len); 1104 seq, qq_get_cmd_desc(cmd), cmd, encrypted_len);
1090 #endif 1105 #endif
1091 1106
1092 sent_len = packet_send_out(gc, cmd, seq, encrypted_data, encrypted_len); 1107 sent_len = packet_send_out(gc, cmd, seq, encrypted, encrypted_len);
1093 if (is_save2trans) { 1108 if (is_save2trans) {
1094 qq_trans_add_client_cmd(gc, cmd, seq, encrypted_data, encrypted_len, 0, 0); 1109 qq_trans_add_client_cmd(gc, cmd, seq, encrypted, encrypted_len, 0, 0);
1095 } 1110 }
1096 return sent_len; 1111 return sent_len;
1097 } 1112 }
1098 1113
1099 /* Encrypt data with session_key, and send packet out */ 1114 /* Encrypt data with session_key, and send packet out */
1100 static gint send_cmd_detail(PurpleConnection *gc, guint16 cmd, guint16 seq, 1115 static gint send_cmd_detail(PurpleConnection *gc, guint16 cmd, guint16 seq,
1101 guint8 *data, gint data_len, gboolean is_save2trans, gint update_class, guint32 ship32) 1116 guint8 *data, gint data_len, gboolean is_save2trans, gint update_class, guint32 ship32)
1102 { 1117 {
1103 qq_data *qd; 1118 qq_data *qd;
1104 guint8 *encrypted_data; 1119 guint8 *encrypted;
1105 gint encrypted_len; 1120 gint encrypted_len;
1106 gint bytes_sent; 1121 gint bytes_sent;
1107 1122
1108 g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1); 1123 g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1);
1109 qd = (qq_data *)gc->proto_data; 1124 qd = (qq_data *)gc->proto_data;
1110 g_return_val_if_fail(data != NULL && data_len > 0, -1); 1125 g_return_val_if_fail(data != NULL && data_len > 0, -1);
1111 1126
1112 /* at most 16 bytes more */ 1127 /* at most 16 bytes more */
1113 encrypted_data = g_newa(guint8, data_len + 16); 1128 encrypted = g_newa(guint8, data_len + 16);
1114 encrypted_len = qq_encrypt(encrypted_data, data, data_len, qd->session_key); 1129 encrypted_len = qq_encrypt(encrypted, data, data_len, qd->session_key);
1115 if (encrypted_len < 16) { 1130 if (encrypted_len < 16) {
1116 purple_debug_error("QQ_ENCRYPT", "Error len %d: [%05d] 0x%04X %s\n", 1131 purple_debug_error("QQ_ENCRYPT", "Error len %d: [%05d] 0x%04X %s\n",
1117 encrypted_len, seq, cmd, qq_get_cmd_desc(cmd)); 1132 encrypted_len, seq, cmd, qq_get_cmd_desc(cmd));
1118 return -1; 1133 return -1;
1119 } 1134 }
1120 1135
1121 bytes_sent = packet_send_out(gc, cmd, seq, encrypted_data, encrypted_len); 1136 bytes_sent = packet_send_out(gc, cmd, seq, encrypted, encrypted_len);
1122 1137
1123 if (is_save2trans) { 1138 if (is_save2trans) {
1124 qq_trans_add_client_cmd(gc, cmd, seq, encrypted_data, encrypted_len, 1139 qq_trans_add_client_cmd(gc, cmd, seq, encrypted, encrypted_len,
1125 update_class, ship32); 1140 update_class, ship32);
1126 } 1141 }
1127 return bytes_sent; 1142 return bytes_sent;
1128 } 1143 }
1129 1144
1172 1187
1173 /* set seq and is_save2trans, then call send_cmd_detail */ 1188 /* set seq and is_save2trans, then call send_cmd_detail */
1174 gint qq_send_server_reply(PurpleConnection *gc, guint16 cmd, guint16 seq, guint8 *data, gint data_len) 1189 gint qq_send_server_reply(PurpleConnection *gc, guint16 cmd, guint16 seq, guint8 *data, gint data_len)
1175 { 1190 {
1176 qq_data *qd; 1191 qq_data *qd;
1177 guint8 *encrypted_data; 1192 guint8 *encrypted;
1178 gint encrypted_len; 1193 gint encrypted_len;
1179 gint bytes_sent; 1194 gint bytes_sent;
1180 1195
1181 g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1); 1196 g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1);
1182 qd = (qq_data *)gc->proto_data; 1197 qd = (qq_data *)gc->proto_data;
1185 #if 1 1200 #if 1
1186 purple_debug_info("QQ", "<== [SRV-%05d], %s(0x%04X), datalen %d\n", 1201 purple_debug_info("QQ", "<== [SRV-%05d], %s(0x%04X), datalen %d\n",
1187 seq, qq_get_cmd_desc(cmd), cmd, data_len); 1202 seq, qq_get_cmd_desc(cmd), cmd, data_len);
1188 #endif 1203 #endif
1189 /* at most 16 bytes more */ 1204 /* at most 16 bytes more */
1190 encrypted_data = g_newa(guint8, data_len + 16); 1205 encrypted = g_newa(guint8, data_len + 16);
1191 encrypted_len = qq_encrypt(encrypted_data, data, data_len, qd->session_key); 1206 encrypted_len = qq_encrypt(encrypted, data, data_len, qd->session_key);
1192 if (encrypted_len < 16) { 1207 if (encrypted_len < 16) {
1193 purple_debug_error("QQ_ENCRYPT", "Error len %d: [%05d] 0x%04X %s\n", 1208 purple_debug_error("QQ_ENCRYPT", "Error len %d: [%05d] 0x%04X %s\n",
1194 encrypted_len, seq, cmd, qq_get_cmd_desc(cmd)); 1209 encrypted_len, seq, cmd, qq_get_cmd_desc(cmd));
1195 return -1; 1210 return -1;
1196 } 1211 }
1197 1212
1198 bytes_sent = packet_send_out(gc, cmd, seq, encrypted_data, encrypted_len); 1213 bytes_sent = packet_send_out(gc, cmd, seq, encrypted, encrypted_len);
1199 qq_trans_add_server_reply(gc, cmd, seq, encrypted_data, encrypted_len); 1214 qq_trans_add_server_reply(gc, cmd, seq, encrypted, encrypted_len);
1200 1215
1201 return bytes_sent; 1216 return bytes_sent;
1202 } 1217 }
1203 1218
1204 static gint send_room_cmd(PurpleConnection *gc, guint8 room_cmd, guint32 room_id, 1219 static gint send_room_cmd(PurpleConnection *gc, guint8 room_cmd, guint32 room_id,
1205 guint8 *data, gint data_len, gint update_class, guint32 ship32) 1220 guint8 *data, gint data_len, gint update_class, guint32 ship32)
1206 { 1221 {
1207 qq_data *qd; 1222 qq_data *qd;
1208 guint8 *buf; 1223 guint8 *buf;
1209 gint buf_len; 1224 gint buf_len;
1210 guint8 *encrypted_data; 1225 guint8 *encrypted;
1211 gint encrypted_len; 1226 gint encrypted_len;
1212 gint bytes_sent; 1227 gint bytes_sent;
1213 guint16 seq; 1228 guint16 seq;
1214 1229
1215 g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1); 1230 g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1);
1230 } 1245 }
1231 1246
1232 qd->send_seq++; 1247 qd->send_seq++;
1233 seq = qd->send_seq; 1248 seq = qd->send_seq;
1234 1249
1235 /* Encrypt to encrypted_data with session_key */ 1250 /* Encrypt to encrypted with session_key */
1236 /* at most 16 bytes more */ 1251 /* at most 16 bytes more */
1237 encrypted_data = g_newa(guint8, buf_len + 16); 1252 encrypted = g_newa(guint8, buf_len + 16);
1238 encrypted_len = qq_encrypt(encrypted_data, buf, buf_len, qd->session_key); 1253 encrypted_len = qq_encrypt(encrypted, buf, buf_len, qd->session_key);
1239 if (encrypted_len < 16) { 1254 if (encrypted_len < 16) {
1240 purple_debug_error("QQ_ENCRYPT", "Error len %d: [%05d] %s (0x%02X)\n", 1255 purple_debug_error("QQ_ENCRYPT", "Error len %d: [%05d] %s (0x%02X)\n",
1241 encrypted_len, seq, qq_get_room_cmd_desc(room_cmd), room_cmd); 1256 encrypted_len, seq, qq_get_room_cmd_desc(room_cmd), room_cmd);
1242 return -1; 1257 return -1;
1243 } 1258 }
1244 1259
1245 bytes_sent = packet_send_out(gc, QQ_CMD_ROOM, seq, encrypted_data, encrypted_len); 1260 bytes_sent = packet_send_out(gc, QQ_CMD_ROOM, seq, encrypted, encrypted_len);
1246 #if 1 1261 #if 1
1247 /* qq_show_packet("send_room_cmd", buf, buf_len); */ 1262 /* qq_show_packet("send_room_cmd", buf, buf_len); */
1248 purple_debug_info("QQ", 1263 purple_debug_info("QQ",
1249 "<== [%05d], %s (0x%02X) to room %d, datalen %d\n", 1264 "<== [%05d], %s (0x%02X) to room %d, datalen %d\n",
1250 seq, qq_get_room_cmd_desc(room_cmd), room_cmd, room_id, buf_len); 1265 seq, qq_get_room_cmd_desc(room_cmd), room_cmd, room_id, buf_len);
1251 #endif 1266 #endif
1252 1267
1253 qq_trans_add_room_cmd(gc, seq, room_cmd, room_id, encrypted_data, encrypted_len, 1268 qq_trans_add_room_cmd(gc, seq, room_cmd, room_id, encrypted, encrypted_len,
1254 update_class, ship32); 1269 update_class, ship32);
1255 return bytes_sent; 1270 return bytes_sent;
1256 } 1271 }
1257 1272
1258 gint qq_send_room_cmd_mess(PurpleConnection *gc, guint8 room_cmd, guint32 room_id, 1273 gint qq_send_room_cmd_mess(PurpleConnection *gc, guint8 room_cmd, guint32 room_id,
1259 guint8 *data, gint data_len, gint update_class, guint32 ship32) 1274 guint8 *data, gint data_len, gint update_class, guint32 ship32)
1260 { 1275 {
1276 g_return_val_if_fail(room_id > 0, -1);
1261 return send_room_cmd(gc, room_cmd, room_id, data, data_len, update_class, ship32); 1277 return send_room_cmd(gc, room_cmd, room_id, data, data_len, update_class, ship32);
1262 } 1278 }
1263 1279
1264 gint qq_send_room_cmd(PurpleConnection *gc, guint8 room_cmd, guint32 room_id, 1280 gint qq_send_room_cmd(PurpleConnection *gc, guint8 room_cmd, guint32 room_id,
1265 guint8 *data, gint data_len) 1281 guint8 *data, gint data_len)