changeset 24085:237e5a94e11c

2008.10.08 - ccpaging <ccpaging(at)gmail.com> * Update group part * Delete some meaningless functions and data * Added 'change my icon' 2008.10.08 - lonicerae <lonicerae(at)gmail.com> * Merge 20081008 patch into trunk
author SHiNE CsyFeK <csyfek@gmail.com>
date Wed, 22 Oct 2008 15:08:30 +0000
parents 340fc40fe4ef
children 3c52353b83ae
files libpurple/protocols/qq/ChangeLog libpurple/protocols/qq/buddy_info.c libpurple/protocols/qq/buddy_info.h libpurple/protocols/qq/buddy_list.c libpurple/protocols/qq/buddy_list.h libpurple/protocols/qq/group.c libpurple/protocols/qq/group.h libpurple/protocols/qq/group_find.c libpurple/protocols/qq/group_find.h libpurple/protocols/qq/group_im.c libpurple/protocols/qq/group_im.h libpurple/protocols/qq/group_info.c libpurple/protocols/qq/group_info.h libpurple/protocols/qq/group_internal.c libpurple/protocols/qq/group_internal.h libpurple/protocols/qq/group_join.c libpurple/protocols/qq/group_search.c libpurple/protocols/qq/group_search.h libpurple/protocols/qq/qq.c libpurple/protocols/qq/qq.h libpurple/protocols/qq/qq_network.c libpurple/protocols/qq/qq_process.c libpurple/protocols/qq/utils.c libpurple/protocols/qq/utils.h
diffstat 24 files changed, 205 insertions(+), 297 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/qq/ChangeLog	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/ChangeLog	Wed Oct 22 15:08:30 2008 +0000
@@ -1,3 +1,8 @@
+2008.10.08 - ccpaging <ccpaging(at)gmail.com>
+	* Update group part
+	* Delete some meaningless functions and data
+	* Added 'change my icon'
+
 2008.10.08 - lonicerae <lonicerae(at)gmail.com>
 	* Update Makefile.mingw
 
--- a/libpurple/protocols/qq/buddy_info.c	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/buddy_info.c	Wed Oct 22 15:08:30 2008 +0000
@@ -75,6 +75,8 @@
 };
 
 #define QQ_FACES	    134
+#define QQ_ICON_PREFIX "qq_"
+#define QQ_ICON_SUFFIX ".png"
 
 enum {
 	QQ_INFO_UID = 0, QQ_INFO_NICK, QQ_INFO_COUNTRY, QQ_INFO_PROVINCE, QQ_INFO_ZIPCODE,
@@ -478,77 +480,42 @@
 	qq_request_buddy_info(gc, qd->uid, 0, QQ_BUDDY_INFO_SET_ICON);
 }
 
-/* return the location of the buddy icon dir
- * any application using libpurple but not installing the QQ buddy icons
- * under datadir needs to set the pref below, or buddy icons won't work */
-static const char *get_icon_dir(void)
-{
-	if (purple_prefs_exists("/plugins/prpl/qq/icon_dir"))
-		return purple_prefs_get_string("/plugins/prpl/qq/icon_dir");
-	else
-		return NULL;
-}
-
-/* TODO: custom faces for QQ members and users with level >= 16 */
-void qq_set_buddy_icon_old(PurpleConnection *gc, PurpleStoredImage *img)
+void qq_change_icon_cb(PurpleConnection *gc, const char *filepath)
 {
-	gchar *icon;
-	gint icon_num;
-	gint icon_len;
-	PurpleAccount *account = purple_connection_get_account(gc);
-	const gchar *icon_path = purple_account_get_buddy_icon_path(account);
-	const gchar *buddy_icon_dir = get_icon_dir();
-	gint prefix_len = strlen(QQ_ICON_PREFIX);
-	gint suffix_len = strlen(QQ_ICON_SUFFIX);
-	gint dir_len = buddy_icon_dir ? strlen(buddy_icon_dir) : 0;
-	gchar *errmsg = g_strdup_printf(_("Setting custom faces is not currently supported. Please choose an image from %s."), buddy_icon_dir ? buddy_icon_dir : "(null)");
-	gboolean icon_global = purple_account_get_bool(gc->account, "use-global-buddyicon", TRUE);
+	gchar **segments;
+	const gchar *filename;
+	gint index;
+	gint face;
 
-	gchar *icon_file_content;
-	gsize icon_file_size;
+	g_return_if_fail(filepath != NULL);
+
+	purple_debug_info("QQ", "Change my icon to %s\n", filepath);
+	segments = g_strsplit_set(filepath, G_DIR_SEPARATOR_S, 0);
 
-	if (!icon_path)
-		icon_path = "";
-
-	icon_len = strlen(icon_path) - dir_len - 1 - prefix_len - suffix_len;
+#if 0
+	for (index = 0; segments[index] != NULL; index++) {
+		purple_debug_info("QQ", "Split to %s\n", segments[index]);
+	}
+#endif
 
-	/* make sure we're using an appropriate icon */
-	if (buddy_icon_dir && !(g_ascii_strncasecmp(icon_path, buddy_icon_dir, dir_len) == 0
-				&& icon_path[dir_len] == G_DIR_SEPARATOR
-				&& g_ascii_strncasecmp(icon_path + dir_len + 1, QQ_ICON_PREFIX, prefix_len) == 0
-				&& g_ascii_strncasecmp(icon_path + dir_len + 1 + prefix_len + icon_len, QQ_ICON_SUFFIX, suffix_len) == 0
-				&& icon_len <= 3)) {
-		if (icon_global)
-			purple_debug_error("QQ", "%s\n", errmsg);
-		else
-			purple_notify_error(gc, _("Invalid QQ Face"), errmsg, NULL);
-		g_free(errmsg);
+	index = g_strv_length(segments) - 1;
+	if (index < 0) {
+		g_strfreev(segments);
 		return;
 	}
-	/* strip everything but number */
-	icon = g_strndup(icon_path + dir_len + 1 + prefix_len, icon_len);
-	icon_num = strtol(icon, NULL, 10);
-	g_free(icon);
-	/* ensure face number in proper range */
-	if (icon_num > QQ_FACES) {
-		if (icon_global)
-			purple_debug_error("QQ", "%s\n", errmsg);
-		else
-			purple_notify_error(gc, _("Invalid QQ Face"), errmsg, NULL);
-		g_free(errmsg);
+
+	filename = segments[index];
+	index = strcspn (filename, "0123456789");
+	if (index < 0 || index >= strlen(filename)) {
+		purple_debug_info("QQ", "No digital in %s\n", filename);
 		return;
 	}
-	g_free(errmsg);
-	/* tell server my icon changed */
-	request_set_buddy_icon(gc, icon_num);
+	face = strtol(filename+index, NULL, 10);
+	purple_debug_info("QQ", "Set face to %d\n", face);
 
-	/* display in blist */
-	if (!g_file_get_contents(icon_path, &icon_file_content, &icon_file_size, NULL)) {
-		purple_debug_error("QQ", "Failed reading icon file %s\n", icon_path);
-		return;
-	}
-	purple_buddy_icons_set_for_user(account, account->username,
-			icon_file_content, icon_file_size, icon);
+	request_set_buddy_icon(gc, face);
+
+	g_strfreev(segments);
 }
 
 void qq_set_custom_icon(PurpleConnection *gc, PurpleStoredImage *img)
@@ -573,20 +540,43 @@
 	g_strfreev(segments);
 }
 
-static gchar *qq_get_icon_path(gchar *icon_name)
+gchar *qq_get_icon_name(gint face)
+{
+	gchar *num_str, *icon_name;
+
+	if (face < 1 || face > QQ_FACES) {
+		num_str = g_strdup_printf("%d", 1);
+	} else {
+		num_str = g_strdup_printf("%d", face / 3 + 1);
+	}
+	icon_name = g_strconcat(QQ_ICON_PREFIX, num_str, QQ_ICON_SUFFIX, NULL);
+	g_free(num_str);
+
+	return icon_name;
+}
+
+gchar *qq_get_icon_path(gchar *icon_name)
 {
 	gchar *icon_path;
 	const gchar *icon_dir;
-	
+#ifdef _WIN32
+	static char *dir = NULL;
+	if (dir == NULL) {
+		dir = g_build_filename(wpurple_install_dir(), "pixmaps",
+				"purple", "buddy_icons", "qq", NULL);
+	}
+#endif
+
 	icon_dir = purple_prefs_get_string("/plugins/prpl/qq/icon_dir");
-	if ( icon_dir == NULL) {
-		purple_debug_error("QQ", "Icon dir is not defined in prefs '/plugins/prpl/qq/icon_dir'\n");
-		return NULL;
+	if ( icon_dir == NULL || strlen(icon_dir) == 0) {
+#ifdef _WIN32
+			icon_dir = dir;
+#else
+			icon_dir = QQ_BUDDY_ICON_DIR;
+#endif
 	}
+	icon_path = g_strconcat(icon_dir, G_DIR_SEPARATOR_S, icon_name, NULL);
 
-	icon_path = g_strconcat(icon_dir, G_DIR_SEPARATOR_S,
-			QQ_ICON_PREFIX, icon_name, QQ_ICON_SUFFIX, NULL);
-	
 	return icon_path;
 }
 
@@ -601,7 +591,7 @@
 
 	purple_debug_info("QQ", "Update %s icon to %d\n", who, face);
 
-	icon_name = g_strdup_printf("%d", face);
+	icon_name = qq_get_icon_name(face);
 	if ((buddy = purple_find_buddy(account, who))) {
 		icon_name_prev = purple_buddy_icons_get_checksum_for_user(buddy);
 		purple_debug_info("QQ", "Previous icon is %s\n", icon_name_prev);
@@ -679,7 +669,7 @@
 	purple_blist_server_alias_buddy(buddy, bd->nickname);
 
 	/* convert face num from packet (0-299) to local face (1-100) */
-	update_buddy_icon(gc->account, who, (bd->face / 3 + 1));
+	update_buddy_icon(gc->account, who, bd->face);
 
 	g_free(who);
 	g_free(alias_utf8);
--- a/libpurple/protocols/qq/buddy_info.h	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/buddy_info.h	Wed Oct 22 15:08:30 2008 +0000
@@ -64,9 +64,6 @@
 #define QQ_BUDDY_GENDER_MM          0x01
 #define QQ_BUDDY_GENDER_UNKNOWN     0xff
 
-#define QQ_ICON_PREFIX "qq_"
-#define QQ_ICON_SUFFIX ".png"
-
 enum {
 	QQ_BUDDY_INFO_UPDATE_ONLY = 0,
 	QQ_BUDDY_INFO_DISPLAY,
@@ -77,6 +74,10 @@
 	QQ_BUDDY_INFO_MODIFY_CONTACT,
 };
 
+gchar *qq_get_icon_name(gint face);
+gchar *qq_get_icon_path(gchar *icon_name);
+void qq_change_icon_cb(PurpleConnection *gc, const char *filepath);
+
 void qq_request_buddy_info(PurpleConnection *gc, guint32 uid,
 		gint update_class, int action);
 void qq_set_custom_icon(PurpleConnection *gc, PurpleStoredImage *img);
--- a/libpurple/protocols/qq/buddy_list.c	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/buddy_list.c	Wed Oct 22 15:08:30 2008 +0000
@@ -402,11 +402,8 @@
 			if(group == NULL) {
 				purple_debug_info("QQ",
 					"Not find room id %d in qq_process_get_buddies_and_rooms\n", uid);
-				qq_set_pending_id(&qd->adding_groups_from_server, uid, TRUE);
-				//group = g_newa(qq_group, 1);
-				//group->id = uid;
 				qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_INFO, uid, NULL, 0,
-						0, 0);
+						0, QQ_ROOM_INFO_CREATE);
 			} else {
 				group->my_role = QQ_ROOM_ROLE_YES;
 				qq_group_refresh(gc, group);
@@ -430,27 +427,6 @@
 /* TODO: figure out what's going on with the IP region. Sometimes I get valid IP addresses,
  * but the port number's weird, other times I get 0s. I get these simultaneously on the same buddy,
  * using different accounts to get info. */
-
-/* Help calculate the correct icon index to tell the server. */
-gint get_icon_offset(PurpleConnection *gc)
-{
-	PurpleAccount *account;
-	PurplePresence *presence;
-
-	account = purple_connection_get_account(gc);
-	presence = purple_account_get_presence(account);
-
-	if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_INVISIBLE)) {
-		return 2;
-	} else if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_AWAY)
-			|| purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_EXTENDED_AWAY)
-			|| purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_UNAVAILABLE)) {
-		return 1;
-	} else {
-		return 0;
-	}
-}
-
 static guint8  get_status_from_purple(PurpleConnection *gc)
 {
 	qq_data *qd;
--- a/libpurple/protocols/qq/buddy_list.h	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/buddy_list.h	Wed Oct 22 15:08:30 2008 +0000
@@ -49,8 +49,6 @@
 void qq_request_get_buddies_and_rooms(PurpleConnection *gc, guint32 position, gint update_class);
 guint32 qq_process_get_buddies_and_rooms(guint8 *data, gint data_len, PurpleConnection *gc);
 
-gint get_icon_offset(PurpleConnection *gc);
-
 void qq_request_change_status(PurpleConnection *gc, gint update_class);
 void qq_process_change_status(guint8 *data, gint data_len, PurpleConnection *gc);
 void qq_process_buddy_change_status(guint8 *data, gint data_len, PurpleConnection *gc);
--- a/libpurple/protocols/qq/group.c	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/group.c	Wed Oct 22 15:08:30 2008 +0000
@@ -41,9 +41,9 @@
 	guint32 ext_id;
 
 	g_return_if_fail(input != NULL);
-	ext_id = qq_string_to_dec_value(input);
+	ext_id = strtol(input, NULL, 10);
 	/* 0x00000000 means search for demo group */
-	qq_send_cmd_group_search_group(gc, ext_id);
+	qq_request_room_search(gc, ext_id, QQ_ROOM_SEARCH_ONLY);
 }
 
 static void _qq_group_search_cancel_callback(PurpleConnection *gc, const gchar *input)
@@ -155,6 +155,7 @@
 
 	account = purple_connection_get_account(gc);
 
+	purple_debug_info("QQ", "Initial QQ Qun configurations\n");
 	purple_group = purple_find_group(PURPLE_GROUP_QQ_QUN);
 	if (purple_group == NULL) {
 		purple_debug_info("QQ", "We have no QQ Qun\n");
@@ -170,7 +171,7 @@
 		chat = (PurpleChat *) node;
 		if (account != chat->account)	/* not qq account*/
 			continue;
-		group = qq_room_create_by_hashtable(gc, chat->components);
+		group = qq_room_data_new_by_hashtable(gc, chat->components);
 		if (group == NULL)
 			continue;
 
--- a/libpurple/protocols/qq/group.h	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/group.h	Wed Oct 22 15:08:30 2008 +0000
@@ -54,9 +54,9 @@
 	gchar *desc_utf8;
 	/* all these will be loaded from the network */
 	gchar *notice_utf8;	/* group notice by admin */
+
+	gboolean is_got_buddies;
 	GList *members;
-
-	gboolean is_got_info;
 } qq_group;
 
 GList *qq_chat_info(PurpleConnection *gc);
--- a/libpurple/protocols/qq/group_find.c	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/group_find.c	Wed Oct 22 15:08:30 2008 +0000
@@ -93,58 +93,6 @@
 	return member;
 }
 
-/* find a qq_group by chatroom channel */
-qq_group *qq_group_find_by_channel(PurpleConnection *gc, gint channel)
-{
-	PurpleConversation *conv;
-	qq_data *qd;
-	qq_group *group;
-	GList *list;
-
-	qd = (qq_data *) gc->proto_data;
-
-	conv = purple_find_chat(gc, channel);
-	g_return_val_if_fail(conv != NULL, NULL);
-
-	list = qd->groups;
-	group = NULL;
-	while (list != NULL) {
-		group = (qq_group *) list->data;
-		if (group->title_utf8 == NULL) {
-			continue;
-		}
-		if (!g_ascii_strcasecmp(purple_conversation_get_name(conv), group->title_utf8))
-			break;
-		list = list->next;
-	}
-
-	return group;
-}
-
-/* find a qq_group by its id, flag is QQ_INTERNAL_ID or QQ_EXTERNAL_ID */
-qq_group *qq_room_search_ext_id(PurpleConnection *gc, guint32 ext_id)
-{
-	GList *list;
-	qq_group *group;
-	qq_data *qd;
-
-	qd = (qq_data *) gc->proto_data;
-
-	if (qd->groups == NULL || ext_id <= 0)
-		return NULL;
-
-	list = qd->groups;
-	while (list != NULL) {
-		group = (qq_group *) list->data;
-		if (group->ext_id == ext_id) {
-			return group;
-		}
-		list = list->next;
-	}
-
-	return NULL;
-}
-
 qq_group *qq_room_search_id(PurpleConnection *gc, guint32 room_id)
 {
 	GList *list;
--- a/libpurple/protocols/qq/group_find.h	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/group_find.h	Wed Oct 22 15:08:30 2008 +0000
@@ -32,9 +32,7 @@
 qq_buddy_data *qq_group_find_member_by_uid(qq_group *group, guint32 uid);
 void qq_group_remove_member_by_uid(qq_group *group, guint32 uid);
 qq_buddy_data *qq_group_find_or_add_member(PurpleConnection *gc, qq_group *group, guint32 member_uid);
-qq_group *qq_group_find_by_channel(PurpleConnection *gc, gint channel);
 
-qq_group *qq_room_search_ext_id(PurpleConnection *gc, guint32 ext_id);
 qq_group *qq_room_search_id(PurpleConnection *gc, guint32 room_id);
 
 qq_group *qq_room_get_next(PurpleConnection *gc, guint32 room_id);
--- a/libpurple/protocols/qq/group_im.c	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/group_im.c	Wed Oct 22 15:08:30 2008 +0000
@@ -45,7 +45,7 @@
 #include "utils.h"
 
 /* show group conversation window */
-PurpleConversation *qq_room_conv_new(PurpleConnection *gc, qq_group *group)
+PurpleConversation *qq_room_conv_open(PurpleConnection *gc, qq_group *group)
 {
 	PurpleConversation *conv;
 	qq_data *qd;
@@ -61,7 +61,7 @@
 		return conv;
 	}
 
-	serv_got_joined_chat(gc, qd->channel++, group->title_utf8);
+	serv_got_joined_chat(gc, group->id, group->title_utf8);
 	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, group->title_utf8, purple_connection_get_account(gc));
 	if (conv != NULL) {
 		topic_utf8 = g_strdup_printf("%d %s", group->ext_id, group->notice_utf8);
@@ -69,7 +69,7 @@
 		purple_conv_chat_set_topic(PURPLE_CONV_CHAT(conv), NULL, topic_utf8);
 		g_free(topic_utf8);
 
-		if (group->is_got_info)
+		if (group->is_got_buddies)
 			qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_ONLINES, group->id);
 		else
 			qq_update_room(gc, 0, group->id);
@@ -87,6 +87,7 @@
 	PurpleConversation *conv;
 	gint flag;
 	gboolean is_find;
+
 	g_return_if_fail(group != NULL);
 
 	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
@@ -157,14 +158,14 @@
 }
 
 /* send IM to a group */
-void qq_send_packet_group_im(PurpleConnection *gc, qq_group *group, const gchar *msg)
+void qq_send_packet_group_im(PurpleConnection *gc, guint32 room_id, const gchar *msg)
 {
 	gint data_len, bytes;
 	guint8 *raw_data, *send_im_tail;
 	guint16 msg_len;
 	gchar *msg_filtered;
 
-	g_return_if_fail(group != NULL && msg != NULL);
+	g_return_if_fail(room_id != 0 && msg != NULL);
 
 	msg_filtered = purple_markup_strip_html(msg);
 	purple_debug_info("QQ_MESG", "Send qun mesg filterd: %s\n", msg_filtered);
@@ -184,7 +185,7 @@
 	g_free(msg_filtered);
 
 	if (bytes == data_len)	/* create OK */
-		qq_send_room_cmd(gc, QQ_ROOM_CMD_SEND_MSG, group->id, raw_data, data_len);
+		qq_send_room_cmd(gc, QQ_ROOM_CMD_SEND_MSG, room_id, raw_data, data_len);
 	else
 		purple_debug_error("QQ",
 				"Fail creating group_im packet, expect %d bytes, build %d bytes\n", data_len, bytes);
@@ -262,7 +263,7 @@
 	conv = purple_find_conversation_with_account(
 			PURPLE_CONV_TYPE_CHAT, group->title_utf8, account);
 	if (conv == NULL && purple_prefs_get_bool("/plugins/prpl/qq/show_room_when_newin")) {
-		conv = qq_room_conv_new(gc, group);
+		conv = qq_room_conv_open(gc, group);
 	}
 
 	if (conv == NULL) {
--- a/libpurple/protocols/qq/group_im.h	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/group_im.h	Wed Oct 22 15:08:30 2008 +0000
@@ -30,13 +30,13 @@
 #include "conversation.h"
 #include "group.h"
 
-PurpleConversation *qq_room_conv_new(PurpleConnection *gc, qq_group *group);
+PurpleConversation *qq_room_conv_open(PurpleConnection *gc, qq_group *group);
 void qq_room_conv_set_onlines(PurpleConnection *gc, qq_group *group);
 
 void qq_room_got_chat_in(PurpleConnection *gc,
 		qq_group *group, guint32 uid_from, const gchar *msg, time_t in_time);
 
-void qq_send_packet_group_im(PurpleConnection *gc, qq_group *group, const gchar *msg);
+void qq_send_packet_group_im(PurpleConnection *gc, guint32 room_id, const gchar *msg);
 
 void qq_process_group_cmd_im(guint8 *data, gint len, PurpleConnection *gc);
 
--- a/libpurple/protocols/qq/group_info.c	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/group_info.c	Wed Oct 22 15:08:30 2008 +0000
@@ -28,6 +28,7 @@
 #include "debug.h"
 
 #include "char_conv.h"
+#include "group_im.h"
 #include "group_find.h"
 #include "group_internal.h"
 #include "group_info.h"
@@ -146,7 +147,6 @@
 	guint8 organization, role;
 	guint16 unknown, max_members;
 	guint32 member_uid, id, ext_id;
-	GSList *pending_id;
 	guint32 unknown4;
 	guint8 unknown1;
 	gint bytes, num;
@@ -165,9 +165,7 @@
 	bytes += qq_get32(&ext_id, data + bytes);
 	g_return_if_fail(ext_id > 0);
 
-	pending_id = qq_get_pending_id(qd->adding_groups_from_server, id);
-	if (pending_id != NULL) {
-		qq_set_pending_id(&qd->adding_groups_from_server, id, FALSE);
+	if (action == QQ_ROOM_INFO_CREATE ) {
 		qq_group_create_internal_record(gc, id, ext_id, NULL);
 	}
 
@@ -299,6 +297,7 @@
 	}
 
 	purple_debug_info("QQ", "Group \"%s\" has %d online members\n", group->title_utf8, num);
+	qq_room_conv_set_onlines(gc, group);
 }
 
 /* process the reply to get_members_info packet */
@@ -358,5 +357,8 @@
 				"group_cmd_get_members_info: Dangerous error! maybe protocol changed, notify developers!");
 	}
 	purple_debug_info("QQ", "Group \"%s\" obtained %d member info\n", group->title_utf8, num);
+
+	group->is_got_buddies = TRUE;
+	qq_room_conv_set_onlines(gc, group);
 }
 
--- a/libpurple/protocols/qq/group_info.h	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/group_info.h	Wed Oct 22 15:08:30 2008 +0000
@@ -32,6 +32,7 @@
 enum {
 	QQ_ROOM_INFO_UPDATE_ONLY = 0,
 	QQ_ROOM_INFO_DISPLAY,
+	QQ_ROOM_INFO_CREATE,
 };
 
 gint qq_request_room_get_buddies(PurpleConnection *gc, qq_group *group, gint update_class);
--- a/libpurple/protocols/qq/group_internal.c	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/group_internal.c	Wed Oct 22 15:08:30 2008 +0000
@@ -142,8 +142,14 @@
 	return components;
 }
 
+static gint str2dec(const gchar *str)
+{
+	g_return_val_if_fail(str != NULL, 0);
+	return strtol(str, NULL, 10);
+}
+
 /* create a qq_group from hashtable */
-qq_group *qq_room_create_by_hashtable(PurpleConnection *gc, GHashTable *data)
+qq_group *qq_room_data_new_by_hashtable(PurpleConnection *gc, GHashTable *data)
 {
 	qq_data *qd;
 	qq_group *group;
@@ -153,23 +159,25 @@
 
 	group = g_new0(qq_group, 1);
 	group->my_role =
-	    qq_string_to_dec_value
+	    str2dec
 	    (NULL ==
 	     g_hash_table_lookup(data,
 				 QQ_ROOM_KEY_ROLE) ?
 	     g_strdup_printf("%d", QQ_ROOM_ROLE_NO) :
 	     g_hash_table_lookup(data, QQ_ROOM_KEY_ROLE));
-	group->id = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_ROOM_KEY_INTERNAL_ID));
-	group->ext_id = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_ROOM_KEY_EXTERNAL_ID));
-	group->type8 = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_ROOM_KEY_TYPE));
-	group->creator_uid = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_ROOM_KEY_CREATOR_UID));
-	group->category = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_ROOM_KEY_CATEGORY));
-	group->auth_type = qq_string_to_dec_value(g_hash_table_lookup(data, QQ_ROOM_KEY_AUTH_TYPE));
+	group->id = str2dec(g_hash_table_lookup(data, QQ_ROOM_KEY_INTERNAL_ID));
+	group->ext_id = str2dec(g_hash_table_lookup(data, QQ_ROOM_KEY_EXTERNAL_ID));
+	group->type8 = str2dec(g_hash_table_lookup(data, QQ_ROOM_KEY_TYPE));
+	group->creator_uid = str2dec(g_hash_table_lookup(data, QQ_ROOM_KEY_CREATOR_UID));
+	group->category = str2dec(g_hash_table_lookup(data, QQ_ROOM_KEY_CATEGORY));
+	group->auth_type = str2dec(g_hash_table_lookup(data, QQ_ROOM_KEY_AUTH_TYPE));
 	group->title_utf8 = g_strdup(g_hash_table_lookup(data, QQ_ROOM_KEY_TITLE_UTF8));
 	group->desc_utf8 = g_strdup(g_hash_table_lookup(data, QQ_ROOM_KEY_DESC_UTF8));
 	group->my_role_desc = get_role_desc(group);
-	group->is_got_info = FALSE;
+	group->is_got_buddies = FALSE;
 
+	purple_debug_info("QQ", "Created room info from hashtable: %s, %d, id %d\n",
+			group->title_utf8, group->ext_id, group->id);
 	qd->groups = g_list_append(qd->groups, group);
 	return group;
 }
@@ -222,21 +230,3 @@
 	g_hash_table_replace(chat->components,
 		     g_strdup(QQ_ROOM_KEY_DESC_UTF8), g_strdup(group->desc_utf8));
 }
-
-/* NOTE: If we knew how to convert between an external and internal group id, as the official
- * client seems to, the following would be unnecessary. That would be ideal. */
-
-/* Use list to specify if id's alternate id is pending discovery. */
-void qq_set_pending_id(GSList **list, guint32 id, gboolean pending)
-{
-	if (pending)
-		*list = g_slist_prepend(*list, GINT_TO_POINTER(id));
-	else
-		*list = g_slist_remove(*list, GINT_TO_POINTER(id));
-}
-
-/* Return the location of id in list, or NULL if not found */
-GSList *qq_get_pending_id(GSList *list, guint32 id)
-{
-        return g_slist_find(list, GINT_TO_POINTER(id));
-}
--- a/libpurple/protocols/qq/group_internal.h	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/group_internal.h	Wed Oct 22 15:08:30 2008 +0000
@@ -44,11 +44,8 @@
 void qq_group_delete_internal_record(qq_data *qd, guint32 id);
 
 GHashTable *qq_group_to_hashtable(qq_group *group);
-qq_group *qq_room_create_by_hashtable(PurpleConnection *gc, GHashTable *data);
+qq_group *qq_room_data_new_by_hashtable(PurpleConnection *gc, GHashTable *data);
 
 void qq_group_refresh(PurpleConnection *gc, qq_group *group);
 
-void qq_set_pending_id(GSList **list, guint32 id, gboolean pending);
-GSList *qq_get_pending_id(GSList *list, guint32 id);
-
 #endif
--- a/libpurple/protocols/qq/group_join.c	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/group_join.c	Wed Oct 22 15:08:30 2008 +0000
@@ -227,7 +227,6 @@
 	qq_data *qd;
 	qq_group *group;
 	gchar *msg;
-	time_t now = time(NULL);
 
 	g_return_if_fail(data != NULL && len > 0);
 	qd = (qq_data *) gc->proto_data;
@@ -244,7 +243,7 @@
 	group = qq_room_search_id(gc, id);
 	if (group != NULL) {
 		msg = g_strdup_printf(_("Successed join to Qun %s (%d)"), group->title_utf8, group->ext_id);
-		qq_room_got_chat_in(gc, group, 0, msg, now);
+		qq_got_attention(gc, msg);
 		g_free(msg);
 	} else {
 		qq_got_attention(gc, _("Successed join to Qun"));
@@ -282,7 +281,7 @@
 		group->my_role = QQ_ROOM_ROLE_YES;
 		qq_group_refresh(gc, group);
 		/* this must be shown before getting online members */
-		qq_room_conv_new(gc, group);
+		qq_room_conv_open(gc, group);
 		break;
 	case QQ_ROOM_JOIN_NEED_AUTH:
 		purple_debug_info("QQ",
@@ -310,30 +309,40 @@
 void qq_group_join(PurpleConnection *gc, GHashTable *data)
 {
 	qq_data *qd;
-	gchar *ext_id_ptr;
+	gchar *ext_id_str;
+	gchar *id_str;
 	guint32 ext_id;
+	guint32 id;
 	qq_group *group;
 
 	g_return_if_fail(data != NULL);
 	qd = (qq_data *) gc->proto_data;
 
-	ext_id_ptr = g_hash_table_lookup(data, QQ_ROOM_KEY_EXTERNAL_ID);
-	g_return_if_fail(ext_id_ptr != NULL);
-	errno = 0;
-	ext_id = strtol(ext_id_ptr, NULL, 10);
-	if (errno != 0) {
-		purple_notify_error(gc, _("Error"),
-				_("You entered a group ID outside the acceptable range"), NULL);
+	ext_id_str = g_hash_table_lookup(data, QQ_ROOM_KEY_EXTERNAL_ID);
+	id_str = g_hash_table_lookup(data, QQ_ROOM_KEY_INTERNAL_ID);
+	purple_debug_info("QQ", "Join room %s, extend id %s\n", id_str, ext_id_str);
+
+	if (id_str != NULL) {
+		id = strtol(id_str, NULL, 10);
+		if (id != 0) {
+			group = qq_room_search_id(gc, id);
+			if (group) {
+				qq_request_room_join(gc, group);
+				return;
+			}
+		}
+	}
+
+	purple_debug_info("QQ", "Search and join extend id %s\n", ext_id_str);
+	if (ext_id_str == NULL) {
+		return;
+	}
+	ext_id = strtol(ext_id_str, NULL, 10);
+	if (ext_id == 0) {
 		return;
 	}
 
-	group = qq_room_search_ext_id(gc, ext_id);
-	if (group) {
-		qq_request_room_join(gc, group);
-	} else {
-		qq_set_pending_id(&qd->joining_groups, ext_id, TRUE);
-		qq_send_cmd_group_search_group(gc, ext_id);
-	}
+	qq_request_room_search(gc, ext_id, QQ_ROOM_SEARCH_FOR_JOIN);
 }
 
 void qq_room_quit(PurpleConnection *gc, GHashTable *data)
--- a/libpurple/protocols/qq/group_search.c	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/group_search.c	Wed Oct 22 15:08:30 2008 +0000
@@ -43,22 +43,23 @@
 };
 
 /* send packet to search for qq_group */
-void qq_send_cmd_group_search_group(PurpleConnection *gc, guint32 ext_id)
+void qq_request_room_search(PurpleConnection *gc, guint32 ext_id, int action)
 {
 	guint8 raw_data[16] = {0};
 	gint bytes = 0;
 	guint8 type;
 
+	purple_debug_info("QQ", "Search QQ Qun %d\n", ext_id);
 	type = (ext_id == 0x00000000) ? QQ_ROOM_SEARCH_TYPE_DEMO : QQ_ROOM_SEARCH_TYPE_BY_ID;
 
 	bytes = 0;
 	bytes += qq_put8(raw_data + bytes, type);
 	bytes += qq_put32(raw_data + bytes, ext_id);
 
-	qq_send_room_cmd_noid(gc, QQ_ROOM_CMD_SEARCH, raw_data, bytes);
+	qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_SEARCH, 0, raw_data, bytes, 0, action);
 }
 
-static void _qq_setup_roomlist(qq_data *qd, qq_group *group)
+static void add_to_roomlist(qq_data *qd, qq_group *group)
 {
 	PurpleRoomlistRoom *room;
 	gchar field[11];
@@ -84,14 +85,13 @@
 }
 
 /* process group cmd reply "search group" */
-void qq_process_group_cmd_search_group(guint8 *data, gint len, PurpleConnection *gc)
+void qq_process_room_search(PurpleConnection *gc, guint8 *data, gint len, guint32 ship32)
 {
 	gint bytes;
 	guint8 search_type;
 	guint16 unknown;
 	qq_group group;
 	qq_data *qd;
-	GSList *pending_id;
 
 	g_return_if_fail(data != NULL && len > 0);
 	qd = (qq_data *) gc->proto_data;
@@ -120,14 +120,12 @@
 			"group_cmd_search_group: Dangerous error! maybe protocol changed, notify developers!");
 	}
 
-	pending_id = qq_get_pending_id(qd->joining_groups, group.ext_id);
-	if (pending_id != NULL) {
-		qq_set_pending_id(&qd->joining_groups, group.ext_id, FALSE);
+	if (ship32 == QQ_ROOM_SEARCH_FOR_JOIN) {
 		if (qq_room_search_id(gc, group.id) == NULL)
 			qq_group_create_internal_record(gc,
 					group.id, group.ext_id, group.title_utf8);
 		qq_request_room_join(gc, &group);
 	} else {
-		_qq_setup_roomlist(qd, &group);
+		add_to_roomlist(qd, &group);
 	}
 }
--- a/libpurple/protocols/qq/group_search.h	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/group_search.h	Wed Oct 22 15:08:30 2008 +0000
@@ -28,7 +28,12 @@
 #include <glib.h>
 #include "connection.h"
 
-void qq_send_cmd_group_search_group(PurpleConnection *gc, guint32 external_group_id);
-void qq_process_group_cmd_search_group(guint8 *data, gint len, PurpleConnection *gc);
+enum {
+	QQ_ROOM_SEARCH_ONLY = 0,
+	QQ_ROOM_SEARCH_FOR_JOIN
+};
+
+void qq_request_room_search(PurpleConnection *gc, guint32 ext_id, int action);
+void qq_process_room_search(PurpleConnection *gc, guint8 *data, gint len, guint32 ship32);
 
 #endif
--- a/libpurple/protocols/qq/qq.c	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/qq.c	Wed Oct 22 15:08:30 2008 +0000
@@ -474,21 +474,18 @@
 }
 
 /* send a chat msg to a QQ Qun */
-static int qq_chat_send(PurpleConnection *gc, int channel, const char *message, PurpleMessageFlags flags)
+static int qq_chat_send(PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags)
 {
 	gchar *msg, *msg_with_qq_smiley;
-	qq_group *group;
+	guint32 room_id = id;
 
 	g_return_val_if_fail(message != NULL, -1);
 	g_return_val_if_fail(strlen(message) <= QQ_MSG_IM_MAX, -E2BIG);
 
-	group = qq_group_find_by_channel(gc, channel);
-	g_return_val_if_fail(group != NULL, -1);
-
 	purple_debug_info("QQ_MESG", "Send qun mesg in utf8: %s\n", message);
 	msg = utf8_to_qq(message, QQ_CHARSET_DEFAULT);
 	msg_with_qq_smiley = purple_smiley_to_qq(msg);
-	qq_send_packet_group_im(gc, group, msg_with_qq_smiley);
+	qq_send_packet_group_im(gc, room_id, msg_with_qq_smiley);
 	g_free(msg);
 	g_free(msg_with_qq_smiley);
 
@@ -536,14 +533,28 @@
 static void action_change_icon(PurplePluginAction *action)
 {
 	PurpleConnection *gc = (PurpleConnection *) action->context;
+	qq_data *qd;
+	gchar *icon_name;
+	gchar *icon_path;
 
 	g_return_if_fail(NULL != gc && NULL != gc->proto_data);
+	qd = (qq_data *) gc->proto_data;
 
-	purple_request_file(action, _("Select icon..."), NULL,
+	if ( !qd->is_login ) {
+		return;
+	}
+
+	icon_name = qq_get_icon_name(qd->my_icon);
+	icon_path = qq_get_icon_path(icon_name);
+	g_free(icon_name);
+
+	purple_debug_info("QQ", "Change prev icon %s to ...\n", icon_path);
+	purple_request_file(action, _("Select icon..."), icon_path,
 			FALSE,
-			NULL, NULL,
+			G_CALLBACK(qq_change_icon_cb), NULL,
 			purple_connection_get_account(gc), NULL, NULL,
 			gc);
+	g_free(icon_path);
 }
 
 static void action_modify_info_base(PurplePluginAction *action)
@@ -794,7 +805,7 @@
 	PurplePluginAction *act;
 
 	m = NULL;
-	act = purple_plugin_action_new(_("Change icon"), action_change_icon);
+	act = purple_plugin_action_new(_("Change Icon"), action_change_icon);
 	m = g_list_append(m, act);
 
 	act = purple_plugin_action_new(_("Modify Information"), action_modify_info_base);
@@ -871,6 +882,26 @@
 	return m;
 }
 
+/* convert name displayed in a chat channel to original QQ UID */
+static gchar *chat_name_to_purple_name(const gchar *const name)
+{
+	const char *start;
+	const char *end;
+	gchar *ret;
+
+	g_return_val_if_fail(name != NULL, NULL);
+
+	/* Sample: (1234567)*/
+	start = strchr(name, '(');
+	g_return_val_if_fail(start != NULL, NULL);
+	end = strchr(start, ')');
+	g_return_val_if_fail(end != NULL && (end - start) > 1, NULL);
+
+	ret = g_strndup(start + 1, end - start - 1);
+
+	return ret;
+}
+
 /* convert chat nickname to uid to get this buddy info */
 /* who is the nickname of buddy in QQ chat-room (Qun) */
 static void qq_get_chat_buddy_info(PurpleConnection *gc, gint channel, const gchar *who)
@@ -879,6 +910,7 @@
 	gchar *uid_str;
 	guint32 uid;
 
+	purple_debug_info("QQ", "Get chat buddy info of %s\n", who);
 	g_return_if_fail(who != NULL);
 
 	uid_str = chat_name_to_purple_name(who);
@@ -1093,7 +1125,6 @@
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
 
 	purple_prefs_add_none("/plugins/prpl/qq");
-	purple_prefs_add_string("/plugins/prpl/qq/icon_dir", QQ_BUDDY_ICON_DIR);
 	purple_prefs_add_bool("/plugins/prpl/qq/show_status_by_icon", TRUE);
 	purple_prefs_add_bool("/plugins/prpl/qq/show_fake_video", FALSE);
 	purple_prefs_add_bool("/plugins/prpl/qq/show_room_when_newin", TRUE);
--- a/libpurple/protocols/qq/qq.h	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/qq.h	Wed Oct 22 15:08:30 2008 +0000
@@ -183,12 +183,8 @@
 	time_t online_last_update;		/* last time send get_friends_online packet */
 
 	PurpleRoomlist *roomlist;
-	gint channel;			/* the id for opened chat conversation */
 
 	GList *groups;
-	GSList *joining_groups;
-	GSList *adding_groups_from_server; /* internal ids of groups the server wants in my blist */
-	GList *group_info_window;
 
 	gboolean is_show_notice;
 	gboolean is_show_news;
--- a/libpurple/protocols/qq/qq_network.c	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/qq_network.c	Wed Oct 22 15:08:30 2008 +0000
@@ -710,7 +710,6 @@
 	qd->send_seq = rand() & 0xffff;
 
 	qd->is_login = FALSE;
-	qd->channel = 1;
 	qd->uid = strtol(purple_account_get_username(purple_connection_get_account(gc)), NULL, 10);
 
 #ifdef DEBUG
@@ -1284,19 +1283,21 @@
 gint qq_send_room_cmd_mess(PurpleConnection *gc, guint8 room_cmd, guint32 room_id,
 		guint8 *data, gint data_len, gint update_class, guint32 ship32)
 {
-	g_return_val_if_fail(room_id > 0, -1);
+	g_return_val_if_fail(room_cmd > 0, -1);
 	return send_room_cmd(gc, room_cmd, room_id, data, data_len, update_class, ship32);
 }
 
 gint qq_send_room_cmd(PurpleConnection *gc, guint8 room_cmd, guint32 room_id,
 		guint8 *data, gint data_len)
 {
+	g_return_val_if_fail(room_cmd > 0 && room_id > 0, -1);
 	return send_room_cmd(gc, room_cmd, room_id, data, data_len, 0, 0);
 }
 
 gint qq_send_room_cmd_noid(PurpleConnection *gc, guint8 room_cmd,
 		guint8 *data, gint data_len)
 {
+	g_return_val_if_fail(room_cmd > 0, -1);
 	return send_room_cmd(gc, room_cmd, 0, data, data_len, 0, 0);
 }
 
--- a/libpurple/protocols/qq/qq_process.c	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/qq_process.c	Wed Oct 22 15:08:30 2008 +0000
@@ -745,13 +745,6 @@
 		return;
 	}
 
-	group = qq_room_search_id(gc, room_id);
-	if (group == NULL) {
-		purple_debug_warning("QQ",
-			"Missing room id in [%05d], 0x%02X %s for %d, len %d\n",
-			seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, rcved_len);
-	}
-
 	bytes = 0;
 	bytes += qq_get8(&reply_cmd, data + bytes);
 	bytes += qq_get8(&reply, data + bytes);
@@ -765,13 +758,14 @@
 
 	/* now process the packet */
 	if (reply != QQ_ROOM_CMD_REPLY_OK) {
-		if (group != NULL) {
-			qq_set_pending_id(&qd->joining_groups, group->ext_id, FALSE);
-		}
-
 		switch (reply) {	/* this should be all errors */
 		case QQ_ROOM_CMD_REPLY_NOT_MEMBER:
-			if (group != NULL) {
+			group = qq_room_search_id(gc, room_id);
+			if (group == NULL) {
+				purple_debug_warning("QQ",
+						"Missing room id in [%05d], 0x%02X %s for %d, len %d\n",
+						seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, rcved_len);
+			} else {
 				purple_debug_warning("QQ",
 					   _("You are not a member of QQ Qun \"%s\"\n"), group->title_utf8);
 				group->my_role = QQ_ROOM_ROLE_NO;
@@ -807,7 +801,7 @@
 		qq_group_process_activate_group_reply(data + bytes, data_len - bytes, gc);
 		break;
 	case QQ_ROOM_CMD_SEARCH:
-		qq_process_group_cmd_search_group(data + bytes, data_len - bytes, gc);
+		qq_process_room_search(gc, data + bytes, data_len - bytes, ship32);
 		break;
 	case QQ_ROOM_CMD_JOIN:
 		qq_process_group_cmd_join_group(data + bytes, data_len - bytes, gc);
@@ -823,15 +817,9 @@
 		break;
 	case QQ_ROOM_CMD_GET_ONLINES:
 		qq_process_room_cmd_get_onlines(data + bytes, data_len - bytes, gc);
-		if (group != NULL)
-			qq_room_conv_set_onlines(gc, group);
 		break;
 	case QQ_ROOM_CMD_GET_BUDDIES:
 		qq_process_room_cmd_get_buddies(data + bytes, data_len - bytes, gc);
-		if (group != NULL) {
-			group->is_got_info = TRUE;
-			qq_room_conv_set_onlines(gc, group);
-		}
 		break;
 	default:
 		purple_debug_warning("QQ", "Unknow room cmd 0x%02X %s\n",
--- a/libpurple/protocols/qq/utils.c	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/utils.c	Wed Oct 22 15:08:30 2008 +0000
@@ -91,12 +91,6 @@
 	return g_strdup_printf("%d", index);
 }
 
-gint qq_string_to_dec_value(const gchar *str)
-{
-	g_return_val_if_fail(str != NULL, 0);
-	return strtol(str, NULL, 10);
-}
-
 /* split the given data(len) with delimit,
  * check the number of field matches the expected_fields (<=0 means all)
  * return gchar* array (needs to be freed by g_strfreev later), or NULL */
@@ -178,26 +172,6 @@
 	return g_strdup_printf(QQ_NAME_FORMAT, uid);
 }
 
-/* convert name displayed in a chat channel to original QQ UID */
-gchar *chat_name_to_purple_name(const gchar *const name)
-{
-	const char *start;
-	const char *end;
-	gchar *ret;
-
-	g_return_val_if_fail(name != NULL, NULL);
-
-	/* Sample: (1234567)*/
-	start = strchr(name, '(');
-	g_return_val_if_fail(start != NULL, NULL);
-	end = strchr(start, ')');
-	g_return_val_if_fail(end != NULL && (end - start) > 1, NULL);
-
-	ret = g_strndup(start + 1, end - start - 1);
-
-	return ret;
-}
-
 /* try to dump the data as GBK */
 gchar* try_dump_as_gbk(const guint8 *const data, gint len)
 {
--- a/libpurple/protocols/qq/utils.h	Wed Oct 22 15:06:26 2008 +0000
+++ b/libpurple/protocols/qq/utils.h	Wed Oct 22 15:08:30 2008 +0000
@@ -34,7 +34,6 @@
 
 gchar *get_name_by_index_str(gchar **array, const gchar *index_str, gint amount);
 gchar *get_index_str_by_name(gchar **array, const gchar *name, gint amount);
-gint qq_string_to_dec_value(const gchar *str);
 
 gchar **split_data(guint8 *data, gint len, const gchar *delimit, gint expected_fields);
 
@@ -43,7 +42,6 @@
 
 guint32 purple_name_to_uid(const gchar *name);
 gchar *uid_to_purple_name(guint32 uid);
-gchar *chat_name_to_purple_name(const gchar *const name);
 
 gchar *try_dump_as_gbk(const guint8 *const data, gint len);