diff libpurple/protocols/qq/im.c @ 24088:147ada94a1d8

2008.08.16 - ccpaging <ecc_hy(at)hotmail.com> * Rename group to room. If you used pidginqq before, this may create a new room with same title, you may delete old one * Replace purple_debug with purple_debug_info, purple_debug_warning, purple_debug_error * Add server notice and server new, and two options to turn on/off * Minor modify for reducing transaction's debug infor * Minor modifies for system notice and QQ news. * Add 4 new strings need translate compare with p10.
author SHiNE CsyFeK <csyfek@gmail.com>
date Thu, 11 Sep 2008 13:25:07 +0000
parents 5f454b975a99
children 23cec4360d4a 25f62d21b3f8
line wrap: on
line diff
--- a/libpurple/protocols/qq/im.c	Thu Sep 11 04:19:37 2008 +0000
+++ b/libpurple/protocols/qq/im.c	Thu Sep 11 13:25:07 2008 +0000
@@ -209,21 +209,17 @@
 			return "QQ_RECV_IM_TEMP_QUN_IM";
 		case QQ_RECV_IM_QUN_IM:
 			return "QQ_RECV_IM_QUN_IM";
+		case QQ_RECV_IM_NEWS:
+			return "QQ_RECV_IM_NEWS";
+		case QQ_RECV_IM_FROM_BUDDY_2006:
+			return "QQ_RECV_IM_FROM_BUDDY_2006";
+		case QQ_RECV_IM_FROM_UNKNOWN_2006:
+			return "QQ_RECV_IM_FROM_UNKNOWN_2006";
 		default:
 			return "QQ_RECV_IM_UNKNOWN";
 	}
 }
 
-/* when we receive a message,
- * we send an ACK which is the first 16 bytes of incoming packet */
-static void _qq_send_packet_recv_im_ack(PurpleConnection *gc, guint16 seq, guint8 *data)
-{
-	qq_data *qd;
-
-	qd = (qq_data *) gc->proto_data;
-	qq_send_cmd_detail(qd, QQ_CMD_RECV_IM, seq, FALSE, data, 16);
-}
-
 /* read the common parts of the normal_im,
  * returns the bytes read if succeed, or -1 if there is any error */
 static gint _qq_normal_im_common_read(guint8 *data, gint len, qq_recv_normal_im_common *common)
@@ -240,13 +236,61 @@
 	bytes += qq_get16(&(common->normal_im_type), data + bytes);
 
 	if (bytes != 28) {	/* read common place fail */
-		purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Expect 28 bytes, read %d bytes\n", bytes);
+		purple_debug_error("QQ", "Expect 28 bytes, read %d bytes\n", bytes);
 		return -1;
 	}
 
 	return bytes;
 }
 
+static void _qq_process_recv_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 *content, *content_utf8;
+
+	g_return_if_fail(data != NULL && data_len != 0);
+
+#if 0
+	qq_show_packet("Rcv news", data, data_len);
+#endif
+
+	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);
+
+	content = g_strdup_printf(_("Title: %s\nBrief: %s\n\n%s"), title, brief, url);
+	content_utf8 = qq_to_utf8(content, QQ_CHARSET_DEFAULT);
+
+	if (qd->is_show_news) {
+		purple_notify_info(gc, NULL, _("QQ Server News"), content_utf8);
+	} else {
+		purple_debug_info("QQ", "QQ Server news:\n%s", content_utf8);
+	}
+	g_free(title);
+	g_free(brief);
+	g_free(url);
+	g_free(content);
+	g_free(content_utf8);
+}
+
 /* process received normal text IM */
 static void _qq_process_recv_normal_im_text(guint8 *data, gint len, qq_recv_normal_im_common *common, PurpleConnection *gc)
 {
@@ -266,7 +310,7 @@
 	/* now it is QQ_NORMAL_IM_TEXT */
 	/*
 	   if (*cursor >= (data + len - 1)) {
-	   purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Received normal IM text is empty\n");
+	   purple_debug_warning("QQ", "Received normal IM text is empty\n");
 	   return;
 	   } else
 	   */
@@ -313,9 +357,9 @@
 	}
 	qq_b = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;
 	if (qq_b != NULL) {
-		qq_b->client_version = common->sender_ver; 
+		qq_b->client_version = common->sender_ver;
 	}
-	
+
 	purple_msg_type = (im_text->msg_type == QQ_IM_AUTO_REPLY) ? PURPLE_MESSAGE_AUTO_RESP : 0;
 
 	msg_with_purple_smiley = qq_smiley_to_purple(im_text->msg);
@@ -350,19 +394,18 @@
 
 	bytes = _qq_normal_im_common_read(data, len, common);
 	if (bytes < 0) {
-		purple_debug (PURPLE_DEBUG_ERROR, "QQ",
-				"Fail read the common part of normal IM\n");
+		purple_debug_error("QQ", "Fail read the common part of normal IM\n");
 		return;
 	}
 
 	switch (common->normal_im_type) {
 		case QQ_NORMAL_IM_TEXT:
-			purple_debug (PURPLE_DEBUG_INFO, "QQ",
+			purple_debug_info("QQ",
 					"Normal IM, text type:\n [%d] => [%d], src: %s (%04X)\n",
 					common->sender_uid, common->receiver_uid,
 					qq_get_ver_desc (common->sender_ver), common->sender_ver);
 			if (bytes >= len - 1) {
-				purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Received normal IM text is empty\n");
+				purple_debug_warning("QQ", "Received normal IM text is empty\n");
 				return;
 			}
 			_qq_process_recv_normal_im_text(data + bytes, len - bytes, common, gc);
@@ -382,16 +425,50 @@
 		case QQ_NORMAL_IM_FILE_NOTIFY:
 			qq_process_recv_file_notify(data + bytes, len - bytes, common->sender_uid, gc);
 			break;
+		case QQ_NORMAL_IM_FILE_REQUEST_TCP:
+			/* Check ReceivedFileIM::parseContents in eva*/
+			/* some client use this function for detect invisable buddy*/
+			purple_debug_warning("QQ", "Normal IM, not support QQ_NORMAL_IM_FILE_REQUEST_TCP\n");
+			qq_show_packet ("Not support", data, len);
+			break;
+		case QQ_NORMAL_IM_FILE_APPROVE_TCP:
+			purple_debug_warning("QQ", "Normal IM, not support QQ_NORMAL_IM_FILE_APPROVE_TCP\n");
+			qq_show_packet ("Not support", data, len);
+			break;
+		case QQ_NORMAL_IM_FILE_REJECT_TCP:
+			purple_debug_warning("QQ", "Normal IM, not support QQ_NORMAL_IM_FILE_REJECT_TCP\n");
+			qq_show_packet ("Not support", data, len);
+			break;
+		case QQ_NORMAL_IM_FILE_PASV:
+			purple_debug_warning("QQ", "Normal IM, not support QQ_NORMAL_IM_FILE_PASV\n");
+			qq_show_packet ("Not support", data, len);
+			break;
+		case QQ_NORMAL_IM_FILE_EX_REQUEST_UDP:
+			purple_debug_warning("QQ", "Normal IM, not support QQ_NORMAL_IM_FILE_REQUEST_TCP\n");
+			qq_show_packet ("QQ", data, len);
+			break;
+		case QQ_NORMAL_IM_FILE_EX_REQUEST_ACCEPT:
+			purple_debug_warning("QQ", "Normal IM, not support QQ_NORMAL_IM_FILE_EX_REQUEST_ACCEPT\n");
+			qq_show_packet ("QQ", data, len);
+			break;
+		case QQ_NORMAL_IM_FILE_EX_REQUEST_CANCEL:
+			purple_debug_warning("QQ", "Normal IM, not support QQ_NORMAL_IM_FILE_EX_REQUEST_CANCEL\n");
+			qq_show_packet ("Not support", data, len);
+			break;
+		case QQ_NORMAL_IM_FILE_EX_NOTIFY_IP:
+			purple_debug_warning("QQ", "Normal IM, not support QQ_NORMAL_IM_FILE_EX_NOTIFY_IP\n");
+			qq_show_packet ("Not support", data, len);
+			break;
 		default:
 			im_unprocessed = g_newa (qq_recv_normal_im_unprocessed, 1);
 			im_unprocessed->common = common;
 			im_unprocessed->unknown = data + bytes;
 			im_unprocessed->length = len - bytes;
 			/* a simple process here, maybe more later */
-			purple_debug (PURPLE_DEBUG_WARNING, "QQ",
+			purple_debug_warning("QQ",
 					"Normal IM, unprocessed type [0x%04x], len %d\n",
 					common->normal_im_type, im_unprocessed->length);
-			qq_show_packet ("QQ unk-im", im_unprocessed->unknown, im_unprocessed->length);
+			qq_show_packet ("QQ", im_unprocessed->unknown, im_unprocessed->length);
 			return;
 	}
 }
@@ -412,7 +489,7 @@
 
 	reply = strtol(segments[0], NULL, 10);
 	if (reply == QQ_RECV_SYS_IM_KICK_OUT)
-		purple_debug(PURPLE_DEBUG_WARNING, "QQ", "We are kicked out by QQ server\n");
+		purple_debug_warning("QQ", "We are kicked out by QQ server\n");
 	msg_utf8 = qq_to_utf8(segments[1], QQ_CHARSET_DEFAULT);
 	purple_notify_warning(gc, NULL, _("System Message"), msg_utf8);
 }
@@ -475,7 +552,7 @@
 		g_datalist_clear(&attribs);
 	}
 
-	purple_debug(PURPLE_DEBUG_INFO, "QQ_MESG", "send mesg: %s\n", msg);
+	purple_debug_info("QQ_MESG", "send mesg: %s\n", msg);
 	msg_filtered = purple_markup_strip_html(msg);
 	msg_len = strlen(msg_filtered);
 	now = time(NULL);
@@ -526,9 +603,9 @@
 	qq_show_packet("QQ_raw_data debug", raw_data, bytes);
 
 	if (bytes == raw_len)	/* create packet OK */
-		qq_send_cmd(qd, QQ_CMD_SEND_IM, raw_data, bytes);
+		qq_send_cmd(gc, QQ_CMD_SEND_IM, raw_data, bytes);
 	else
-		purple_debug(PURPLE_DEBUG_ERROR, "QQ",
+		purple_debug_error("QQ",
 				"Fail creating send_im packet, expect %d bytes, build %d bytes\n", raw_len, bytes);
 
 	if (font_color)
@@ -549,10 +626,10 @@
 	qd = gc->proto_data;
 
 	if (data[0] != QQ_SEND_IM_REPLY_OK) {
-		purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Send IM fail\n");
+		purple_debug_warning("QQ", "Send IM fail\n");
 		purple_notify_error(gc, _("Error"), _("Failed to send IM."), NULL);
 	}	else {
-		purple_debug(PURPLE_DEBUG_INFO, "QQ", "IM ACK OK\n");
+		purple_debug_info("QQ", "IM ACK OK\n");
 	}
 }
 
@@ -569,16 +646,17 @@
 	qd = (qq_data *) gc->proto_data;
 
 	if (data_len < 16) {	/* we need to ack with the first 16 bytes */
-		purple_debug(PURPLE_DEBUG_ERROR, "QQ", "IM is too short\n");
+		purple_debug_error("QQ", "MSG is too short\n");
 		return;
 	} else {
-		_qq_send_packet_recv_im_ack(gc, seq, data);
+		/* 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(PURPLE_DEBUG_ERROR, "QQ",
-				"Fail read recv IM header, len should longer than 20 bytes, read %d bytes\n", data_len);
+		purple_debug_error("QQ", "Invald MSG header, len %d < 20\n", data_len);
 		return;
 	}
 
@@ -594,77 +672,71 @@
 	/* im_header prepared */
 
 	if (im_header->receiver_uid != qd->uid) {	/* should not happen */
-		purple_debug(PURPLE_DEBUG_ERROR, "QQ", "IM to [%d], NOT me\n", im_header->receiver_uid);
+		purple_debug_error("QQ", "MSG to [%d], NOT me\n", im_header->receiver_uid);
 		return;
 	}
 
 	/* check bytes */
 	if (bytes >= data_len - 1) {
-		purple_debug (PURPLE_DEBUG_WARNING, "QQ", "Received IM is empty\n");
+		purple_debug_warning("QQ", "Empty MSG\n");
 		return;
 	}
 
 	switch (im_header->im_type) {
+		case QQ_RECV_IM_NEWS:
+			_qq_process_recv_news(data + bytes, data_len - bytes, gc);
+			break;
+		case QQ_RECV_IM_FROM_BUDDY_2006:
+		case QQ_RECV_IM_FROM_UNKNOWN_2006:
+		case QQ_RECV_IM_TO_UNKNOWN:
 		case QQ_RECV_IM_TO_BUDDY:
-			purple_debug(PURPLE_DEBUG_INFO, "QQ",
-					"IM from buddy [%d], I am in his/her buddy list\n", im_header->sender_uid);
-			_qq_process_recv_normal_im(data + bytes, data_len - bytes, gc); /* position and rest length */
-			break;
-		case QQ_RECV_IM_TO_UNKNOWN:
-			purple_debug(PURPLE_DEBUG_INFO, "QQ",
-					"IM from buddy [%d], I am a stranger to him/her\n", im_header->sender_uid);
+			purple_debug_info("QQ", "MSG from buddy [%d]\n", im_header->sender_uid);
 			_qq_process_recv_normal_im(data + bytes, data_len - bytes, gc);
 			break;
 		case QQ_RECV_IM_UNKNOWN_QUN_IM:
 		case QQ_RECV_IM_TEMP_QUN_IM:
 		case QQ_RECV_IM_QUN_IM:
-			purple_debug(PURPLE_DEBUG_INFO, "QQ", "IM from group, internal_id [%d]\n", im_header->sender_uid);
+			purple_debug_info("QQ", "MSG from room [%d]\n", im_header->sender_uid);
 			/* sender_uid is in fact id */
-			qq_process_recv_group_im(data + bytes, data_len - bytes, im_header->sender_uid, gc, im_header->im_type);
+			qq_process_room_msg_normal(data + bytes, data_len - bytes, im_header->sender_uid, gc, im_header->im_type);
 			break;
 		case QQ_RECV_IM_ADD_TO_QUN:
-			purple_debug(PURPLE_DEBUG_INFO, "QQ",
-					"IM from group, added by group internal_id [%d]\n", im_header->sender_uid);
+			purple_debug_info("QQ", "Notice from [%d], Added\n", im_header->sender_uid);
 			/* sender_uid is group id
 			 * we need this to create a dummy group and add to blist */
-			qq_process_recv_group_im_been_added(data + bytes, data_len - bytes, im_header->sender_uid, gc);
+			qq_process_room_msg_been_added(data + bytes, data_len - bytes, im_header->sender_uid, gc);
 			break;
 		case QQ_RECV_IM_DEL_FROM_QUN:
-			purple_debug(PURPLE_DEBUG_INFO, "QQ",
-					"IM from group, removed by group internal_ID [%d]\n", im_header->sender_uid);
+			purple_debug_info("QQ", "Notice from room [%d], Removed\n", im_header->sender_uid);
 			/* sender_uid is group id */
-			qq_process_recv_group_im_been_removed(data + bytes, data_len - bytes, im_header->sender_uid, gc);
+			qq_process_room_msg_been_removed(data + bytes, data_len - bytes, im_header->sender_uid, gc);
 			break;
 		case QQ_RECV_IM_APPLY_ADD_TO_QUN:
-			purple_debug(PURPLE_DEBUG_INFO, "QQ",
-					"IM from group, apply to join group internal_ID [%d]\n", im_header->sender_uid);
+			purple_debug_info("QQ", "Notice from room [%d], Joined\n", im_header->sender_uid);
 			/* sender_uid is group id */
-			qq_process_recv_group_im_apply_join(data + bytes, data_len - bytes, im_header->sender_uid, gc);
+			qq_process_room_msg_apply_join(data + bytes, data_len - bytes, im_header->sender_uid, gc);
 			break;
 		case QQ_RECV_IM_APPROVE_APPLY_ADD_TO_QUN:
-			purple_debug(PURPLE_DEBUG_INFO, "QQ",
-					"IM for group system info, approved by group internal_id [%d]\n",
+			purple_debug_info("QQ", "Notice from room [%d], Confirm add in\n",
 					im_header->sender_uid);
 			/* sender_uid is group id */
-			qq_process_recv_group_im_been_approved(data + bytes, data_len - bytes, im_header->sender_uid, gc);
+			qq_process_room_msg_been_approved(data + bytes, data_len - bytes, im_header->sender_uid, gc);
 			break;
 		case QQ_RECV_IM_REJCT_APPLY_ADD_TO_QUN:
-			purple_debug(PURPLE_DEBUG_INFO, "QQ",
-					"IM for group system info, rejected by group internal_id [%d]\n",
+			purple_debug_info("QQ", "Notice from room [%d], Refuse add in\n",
 					im_header->sender_uid);
 			/* sender_uid is group id */
-			qq_process_recv_group_im_been_rejected(data + bytes, data_len - bytes, im_header->sender_uid, gc);
+			qq_process_room_msg_been_rejected(data + bytes, data_len - bytes, im_header->sender_uid, gc);
 			break;
 		case QQ_RECV_IM_SYS_NOTIFICATION:
-			purple_debug(PURPLE_DEBUG_INFO, "QQ",
-					"IM from [%d], should be a system administrator\n", im_header->sender_uid);
+			purple_debug_info("QQ", "Admin notice from [%d]\n", im_header->sender_uid);
 			_qq_process_recv_sys_im(data + bytes, data_len - bytes, gc);
 			break;
 		default:
-			purple_debug(PURPLE_DEBUG_WARNING, "QQ",
-					"IM from [%d], [0x%02x] %s is not processed\n",
-					im_header->sender_uid,
-					im_header->im_type, qq_get_recv_im_type_str(im_header->im_type));
+			purple_debug_warning("QQ", "MSG from [%d], unknown type %s [0x%02x]\n",
+					im_header->sender_uid, qq_get_recv_im_type_str(im_header->im_type),
+					im_header->im_type);
+			qq_show_packet("Unknown MSG type", data, data_len);
 	}
 }