# HG changeset patch # User SHiNE CsyFeK # Date 1234194554 0 # Node ID 7f903e67a99518b050308ad560b7204548182e15 # Parent cddd7961901f5f81e245829ebdc868396f8acd96 2009.02.09 - Chengming Wang * Added buddy 'get memo', 'remove memo', 'upload memo' functions diff -r cddd7961901f -r 7f903e67a995 libpurple/protocols/qq/AUTHORS --- 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 ========= diff -r cddd7961901f -r 7f903e67a995 libpurple/protocols/qq/ChangeLog --- 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 + * Added buddy 'get memo', 'remove memo', 'upload memo' functions + 2009.02.08 - flos * Fixed showing message of chat room when message comes in diff -r cddd7961901f -r 7f903e67a995 libpurple/protocols/qq/Makefile.am --- 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 \ diff -r cddd7961901f -r 7f903e67a995 libpurple/protocols/qq/buddy_list.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) { diff -r cddd7961901f -r 7f903e67a995 libpurple/protocols/qq/buddy_memo.c --- /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 +#include +#include + + +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; indexmemo[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; indexmemo[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; indexproto_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; kmemo[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; kmemo == 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 + +#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 */ + diff -r cddd7961901f -r 7f903e67a995 libpurple/protocols/qq/char_conv.c --- 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); +} + diff -r cddd7961901f -r 7f903e67a995 libpurple/protocols/qq/char_conv.h --- 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 diff -r cddd7961901f -r 7f903e67a995 libpurple/protocols/qq/qq.c --- 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)) { diff -r cddd7961901f -r 7f903e67a995 libpurple/protocols/qq/qq.h --- 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 */ }; diff -r cddd7961901f -r 7f903e67a995 libpurple/protocols/qq/qq_define.c --- 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"; } diff -r cddd7961901f -r 7f903e67a995 libpurple/protocols/qq/qq_define.h --- 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 diff -r cddd7961901f -r 7f903e67a995 libpurple/protocols/qq/qq_process.c --- 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;