# HG changeset patch # User SHiNE CsyFeK # Date 1224688110 0 # Node ID 237e5a94e11ce13d2fa19cd061e2a2b34f6df3b0 # Parent 340fc40fe4ef093d8dc611329e7077ffbd70d4d7 2008.10.08 - ccpaging * Update group part * Delete some meaningless functions and data * Added 'change my icon' 2008.10.08 - lonicerae * Merge 20081008 patch into trunk diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/ChangeLog --- 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 + * Update group part + * Delete some meaningless functions and data + * Added 'change my icon' + 2008.10.08 - lonicerae * Update Makefile.mingw diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/buddy_info.c --- 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); diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/buddy_info.h --- 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); diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/buddy_list.c --- 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; diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/buddy_list.h --- 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); diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/group.c --- 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; diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/group.h --- 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); diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/group_find.c --- 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; diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/group_find.h --- 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); diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/group_im.c --- 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) { diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/group_im.h --- 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); diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/group_info.c --- 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); } diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/group_info.h --- 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); diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/group_internal.c --- 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)); -} diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/group_internal.h --- 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 diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/group_join.c --- 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) diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/group_search.c --- 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); } } diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/group_search.h --- 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 #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 diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/qq.c --- 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); diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/qq.h --- 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; diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/qq_network.c --- 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); } diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/qq_process.c --- 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", diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/utils.c --- 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) { diff -r 340fc40fe4ef -r 237e5a94e11c libpurple/protocols/qq/utils.h --- 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);