⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 im.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	else		common = g_newa (qq_recv_normal_im_common, 1);	bytes = _qq_normal_im_common_read (data, cursor, len, common);	if (bytes < 0) {		purple_debug (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",			    "Normal IM, text type:\n [%d] => [%d], src: %s\n",			    common->sender_uid, common->receiver_uid,			    qq_get_source_str (common->sender_ver));		_qq_process_recv_normal_im_text (data, cursor, len, common,						 gc);		break;	case QQ_NORMAL_IM_FILE_REJECT_UDP:		qq_process_recv_file_reject (data, cursor, len,					     common->sender_uid, gc);		break;	case QQ_NORMAL_IM_FILE_APPROVE_UDP:		qq_process_recv_file_accept (data, cursor, len,					     common->sender_uid, gc);		break;	case QQ_NORMAL_IM_FILE_REQUEST_UDP:		qq_process_recv_file_request (data, cursor, len,					      common->sender_uid, gc);		break;	case QQ_NORMAL_IM_FILE_CANCEL:		qq_process_recv_file_cancel (data, cursor, len,					     common->sender_uid, gc);		break;	case QQ_NORMAL_IM_FILE_NOTIFY:		qq_process_recv_file_notify (data, cursor, len,				common->sender_uid, gc);		break;	default:		im_unprocessed = g_newa (qq_recv_normal_im_unprocessed, 1);		im_unprocessed->common = common;		im_unprocessed->unknown = *cursor;		im_unprocessed->length = data + len - *cursor;		/* a simple process here, maybe more later */		purple_debug (PURPLE_DEBUG_WARNING, "QQ",			    "Normal IM, unprocessed type [0x%04x]\n",			    common->normal_im_type);	       	hex_dump = hex_dump_to_str(im_unprocessed->unknown, im_unprocessed->length);		purple_debug (PURPLE_DEBUG_WARNING, "QQ", "Dump unknown part.\n%s", hex_dump);		g_free(hex_dump);		g_free (common->session_md5);		return;	}	g_free (common->session_md5);}/* process im from system administrator */static void _qq_process_recv_sys_im(guint8 *data, guint8 **cursor, gint data_len, PurpleConnection *gc){	gint len;	guint8 reply;	gchar **segments, *msg_utf8;	g_return_if_fail(data != NULL && data_len != 0);	if (*cursor >= (data + data_len - 1)) {		purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Received sys IM is empty\n");		return;	}	len = data + data_len - *cursor;	if (NULL == (segments = split_data(*cursor, len, "\x2f", 2)))		return;	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");	msg_utf8 = qq_to_utf8(segments[1], QQ_CHARSET_DEFAULT);	purple_notify_warning(gc, NULL, _("System Message"), msg_utf8);}/* send an IM to to_uid */void qq_send_packet_im(PurpleConnection *gc, guint32 to_uid, gchar *msg, gint type){	qq_data *qd;	guint8 *cursor, *raw_data, *send_im_tail;	guint16 client_tag, normal_im_type;	gint msg_len, raw_len, font_name_len, tail_len, bytes;	time_t now;	gchar *msg_filtered;	GData *attribs;	gchar *font_size = NULL, *font_color = NULL, *font_name = NULL, *tmp;	gboolean is_bold = FALSE, is_italic = FALSE, is_underline = FALSE;	const gchar *start, *end, *last;	qd = (qq_data *) gc->proto_data;	client_tag = QQ_CLIENT;	normal_im_type = QQ_NORMAL_IM_TEXT;	last = msg;	while (purple_markup_find_tag("font", last, &start, &end, &attribs)) {		tmp = g_datalist_get_data(&attribs, "size");		if (tmp) {			if (font_size)				g_free(font_size);			font_size = g_strdup(tmp);		}		tmp = g_datalist_get_data(&attribs, "color");		if (tmp) {			if (font_color)				g_free(font_color);			font_color = g_strdup(tmp);		}		tmp = g_datalist_get_data(&attribs, "face");		if (tmp) {			if (font_name)				g_free(font_name);			font_name = g_strdup(tmp);		}		g_datalist_clear(&attribs);		last = end + 1;	}	if (purple_markup_find_tag("b", msg, &start, &end, &attribs)) {		is_bold = TRUE;		g_datalist_clear(&attribs);	}	if (purple_markup_find_tag("i", msg, &start, &end, &attribs)) {		is_italic = TRUE;		g_datalist_clear(&attribs);	}	if (purple_markup_find_tag("u", msg, &start, &end, &attribs)) {		is_underline = TRUE;		g_datalist_clear(&attribs);	}	purple_debug(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);	font_name_len = (font_name) ? strlen(font_name) : DEFAULT_FONT_NAME_LEN;	tail_len = font_name_len + QQ_SEND_IM_AFTER_MSG_HEADER_LEN + 1;	raw_len = QQ_SEND_IM_BEFORE_MSG_LEN + msg_len + tail_len;	raw_data = g_newa(guint8, raw_len);	cursor = raw_data;	bytes = 0;	/* 000-003: receiver uid */	bytes += create_packet_dw(raw_data, &cursor, qd->uid);	/* 004-007: sender uid */	bytes += create_packet_dw(raw_data, &cursor, to_uid);	/* 008-009: sender client version */	bytes += create_packet_w(raw_data, &cursor, client_tag);	/* 010-013: receiver uid */	bytes += create_packet_dw(raw_data, &cursor, qd->uid);	/* 014-017: sender uid */	bytes += create_packet_dw(raw_data, &cursor, to_uid);	/* 018-033: md5 of (uid+session_key) */	bytes += create_packet_data(raw_data, &cursor, qd->session_md5, 16);	/* 034-035: message type */	bytes += create_packet_w(raw_data, &cursor, normal_im_type);	/* 036-037: sequence number */	bytes += create_packet_w(raw_data, &cursor, qd->send_seq);	/* 038-041: send time */	bytes += create_packet_dw(raw_data, &cursor, (guint32) now);	/* 042-043: sender icon */	bytes += create_packet_w(raw_data, &cursor, qd->my_icon);	/* 044-046: always 0x00 */	bytes += create_packet_w(raw_data, &cursor, 0x0000);	bytes += create_packet_b(raw_data, &cursor, 0x00);	/* 047-047: we use font attr */	bytes += create_packet_b(raw_data, &cursor, 0x01);	/* 048-051: always 0x00 */	bytes += create_packet_dw(raw_data, &cursor, 0x00000000);	/* 052-052: text message type (normal/auto-reply) */	bytes += create_packet_b(raw_data, &cursor, type);	/* 053-   : msg ends with 0x00 */	bytes += create_packet_data(raw_data, &cursor, (guint8 *) msg_filtered, msg_len);	send_im_tail = qq_get_send_im_tail(font_color, font_size, font_name, is_bold,						   is_italic, is_underline, tail_len);	_qq_show_packet("QQ_MESG debug", send_im_tail, tail_len);	bytes += create_packet_data(raw_data, &cursor, send_im_tail, tail_len);	_qq_show_packet("QQ_MESG raw", raw_data, cursor - raw_data);	if (bytes == raw_len)	/* create packet OK */		qq_send_cmd(gc, QQ_CMD_SEND_IM, TRUE, 0, TRUE, raw_data, cursor - raw_data);	else		purple_debug(PURPLE_DEBUG_ERROR, "QQ",			   "Fail creating send_im packet, expect %d bytes, build %d bytes\n", raw_len, bytes);	if (font_color)		g_free(font_color);	if (font_size)		g_free(font_size);	g_free(send_im_tail);	g_free(msg_filtered);}/* parse the reply to send_im */void qq_process_send_im_reply(guint8 *buf, gint buf_len, PurpleConnection *gc){	qq_data *qd;	gint len;	guint8 *data, *cursor, reply;	g_return_if_fail(buf != NULL && buf_len != 0);	qd = gc->proto_data;	len = buf_len;	data = g_newa(guint8, len);	if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) {		cursor = data;		read_packet_b(data, &cursor, len, &reply);		if (reply != QQ_SEND_IM_REPLY_OK) {			purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Send IM fail\n");			purple_notify_error(gc, _("Server ACK"), _("Send IM fail\n"), NULL);		}		else			purple_debug(PURPLE_DEBUG_INFO, "QQ", "IM ACK OK\n");	} else {		purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Error decrypt send im reply\n");	}}/* I receive a message, mainly it is text msg, * but we need to proess other types (group etc) */void qq_process_recv_im(guint8 *buf, gint buf_len, guint16 seq, PurpleConnection *gc){	qq_data *qd;	gint len, bytes;	guint8 *data, *cursor;	qq_recv_im_header *im_header;	g_return_if_fail(buf != NULL && buf_len != 0);	qd = (qq_data *) gc->proto_data;	len = buf_len;	data = g_newa(guint8, len);	if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) {		if (len < 16) {	/* we need to ack with the first 16 bytes */			purple_debug(PURPLE_DEBUG_ERROR, "QQ", "IM is too short\n");			return;		} else			_qq_send_packet_recv_im_ack(gc, seq, data);		cursor = data;		bytes = 0;		im_header = g_newa(qq_recv_im_header, 1);		bytes += read_packet_dw(data, &cursor, len, &(im_header->sender_uid));		bytes += read_packet_dw(data, &cursor, len, &(im_header->receiver_uid));		bytes += read_packet_dw(data, &cursor, len, &(im_header->server_im_seq));		/* if the message is delivered via server, it is server IP/port */		bytes += read_packet_data(data, &cursor, len, (guint8 *) & (im_header->sender_ip), 4);		bytes += read_packet_w(data, &cursor, len, &(im_header->sender_port));		bytes += read_packet_w(data, &cursor, len, &(im_header->im_type));		if (bytes != 20) {	/* length of im_header */			purple_debug(PURPLE_DEBUG_ERROR, "QQ",				   "Fail read recv IM header, expect 20 bytes, read %d bytes\n", bytes);			return;		}		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);			return;		}		switch (im_header->im_type) {		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, &cursor, len, gc);			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);			_qq_process_recv_normal_im(data, &cursor, len, 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);			/* sender_uid is in fact internal_group_id */			qq_process_recv_group_im(data, &cursor, len, 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);			/* sender_uid is in fact internal_group_id			 * we need this to create a dummy group and add to blist */			qq_process_recv_group_im_been_added(data, &cursor, len, 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);			/* sender_uid is in fact internal_group_id */			qq_process_recv_group_im_been_removed(data, &cursor, len, 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);			/* sender_uid is in fact internal_group_id */			qq_process_recv_group_im_apply_join(data, &cursor, len, 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",				   im_header->sender_uid);			/* sender_uid is in fact internal_group_id */			qq_process_recv_group_im_been_approved(data, &cursor, len, 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",				   im_header->sender_uid);			/* sender_uid is in fact internal_group_id */			qq_process_recv_group_im_been_rejected(data, &cursor, len, 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);			_qq_process_recv_sys_im(data, &cursor, len, 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));		}	} else {		purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Error decrypt rev im\n");	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -