diff libpurple/protocols/qq/qq_process.c @ 24145:ec3f7d3e0445

2008.10.04 - lonicerae <lonicerae(at)gmail.com> * fixed a bug in qq_base.c
author SHiNE CsyFeK <csyfek@gmail.com>
date Wed, 22 Oct 2008 14:49:38 +0000
parents a95c7e71064c
children ce94189f15ad
line wrap: on
line diff
--- a/libpurple/protocols/qq/qq_process.c	Wed Oct 22 14:48:46 2008 +0000
+++ b/libpurple/protocols/qq/qq_process.c	Wed Oct 22 14:49:38 2008 +0000
@@ -58,7 +58,7 @@
 };
 
 /* default process, decrypt and dump */
-static void process_unknow_cmd(PurpleConnection *gc,const gchar *title, guint8 *data, gint data_len, guint16 cmd, guint16 seq)
+static void process_cmd_unknow(PurpleConnection *gc,const gchar *title, guint8 *data, gint data_len, guint16 cmd, guint16 seq)
 {
 	qq_data *qd;
 	gchar *msg_utf8 = NULL;
@@ -81,285 +81,8 @@
 	}
 }
 
-/* parse the reply to send_im */
-static void do_im_ack(guint8 *data, gint data_len, PurpleConnection *gc)
-{
-	qq_data *qd;
-
-	g_return_if_fail(data != NULL && data_len != 0);
-
-	qd = gc->proto_data;
-
-	if (data[0] != 0) {
-		purple_debug_warning("QQ", "Failed sent IM\n");
-		purple_notify_error(gc, _("Error"), _("Failed to send IM."), NULL);
-		return;
-	}
-
-	purple_debug_info("QQ", "OK sent IM\n");
-}
-
-static void do_server_news(guint8 *data, gint data_len, PurpleConnection *gc)
-{
-	qq_data *qd = (qq_data *) gc->proto_data;
-	gint bytes;
-	guint8 *temp;
-	guint8 temp_len;
-	gchar *title, *brief, *url;
-	gchar *title_utf8;
-	gchar *content, *content_utf8;
-
-	g_return_if_fail(data != NULL && data_len != 0);
-
-	/* qq_show_packet("Rcv news", data, data_len); */
-
-	temp = g_newa(guint8, data_len);
-	bytes = 4;	/* ignore unknown 4 bytes */
-
-	bytes += qq_get8(&temp_len, data + bytes);
-	g_return_if_fail(bytes + temp_len <= data_len);
-	bytes += qq_getdata(temp, temp_len, data+bytes);
-	title = g_strndup((gchar *)temp, temp_len);
-
-	bytes += qq_get8(&temp_len, data + bytes);
-	g_return_if_fail(bytes + temp_len <= data_len);
-	bytes += qq_getdata(temp, temp_len, data+bytes);
-	brief = g_strndup((gchar *)temp, temp_len);
-
-	bytes += qq_get8(&temp_len, data + bytes);
-	g_return_if_fail(bytes + temp_len <= data_len);
-	bytes += qq_getdata(temp, temp_len, data+bytes);
-	url = g_strndup((gchar *)temp, temp_len);
-
-	title_utf8 = qq_to_utf8(title, QQ_CHARSET_DEFAULT);
-	content = g_strdup_printf(_("Server News:\n%s\n%s\n%s"), title, brief, url);
-	content_utf8 = qq_to_utf8(content, QQ_CHARSET_DEFAULT);
-
-	if (qd->is_show_news) {
-		qq_got_attention(gc, content_utf8);
-	} else {
-		purple_debug_info("QQ", "QQ Server news:\n%s\n%s", title_utf8, content_utf8);
-	}
-	g_free(title);
-	g_free(title_utf8);
-	g_free(brief);
-	g_free(url);
-	g_free(content);
-	g_free(content_utf8);
-}
-
-static void do_msg_sys_30(PurpleConnection *gc, guint8 *data, gint data_len)
-{
-	gint len;
-	guint8 reply;
-	gchar **segments, *msg_utf8;
-
-	g_return_if_fail(data != NULL && data_len != 0);
-
-	len = data_len;
-
-	if (NULL == (segments = split_data(data, len, "\x2f", 2)))
-		return;
-
-	reply = strtol(segments[0], NULL, 10);
-	if (reply == 1)
-		purple_debug_warning("QQ", "We are kicked out by QQ server\n");
-
-	msg_utf8 = qq_to_utf8(segments[1], QQ_CHARSET_DEFAULT);
-	qq_got_attention(gc, msg_utf8);
-}
-
-static void do_msg_sys_4c(PurpleConnection *gc, guint8 *data, gint data_len)
-{
-	gint bytes;
-	gint msg_len;
-	GString *content;
-	gchar *msg = NULL;
-
-	g_return_if_fail(data != NULL && data_len > 0);
-
-	bytes = 6; /* skip 0x(06 00 01 1e 01 1c)*/
-
-	content = g_string_new("");
-	while (bytes < data_len) {
-		msg_len = qq_get_vstr(&msg, QQ_CHARSET_DEFAULT, data + bytes);
-		g_string_append(content, msg);
-		g_string_append(content, "\n");
-		g_free(msg);
-
-		if (msg_len <= 1) {
-			break;
-		}
-		bytes += msg_len;
-	}
-	if (bytes != data_len) {
-		purple_debug_warning("QQ", "Failed to read QQ_MSG_SYS_4C\n");
-		qq_show_packet("do_msg_sys_4c", data, data_len);
-	}
-	qq_got_attention(gc, content->str);
-	g_string_free(content, FALSE);
-}
-
-static const gchar *get_im_type_desc(gint type)
-{
-	switch (type) {
-		case QQ_MSG_TO_BUDDY:
-			return "QQ_MSG_TO_BUDDY";
-		case QQ_MSG_TO_UNKNOWN:
-			return "QQ_MSG_TO_UNKNOWN";
-		case QQ_MSG_UNKNOWN_QUN_IM:
-			return "QQ_MSG_UNKNOWN_QUN_IM";
-		case QQ_MSG_ADD_TO_QUN:
-			return "QQ_MSG_ADD_TO_QUN";
-		case QQ_MSG_DEL_FROM_QUN:
-			return "QQ_MSG_DEL_FROM_QUN";
-		case QQ_MSG_APPLY_ADD_TO_QUN:
-			return "QQ_MSG_APPLY_ADD_TO_QUN";
-		case QQ_MSG_CREATE_QUN:
-			return "QQ_MSG_CREATE_QUN";
-		case QQ_MSG_SYS_30:
-			return "QQ_MSG_SYS_30";
-		case QQ_MSG_SYS_4C:
-			return "QQ_MSG_SYS_4C";
-		case QQ_MSG_APPROVE_APPLY_ADD_TO_QUN:
-			return "QQ_MSG_APPROVE_APPLY_ADD_TO_QUN";
-		case QQ_MSG_REJCT_APPLY_ADD_TO_QUN:
-			return "QQ_MSG_REJCT_APPLY_ADD_TO_QUN";
-		case QQ_MSG_TEMP_QUN_IM:
-			return "QQ_MSG_TEMP_QUN_IM";
-		case QQ_MSG_QUN_IM:
-			return "QQ_MSG_QUN_IM";
-		case QQ_MSG_NEWS:
-			return "QQ_MSG_NEWS";
-		case QQ_MSG_EXTEND:
-			return "QQ_MSG_EXTEND";
-		case QQ_MSG_EXTEND_85:
-			return "QQ_MSG_EXTEND_85";
-		default:
-			return "QQ_MSG_UNKNOWN";
-	}
-}
-
-/* I receive a message, mainly it is text msg,
- * but we need to proess other types (group etc) */
-static void process_private_msg(guint8 *data, gint data_len, guint16 seq, PurpleConnection *gc)
-{
-	qq_data *qd;
-	gint bytes;
-
-	struct {
-		guint32 uid_from;
-		guint32 uid_to;
-		guint32 seq;
-		struct in_addr ip_from;
-		guint16 port_from;
-		guint16 msg_type;
-	} header;
-
-	g_return_if_fail(data != NULL && data_len != 0);
-
-	qd = (qq_data *) gc->proto_data;
-
-	if (data_len < 16) {	/* we need to ack with the first 16 bytes */
-		purple_debug_error("QQ", "MSG is too short\n");
-		return;
-	} else {
-		/* when we receive a message,
-		 * we send an ACK which is the first 16 bytes of incoming packet */
-		qq_send_server_reply(gc, QQ_CMD_RECV_IM, seq, data, 16);
-	}
-
-	/* check len first */
-	if (data_len < 20) {	/* length of im_header */
-		purple_debug_error("QQ", "Invald MSG header, len %d < 20\n", data_len);
-		return;
-	}
-
-	bytes = 0;
-	bytes += qq_get32(&(header.uid_from), data + bytes);
-	bytes += qq_get32(&(header.uid_to), data + bytes);
-	bytes += qq_get32(&(header.seq), data + bytes);
-	/* if the message is delivered via server, it is server IP/port */
-	bytes += qq_getIP(&(header.ip_from), data + bytes);
-	bytes += qq_get16(&(header.port_from), data + bytes);
-	bytes += qq_get16(&(header.msg_type), data + bytes);
-	/* im_header prepared */
-
-	if (header.uid_to != qd->uid) {	/* should not happen */
-		purple_debug_error("QQ", "MSG to [%d], NOT me\n", header.uid_to);
-		return;
-	}
-
-	/* check bytes */
-	if (bytes >= data_len - 1) {
-		purple_debug_warning("QQ", "Empty MSG\n");
-		return;
-	}
-
-	switch (header.msg_type) {
-		case QQ_MSG_NEWS:
-			do_server_news(data + bytes, data_len - bytes, gc);
-			break;
-		case QQ_MSG_EXTEND:
-		case QQ_MSG_EXTEND_85:
-			purple_debug_info("QQ", "MSG from buddy [%d]\n", header.uid_from);
-			qq_process_extend_im(gc, data + bytes, data_len - bytes);
-			break;
-		case QQ_MSG_TO_UNKNOWN:
-		case QQ_MSG_TO_BUDDY:
-			purple_debug_info("QQ", "MSG from buddy [%d]\n", header.uid_from);
-			qq_process_im(gc, data + bytes, data_len - bytes);
-			break;
-		case QQ_MSG_UNKNOWN_QUN_IM:
-		case QQ_MSG_TEMP_QUN_IM:
-		case QQ_MSG_QUN_IM:
-			purple_debug_info("QQ", "MSG from room [%d]\n", header.uid_from);
-			qq_process_room_msg_normal(data + bytes, data_len - bytes, header.uid_from, gc, header.msg_type);
-			break;
-		case QQ_MSG_ADD_TO_QUN:
-			purple_debug_info("QQ", "Notice from [%d], Added\n", header.uid_from);
-			/* uid_from is group id
-			 * we need this to create a dummy group and add to blist */
-			qq_process_room_msg_been_added(data + bytes, data_len - bytes, header.uid_from, gc);
-			break;
-		case QQ_MSG_DEL_FROM_QUN:
-			purple_debug_info("QQ", "Notice from room [%d], Removed\n", header.uid_from);
-			/* uid_from is group id */
-			qq_process_room_msg_been_removed(data + bytes, data_len - bytes, header.uid_from, gc);
-			break;
-		case QQ_MSG_APPLY_ADD_TO_QUN:
-			purple_debug_info("QQ", "Notice from room [%d], Joined\n", header.uid_from);
-			/* uid_from is group id */
-			qq_process_room_msg_apply_join(data + bytes, data_len - bytes, header.uid_from, gc);
-			break;
-		case QQ_MSG_APPROVE_APPLY_ADD_TO_QUN:
-			purple_debug_info("QQ", "Notice from room [%d], Confirm add in\n",
-					header.uid_from);
-			/* uid_from is group id */
-			qq_process_room_msg_been_approved(data + bytes, data_len - bytes, header.uid_from, gc);
-			break;
-		case QQ_MSG_REJCT_APPLY_ADD_TO_QUN:
-			purple_debug_info("QQ", "Notice from room [%d], Refuse add in\n",
-					header.uid_from);
-			/* uid_from is group id */
-			qq_process_room_msg_been_rejected(data + bytes, data_len - bytes, header.uid_from, gc);
-			break;
-		case QQ_MSG_SYS_30:
-			do_msg_sys_30(gc, data + bytes, data_len - bytes);
-			break;
-		case QQ_MSG_SYS_4C:
-			do_msg_sys_4c(gc, data + bytes, data_len - bytes);
-			break;
-		default:
-			purple_debug_warning("QQ", "MSG from [%d], unknown type %s [0x%04X]\n",
-					header.uid_from, get_im_type_desc(header.msg_type), header.msg_type);
-			qq_show_packet("Unknown MSG type", data, data_len);
-			break;
-	}
-}
-
 /* Send ACK if the sys message needs an ACK */
-static void request_server_ack(PurpleConnection *gc, guint8 code, guint32 from, guint16 seq)
+static void ack_server_msg(PurpleConnection *gc, guint8 code, guint32 from, guint16 seq)
 {
 	qq_data *qd;
 	guint8 bar, *ack;
@@ -389,7 +112,7 @@
 			   "Fail creating sys msg ACK, expect %d bytes, build %d bytes\n", ack_len, bytes);
 }
 
-static void do_server_notice(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8)
+static void process_server_notice(PurpleConnection *gc, gchar *from, gchar *to, gchar *msg_utf8)
 {
 	qq_data *qd = (qq_data *) gc->proto_data;
 	gchar *title, *content;
@@ -425,7 +148,7 @@
 	to = segments[2];
 	msg = segments[3];
 
-	request_server_ack(gc, code[0], strtol(from, NULL, 10), seq);
+	ack_server_msg(gc, code[0], strtol(from, NULL, 10), seq);
 
 	if (strtol(to, NULL, 10) != qd->uid) {	/* not to me */
 		purple_debug_error("QQ", "Recv sys msg to [%s], not me!, discard\n", to);
@@ -450,7 +173,7 @@
 			qq_process_buddy_from_server(gc,  funct, from, to, msg_utf8);
 			break;
 		case QQ_SERVER_NOTICE:
-			do_server_notice(gc, from, to, msg_utf8);
+			process_server_notice(gc, from, to, msg_utf8);
 			break;
 		case QQ_SERVER_NEW_CLIENT:
 			purple_debug_warning("QQ", "QQ Server has newer client version\n");
@@ -493,7 +216,7 @@
 	/* now process the packet */
 	switch (cmd) {
 		case QQ_CMD_RECV_IM:
-			process_private_msg(data, data_len, seq, gc);
+			qq_process_recv_im(data, data_len, seq, gc);
 			break;
 		case QQ_CMD_RECV_MSG_SYS:
 			process_server_msg(data, data_len, seq, gc);
@@ -502,7 +225,7 @@
 			qq_process_buddy_change_status(data, data_len, gc);
 			break;
 		default:
-			process_unknow_cmd(gc, _("Unknow SERVER CMD"), data, data_len, cmd, seq);
+			process_cmd_unknow(gc, _("Unknow SERVER CMD"), data, data_len, cmd, seq);
 			break;
 	}
 }
@@ -898,16 +621,25 @@
 		case QQ_CMD_LOGIN:
 		default:
 			if (qd->client_version >= 2007) {
+				purple_debug_warning("QQ", "Decrypt login packet by pwd_twice_md5\n");
 				data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.pwd_twice_md5);
+
 				if (data_len >= 0) {
-					purple_debug_warning("QQ", "Decrypt login packet by pwd_twice_md5\n");
-				} else {
+					purple_debug_warning("QQ", "Dpwd_twice_md5 *OK*\n");
+				}
+				else {
+					purple_debug_warning("QQ", "Dpwd_twice_md5 *FAILED*, try login_key, last data_len=%d\n", data_len);
 					data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.login_key);
+
 					if (data_len >= 0) {
-						purple_debug_warning("QQ", "Decrypt login packet by login_key\n");
+						purple_debug_warning("QQ", "Dlogin_key *OK*\n");
+					}
+					else {
+						purple_debug_warning("QQ", "Dlogin_key *FAILED*\n");
 					}
 				}
-			} else {
+			}
+			else {
 				/* May use password_twice_md5 in the past version like QQ2005 */
 				data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.random_key);
 				if (data_len >= 0) {
@@ -933,6 +665,7 @@
 		return QQ_LOGIN_REPLY_ERR;
 	}
 
+	purple_debug_warning("QQ", "we are processing: 0x%02x\n", cmd);
 	switch (cmd) {
 		case QQ_CMD_GET_SERVER:
 			ret_8 = qq_process_get_server(gc, data, data_len);
@@ -958,7 +691,7 @@
 		case QQ_CMD_CHECK_PWD:
 			ret_8 = qq_process_check_pwd(gc, data, data_len);
 			if (ret_8 != QQ_LOGIN_REPLY_OK) {
-				return ret_8;
+				return  ret_8;
 			}
 			if (qd->client_version == 2008) {
 				qq_request_login_2008(gc);
@@ -975,7 +708,7 @@
 				ret_8 = qq_process_login(gc, data, data_len);
 			}
 			if (ret_8 != QQ_LOGIN_REPLY_OK) {
-				return ret_8;
+				return  ret_8;
 			}
 
 			purple_connection_update_progress(gc, _("Logined"), QQ_CONNECT_STEPS - 1, QQ_CONNECT_STEPS);
@@ -992,7 +725,8 @@
 			qq_update_all(gc, 0);
 			break;
 		default:
-			process_unknow_cmd(gc, _("Unknow LOGIN CMD"), data, data_len, cmd, seq);
+			purple_debug_warning("QQ", "UNKNOWN LOGIN CMD: %d\n", cmd);
+			process_cmd_unknow(gc, _("Unknow LOGIN CMD"), data, data_len, cmd, seq);
 			return QQ_LOGIN_REPLY_ERR;
 	}
 	return QQ_LOGIN_REPLY_OK;
@@ -1056,7 +790,7 @@
 			qq_process_change_status_reply(data, data_len, gc);
 			break;
 		case QQ_CMD_SEND_IM:
-			do_im_ack(data, data_len, gc);
+			qq_process_send_im_reply(data, data_len, gc);
 			break;
 		case QQ_CMD_KEEP_ALIVE:
 			if (qd->client_version >= 2008) {
@@ -1099,7 +833,7 @@
 			purple_debug_info("QQ", "All buddies and groups received\n");
 			break;
 		default:
-			process_unknow_cmd(gc, _("Unknow CLIENT CMD"), data, data_len, cmd, seq);
+			process_cmd_unknow(gc, _("Unknow CLIENT CMD"), data, data_len, cmd, seq);
 			is_unknow = TRUE;
 			break;
 	}