changeset 25515:7f903e67a995

2009.02.09 - Chengming Wang <tiger2007532246(at)gmail.com> * Added buddy 'get memo', 'remove memo', 'upload memo' functions
author SHiNE CsyFeK <csyfek@gmail.com>
date Mon, 09 Feb 2009 15:49:14 +0000
parents cddd7961901f
children 8bc9f89f305e
files libpurple/protocols/qq/AUTHORS libpurple/protocols/qq/ChangeLog libpurple/protocols/qq/Makefile.am libpurple/protocols/qq/buddy_list.c libpurple/protocols/qq/buddy_memo.c libpurple/protocols/qq/buddy_memo.h libpurple/protocols/qq/char_conv.c libpurple/protocols/qq/char_conv.h libpurple/protocols/qq/qq.c libpurple/protocols/qq/qq.h libpurple/protocols/qq/qq_define.c libpurple/protocols/qq/qq_define.h libpurple/protocols/qq/qq_process.c
diffstat 13 files changed, 447 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/qq/AUTHORS	Sun Feb 08 10:34:31 2009 +0000
+++ b/libpurple/protocols/qq/AUTHORS	Mon Feb 09 15:49:14 2009 +0000
@@ -23,6 +23,8 @@
 Coly Li		: qun processing
 Emil Alexiev	: captcha verification on login based on LumaQQ for MAC (2007), 
 		  login, add buddy, remove buddy, message exchange and logout
+Chengming Wang 	: buddy memo
+lonicerae 	: chat room window bugfix, server list bugfix
 
 Acknowledgement
 =========
--- a/libpurple/protocols/qq/ChangeLog	Sun Feb 08 10:34:31 2009 +0000
+++ b/libpurple/protocols/qq/ChangeLog	Mon Feb 09 15:49:14 2009 +0000
@@ -1,3 +1,6 @@
+2009.02.09 - Chengming Wang <tiger2007532246(at)gmail.com>
+	* Added buddy 'get memo', 'remove memo', 'upload memo' functions
+
 2009.02.08 - flos <lonicerae(at)gmail.com>
 	* Fixed showing message of chat room when message comes in
 
--- a/libpurple/protocols/qq/Makefile.am	Sun Feb 08 10:34:31 2009 +0000
+++ b/libpurple/protocols/qq/Makefile.am	Mon Feb 09 15:49:14 2009 +0000
@@ -6,6 +6,8 @@
 QQSOURCES = \
 	buddy_info.c \
 	buddy_info.h \
+	buddy_memo.c \
+	buddy_memo.h \
 	buddy_list.c \
 	buddy_list.h \
 	buddy_opt.c \
--- a/libpurple/protocols/qq/buddy_list.c	Sun Feb 08 10:34:31 2009 +0000
+++ b/libpurple/protocols/qq/buddy_list.c	Mon Feb 09 15:49:14 2009 +0000
@@ -31,6 +31,7 @@
 #include "utils.h"
 #include "packet_parse.h"
 #include "buddy_info.h"
+#include "buddy_memo.h"
 #include "buddy_list.h"
 #include "buddy_opt.h"
 #include "char_conv.h"
@@ -346,6 +347,7 @@
 		/* nickname has been copy to buddy_data do not free
 		   g_free(bd.nickname);
 		*/
+		qq_request_buddy_memo_download( gc,((qq_buddy_data*)buddy->proto_data)->uid );
 	}
 
 	if(bytes > data_len) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/qq/buddy_memo.c	Mon Feb 09 15:49:14 2009 +0000
@@ -0,0 +1,317 @@
+
+#include "buddy_memo.h"
+#include "internal.h"
+#include "debug.h"
+#include "notify.h"
+#include "request.h"
+
+#include "utils.h"
+#include "packet_parse.h"
+#include "buddy_list.h"
+#include "buddy_info.h"
+#include "char_conv.h"
+#include "im.h"
+#include "qq_define.h"
+#include "qq_base.h"
+#include "qq_network.h"
+#include "../../blist.h"
+
+
+#include<string.h>
+#include<stdlib.h>
+#include<stdio.h>
+
+
+static const gchar* buddy_memo_txt[] = {
+	"Name",
+	"Mobile",
+	"Telephone",
+	"Address",
+	"Email",
+	"ZipCode",
+	"Note"
+};/* 备注信息的名称 */
+
+
+/** 
+ * 打印出好友备注信息
+ * 
+ * @param memo 
+ */
+static void buddy_memo_debug( gchar* memo[] );
+
+/** 
+ * 好友备注对话框中上传按钮的响应函数
+ * 
+ * @param info_request 
+ * @param fields 
+ */
+static void buddy_memo_on_upload(void *info_request, PurpleRequestFields *fields);
+
+
+static gchar** buddy_memo_init_data(  );
+
+
+
+/** 
+ * 弹出窗口显示好友备注信息
+ * 
+ * @param node 
+ * @param buddy_data 
+ */
+static void qq_show_buddy_memo( void* node, void* buddy_data );
+
+
+
+
+
+/** 
+ * 向服务器发送更新好友信息请求
+ * 
+ * @param gc 
+ * @param buddy_data 
+ */
+static void qq_request_buddy_memo_upload( PurpleBuddy * buddy );
+
+
+
+/*********************************************************************************************/
+
+
+
+
+
+void buddy_memo_on_upload(void *bd, PurpleRequestFields *fields)
+{
+	int index;
+	PurpleBuddy *buddy;
+	qq_buddy_data* buddy_data;
+	int memoChanged;
+	const char *utf8_str;
+	buddy = ( PurpleBuddy* )bd;
+	buddy_data = ( qq_buddy_data* )( buddy->proto_data );
+	
+	
+	purple_debug_info("QQ", "update memo\n");
+	memoChanged = 0;
+	for( index=0; index<QQ_BUDDY_MEMO_SIZE; index++ ){
+		utf8_str = purple_request_fields_get_string(fields, buddy_memo_txt[index]);
+		if( utf8_str == NULL ){
+			if( buddy_data->memo[index] != NULL ){
+				g_free( buddy_data->memo[index] );
+				memoChanged = 1;
+			}
+			buddy_data->memo[index] = g_new0( gchar,1 );
+		}
+		else if( buddy_data->memo[index] == NULL ||
+			strcmp( utf8_str, buddy_data->memo[index] ) != 0 )
+		{
+			if( buddy_data->memo[index] != NULL )
+				g_free( buddy_data->memo[index] );
+			buddy_data->memo[index] = g_new( gchar,strlen(utf8_str)+2 );
+			strcpy( buddy_data->memo[index], utf8_str );
+			memoChanged = 1;
+			purple_debug_info( "QQ","%s=%s\n",buddy_memo_txt[index],utf8_str );
+		}
+
+	}
+	if( memoChanged == 1 ){
+		qq_request_buddy_memo_upload( buddy );
+		purple_blist_alias_buddy( buddy,buddy_data->memo[QQ_BUDDY_MEMO_NAME] );
+	}
+	return;
+}
+
+void qq_request_buddy_memo_upload( PurpleBuddy * buddy )
+{
+	PurpleConnection* gc;
+	qq_buddy_data* buddy_data;
+	guint8* rawData;
+	guint8* pos;
+	int rawDataSize;
+	int index;
+	int memoItemSize[QQ_BUDDY_MEMO_SIZE];
+	gchar* qqCharSetTxt[QQ_BUDDY_MEMO_SIZE];
+
+	gc = buddy->account->gc;
+	buddy_data = ( qq_buddy_data* )buddy->proto_data;
+	purple_debug_info( "QQ","call qq_request_buddy_memo_download_upload\n" );
+	rawDataSize = 7;
+	for( index=0; index<QQ_BUDDY_MEMO_SIZE; index++ ){
+		qqCharSetTxt[index] = utf8_to_qq( buddy_data->memo[index], QQ_CHARSET_DEFAULT );
+		memoItemSize[index] = strlen( qqCharSetTxt[index] );
+		rawDataSize += memoItemSize[index]+1;
+	}
+	rawData = g_new0( guint8,rawDataSize );
+	pos = rawData;
+	(*pos) = QQ_BUDDY_MEMO_UPLOAD;
+	pos += 2;
+	(*(guint32*)pos) = htonl( buddy_data->uid );
+	pos += 5;
+	for( index=0; index<QQ_BUDDY_MEMO_SIZE; index++ ){
+		(*pos) = 0xff&memoItemSize[index];
+		pos++;
+		memcpy( pos, qqCharSetTxt[index], memoItemSize[index] );
+		pos += memoItemSize[index];
+	}
+
+	qq_send_cmd( gc, QQ_CMD_BUDDY_MEMO, rawData, rawDataSize );
+	for( index=0; index<QQ_BUDDY_MEMO_SIZE; index++ ){
+		g_free( qqCharSetTxt[index] );
+	}
+}
+
+
+
+void qq_request_buddy_memo_download(PurpleConnection *gc, guint32 uid)
+{
+	gchar raw_data[16] = {0};
+	unsigned int tmp;
+	purple_debug_info("QQ", "Call qq_request_buddy_memo_download! qq number =%u\n", uid);
+	g_return_if_fail(uid != 0);
+	raw_data[0] = QQ_BUDDY_MEMO_GET;
+
+	tmp = htonl((unsigned int)uid);
+	memcpy(raw_data+1, &tmp, 4);
+	
+	qq_send_cmd(gc, QQ_CMD_BUDDY_MEMO, (guint8*)raw_data, 5);
+}
+
+
+void qq_process_get_buddy_memo( PurpleConnection *gc, guint8* data, gint len )
+{
+	qq_data *qd;
+	//_buddy_memo memo;
+	PurpleBuddy *buddy;
+	gchar *who;
+	qq_buddy_data* bd;
+	guint8* pos;
+	gint lenth;
+	guint32 qq_number;
+	int k;
+
+	pos = data;
+	switch( *pos ){
+	    case QQ_BUDDY_MEMO_UPLOAD :
+    	case QQ_BUDDY_MEMO_REMOVE :
+			if( data[1] == QQ_BUDDY_MEMO_REQUEST_SUCCESS ){//显示服务器接受请求对话框
+				//TODO:
+				purple_debug_info( "QQ","服务器接受了请求\n" );
+				purple_notify_message( gc,
+									   PURPLE_NOTIFY_MSG_INFO,
+									   _( "Your request was accepted" ),
+									   _( "Your request was accepted" ),
+									   _( "Your request was accepted" ),
+									   NULL,
+									   NULL);
+			}
+			break;
+	    case QQ_BUDDY_MEMO_GET:
+			qd = (qq_data *) gc->proto_data;
+			pos++;
+			qq_number = ntohl( *(uint32_t*)pos ); 
+			pos += 5;//qq号后面有一个字节不知道什么作用
+			who = uid_to_purple_name( qq_number );
+			buddy = purple_find_buddy( gc->account, who );
+			if (buddy == NULL || buddy->proto_data == NULL) {
+				g_free(who);
+				purple_debug_info("QQ", "Error Can not find %d!\n", qq_number);
+				return;
+			}
+			bd = (qq_buddy_data *)buddy->proto_data;
+			
+			if( bd->memo == NULL ){
+				bd->memo = g_new0( gchar*,QQ_BUDDY_MEMO_SIZE );
+			}
+			for( k=0; k<QQ_BUDDY_MEMO_SIZE; k++ ){
+				lenth = pos[0];
+				pos++;
+				if( bd->memo[k] != NULL )
+					g_free( bd->memo[k] );
+				bd->memo[k] = qq_to_utf8_len( (gchar*)pos, lenth, QQ_CHARSET_DEFAULT );
+				pos += lenth;
+			}
+			buddy_memo_debug( bd->memo );
+			purple_blist_alias_buddy( buddy,
+									  (const char*)bd->memo[QQ_BUDDY_MEMO_NAME] );//改名
+			break;
+	default:
+			purple_debug_info( "QQ","error: unknown memo cmd\n" );
+	        break;
+	}
+	
+	
+}
+
+void buddy_memo_debug( gchar* memo[] )
+{
+	gint k=0;
+	for( k=0; k<QQ_BUDDY_MEMO_SIZE; k++ ){
+		purple_debug_info( "QQ","备注: %s=%s\n",buddy_memo_txt[k],memo[k] );
+	}
+}
+
+void qq_show_buddy_memo( void* node, void* buddy_data )
+{
+	qq_buddy_data* data;
+	PurpleRequestField *field;
+	PurpleRequestFields *fields;
+	PurpleRequestFieldGroup *group;
+	int index;
+	
+	data = ( qq_buddy_data* )buddy_data;
+	
+	fields = purple_request_fields_new();
+	group = purple_request_field_group_new(NULL);
+	purple_request_fields_add_group(fields, group);
+
+	for( index=0; index<QQ_BUDDY_MEMO_SIZE; index++ ){
+		if( data->memo == NULL ){
+			data->memo = buddy_memo_init_data(  );
+		}
+		field = purple_request_field_string_new(buddy_memo_txt[index],
+												buddy_memo_txt[index],
+												data->memo[index],
+												FALSE);
+		purple_request_field_group_add_field(group, field);	
+	}
+	
+	purple_request_fields(node,
+						  _( "Buddy_memo" ),
+						  "",
+						  NULL,
+						  fields,
+						  _("_Upload"), G_CALLBACK(buddy_memo_on_upload),
+						  _("_Cancel"), NULL,
+						  ((PurpleBuddy *)node)->account, ((PurpleBuddy *)node)->name, NULL,
+						  node);
+}
+
+
+
+void qq_on_show_memo(PurpleBlistNode *node, gpointer data)
+{
+
+	PurpleBuddy *buddy;
+
+	g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+
+	buddy = (PurpleBuddy *) node;
+
+	qq_show_buddy_memo( node, buddy->proto_data );
+
+	
+	purple_debug_info( "QQ","show memo" );
+}
+
+
+static gchar** buddy_memo_init_data(  )
+{
+	gchar** pmemo;
+	int index;
+	pmemo = g_new0( gchar*,QQ_BUDDY_MEMO_SIZE );
+	for( index=0; index<QQ_BUDDY_MEMO_SIZE; index++ ){
+		pmemo[index] = g_new0( gchar,1 );
+	}
+	return pmemo;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/qq/buddy_memo.h	Mon Feb 09 15:49:14 2009 +0000
@@ -0,0 +1,80 @@
+
+#ifndef _BUDDY_MEMO_H
+#define _BUDDY_MEMO_H 
+
+#include <glib.h>
+
+#include "connection.h"
+#include "buddy_opt.h"
+#include "qq.h"
+
+
+
+#include "internal.h"
+#include "debug.h"
+#include "notify.h"
+#include "request.h"
+#include "utils.h"
+#include "packet_parse.h"
+#include "buddy_list.h"
+#include "buddy_info.h"
+#include "char_conv.h"
+#include "im.h"
+#include "qq_define.h"
+#include "qq_base.h"
+#include "qq_network.h"
+#include "../../blist.h"
+
+
+
+
+
+enum {
+	QQ_BUDDY_MEMO_NAME = 0,
+	QQ_BUDDY_MEMO_MOBILD,
+	QQ_BUDDY_MEMO_TELEPHONE,
+	QQ_BUDDY_MEMO_ADDRESS,
+	QQ_BUDDY_MEMO_EMAIL,
+	QQ_BUDDY_MEMO_ZIPCODE,
+	QQ_BUDDY_MEMO_NOTE,
+	QQ_BUDDY_MEMO_SIZE
+};
+
+
+
+
+
+
+/** 
+ * 向服务器发送下载好友备注信息的请求
+ * 
+ * @param gc 
+ * @param uid 好友qq号码
+ */
+void qq_request_buddy_memo_download(PurpleConnection *gc, guint32 uid);
+
+
+
+
+
+/** 
+ * 处理服务器对好友备注信息的响应
+ * 
+ * @param gc 
+ * @param data 解密后的数据
+ * @param len data数据长度
+ */
+void qq_process_get_buddy_memo( PurpleConnection *gc, guint8* data, gint len );
+
+
+/** 
+ * 在好友列表项上右键菜单中显示好友信息的响应函数
+ * 
+ * @param node 
+ * @param data 
+ */
+void qq_on_show_memo(PurpleBlistNode *node, gpointer data);
+
+
+#endif /* _BUDDY_MEMO_H */
+
--- a/libpurple/protocols/qq/char_conv.c	Sun Feb 08 10:34:31 2009 +0000
+++ b/libpurple/protocols/qq/char_conv.c	Mon Feb 09 15:49:14 2009 +0000
@@ -111,3 +111,14 @@
 	return do_convert(str, -1, UTF8, from_charset);
 }
 
+
+
+gchar *utf8_to_qq_len(const gchar *str, const gint len, const gchar *to_charset)
+{
+	return do_convert(str, len, to_charset, UTF8);
+}
+gchar *qq_to_utf8_len(const gchar *str, const gint len, const gchar *from_charset)
+{
+	return do_convert(str, len, UTF8, from_charset);
+}
+
--- a/libpurple/protocols/qq/char_conv.h	Sun Feb 08 10:34:31 2009 +0000
+++ b/libpurple/protocols/qq/char_conv.h	Mon Feb 09 15:49:14 2009 +0000
@@ -35,4 +35,7 @@
 gchar *utf8_to_qq(const gchar *str, const gchar *to_charset);
 gchar *qq_to_utf8(const gchar *str, const gchar *from_charset);
 
+gchar *utf8_to_qq_len(const gchar *str, const gint len, const gchar *to_charset);
+gchar *qq_to_utf8_len(const gchar *str, const gint len, const gchar *from_charset);
+
 #endif
--- a/libpurple/protocols/qq/qq.c	Sun Feb 08 10:34:31 2009 +0000
+++ b/libpurple/protocols/qq/qq.c	Mon Feb 09 15:49:14 2009 +0000
@@ -36,6 +36,7 @@
 #include "util.h"
 
 #include "buddy_info.h"
+#include "buddy_memo.h"
 #include "buddy_opt.h"
 #include "buddy_list.h"
 #include "char_conv.h"
@@ -826,6 +827,11 @@
 
 	}
 
+
+	act = purple_menu_action_new(_("Buddy memo"), PURPLE_CALLBACK(qq_on_show_memo), NULL, NULL); /* add NULL by gfhuang */
+	m = g_list_append(m, act);
+
+	
 /* TODO : not working, temp commented out by gfhuang */
 #if 0
 	if (bd && is_online(bd->status)) {
--- a/libpurple/protocols/qq/qq.h	Sun Feb 08 10:34:31 2009 +0000
+++ b/libpurple/protocols/qq/qq.h	Mon Feb 09 15:49:14 2009 +0000
@@ -98,6 +98,7 @@
 	time_t signon;
 	time_t idle;
 	time_t last_update;
+	gchar** memo;
 
 	gint8  role;		/* role in group, used only in group->members list */
 };
--- a/libpurple/protocols/qq/qq_define.c	Sun Feb 08 10:34:31 2009 +0000
+++ b/libpurple/protocols/qq/qq_define.c	Mon Feb 09 15:49:14 2009 +0000
@@ -189,6 +189,8 @@
 		return "CMD_BUDDY_CHECK_CODE";
 	case QQ_CMD_BUDDY_QUESTION:
 		return "CMD_BUDDY_QUESTION";
+	case QQ_CMD_BUDDY_MEMO:
+		return "CMD_BUDDY_MEMO";
 	default:
 		return "CMD_UNKNOW";
 	}
--- a/libpurple/protocols/qq/qq_define.h	Sun Feb 08 10:34:31 2009 +0000
+++ b/libpurple/protocols/qq/qq_define.h	Mon Feb 09 15:49:14 2009 +0000
@@ -66,7 +66,9 @@
 	QQ_CMD_TOKEN  = 0x0062, 		/* get login token */
 	QQ_CMD_RECV_MSG_SYS = 0x0080,			/* receive a system message */
 	QQ_CMD_BUDDY_CHANGE_STATUS = 0x0081,	/* buddy change status */
-	/* for QQ2007*/
+	QQ_CMD_BUDDY_MEMO = 0x003E,    /* the message about buddy memo */
+
+    /* for QQ2007*/
 	QQ_CMD_GET_SERVER = 0x0091,					/* select login server */
 	QQ_CMD_TOKEN_EX = 0x00BA,						/* get LOGIN token */
 	QQ_CMD_CHECK_PWD = 0x00DD,				/* Password verify */
@@ -131,6 +133,16 @@
 	QQ_BUDDY_ONLINE_BUSY = 50
 };
 
+
+enum //好友备注相关         
+{   
+	QQ_BUDDY_MEMO_UPLOAD = 0x01,   // 上传好友备注
+	QQ_BUDDY_MEMO_REMOVE,          // 清除好友备注
+	QQ_BUDDY_MEMO_GET              // 获取好友备注
+};
+
+#define QQ_BUDDY_MEMO_REQUEST_SUCCESS 0x00
+
 gboolean is_online(guint8 status);
 
 #endif
--- a/libpurple/protocols/qq/qq_process.c	Sun Feb 08 10:34:31 2009 +0000
+++ b/libpurple/protocols/qq/qq_process.c	Mon Feb 09 15:49:14 2009 +0000
@@ -47,6 +47,7 @@
 #include "qq_network.h"
 #include "qq_trans.h"
 #include "utils.h"
+#include "buddy_memo.h"
 
 enum {
 	QQ_ROOM_CMD_REPLY_OK = 0x00,
@@ -1142,6 +1143,10 @@
 		case QQ_CMD_BUDDY_CHECK_CODE:
 			qq_process_buddy_check_code(gc, data, data_len);
 			break;
+    	case QQ_CMD_BUDDY_MEMO:
+			purple_debug_info("QQ", "Receive memo from server!\n");
+			qq_process_get_buddy_memo( gc, data, data_len );
+			break;
 		default:
 			process_unknow_cmd(gc, _("Unknown CLIENT CMD"), data, data_len, cmd, seq);
 			is_unknow = TRUE;