# HG changeset patch # User SHiNE CsyFeK # Date 1225211896 0 # Node ID 1ee91ff0d5fefa400d3c28039ff1b8bf741dd8a7 # Parent 147f1b17b6ce4fa0d0108c454a03927949d99ca0 2008.10.09 - ccpaging * Update 'group' protocol * Functions of group_find, group_free, group_search merged into group_join and group_internal * Removed group_find.c/h, group_free.c/h, group_search.c/h diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/ChangeLog --- a/libpurple/protocols/qq/ChangeLog Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/ChangeLog Tue Oct 28 16:38:16 2008 +0000 @@ -1,3 +1,8 @@ +2008.10.09 - ccpaging + * Update 'group' protocol + * Functions of group_find, group_free, group_search merged into group_join and group_internal + * Removed group_find.c/h, group_free.c/h, group_search.c/h + 2008.10.08 - ccpaging * Update 'group' protocol diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/Makefile.am --- a/libpurple/protocols/qq/Makefile.am Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/Makefile.am Tue Oct 28 16:38:16 2008 +0000 @@ -18,10 +18,6 @@ file_trans.h \ group.c \ group.h \ - group_find.c \ - group_find.h \ - group_free.c \ - group_free.h \ group_internal.c \ group_internal.h \ group_im.c \ @@ -32,8 +28,6 @@ group_join.h \ group_opt.c \ group_opt.h \ - group_search.c \ - group_search.h \ qq_define.c \ qq_define.h \ im.c \ diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/Makefile.mingw --- a/libpurple/protocols/qq/Makefile.mingw Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/Makefile.mingw Tue Oct 28 16:38:16 2008 +0000 @@ -50,14 +50,11 @@ qq_crypt.c \ file_trans.c \ group.c \ - group_find.c \ - group_free.c \ group_internal.c \ group_im.c \ group_info.c \ group_join.c \ group_opt.c \ - group_search.c \ qq_define.c \ im.c \ packet_parse.c \ diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/buddy_list.c --- a/libpurple/protocols/qq/buddy_list.c Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/buddy_list.c Tue Oct 28 16:38:16 2008 +0000 @@ -37,7 +37,6 @@ #include "qq_define.h" #include "qq_base.h" #include "group.h" -#include "group_find.h" #include "group_internal.h" #include "group_info.h" @@ -236,13 +235,15 @@ if(0 != fe->s->client_tag) q_bud->client_tag = fe->s->client_tag; */ + if (bd->status != bs.status || bd->comm_flag != packet.comm_flag) { + bd->status = bs.status; + bd->comm_flag = packet.comm_flag; + qq_update_buddy_status(gc, bd->uid, bd->status, bd->comm_flag); + } bd->ip.s_addr = bs.ip.s_addr; bd->port = bs.port; - bd->status = bs.status; bd->ext_flag = packet.ext_flag; - bd->comm_flag = packet.comm_flag; bd->last_update = time(NULL); - qq_update_buddy_status(gc, bd->uid, bd->status, bd->comm_flag); count++; } @@ -358,7 +359,7 @@ guint32 unknown, position; guint32 uid; guint8 type; - qq_group *group; + qq_room_data *rmd; g_return_val_if_fail(data != NULL && data_len != 0, -1); @@ -394,15 +395,12 @@ * qq_request_get_buddies */ ++i; } else { /* a group */ - group = qq_room_search_id(gc, uid); - if(group == NULL) { - purple_debug_info("QQ", - "Not find room id %d in qq_process_get_buddies_and_rooms\n", uid); - qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_INFO, uid, NULL, 0, - 0, QQ_ROOM_INFO_CREATE); + rmd = qq_room_data_find(gc, uid); + if(rmd == NULL) { + purple_debug_info("QQ", "Unknow room id %d", uid); + qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_INFO, uid); } else { - group->my_role = QQ_ROOM_ROLE_YES; - qq_group_refresh(gc, group); + rmd->my_role = QQ_ROOM_ROLE_YES; } ++j; } @@ -561,10 +559,11 @@ bd->ip.s_addr = bs.ip.s_addr; bd->port = bs.port; } - bd->status =bs.status; - + if (bd->status != bs.status) { + bd->status = bs.status; + qq_update_buddy_status(gc, bd->uid, bd->status, bd->comm_flag); + } bd->last_update = time(NULL); - qq_update_buddy_status(gc, bd->uid, bd->status, bd->comm_flag); if (bd->status == QQ_BUDDY_ONLINE_NORMAL && bd->level <= 0) { if (qd->client_version >= 2007) { @@ -649,6 +648,7 @@ if (bd->uid == qd->uid) continue; /* my status is always online in my buddy list */ if (tm_limit < bd->last_update) continue; if (bd->status == QQ_BUDDY_ONLINE_INVISIBLE) continue; + if (bd->status == QQ_BUDDY_CHANGE_TO_OFFLINE) continue; bd->status = QQ_BUDDY_CHANGE_TO_OFFLINE; bd->last_update = time(NULL); diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group.c --- a/libpurple/protocols/qq/group.c Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/group.c Tue Oct 28 16:38:16 2008 +0000 @@ -30,11 +30,10 @@ #include "group_internal.h" #include "group_info.h" -#include "group_search.h" +#include "group_join.h" #include "utils.h" #include "qq_network.h" #include "qq_define.h" -#include "group_free.h" static void _qq_group_search_callback(PurpleConnection *gc, const gchar *input) { @@ -130,44 +129,3 @@ purple_roomlist_set_in_progress(list, FALSE); purple_roomlist_unref(list); } - -/* this should be called upon signin, even when we did not open group chat window */ -void qq_group_init(PurpleConnection *gc) -{ - PurpleAccount *account; - PurpleChat *chat; - PurpleGroup *purple_group; - PurpleBlistNode *node; - qq_group *group; - gint count; - - 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"); - return; - } - - count = 0; - for (node = ((PurpleBlistNode *) purple_group)->child; node != NULL; node = node->next) { - if ( !PURPLE_BLIST_NODE_IS_CHAT(node)) { - continue; - } - /* got one */ - chat = (PurpleChat *) node; - if (account != chat->account) /* not qq account*/ - continue; - group = qq_room_data_new_by_hashtable(gc, chat->components); - if (group == NULL) - continue; - - if (group->id <= 0) - continue; - - count++; - } - - purple_debug_info("QQ", "Load %d QQ Qun configurations\n", count); -} diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group.h --- a/libpurple/protocols/qq/group.h Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/group.h Tue Oct 28 16:38:16 2008 +0000 @@ -40,7 +40,8 @@ QQ_ROOM_ROLE_ADMIN, } qq_room_role; -typedef struct _qq_group { +typedef struct _qq_room_data qq_room_data; +struct _qq_room_data { /* all these will be saved when we exit Purple */ qq_room_role my_role; /* my role for this room */ guint32 id; @@ -56,13 +57,11 @@ gboolean is_got_buddies; GList *members; -} qq_group; +}; GList *qq_chat_info(PurpleConnection *gc); GHashTable *qq_chat_info_defaults(PurpleConnection *gc, const gchar *chat_name); -void qq_group_init(PurpleConnection *gc); - PurpleRoomlist *qq_roomlist_get_list(PurpleConnection *gc); void qq_roomlist_cancel(PurpleRoomlist *list); diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group_find.c --- a/libpurple/protocols/qq/group_find.c Tue Oct 28 16:35:06 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,197 +0,0 @@ -/** - * @file group_find.c - * - * purple - * - * Purple is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "qq.h" - -#include "conversation.h" -#include "debug.h" -#include "util.h" - -#include "group_find.h" -#include "utils.h" - -/* find a qq_buddy_data by uid, called by im.c */ -qq_buddy_data *qq_group_find_member_by_uid(qq_group *group, guint32 uid) -{ - GList *list; - qq_buddy_data *bd; - g_return_val_if_fail(group != NULL && uid > 0, NULL); - - list = group->members; - while (list != NULL) { - bd = (qq_buddy_data *) list->data; - if (bd->uid == uid) - return bd; - else - list = list->next; - } - - return NULL; -} - -/* remove a qq_buddy_data by uid, called by qq_group_opt.c */ -void qq_group_remove_member_by_uid(qq_group *group, guint32 uid) -{ - GList *list; - qq_buddy_data *bd; - g_return_if_fail(group != NULL && uid > 0); - - list = group->members; - while (list != NULL) { - bd = (qq_buddy_data *) list->data; - if (bd->uid == uid) { - group->members = g_list_remove(group->members, bd); - return; - } else { - list = list->next; - } - } -} - -qq_buddy_data *qq_group_find_or_add_member(PurpleConnection *gc, qq_group *group, guint32 member_uid) -{ - qq_buddy_data *member, *bd; - PurpleBuddy *buddy; - g_return_val_if_fail(group != NULL && member_uid > 0, NULL); - - member = qq_group_find_member_by_uid(group, member_uid); - if (member == NULL) { /* first appear during my session */ - member = g_new0(qq_buddy_data, 1); - member->uid = member_uid; - buddy = purple_find_buddy(purple_connection_get_account(gc), uid_to_purple_name(member_uid)); - if (buddy != NULL) { - bd = (qq_buddy_data *) buddy->proto_data; - if (bd != NULL && bd->nickname != NULL) - member->nickname = g_strdup(bd->nickname); - else if (buddy->alias != NULL) - member->nickname = g_strdup(buddy->alias); - } - group->members = g_list_append(group->members, member); - } - - return member; -} - -qq_group *qq_room_search_id(PurpleConnection *gc, guint32 room_id) -{ - GList *list; - qq_group *group; - qq_data *qd; - - qd = (qq_data *) gc->proto_data; - - if (qd->groups == NULL || room_id <= 0) - return NULL; - - list = qd->groups; - while (list != NULL) { - group = (qq_group *) list->data; - if (group->id == room_id) { - return group; - } - list = list->next; - } - - return NULL; -} - -qq_group *qq_room_get_next(PurpleConnection *gc, guint32 room_id) -{ - GList *list; - qq_group *group; - qq_data *qd; - gboolean is_find = FALSE; - - qd = (qq_data *) gc->proto_data; - - if (qd->groups == NULL) { - return NULL; - } - - if (room_id <= 0) { - return (qq_group *) qd->groups->data; - } - - list = qd->groups; - while (list != NULL) { - group = (qq_group *) list->data; - list = list->next; - if (group->id == room_id) { - is_find = TRUE; - break; - } - } - - if ( !is_find || list == NULL) { - return NULL; - } - - return (qq_group *)list->data; -} - -qq_group *qq_room_get_next_conv(PurpleConnection *gc, guint32 room_id) -{ - GList *list; - qq_group *group; - qq_data *qd; - gboolean is_find; - - qd = (qq_data *) gc->proto_data; - - list = qd->groups; - if (room_id > 0) { - /* search next room */ - is_find = FALSE; - while (list != NULL) { - group = (qq_group *) list->data; - list = list->next; - if (group->id == room_id) { - is_find = TRUE; - break; - } - } - if ( !is_find || list == NULL) { - return NULL; - } - } - - is_find = FALSE; - while (list != NULL) { - group = (qq_group *) list->data; - if (group->my_role == QQ_ROOM_ROLE_YES || group->my_role == QQ_ROOM_ROLE_ADMIN) { - if (NULL != purple_find_conversation_with_account( - PURPLE_CONV_TYPE_CHAT,group->title_utf8, purple_connection_get_account(gc))) { - /* In convseration*/ - is_find = TRUE; - break; - } - } - list = list->next; - } - - if ( !is_find) { - return NULL; - } - return group; -} diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group_find.h --- a/libpurple/protocols/qq/group_find.h Tue Oct 28 16:35:06 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/** - * @file group_find.h - * - * purple - * - * Purple is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef _QQ_GROUP_FIND_H_ -#define _QQ_GROUP_FIND_H_ - -#include -#include "connection.h" -#include "group.h" - -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_room_search_id(PurpleConnection *gc, guint32 room_id); - -qq_group *qq_room_get_next(PurpleConnection *gc, guint32 room_id); -qq_group *qq_room_get_next_conv(PurpleConnection *gc, guint32 room_id); - -#endif diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group_free.c --- a/libpurple/protocols/qq/group_free.c Tue Oct 28 16:35:06 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/** - * @file group_free.c - * - * purple - * - * Purple is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "internal.h" - -#include "debug.h" - -#include "buddy_opt.h" -#include "group_free.h" - -/* gracefully free all members in a group */ -static void qq_group_free_member(qq_group *group) -{ - gint i; - GList *list; - qq_buddy_data *bd; - - g_return_if_fail(group != NULL); - i = 0; - while (NULL != (list = group->members)) { - bd = (qq_buddy_data *) list->data; - i++; - group->members = g_list_remove(group->members, bd); - qq_buddy_data_free(bd); - } - - group->members = NULL; -} - -/* gracefully free the memory for one qq_group */ -void qq_group_free(qq_group *group) -{ - g_return_if_fail(group != NULL); - qq_group_free_member(group); - g_free(group->title_utf8); - g_free(group->desc_utf8); - g_free(group->notice_utf8); - g_free(group); -} - -void qq_group_free_all(PurpleConnection *gc) -{ - qq_data *qd; - qq_group *group; - gint count; - - g_return_if_fail (gc != NULL && gc->proto_data != NULL); - qd = (qq_data *) gc->proto_data; - - count = 0; - while (qd->groups != NULL) { - group = (qq_group *) qd->groups->data; - qd->groups = g_list_remove(qd->groups, group); - qq_group_free(group); - count++; - } - - if (count > 0) { - purple_debug_info("QQ", "%d rooms are freed\n", count); - } -} diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group_free.h --- a/libpurple/protocols/qq/group_free.h Tue Oct 28 16:35:06 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/** - * @file group_free.h - * - * purple - * - * Purple is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef _QQ_GROUP_FREE_H_ -#define _QQ_GROUP_FREE_H_ - -#include -#include "qq.h" -#include "group.h" - -void qq_group_free(qq_group *group); -void qq_group_free_all(PurpleConnection *gc); - -#endif diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group_im.c --- a/libpurple/protocols/qq/group_im.c Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/group_im.c Tue Oct 28 16:38:16 2008 +0000 @@ -32,7 +32,6 @@ #include "util.h" #include "char_conv.h" -#include "group_find.h" #include "group_internal.h" #include "group_info.h" #include "group_im.h" @@ -45,41 +44,41 @@ #include "utils.h" /* show group conversation window */ -PurpleConversation *qq_room_conv_open(PurpleConnection *gc, qq_group *group) +PurpleConversation *qq_room_conv_open(PurpleConnection *gc, qq_room_data *rmd) { PurpleConversation *conv; qq_data *qd; gchar *topic_utf8; - g_return_val_if_fail(group != NULL, NULL); + g_return_val_if_fail(rmd != NULL, NULL); qd = (qq_data *) gc->proto_data; conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - group->title_utf8, purple_connection_get_account(gc)); + rmd->title_utf8, purple_connection_get_account(gc)); if (conv != NULL) { - /* show only one conversation per group */ + /* show only one conversation per room */ return conv; } - 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)); + serv_got_joined_chat(gc, rmd->id, rmd->title_utf8); + conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, rmd->title_utf8, purple_connection_get_account(gc)); if (conv != NULL) { - topic_utf8 = g_strdup_printf("%d %s", group->ext_id, group->notice_utf8); + topic_utf8 = g_strdup_printf("%d %s", rmd->ext_id, rmd->notice_utf8); purple_debug_info("QQ", "Set chat topic to %s\n", topic_utf8); purple_conv_chat_set_topic(PURPLE_CONV_CHAT(conv), NULL, topic_utf8); g_free(topic_utf8); - if (group->is_got_buddies) - qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_ONLINES, group->id); + if (rmd->is_got_buddies) + qq_send_room_cmd_only(gc, QQ_ROOM_CMD_GET_ONLINES, rmd->id); else - qq_update_room(gc, 0, group->id); + qq_update_room(gc, 0, rmd->id); return conv; } return NULL; } /* refresh online member in group conversation window */ -void qq_room_conv_set_onlines(PurpleConnection *gc, qq_group *group) +void qq_room_conv_set_onlines(PurpleConnection *gc, qq_room_data *rmd) { GList *names, *list, *flags; qq_buddy_data *bd; @@ -88,20 +87,20 @@ gint flag; gboolean is_find; - g_return_if_fail(group != NULL); + g_return_if_fail(rmd != NULL); conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - group->title_utf8, purple_connection_get_account(gc)); + rmd->title_utf8, purple_connection_get_account(gc)); if (conv == NULL) { - purple_debug_warning("QQ", "Conversation \"%s\" is not opened\n", group->title_utf8); + purple_debug_warning("QQ", "Conversation \"%s\" is not opened\n", rmd->title_utf8); return; } - g_return_if_fail(group->members != NULL); + g_return_if_fail(rmd->members != NULL); names = NULL; flags = NULL; - list = group->members; + list = rmd->members; while (list != NULL) { bd = (qq_buddy_data *) list->data; @@ -116,7 +115,7 @@ /* TYPING to put online above OP and FOUNDER */ if (is_online(bd->status)) flag |= (PURPLE_CBFLAGS_TYPING | PURPLE_CBFLAGS_VOICE); if(1 == (bd->role & 1)) flag |= PURPLE_CBFLAGS_OP; - if(bd->uid == group->creator_uid) flag |= PURPLE_CBFLAGS_FOUNDER; + if(bd->uid == rmd->creator_uid) flag |= PURPLE_CBFLAGS_FOUNDER; is_find = TRUE; if (purple_conv_chat_find_user(PURPLE_CONV_CHAT(conv), member_name)) @@ -251,19 +250,21 @@ } void qq_room_got_chat_in(PurpleConnection *gc, - qq_group *group, guint32 uid_from, const gchar *msg, time_t in_time) + guint32 room_id, guint32 uid_from, const gchar *msg, time_t in_time) { - PurpleAccount *account = purple_connection_get_account(gc); PurpleConversation *conv; qq_buddy_data *bd; + qq_room_data *rmd; gchar *from; - g_return_if_fail(group != NULL); + g_return_if_fail(gc != NULL && room_id != 0); - conv = purple_find_conversation_with_account( - PURPLE_CONV_TYPE_CHAT, group->title_utf8, account); + conv = purple_find_chat(gc, room_id); + rmd = qq_room_data_find(gc, room_id); + g_return_if_fail(rmd != NULL); + if (conv == NULL && purple_prefs_get_bool("/plugins/prpl/qq/show_room_when_newin")) { - conv = qq_room_conv_open(gc, group); + conv = qq_room_conv_open(gc, rmd); } if (conv == NULL) { @@ -271,7 +272,8 @@ } if (uid_from != 0) { - bd = qq_group_find_member_by_uid(group, uid_from); + + bd = qq_room_buddy_find(rmd, uid_from); if (bd == NULL || bd->nickname == NULL) from = g_strdup_printf("%d", uid_from); else @@ -279,9 +281,7 @@ } else { from = g_strdup(""); } - serv_got_chat_in(gc, - purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), - from, 0, msg, in_time); + serv_got_chat_in(gc, room_id, from, 0, msg, in_time); g_free(from); } @@ -291,7 +291,7 @@ guint32 ext_id, admin_uid; guint8 type8; gchar *reason_utf8, *msg, *reason; - qq_group *group; + qq_room_data *rmd; gint bytes; g_return_if_fail(data != NULL && len > 0); @@ -312,10 +312,10 @@ purple_notify_warning(gc, _("QQ Qun Operation"), msg, reason); - group = qq_room_search_id(gc, id); - if (group != NULL) { - group->my_role = QQ_ROOM_ROLE_NO; - qq_group_refresh(gc, group); + qq_room_find_or_new(gc, id, ext_id); + rmd = qq_room_data_find(gc, id); + if (rmd != NULL) { + rmd->my_role = QQ_ROOM_ROLE_NO; } g_free(msg); @@ -329,7 +329,7 @@ guint32 ext_id, admin_uid; guint8 type8; gchar *msg, *reason; - qq_group *group; + qq_room_data *rmd; gint bytes; time_t now; @@ -345,16 +345,16 @@ /* it is also a "无" here, so do not display */ bytes += qq_get_vstr(&reason, QQ_CHARSET_DEFAULT, data + bytes); - group = qq_room_search_id(gc, id); - if (group != NULL) { - group->my_role = QQ_ROOM_ROLE_YES; - qq_group_refresh(gc, group); + qq_room_find_or_new(gc, id, ext_id); + rmd = qq_room_data_find(gc, id); + if (rmd != NULL) { + rmd->my_role = QQ_ROOM_ROLE_YES; } msg = g_strdup_printf(_("Joinning Qun %d is approved by Admin %d for %s"), ext_id, admin_uid, reason); now = time(NULL); - qq_room_got_chat_in(gc, group, 0, msg, now); + qq_room_got_chat_in(gc, id, 0, msg, now); g_free(msg); g_free(reason); @@ -366,7 +366,7 @@ guint32 ext_id, uid; guint8 type8; gchar *msg; - qq_group *group; + qq_room_data *rmd; gint bytes = 0; time_t now = time(NULL); @@ -380,14 +380,14 @@ g_return_if_fail(ext_id > 0 && uid > 0); - group = qq_room_search_id(gc, id); - if (group != NULL) { - group->my_role = QQ_ROOM_ROLE_NO; - qq_group_refresh(gc, group); + qq_room_find_or_new(gc, id, ext_id); + rmd = qq_room_data_find(gc, id); + if (rmd != NULL) { + rmd->my_role = QQ_ROOM_ROLE_NO; } msg = g_strdup_printf(_("Removed buddy %d."), uid); - qq_room_got_chat_in(gc, group, 0, msg, now); + qq_room_got_chat_in(gc, id, 0, msg, now); g_free(msg); } @@ -396,9 +396,9 @@ { guint32 ext_id, uid; guint8 type8; - qq_group *group; + qq_room_data *rmd; + gint bytes; gchar *msg; - gint bytes; time_t now = time(NULL); g_return_if_fail(data != NULL && len > 0); @@ -409,22 +409,18 @@ bytes += qq_get8(&type8, data + bytes); bytes += qq_get32(&uid, data + bytes); - g_return_if_fail(ext_id > 0 && uid > 0); + g_return_if_fail(ext_id > 0 && id > 0); - group = qq_room_search_id(gc, id); - if (group != NULL) { - group->my_role = QQ_ROOM_ROLE_YES; - qq_group_refresh(gc, group); - } else { /* no such group, try to create a dummy first, and then update */ - group = qq_group_create_internal_record(gc, id, ext_id, NULL); - group->my_role = QQ_ROOM_ROLE_YES; - qq_group_refresh(gc, group); - qq_update_room(gc, 0, group->id); - /* the return of this cmd will automatically update the group in blist */ - } + qq_room_find_or_new(gc, id, ext_id); + rmd = qq_room_data_find(gc, id); + g_return_if_fail(rmd != NULL); + + rmd->my_role = QQ_ROOM_ROLE_YES; + + qq_update_room(gc, 0, rmd->id); msg = g_strdup_printf(_("Added new buddy %d."), uid); - qq_room_got_chat_in(gc, group, 0, msg, now); + qq_room_got_chat_in(gc, id, 0, msg, now); g_free(msg); } @@ -433,7 +429,6 @@ { gchar *msg_with_purple_smiley, *msg_utf8_encoded; qq_data *qd; - qq_group *group; gint skip_len; gint bytes ; struct { @@ -458,7 +453,7 @@ qd = (qq_data *) gc->proto_data; #if 1 - qq_hex_dump(PURPLE_DEBUG_INFO, "QQ", data, data_len, "group im hex dump"); + qq_show_packet("Room IM", data, data_len); #endif memset(&packet, 0, sizeof(packet)); bytes = 0; @@ -519,8 +514,7 @@ } else { msg_utf8_encoded = qq_to_utf8(msg_with_purple_smiley, QQ_CHARSET_DEFAULT); } - group = qq_room_search_id(gc, id); - qq_room_got_chat_in(gc, group, packet.member_uid, msg_utf8_encoded, packet.send_time); + qq_room_got_chat_in(gc, id, packet.member_uid, msg_utf8_encoded, packet.send_time); g_free(msg_with_purple_smiley); g_free(msg_utf8_encoded); diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group_im.h --- a/libpurple/protocols/qq/group_im.h Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/group_im.h Tue Oct 28 16:38:16 2008 +0000 @@ -30,11 +30,11 @@ #include "conversation.h" #include "group.h" -PurpleConversation *qq_room_conv_open(PurpleConnection *gc, qq_group *group); -void qq_room_conv_set_onlines(PurpleConnection *gc, qq_group *group); +PurpleConversation *qq_room_conv_open(PurpleConnection *gc, qq_room_data *rmd); +void qq_room_conv_set_onlines(PurpleConnection *gc, qq_room_data *rmd); void qq_room_got_chat_in(PurpleConnection *gc, - qq_group *group, guint32 uid_from, const gchar *msg, time_t in_time); + guint32 room_id, guint32 uid_from, const gchar *msg, time_t in_time); void qq_send_packet_group_im(PurpleConnection *gc, guint32 room_id, const gchar *msg); diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group_info.c --- a/libpurple/protocols/qq/group_info.c Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/group_info.c Tue Oct 28 16:38:16 2008 +0000 @@ -29,7 +29,6 @@ #include "char_conv.h" #include "group_im.h" -#include "group_find.h" #include "group_internal.h" #include "group_info.h" #include "buddy_list.h" @@ -51,13 +50,13 @@ /* this is done when we receive the reply to get_online_members sub_cmd * all member are set offline, and then only those in reply packets are online */ -static void set_all_offline(qq_group *group) +static void set_all_offline(qq_room_data *rmd) { GList *list; qq_buddy_data *bd; - g_return_if_fail(group != NULL); + g_return_if_fail(rmd != NULL); - list = group->members; + list = rmd->members; while (list != NULL) { bd = (qq_buddy_data *) list->data; bd->status = QQ_BUDDY_CHANGE_TO_OFFLINE; @@ -66,15 +65,20 @@ } /* send packet to get info for each group member */ -gint qq_request_room_get_buddies(PurpleConnection *gc, qq_group *group, gint update_class) +gint qq_request_room_get_buddies(PurpleConnection *gc, guint32 room_id, gint update_class) { guint8 *raw_data; gint bytes, num; GList *list; + qq_room_data *rmd; qq_buddy_data *bd; - g_return_val_if_fail(group != NULL, 0); - for (num = 0, list = group->members; list != NULL; list = list->next) { + g_return_val_if_fail(room_id > 0, 0); + + rmd = qq_room_data_find(gc, room_id); + g_return_val_if_fail(rmd != NULL, 0); + + for (num = 0, list = rmd->members; list != NULL; list = list->next) { bd = (qq_buddy_data *) list->data; if (check_update_interval(bd)) num++; @@ -89,7 +93,7 @@ bytes = 0; - list = group->members; + list = rmd->members; while (list != NULL) { bd = (qq_buddy_data *) list->data; if (check_update_interval(bd)) @@ -97,7 +101,7 @@ list = list->next; } - qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_BUDDIES, group->id, raw_data, bytes, + qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_BUDDIES, rmd->id, raw_data, bytes, update_class, 0); return num; } @@ -125,38 +129,38 @@ return g_strdup(role_desc); } -static void room_info_display(PurpleConnection *gc, qq_group *group) +static void room_info_display(PurpleConnection *gc, qq_room_data *rmd) { PurpleNotifyUserInfo *room_info; gchar *utf8_value; - g_return_if_fail(group != NULL && group->id > 0); + g_return_if_fail(rmd != NULL && rmd->id > 0); room_info = purple_notify_user_info_new(); - purple_notify_user_info_add_pair(room_info, _("Title"), group->title_utf8); - purple_notify_user_info_add_pair(room_info, _("Notice"), group->notice_utf8); - purple_notify_user_info_add_pair(room_info, _("Detail"), group->desc_utf8); + purple_notify_user_info_add_pair(room_info, _("Title"), rmd->title_utf8); + purple_notify_user_info_add_pair(room_info, _("Notice"), rmd->notice_utf8); + purple_notify_user_info_add_pair(room_info, _("Detail"), rmd->desc_utf8); purple_notify_user_info_add_section_break(room_info); - utf8_value = g_strdup_printf(("%d"), group->creator_uid); + utf8_value = g_strdup_printf(("%d"), rmd->creator_uid); purple_notify_user_info_add_pair(room_info, _("Creator"), utf8_value); g_free(utf8_value); - utf8_value = get_role_desc(group->my_role); + utf8_value = get_role_desc(rmd->my_role); purple_notify_user_info_add_pair(room_info, _("About me"), utf8_value); g_free(utf8_value); - utf8_value = g_strdup_printf(("%d"), group->category); + utf8_value = g_strdup_printf(("%d"), rmd->category); purple_notify_user_info_add_pair(room_info, _("Category"), utf8_value); g_free(utf8_value); - utf8_value = g_strdup_printf(("%d"), group->auth_type); + utf8_value = g_strdup_printf(("%d"), rmd->auth_type); purple_notify_user_info_add_pair(room_info, _("Authorize"), utf8_value); g_free(utf8_value); - utf8_value = g_strdup_printf(("%d"), group->ext_id); + utf8_value = g_strdup_printf(("%d"), rmd->ext_id); purple_notify_userinfo(gc, utf8_value, room_info, NULL, NULL); g_free(utf8_value); @@ -165,9 +169,10 @@ void qq_process_room_cmd_get_info(guint8 *data, gint data_len, guint32 action, PurpleConnection *gc) { - qq_group *group; + qq_data *qd; + qq_room_data *rmd; qq_buddy_data *bd; - qq_data *qd; + PurpleChat *chat; PurpleConversation *conv; guint8 organization, role; guint16 unknown, max_members; @@ -190,20 +195,18 @@ bytes += qq_get32(&ext_id, data + bytes); g_return_if_fail(ext_id > 0); - if (action == QQ_ROOM_INFO_CREATE ) { - qq_group_create_internal_record(gc, id, ext_id, NULL); - } + chat = qq_room_find_or_new(gc, id, ext_id); + g_return_if_fail(chat != NULL); + rmd = qq_room_data_find(gc, id); + g_return_if_fail(rmd != NULL); - group = qq_room_search_id(gc, id); - g_return_if_fail(group != NULL); - - bytes += qq_get8(&(group->type8), data + bytes); + bytes += qq_get8(&(rmd->type8), data + bytes); bytes += qq_get32(&unknown4, data + bytes); /* unknown 4 bytes */ - bytes += qq_get32(&(group->creator_uid), data + bytes); - bytes += qq_get8(&(group->auth_type), data + bytes); + bytes += qq_get32(&(rmd->creator_uid), data + bytes); + bytes += qq_get8(&(rmd->auth_type), data + bytes); bytes += qq_get32(&unknown4, data + bytes); /* oldCategory */ bytes += qq_get16(&unknown, data + bytes); - bytes += qq_get32(&(group->category), data + bytes); + bytes += qq_get32(&(rmd->category), data + bytes); bytes += qq_get16(&max_members, data + bytes); bytes += qq_get8(&unknown1, data + bytes); /* the following, while Eva: @@ -212,7 +215,7 @@ * qunDestLen(qunDestcontent)) */ bytes += qq_get8(&unknown1, data + bytes); purple_debug_info("QQ", "type=%u creatorid=%u category=%u maxmembers=%u\n", - group->type8, group->creator_uid, group->category, max_members); + rmd->type8, rmd->creator_uid, rmd->category, max_members); if (qd->client_version >= 2007) { /* skip 7 bytes unknow in qq2007 0x(00 00 01 00 00 00 fc)*/ @@ -220,13 +223,13 @@ } /* qq_show_packet("Room Info", data + bytes, data_len - bytes); */ /* strlen + */ - bytes += qq_get_vstr(&(group->title_utf8), QQ_CHARSET_DEFAULT, data + bytes); + bytes += qq_get_vstr(&(rmd->title_utf8), QQ_CHARSET_DEFAULT, data + bytes); bytes += qq_get16(&unknown, data + bytes); /* 0x0000 */ bytes += qq_get_vstr(¬ice, QQ_CHARSET_DEFAULT, data + bytes); - bytes += qq_get_vstr(&(group->desc_utf8), QQ_CHARSET_DEFAULT, data + bytes); + bytes += qq_get_vstr(&(rmd->desc_utf8), QQ_CHARSET_DEFAULT, data + bytes); purple_debug_info("QQ", "room [%s] notice [%s] desc [%s] unknow 0x%04X\n", - group->title_utf8, notice, group->desc_utf8, unknown); + rmd->title_utf8, notice, rmd->desc_utf8, unknown); num = 0; /* now comes the member list separated by 0x00 */ @@ -242,7 +245,7 @@ } #endif - bd = qq_group_find_or_add_member(gc, group, member_uid); + bd = qq_room_buddy_find_or_new(gc, rmd, member_uid); if (bd != NULL) bd->role = role; } @@ -251,30 +254,30 @@ "group_cmd_get_group_info: Dangerous error! maybe protocol changed, notify me!"); } - purple_debug_info("QQ", "group \"%s\" has %d members\n", group->title_utf8, num); + purple_debug_info("QQ", "group \"%s\" has %d members\n", rmd->title_utf8, num); - if (group->creator_uid == qd->uid) - group->my_role = QQ_ROOM_ROLE_ADMIN; + if (rmd->creator_uid == qd->uid) + rmd->my_role = QQ_ROOM_ROLE_ADMIN; /* filter \r\n in notice */ qq_filter_str(notice); - group->notice_utf8 = strdup(notice); + rmd->notice_utf8 = strdup(notice); g_free(notice); - qq_group_refresh(gc, group); + qq_room_update_chat_info(chat, rmd); if (action == QQ_ROOM_INFO_DISPLAY) { - room_info_display(gc, group); + room_info_display(gc, rmd); } conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - group->title_utf8, purple_connection_get_account(gc)); + rmd->title_utf8, purple_connection_get_account(gc)); if(NULL == conv) { - purple_debug_warning("QQ", "Conversation \"%s\" is not opened\n", group->title_utf8); + purple_debug_warning("QQ", "Conversation \"%s\" is not opened\n", rmd->title_utf8); return; } - topic_utf8 = g_strdup_printf("%d %s", group->ext_id, group->notice_utf8); + topic_utf8 = g_strdup_printf("%d %s", rmd->ext_id, rmd->notice_utf8); purple_debug_info("QQ", "Set chat topic to %s\n", topic_utf8); purple_conv_chat_set_topic(PURPLE_CONV_CHAT(conv), NULL, topic_utf8); g_free(topic_utf8); @@ -285,7 +288,7 @@ guint32 id, member_uid; guint8 unknown; gint bytes, num; - qq_group *group; + qq_room_data *rmd; qq_buddy_data *bd; g_return_if_fail(data != NULL && len > 0); @@ -300,19 +303,19 @@ bytes += qq_get8(&unknown, data + bytes); /* 0x3c ?? */ g_return_if_fail(id > 0); - group = qq_room_search_id(gc, id); - if (group == NULL) { + rmd = qq_room_data_find(gc, id); + if (rmd == NULL) { purple_debug_error("QQ", "We have no group info for internal id [%d]\n", id); return; } /* set all offline first, then update those online */ - set_all_offline(group); + set_all_offline(rmd); num = 0; while (bytes < len) { bytes += qq_get32(&member_uid, data + bytes); num++; - bd = qq_group_find_or_add_member(gc, group, member_uid); + bd = qq_room_buddy_find_or_new(gc, rmd, member_uid); if (bd != NULL) bd->status = QQ_BUDDY_ONLINE_NORMAL; } @@ -321,8 +324,8 @@ "group_cmd_get_online_members: Dangerous error! maybe protocol changed, notify developers!"); } - purple_debug_info("QQ", "Group \"%s\" has %d online members\n", group->title_utf8, num); - qq_room_conv_set_onlines(gc, group); + purple_debug_info("QQ", "Group \"%s\" has %d online members\n", rmd->title_utf8, num); + qq_room_conv_set_onlines(gc, rmd); } /* process the reply to get_members_info packet */ @@ -332,7 +335,7 @@ gint num; guint32 id, member_uid; guint16 unknown; - qq_group *group; + qq_room_data *rmd; qq_buddy_data *bd; gchar *nick; @@ -344,15 +347,15 @@ bytes += qq_get32(&id, data + bytes); g_return_if_fail(id > 0); - group = qq_room_search_id(gc, id); - g_return_if_fail(group != NULL); + rmd = qq_room_data_find(gc, id); + g_return_if_fail(rmd != NULL); num = 0; /* now starts the member info, as get buddy list reply */ while (bytes < len) { bytes += qq_get32(&member_uid, data + bytes); g_return_if_fail(member_uid > 0); - bd = qq_group_find_member_by_uid(group, member_uid); + bd = qq_room_buddy_find_or_new(gc, rmd, member_uid); g_return_if_fail(bd != NULL); num++; @@ -381,9 +384,9 @@ purple_debug_error("QQ", "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); + purple_debug_info("QQ", "Group \"%s\" obtained %d member info\n", rmd->title_utf8, num); - group->is_got_buddies = TRUE; - qq_room_conv_set_onlines(gc, group); + rmd->is_got_buddies = TRUE; + qq_room_conv_set_onlines(gc, rmd); } diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group_info.h --- a/libpurple/protocols/qq/group_info.h Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/group_info.h Tue Oct 28 16:38:16 2008 +0000 @@ -32,10 +32,9 @@ 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); +gint qq_request_room_get_buddies(PurpleConnection *gc, guint32 room_id, gint update_class); void qq_process_room_cmd_get_info(guint8 *data, gint len, guint32 action, PurpleConnection *gc); void qq_process_room_cmd_get_onlines(guint8 *data, gint len, PurpleConnection *gc); diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group_internal.c --- a/libpurple/protocols/qq/group_internal.c Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/group_internal.c Tue Oct 28 16:38:16 2008 +0000 @@ -27,151 +27,395 @@ #include "debug.h" #include "buddy_opt.h" -#include "group_free.h" #include "group_internal.h" #include "utils.h" -static void add_room_to_blist(PurpleConnection *gc, qq_group *group) +static qq_room_data *room_data_new(guint32 id, guint32 ext_id, gchar *title) +{ + qq_room_data *rmd; + + purple_debug_info("QQ", "Created room data: %s, ext id %d, id %d\n", + title, ext_id, id); + rmd = g_new0(qq_room_data, 1); + rmd->my_role = QQ_ROOM_ROLE_NO; + rmd->id = id; + rmd->ext_id = ext_id; + rmd->type8 = 0x01; /* assume permanent Qun */ + rmd->creator_uid = 10000; /* assume by QQ admin */ + rmd->category = 0x01; + rmd->auth_type = 0x02; /* assume need auth */ + rmd->title_utf8 = g_strdup(title == NULL ? "" : title); + rmd->desc_utf8 = g_strdup(""); + rmd->notice_utf8 = g_strdup(""); + rmd->members = NULL; + rmd->is_got_buddies = FALSE; + return rmd; +} + +/* create a qq_room_data from hashtable */ +static qq_room_data *room_data_new_by_hashtable(PurpleConnection *gc, GHashTable *data) +{ + qq_room_data *rmd; + guint32 id, ext_id; + gchar *value; + + value = g_hash_table_lookup(data, QQ_ROOM_KEY_INTERNAL_ID); + id = value ? strtol(value, NULL, 10) : 0; + value= g_hash_table_lookup(data, QQ_ROOM_KEY_EXTERNAL_ID); + ext_id = value ? strtol(value, NULL, 10) : 0; + value = g_strdup(g_hash_table_lookup(data, QQ_ROOM_KEY_TITLE_UTF8)); + + rmd = room_data_new(id, ext_id, value); + rmd->my_role = QQ_ROOM_ROLE_YES; + return rmd; +} + +/* gracefully free all members in a room */ +static void room_buddies_free(qq_room_data *rmd) +{ + gint i; + GList *list; + qq_buddy_data *bd; + + g_return_if_fail(rmd != NULL); + i = 0; + while (NULL != (list = rmd->members)) { + bd = (qq_buddy_data *) list->data; + i++; + rmd->members = g_list_remove(rmd->members, bd); + qq_buddy_data_free(bd); + } + + rmd->members = NULL; +} + +/* gracefully free the memory for one qq_room_data */ +static void room_data_free(qq_room_data *rmd) +{ + g_return_if_fail(rmd != NULL); + room_buddies_free(rmd); + g_free(rmd->title_utf8); + g_free(rmd->desc_utf8); + g_free(rmd->notice_utf8); + g_free(rmd); +} + +void qq_room_update_chat_info(PurpleChat *chat, qq_room_data *rmd) +{ + if (rmd->title_utf8 != NULL && strlen(rmd->title_utf8) > 0) { + purple_blist_alias_chat(chat, rmd->title_utf8); + } + g_hash_table_replace(chat->components, + g_strdup(QQ_ROOM_KEY_INTERNAL_ID), + g_strdup_printf("%d", rmd->id)); + g_hash_table_replace(chat->components, + g_strdup(QQ_ROOM_KEY_EXTERNAL_ID), + g_strdup_printf("%d", rmd->ext_id)); + g_hash_table_replace(chat->components, + g_strdup(QQ_ROOM_KEY_TITLE_UTF8), g_strdup(rmd->title_utf8)); +} + +static PurpleChat *chat_new(PurpleConnection *gc, qq_room_data *rmd) { GHashTable *components; PurpleGroup *g; PurpleChat *chat; - components = qq_group_to_hashtable(group); - chat = purple_chat_new(purple_connection_get_account(gc), group->title_utf8, components); + + purple_debug_info("QQ", "Add new chat: id %d, ext id %d, title %s\n", + rmd->id, rmd->ext_id, rmd->title_utf8); + + components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + g_hash_table_insert(components, + g_strdup(QQ_ROOM_KEY_INTERNAL_ID), g_strdup_printf("%d", rmd->id)); + g_hash_table_insert(components, g_strdup(QQ_ROOM_KEY_EXTERNAL_ID), + g_strdup_printf("%d", rmd->ext_id)); + g_hash_table_insert(components, g_strdup(QQ_ROOM_KEY_TITLE_UTF8), g_strdup(rmd->title_utf8)); + + chat = purple_chat_new(purple_connection_get_account(gc), rmd->title_utf8, components); g = qq_group_find_or_new(PURPLE_GROUP_QQ_QUN); purple_blist_add_chat(chat, g, NULL); - purple_debug_info("QQ", "Added room \"%s\" to blist locally\n", group->title_utf8); + + return chat; +} + +PurpleChat *qq_room_find_or_new(PurpleConnection *gc, guint32 id, guint32 ext_id) +{ + qq_data *qd; + qq_room_data *rmd; + PurpleChat *chat; + gchar *num_str; + + g_return_val_if_fail (gc != NULL && gc->proto_data != NULL, NULL); + qd = (qq_data *) gc->proto_data; + + g_return_val_if_fail(id != 0 && ext_id != 0, NULL); + + purple_debug_info("QQ", "Find or add new room: id %d, ext id %d\n", id, ext_id); + + rmd = qq_room_data_find(gc, id); + if (rmd == NULL) { + rmd = room_data_new(id, ext_id, NULL); + g_return_val_if_fail(rmd != NULL, NULL); + qd->groups = g_list_append(qd->groups, rmd); + } + + num_str = g_strdup_printf("%d", ext_id); + chat = purple_blist_find_chat(purple_connection_get_account(gc), num_str); + g_free(num_str); + if (chat) { + return chat; + } + + return chat_new(gc, rmd); } -/* Create a dummy qq_group, which includes only internal_id, ext_id, - * and potentially title_utf8, in case we need to call group_conv_show_window - * right after creation. All other attributes are set to empty. - * We need to send a get_group_info to the QQ server to update it right away */ -qq_group *qq_group_create_internal_record(PurpleConnection *gc, - guint32 internal_id, guint32 ext_id, gchar *title_utf8) +void qq_room_remove(PurpleConnection *gc, guint32 id) { - qq_group *group; - qq_data *qd; + qq_data *qd; + PurpleChat *chat; + qq_room_data *rmd; + gchar *num_str; + guint32 ext_id; - g_return_val_if_fail(internal_id > 0, NULL); - qd = (qq_data *) gc->proto_data; + g_return_if_fail (gc != NULL && gc->proto_data != NULL); + qd = (qq_data *) gc->proto_data; - group = g_new0(qq_group, 1); - group->my_role = QQ_ROOM_ROLE_NO; - group->id = internal_id; - group->ext_id = ext_id; - group->type8 = 0x01; /* assume permanent Qun */ - group->creator_uid = 10000; /* assume by QQ admin */ - group->category = 0x01; - group->auth_type = 0x02; /* assume need auth */ - group->title_utf8 = g_strdup(title_utf8 == NULL ? "" : title_utf8); - group->desc_utf8 = g_strdup(""); - group->notice_utf8 = g_strdup(""); - group->members = NULL; + purple_debug_info("QQ", "Find and remove room data, id %d", id); + rmd = qq_room_data_find(gc, id); + g_return_if_fail (rmd != NULL); + + ext_id = rmd->ext_id; + qd->groups = g_list_remove(qd->groups, rmd); + room_data_free(rmd); - qd->groups = g_list_append(qd->groups, group); - add_room_to_blist(gc, group); + purple_debug_info("QQ", "Find and remove chat, ext_id %d", ext_id); + num_str = g_strdup_printf("%d", ext_id); + chat = purple_blist_find_chat(purple_connection_get_account(gc), num_str); + g_free(num_str); - return group; + g_return_if_fail (chat != NULL); + + purple_blist_remove_chat(chat); } -void qq_group_delete_internal_record(qq_data *qd, guint32 id) +/* find a qq_buddy_data by uid, called by im.c */ +qq_buddy_data *qq_room_buddy_find(qq_room_data *rmd, guint32 uid) { - qq_group *group; - GList *list; + GList *list; + qq_buddy_data *bd; + g_return_val_if_fail(rmd != NULL && uid > 0, NULL); + + list = rmd->members; + while (list != NULL) { + bd = (qq_buddy_data *) list->data; + if (bd->uid == uid) + return bd; + else + list = list->next; + } - list = qd->groups; - while (list != NULL) { - group = (qq_group *) qd->groups->data; - if (id == group->id) { - qd->groups = g_list_remove(qd->groups, group); - qq_group_free(group); - break; - } else { - list = list->next; - } - } + return NULL; +} + +/* remove a qq_buddy_data by uid, called by qq_group_opt.c */ +void qq_room_buddy_remove(qq_room_data *rmd, guint32 uid) +{ + GList *list; + qq_buddy_data *bd; + g_return_if_fail(rmd != NULL && uid > 0); + + list = rmd->members; + while (list != NULL) { + bd = (qq_buddy_data *) list->data; + if (bd->uid == uid) { + rmd->members = g_list_remove(rmd->members, bd); + return; + } else { + list = list->next; + } + } } -/* convert a qq_group to hash-table, which could be component of PurpleChat */ -GHashTable *qq_group_to_hashtable(qq_group *group) +qq_buddy_data *qq_room_buddy_find_or_new(PurpleConnection *gc, qq_room_data *rmd, guint32 member_uid) { - GHashTable *components; - components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + qq_buddy_data *member, *bd; + PurpleBuddy *buddy; + g_return_val_if_fail(rmd != NULL && member_uid > 0, NULL); - g_hash_table_insert(components, - g_strdup(QQ_ROOM_KEY_INTERNAL_ID), g_strdup_printf("%d", group->id)); - g_hash_table_insert(components, g_strdup(QQ_ROOM_KEY_EXTERNAL_ID), - g_strdup_printf("%d", group->ext_id)); - g_hash_table_insert(components, g_strdup(QQ_ROOM_KEY_TITLE_UTF8), g_strdup(group->title_utf8)); - return components; + member = qq_room_buddy_find(rmd, member_uid); + if (member == NULL) { /* first appear during my session */ + member = g_new0(qq_buddy_data, 1); + member->uid = member_uid; + buddy = purple_find_buddy(purple_connection_get_account(gc), uid_to_purple_name(member_uid)); + if (buddy != NULL) { + bd = (qq_buddy_data *) buddy->proto_data; + if (bd != NULL && bd->nickname != NULL) + member->nickname = g_strdup(bd->nickname); + else if (buddy->alias != NULL) + member->nickname = g_strdup(buddy->alias); + } + rmd->members = g_list_append(rmd->members, member); + } + + return member; } -static gint str2dec(const gchar *str) +qq_room_data *qq_room_data_find(PurpleConnection *gc, guint32 room_id) { - g_return_val_if_fail(str != NULL, 0); - return strtol(str, NULL, 10); + GList *list; + qq_room_data *rmd; + qq_data *qd; + + qd = (qq_data *) gc->proto_data; + + if (qd->groups == NULL || room_id <= 0) + return 0; + + list = qd->groups; + while (list != NULL) { + rmd = (qq_room_data *) list->data; + if (rmd->id == room_id) { + return rmd; + } + list = list->next; + } + + return NULL; } -/* create a qq_group from hashtable */ -qq_group *qq_room_data_new_by_hashtable(PurpleConnection *gc, GHashTable *data) +guint32 qq_room_get_next(PurpleConnection *gc, guint32 room_id) { + GList *list; + qq_room_data *rmd; qq_data *qd; - qq_group *group; + gboolean is_find = FALSE; - g_return_val_if_fail(data != NULL, NULL); qd = (qq_data *) gc->proto_data; - group = g_new0(qq_group, 1); - memset(group, 0, sizeof(qq_group)); - group->my_role = QQ_ROOM_ROLE_YES; - 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->title_utf8 = g_strdup(g_hash_table_lookup(data, QQ_ROOM_KEY_TITLE_UTF8)); - group->type8 = 0x01; /* assume permanent Qun */ - group->creator_uid = 10000; /* assume by QQ admin */ - group->category = 0x01; - group->auth_type = 0x02; /* assume need auth */ - group->desc_utf8 = g_strdup(""); - group->notice_utf8 = g_strdup(""); - group->members = NULL; - group->is_got_buddies = FALSE; + if (qd->groups == NULL) { + return 0; + } + + if (room_id <= 0) { + rmd = (qq_room_data *) qd->groups->data; + return rmd->id; + } - 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; + list = qd->groups; + while (list != NULL) { + rmd = (qq_room_data *) list->data; + list = list->next; + if (rmd->id == room_id) { + is_find = TRUE; + break; + } + } + + g_return_val_if_fail(is_find, 0); + if (list == NULL) return 0; /* be the end */ + rmd = (qq_room_data *) list->data; + g_return_val_if_fail(rmd != NULL, 0); + return rmd->id; } -/* refresh group local subscription */ -void qq_group_refresh(PurpleConnection *gc, qq_group *group) +guint32 qq_room_get_next_conv(PurpleConnection *gc, guint32 room_id) { + GList *list; + qq_room_data *rmd; + qq_data *qd; + gboolean is_find; + + qd = (qq_data *) gc->proto_data; + + list = qd->groups; + if (room_id > 0) { + /* search next room */ + is_find = FALSE; + while (list != NULL) { + rmd = (qq_room_data *) list->data; + list = list->next; + if (rmd->id == room_id) { + is_find = TRUE; + break; + } + } + g_return_val_if_fail(is_find, 0); + } + + while (list != NULL) { + rmd = (qq_room_data *) list->data; + g_return_val_if_fail(rmd != NULL, 0); + + if (rmd->my_role == QQ_ROOM_ROLE_YES || rmd->my_role == QQ_ROOM_ROLE_ADMIN) { + if (NULL != purple_find_conversation_with_account( + PURPLE_CONV_TYPE_CHAT,rmd->title_utf8, purple_connection_get_account(gc))) { + /* In convseration*/ + return rmd->id; + } + } + list = list->next; + } + + return 0; +} + +/* this should be called upon signin, even when we did not open group chat window */ +void qq_room_data_initial(PurpleConnection *gc) +{ + PurpleAccount *account; PurpleChat *chat; - gchar *ext_id; - g_return_if_fail(group != NULL); + PurpleGroup *purple_group; + PurpleBlistNode *node; + qq_data *qd; + qq_room_data *rmd; + gint count; - ext_id = g_strdup_printf("%d", group->ext_id); - chat = purple_blist_find_chat(purple_connection_get_account(gc), ext_id); - g_free(ext_id); - if (chat == NULL && group->my_role != QQ_ROOM_ROLE_NO) { - add_room_to_blist(gc, group); + account = purple_connection_get_account(gc); + qd = (qq_data *) gc->proto_data; + + 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"); return; } - if (chat == NULL) { - return; + count = 0; + for (node = ((PurpleBlistNode *) purple_group)->child; node != NULL; node = node->next) { + if ( !PURPLE_BLIST_NODE_IS_CHAT(node)) { + continue; + } + /* got one */ + chat = (PurpleChat *) node; + if (account != chat->account) /* not qq account*/ + continue; + + rmd = room_data_new_by_hashtable(gc, chat->components); + qd->groups = g_list_append(qd->groups, rmd); + count++; } - /* we have a local record, update its info */ - /* if there is title_utf8, we update the group name */ - if (group->title_utf8 != NULL && strlen(group->title_utf8) > 0) - purple_blist_alias_chat(chat, group->title_utf8); - g_hash_table_replace(chat->components, - g_strdup(QQ_ROOM_KEY_INTERNAL_ID), - g_strdup_printf("%d", group->id)); - g_hash_table_replace(chat->components, - g_strdup(QQ_ROOM_KEY_EXTERNAL_ID), - g_strdup_printf("%d", group->ext_id)); - g_hash_table_replace(chat->components, - g_strdup(QQ_ROOM_KEY_TITLE_UTF8), g_strdup(group->title_utf8)); + purple_debug_info("QQ", "Load %d QQ Qun configurations\n", count); } + +void qq_room_data_free_all(PurpleConnection *gc) +{ + qq_data *qd; + qq_room_data *rmd; + gint count; + + g_return_if_fail (gc != NULL && gc->proto_data != NULL); + qd = (qq_data *) gc->proto_data; + + count = 0; + while (qd->groups != NULL) { + rmd = (qq_room_data *) qd->groups->data; + qd->groups = g_list_remove(qd->groups, rmd); + room_data_free(rmd); + count++; + } + + if (count > 0) { + purple_debug_info("QQ", "%d rooms are freed\n", count); + } +} diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group_internal.h --- a/libpurple/protocols/qq/group_internal.h Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/group_internal.h Tue Oct 28 16:38:16 2008 +0000 @@ -32,13 +32,19 @@ #define QQ_ROOM_KEY_EXTERNAL_ID "ext_id" #define QQ_ROOM_KEY_TITLE_UTF8 "title_utf8" -qq_group *qq_group_create_internal_record(PurpleConnection *gc, - guint32 internal_id, guint32 ext_id, gchar *group_name_utf8); -void qq_group_delete_internal_record(qq_data *qd, guint32 id); +PurpleChat *qq_room_find_or_new(PurpleConnection *gc, guint32 id, guint32 ext_id); +void qq_room_remove(PurpleConnection *gc, guint32 id); +void qq_room_update_chat_info(PurpleChat *chat, qq_room_data *rmd); -GHashTable *qq_group_to_hashtable(qq_group *group); -qq_group *qq_room_data_new_by_hashtable(PurpleConnection *gc, GHashTable *data); +qq_buddy_data *qq_room_buddy_find(qq_room_data *rmd, guint32 uid); +void qq_room_buddy_remove(qq_room_data *rmd, guint32 uid); +qq_buddy_data *qq_room_buddy_find_or_new(PurpleConnection *gc, qq_room_data *rmd, guint32 member_uid); -void qq_group_refresh(PurpleConnection *gc, qq_group *group); +void qq_room_data_initial(PurpleConnection *gc); +void qq_room_data_free_all(PurpleConnection *gc); +qq_room_data *qq_room_data_find(PurpleConnection *gc, guint32 room_id); + +guint32 qq_room_get_next(PurpleConnection *gc, guint32 room_id); +guint32 qq_room_get_next_conv(PurpleConnection *gc, guint32 room_id); #endif diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group_join.c --- a/libpurple/protocols/qq/group_join.c Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/group_join.c Tue Oct 28 16:38:16 2008 +0000 @@ -31,12 +31,10 @@ #include "char_conv.h" #include "im.h" -#include "group_find.h" #include "group_internal.h" #include "group_info.h" #include "group_join.h" #include "group_opt.h" -#include "group_search.h" #include "group_im.h" #include "qq_define.h" #include "packet_parse.h" @@ -49,11 +47,16 @@ QQ_ROOM_JOIN_DENIED = 0x03, }; +enum { + QQ_ROOM_SEARCH_TYPE_BY_ID = 0x01, + QQ_ROOM_SEARCH_TYPE_DEMO = 0x02 +}; + static void group_quit_cb(qq_add_request *add_req) { PurpleConnection *gc; guint32 id; - qq_group *group; + qq_room_data *rmd; if (add_req->gc == NULL || add_req->uid == 0) { g_free(add_req); @@ -63,48 +66,47 @@ gc = add_req->gc; id = add_req->uid; - group = qq_room_search_id(gc, id); - if (group == NULL) { + rmd = qq_room_data_find(gc, id); + if (rmd == NULL) { g_free(add_req); return; } - qq_send_room_cmd_only(gc, QQ_ROOM_CMD_QUIT, group->id); + qq_send_room_cmd_only(gc, QQ_ROOM_CMD_QUIT, rmd->id); g_free(add_req); } /* send packet to join a group without auth */ -void qq_request_room_join(PurpleConnection *gc, qq_group *group) +void qq_request_room_join(PurpleConnection *gc, qq_room_data *rmd) { - g_return_if_fail(group != NULL); + g_return_if_fail(rmd != NULL); - if (group->my_role == QQ_ROOM_ROLE_NO) { - group->my_role = QQ_ROOM_ROLE_REQUESTING; - qq_group_refresh(gc, group); + if (rmd->my_role == QQ_ROOM_ROLE_NO) { + rmd->my_role = QQ_ROOM_ROLE_REQUESTING; } - switch (group->auth_type) { + switch (rmd->auth_type) { case QQ_ROOM_AUTH_TYPE_NO_AUTH: case QQ_ROOM_AUTH_TYPE_NEED_AUTH: break; case QQ_ROOM_AUTH_TYPE_NO_ADD: - if (group->my_role == QQ_ROOM_ROLE_NO - && group->my_role == QQ_ROOM_ROLE_REQUESTING) { + if (rmd->my_role == QQ_ROOM_ROLE_NO + && rmd->my_role == QQ_ROOM_ROLE_REQUESTING) { purple_notify_warning(gc, NULL, _("The Qun does not allow others to join"), NULL); return; } break; default: - purple_debug_error("QQ", "Unknown room auth type: %d\n", group->auth_type); + purple_debug_error("QQ", "Unknown room auth type: %d\n", rmd->auth_type); break; } - qq_send_room_cmd_only(gc, QQ_ROOM_CMD_JOIN, group->id); + qq_send_room_cmd_only(gc, QQ_ROOM_CMD_JOIN, rmd->id); } static void group_join_cb(qq_add_request *add_req, const gchar *reason_utf8) { - qq_group *group; + qq_room_data *rmd; g_return_if_fail(add_req != NULL); if (add_req->gc == NULL || add_req->uid == 0) { @@ -112,14 +114,14 @@ return; } - group = qq_room_search_id(add_req->gc, add_req->uid); - if (group == NULL) { - purple_debug_error("QQ", "Can not find qq_group by internal_id: %d\n", add_req->uid); + rmd = qq_room_data_find(add_req->gc, add_req->uid); + if (rmd == NULL) { + purple_debug_error("QQ", "Can not find qq_room_data by internal_id: %d\n", add_req->uid); g_free(add_req); return; } - qq_send_cmd_group_auth(add_req->gc, group, QQ_ROOM_AUTH_REQUEST_APPLY, 0, reason_utf8); + qq_send_cmd_group_auth(add_req->gc, rmd, QQ_ROOM_AUTH_REQUEST_APPLY, 0, reason_utf8); g_free(add_req); } @@ -129,36 +131,36 @@ g_free(add_req); } -static void _qq_group_join_auth(PurpleConnection *gc, qq_group *group) +static void _qq_group_join_auth(PurpleConnection *gc, qq_room_data *rmd) { gchar *msg; qq_add_request *add_req; - g_return_if_fail(group != NULL); + g_return_if_fail(rmd != NULL); - purple_debug_info("QQ", "Group (internal id: %d) needs authentication\n", group->id); + purple_debug_info("QQ", "Group (internal id: %d) needs authentication\n", rmd->id); - msg = g_strdup_printf("Group \"%s\" needs authentication\n", group->title_utf8); + msg = g_strdup_printf("Group \"%s\" needs authentication\n", rmd->title_utf8); add_req = g_new0(qq_add_request, 1); add_req->gc = gc; - add_req->uid = group->id; + add_req->uid = rmd->id; purple_request_input(gc, NULL, msg, _("Input request here"), _("Would you be my friend?"), TRUE, FALSE, NULL, _("Send"), G_CALLBACK(group_join_cb), _("Cancel"), G_CALLBACK(qq_group_cancel_cb), - purple_connection_get_account(gc), group->title_utf8, NULL, + purple_connection_get_account(gc), rmd->title_utf8, NULL, add_req); g_free(msg); } -void qq_send_cmd_group_auth(PurpleConnection *gc, qq_group *group, guint8 opt, guint32 uid, const gchar *reason_utf8) +void qq_send_cmd_group_auth(PurpleConnection *gc, qq_room_data *rmd, guint8 opt, guint32 uid, const gchar *reason_utf8) { guint8 *raw_data; gchar *reason_qq; gint bytes; - g_return_if_fail(group != NULL); + g_return_if_fail(rmd != NULL); if (reason_utf8 == NULL || strlen(reason_utf8) == 0) reason_qq = g_strdup(""); @@ -166,8 +168,7 @@ reason_qq = utf8_to_qq(reason_utf8, QQ_CHARSET_DEFAULT); if (opt == QQ_ROOM_AUTH_REQUEST_APPLY) { - group->my_role = QQ_ROOM_ROLE_REQUESTING; - qq_group_refresh(gc, group); + rmd->my_role = QQ_ROOM_ROLE_REQUESTING; uid = 0; } @@ -179,18 +180,15 @@ bytes += qq_put8(raw_data + bytes, strlen(reason_qq)); bytes += qq_putdata(raw_data + bytes, (guint8 *) reason_qq, strlen(reason_qq)); - qq_send_room_cmd(gc, QQ_ROOM_CMD_AUTH, group->id, raw_data, bytes); + qq_send_room_cmd(gc, QQ_ROOM_CMD_AUTH, rmd->id, raw_data, bytes); } /* If comes here, cmd is OK already */ void qq_process_group_cmd_exit_group(guint8 *data, gint len, PurpleConnection *gc) { + qq_data *qd; gint bytes; guint32 id; - PurpleChat *chat; - qq_group *group; - qq_data *qd; - gchar *msg; g_return_if_fail(data != NULL && len > 0); qd = (qq_data *) gc->proto_data; @@ -203,20 +201,7 @@ bytes = 0; bytes += qq_get32(&id, data + bytes); - group = qq_room_search_id(gc, id); - if (group != NULL) { - msg = g_strdup_printf(_("Successed quit Qun %s (%d)"), - group->title_utf8, group->ext_id); - chat = purple_blist_find_chat - (purple_connection_get_account(gc), g_strdup_printf("%d", group->ext_id)); - if (chat != NULL) - purple_blist_remove_chat(chat); - qq_group_delete_internal_record(qd, id); - } else { - msg = g_strdup(_("Successed quit Qun")); - } - qq_got_attention(gc, msg); - g_free(msg); + qq_room_remove(gc, id); } /* Process the reply to group_auth subcmd */ @@ -225,7 +210,7 @@ gint bytes; guint32 id; qq_data *qd; - qq_group *group; + qq_room_data *rmd; gchar *msg; g_return_if_fail(data != NULL && len > 0); @@ -240,9 +225,9 @@ bytes += qq_get32(&id, data + bytes); g_return_if_fail(id > 0); - 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); + rmd = qq_room_data_find(gc, id); + if (rmd != NULL) { + msg = g_strdup_printf(_("Successed join to Qun %s (%d)"), rmd->title_utf8, rmd->ext_id); qq_got_attention(gc, msg); g_free(msg); } else { @@ -256,14 +241,14 @@ gint bytes; guint32 id; guint8 reply; - qq_group *group; + qq_room_data *rmd; gchar *msg; g_return_if_fail(data != NULL && len > 0); if (len < 5) { purple_debug_error("QQ", - "Invalid join group reply, expect %d bytes, read %d bytes\n", 5, len); + "Invalid join room reply, expect %d bytes, read %d bytes\n", 5, len); return; } @@ -272,34 +257,32 @@ bytes += qq_get8(&reply, data + bytes); /* join group OK */ - group = qq_room_search_id(gc, id); + rmd = qq_room_data_find(gc, id); /* need to check if group is NULL or not. */ - g_return_if_fail(group != NULL); + g_return_if_fail(rmd != NULL); switch (reply) { case QQ_ROOM_JOIN_OK: - purple_debug_info("QQ", "Successed in joining group \"%s\"\n", group->title_utf8); - group->my_role = QQ_ROOM_ROLE_YES; - qq_group_refresh(gc, group); + purple_debug_info("QQ", "Successed in joining group \"%s\"\n", rmd->title_utf8); + rmd->my_role = QQ_ROOM_ROLE_YES; /* this must be shown before getting online members */ - qq_room_conv_open(gc, group); + qq_room_conv_open(gc, rmd); break; case QQ_ROOM_JOIN_NEED_AUTH: purple_debug_info("QQ", "Fail joining group [%d] %s, needs authentication\n", - group->ext_id, group->title_utf8); - group->my_role = QQ_ROOM_ROLE_NO; - qq_group_refresh(gc, group); - _qq_group_join_auth(gc, group); + rmd->ext_id, rmd->title_utf8); + rmd->my_role = QQ_ROOM_ROLE_NO; + _qq_group_join_auth(gc, rmd); break; case QQ_ROOM_JOIN_DENIED: - msg = g_strdup_printf(_("Qun %d denied to join"), group->ext_id); + msg = g_strdup_printf(_("Qun %d denied to join"), rmd->ext_id); purple_notify_info(gc, _("QQ Qun Operation"), _("Failed:"), msg); g_free(msg); break; default: purple_debug_info("QQ", "Failed joining group [%d] %s, unknown reply: 0x%02x\n", - group->ext_id, group->title_utf8, reply); + rmd->ext_id, rmd->title_utf8, reply); purple_notify_info(gc, _("QQ Qun Operation"), _("Failed:"), _("Join Qun, Unknow Reply")); } @@ -313,7 +296,7 @@ gchar *id_str; guint32 ext_id; guint32 id; - qq_group *group; + qq_room_data *rmd; g_return_if_fail(data != NULL); qd = (qq_data *) gc->proto_data; @@ -325,9 +308,9 @@ 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); + rmd = qq_room_data_find(gc, id); + if (rmd) { + qq_request_room_join(gc, rmd); return; } } @@ -362,3 +345,93 @@ G_CALLBACK(qq_group_cancel_cb), _("Continue"), G_CALLBACK(group_quit_cb)); } + +/* send packet to search for qq_group */ +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_mess(gc, QQ_ROOM_CMD_SEARCH, 0, raw_data, bytes, 0, action); +} + +static void add_to_roomlist(qq_data *qd, qq_room_data *rmd) +{ + PurpleRoomlistRoom *room; + gchar field[11]; + + room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, rmd->title_utf8, NULL); + g_snprintf(field, sizeof(field), "%d", rmd->ext_id); + purple_roomlist_room_add_field(qd->roomlist, room, field); + g_snprintf(field, sizeof(field), "%d", rmd->creator_uid); + purple_roomlist_room_add_field(qd->roomlist, room, field); + purple_roomlist_room_add_field(qd->roomlist, room, rmd->desc_utf8); + g_snprintf(field, sizeof(field), "%d", rmd->id); + purple_roomlist_room_add_field(qd->roomlist, room, field); + g_snprintf(field, sizeof(field), "%d", rmd->type8); + purple_roomlist_room_add_field(qd->roomlist, room, field); + g_snprintf(field, sizeof(field), "%d", rmd->auth_type); + purple_roomlist_room_add_field(qd->roomlist, room, field); + g_snprintf(field, sizeof(field), "%d", rmd->category); + purple_roomlist_room_add_field(qd->roomlist, room, field); + purple_roomlist_room_add_field(qd->roomlist, room, rmd->title_utf8); + purple_roomlist_room_add(qd->roomlist, room); + + purple_roomlist_set_in_progress(qd->roomlist, FALSE); +} + +/* process group cmd reply "search group" */ +void qq_process_room_search(PurpleConnection *gc, guint8 *data, gint len, guint32 ship32) +{ + qq_data *qd; + qq_room_data rmd; + PurpleChat *chat; + gint bytes; + guint8 search_type; + guint16 unknown; + + g_return_if_fail(data != NULL && len > 0); + qd = (qq_data *) gc->proto_data; + + bytes = 0; + bytes += qq_get8(&search_type, data + bytes); + + /* now it starts with group_info_entry */ + bytes += qq_get32(&(rmd.id), data + bytes); + bytes += qq_get32(&(rmd.ext_id), data + bytes); + bytes += qq_get8(&(rmd.type8), data + bytes); + bytes += qq_get16(&(unknown), data + bytes); + bytes += qq_get16(&(unknown), data + bytes); + bytes += qq_get32(&(rmd.creator_uid), data + bytes); + bytes += qq_get16(&(unknown), data + bytes); + bytes += qq_get16(&(unknown), data + bytes); + bytes += qq_get16(&(unknown), data + bytes); + bytes += qq_get32(&(rmd.category), data + bytes); + bytes += qq_get_vstr(&(rmd.title_utf8), QQ_CHARSET_DEFAULT, data + bytes); + bytes += qq_get16(&(unknown), data + bytes); + bytes += qq_get8(&(rmd.auth_type), data + bytes); + bytes += qq_get_vstr(&(rmd.desc_utf8), QQ_CHARSET_DEFAULT, data + bytes); + /* end of one qq_group */ + if(bytes != len) { + purple_debug_error("QQ", + "group_cmd_search_group: Dangerous error! maybe protocol changed, notify developers!"); + } + + if (ship32 == QQ_ROOM_SEARCH_FOR_JOIN) { + chat = qq_room_find_or_new(gc, rmd.id, rmd.ext_id); + g_return_if_fail(chat != NULL); + + qq_room_update_chat_info(gc, &rmd); + qq_request_room_join(gc, &rmd); + } else { + add_to_roomlist(qd, &rmd); + } +} diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group_join.h --- a/libpurple/protocols/qq/group_join.h Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/group_join.h Tue Oct 28 16:38:16 2008 +0000 @@ -41,9 +41,17 @@ QQ_ROOM_AUTH_REQUEST_REJECT = 0x03 }; -void qq_send_cmd_group_auth(PurpleConnection *gc, qq_group *group, guint8 opt, guint32 uid, const gchar *reason_utf8); +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); + +void qq_send_cmd_group_auth(PurpleConnection *gc, qq_room_data *rmd, guint8 opt, guint32 uid, const gchar *reason_utf8); void qq_group_join(PurpleConnection *gc, GHashTable *data); -void qq_request_room_join(PurpleConnection *gc, qq_group *group); +void qq_request_room_join(PurpleConnection *gc, qq_room_data *rmd); void qq_room_quit(PurpleConnection *gc, guint32 room_id); void qq_process_group_cmd_exit_group(guint8 *data, gint len, PurpleConnection *gc); void qq_process_group_cmd_join_group_auth(guint8 *data, gint len, PurpleConnection *gc); diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group_opt.c --- a/libpurple/protocols/qq/group_opt.c Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/group_opt.c Tue Oct 28 16:38:16 2008 +0000 @@ -30,7 +30,6 @@ #include "buddy_info.h" #include "char_conv.h" -#include "group_find.h" #include "group_internal.h" #include "group_info.h" #include "group_join.h" @@ -58,7 +57,7 @@ qsort (list, i, sizeof (guint32), _compare_guint32); } -static void _qq_group_member_opt(PurpleConnection *gc, qq_group *group, gint operation, guint32 *members) +static void _qq_group_member_opt(PurpleConnection *gc, qq_room_data *rmd, gint operation, guint32 *members) { guint8 *data; gint i, count, data_len; @@ -75,7 +74,7 @@ for (i = 0; i < count; i++) bytes += qq_put32(data + bytes, members[i]); - qq_send_room_cmd(gc, QQ_ROOM_CMD_MEMBER_OPT, group->id, data, bytes); + qq_send_room_cmd(gc, QQ_ROOM_CMD_MEMBER_OPT, rmd->id, data, bytes); } static void _qq_group_do_nothing_with_struct(group_member_opt *g) @@ -86,11 +85,11 @@ static void _qq_group_reject_application_real(group_member_opt *g, gchar *msg_utf8) { - qq_group *group; + qq_room_data *rmd; g_return_if_fail(g != NULL && g->gc != NULL && g->id > 0 && g->member > 0); - group = qq_room_search_id(g->gc, g->id); - g_return_if_fail(group != NULL); - qq_send_cmd_group_auth(g->gc, group, QQ_ROOM_AUTH_REQUEST_REJECT, g->member, msg_utf8); + rmd = qq_room_data_find(g->gc, g->id); + g_return_if_fail(rmd != NULL); + qq_send_cmd_group_auth(g->gc, rmd, QQ_ROOM_AUTH_REQUEST_REJECT, g->member, msg_utf8); g_free(g); } @@ -131,16 +130,16 @@ void qq_group_approve_application_with_struct(group_member_opt *g) { - qq_group *group; + qq_room_data *rmd; g_return_if_fail(g != NULL && g->gc != NULL && g->id > 0 && g->member > 0); - group = qq_room_search_id(g->gc, g->id); - g_return_if_fail(group != NULL); - qq_send_cmd_group_auth(g->gc, group, QQ_ROOM_AUTH_REQUEST_APPROVE, g->member, ""); - qq_group_find_or_add_member(g->gc, group, g->member); + rmd = qq_room_data_find(g->gc, g->id); + g_return_if_fail(rmd != NULL); + qq_send_cmd_group_auth(g->gc, rmd, QQ_ROOM_AUTH_REQUEST_APPROVE, g->member, ""); + qq_room_buddy_find_or_new(g->gc, rmd, g->member); g_free(g); } -void qq_group_modify_members(PurpleConnection *gc, qq_group *group, guint32 *new_members) +void qq_group_modify_members(PurpleConnection *gc, qq_room_data *rmd, guint32 *new_members) { guint32 *old_members, *del_members, *add_members; qq_buddy_data *bd; @@ -148,7 +147,7 @@ gint i = 0, old = 0, new = 0, del = 0, add = 0; GList *list; - g_return_if_fail(group != NULL); + g_return_if_fail(rmd != NULL); qd = (qq_data *) gc->proto_data; if (new_members[0] == 0xffffffff) return; @@ -158,7 +157,7 @@ add_members = g_newa(guint32, QQ_QUN_MEMBER_MAX); /* construct the old member list */ - list = group->members; + list = rmd->members; while (list != NULL) { bd = (qq_buddy_data *) list->data; if (bd != NULL) @@ -186,14 +185,14 @@ del_members[del] = add_members[add] = 0xffffffff; for (i = 0; i < del; i++) - qq_group_remove_member_by_uid(group, del_members[i]); + qq_room_buddy_remove(rmd, del_members[i]); for (i = 0; i < add; i++) - qq_group_find_or_add_member(gc, group, add_members[i]); + qq_room_buddy_find_or_new(gc, rmd, add_members[i]); if (del > 0) - _qq_group_member_opt(gc, group, QQ_ROOM_MEMBER_DEL, del_members); + _qq_group_member_opt(gc, rmd, QQ_ROOM_MEMBER_DEL, del_members); if (add > 0) - _qq_group_member_opt(gc, group, QQ_ROOM_MEMBER_ADD, add_members); + _qq_group_member_opt(gc, rmd, QQ_ROOM_MEMBER_ADD, add_members); } void qq_group_process_modify_members_reply(guint8 *data, gint len, PurpleConnection *gc) @@ -201,7 +200,7 @@ gint bytes; guint32 id; time_t now = time(NULL); - qq_group *group; + qq_room_data *rmd; g_return_if_fail(data != NULL); bytes = 0; @@ -209,26 +208,26 @@ g_return_if_fail(id > 0); /* we should have its info locally */ - group = qq_room_search_id(gc, id); - g_return_if_fail(group != NULL); + rmd = qq_room_data_find(gc, id); + g_return_if_fail(rmd != NULL); - purple_debug_info("QQ", "Succeed in modify members for room %d\n", group->ext_id); + purple_debug_info("QQ", "Succeed in modify members for room %d\n", rmd->ext_id); - qq_room_got_chat_in(gc, group, 0, _("Successed changing Qun member"), now); + qq_room_got_chat_in(gc, id, 0, _("Successed changing Qun member"), now); } -void qq_room_change_info(PurpleConnection *gc, qq_group *group) +void qq_room_change_info(PurpleConnection *gc, qq_room_data *rmd) { guint8 *data; gint data_len; gint bytes; gchar *group_name, *group_desc, *notice; - g_return_if_fail(group != NULL); + g_return_if_fail(rmd != NULL); - group_name = group->title_utf8 == NULL ? "" : utf8_to_qq(group->title_utf8, QQ_CHARSET_DEFAULT); - group_desc = group->desc_utf8 == NULL ? "" : utf8_to_qq(group->desc_utf8, QQ_CHARSET_DEFAULT); - notice = group->notice_utf8 == NULL ? "" : utf8_to_qq(group->notice_utf8, QQ_CHARSET_DEFAULT); + group_name = rmd->title_utf8 == NULL ? "" : utf8_to_qq(rmd->title_utf8, QQ_CHARSET_DEFAULT); + group_desc = rmd->desc_utf8 == NULL ? "" : utf8_to_qq(rmd->desc_utf8, QQ_CHARSET_DEFAULT); + notice = rmd->notice_utf8 == NULL ? "" : utf8_to_qq(rmd->notice_utf8, QQ_CHARSET_DEFAULT); data_len = 64 + strlen(group_name) + strlen(group_desc) + strlen(notice); data = g_newa(guint8, data_len); @@ -236,11 +235,11 @@ /* 005-005 */ bytes += qq_put8(data + bytes, 0x01); /* 006-006 */ - bytes += qq_put8(data + bytes, group->auth_type); + bytes += qq_put8(data + bytes, rmd->auth_type); /* 007-008 */ bytes += qq_put16(data + bytes, 0x0000); /* 009-010 */ - bytes += qq_put16(data + bytes, group->category); + bytes += qq_put16(data + bytes, rmd->category); bytes += qq_put8(data + bytes, strlen(group_name)); bytes += qq_putdata(data + bytes, (guint8 *) group_name, strlen(group_name)); @@ -259,14 +258,13 @@ data_len, bytes); return; } - qq_send_room_cmd(gc, QQ_ROOM_CMD_CHANGE_INFO, group->id, data, bytes); + qq_send_room_cmd(gc, QQ_ROOM_CMD_CHANGE_INFO, rmd->id, data, bytes); } void qq_group_process_modify_info_reply(guint8 *data, gint len, PurpleConnection *gc) { gint bytes; guint32 id; - qq_group *group; time_t now = time(NULL); g_return_if_fail(data != NULL); @@ -275,17 +273,12 @@ bytes += qq_get32(&id, data + bytes); g_return_if_fail(id > 0); - /* we should have its info locally */ - group = qq_room_search_id(gc, id); - g_return_if_fail(group != NULL); + purple_debug_info("QQ", "Succeed modify room info of %d\n", id); - purple_debug_info("QQ", "Succeed in modify info for Qun %d\n", group->ext_id); - qq_group_refresh(gc, group); - - qq_room_got_chat_in(gc, group, 0, _("Successed changing Qun information"), now); + qq_room_got_chat_in(gc, id, 0, _("Successed changing Qun information"), now); } -/* we create a very simple group first, and then let the user to modify */ +/* we create a very simple room first, and then let the user to modify */ void qq_room_create_new(PurpleConnection *gc, const gchar *name) { guint8 *data; @@ -328,21 +321,21 @@ static void qq_group_setup_cb(qq_add_request *add_req) { - qq_group *group; + qq_room_data *rmd; g_return_if_fail(add_req != NULL); if (add_req->gc == NULL || add_req->uid == 0) { g_free(add_req); return; } - group = qq_room_search_id(add_req->gc, add_req->uid); - if (group == NULL) { + rmd = qq_room_data_find(add_req->gc, add_req->uid); + if (rmd == NULL) { g_free(add_req); return; } /* TODO insert UI code here */ - /* qq_group_detail_window_show(g->gc, group); */ + /* qq_group_detail_window_show(g->gc, rmd); */ g_free(add_req); } @@ -350,7 +343,7 @@ { gint bytes; guint32 id, ext_id; - qq_group *group; + qq_room_data *rmd; qq_add_request *add_req; qq_data *qd; @@ -363,15 +356,17 @@ bytes += qq_get32(&ext_id, data + bytes); g_return_if_fail(id > 0 && ext_id); - group = qq_group_create_internal_record(gc, id, ext_id, NULL); - group->my_role = QQ_ROOM_ROLE_ADMIN; - group->creator_uid = qd->uid; - qq_group_refresh(gc, group); + qq_room_find_or_new(gc, id, ext_id); + rmd = qq_room_data_find(gc, id); + g_return_if_fail(rmd != NULL); + + rmd->my_role = QQ_ROOM_ROLE_ADMIN; + rmd->creator_uid = qd->uid; qq_send_room_cmd_only(gc, QQ_ROOM_CMD_ACTIVATE, id); - qq_update_room(gc, 0, group->id); + qq_update_room(gc, 0, rmd->id); - purple_debug_info("QQ", "Succeed in create Qun, external ID %d\n", group->ext_id); + purple_debug_info("QQ", "Succeed in create Qun, external ID %d\n", rmd->ext_id); add_req = g_new0(qq_add_request, 1); add_req->gc = gc; @@ -391,7 +386,7 @@ { gint bytes; guint32 id; - qq_group *group; + qq_room_data *rmd; g_return_if_fail(data != NULL); bytes = 0; @@ -399,17 +394,17 @@ g_return_if_fail(id > 0); /* we should have its info locally */ - group = qq_room_search_id(gc, id); - g_return_if_fail(group != NULL); + rmd = qq_room_data_find(gc, id); + g_return_if_fail(rmd != NULL); - purple_debug_info("QQ", "Succeed in activate Qun %d\n", group->ext_id); + purple_debug_info("QQ", "Succeed in activate Qun %d\n", rmd->ext_id); } void qq_group_manage_group(PurpleConnection *gc, GHashTable *data) { gchar *id_ptr; guint32 id; - qq_group *group; + qq_room_data *rmd; g_return_if_fail(data != NULL); @@ -417,9 +412,9 @@ id = strtol(id_ptr, NULL, 10); g_return_if_fail(id > 0); - group = qq_room_search_id(gc, id); - g_return_if_fail(group != NULL); + rmd = qq_room_data_find(gc, id); + g_return_if_fail(rmd != NULL); /* XXX insert UI code here */ - /* qq_group_detail_window_show(gc, group); */ + /* qq_group_detail_window_show(gc, rmd); */ } diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group_opt.h --- a/libpurple/protocols/qq/group_opt.h Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/group_opt.h Tue Oct 28 16:38:16 2008 +0000 @@ -47,8 +47,8 @@ QQ_ROOM_MEMBER_DEL }; -void qq_group_modify_members(PurpleConnection *gc, qq_group *group, guint32 *new_members); -void qq_room_change_info(PurpleConnection *gc, qq_group *group); +void qq_group_modify_members(PurpleConnection *gc, qq_room_data *rmd, guint32 *new_members); +void qq_room_change_info(PurpleConnection *gc, qq_room_data *rmd); void qq_group_approve_application_with_struct(group_member_opt *g); void qq_group_reject_application_with_struct(group_member_opt *g); diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group_search.c --- a/libpurple/protocols/qq/group_search.c Tue Oct 28 16:35:06 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,131 +0,0 @@ -/** - * @file group_search.c - * - * purple - * - * Purple is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "internal.h" - -#include "debug.h" - -#include "char_conv.h" -#include "group_find.h" -#include "group_free.h" -#include "group_internal.h" -#include "group_join.h" -#include "group_search.h" -#include "utils.h" -#include "qq_define.h" -#include "packet_parse.h" -#include "qq_network.h" - -enum { - QQ_ROOM_SEARCH_TYPE_BY_ID = 0x01, - QQ_ROOM_SEARCH_TYPE_DEMO = 0x02 -}; - -/* send packet to search for qq_group */ -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_mess(gc, QQ_ROOM_CMD_SEARCH, 0, raw_data, bytes, 0, action); -} - -static void add_to_roomlist(qq_data *qd, qq_group *group) -{ - PurpleRoomlistRoom *room; - gchar field[11]; - - room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, group->title_utf8, NULL); - g_snprintf(field, sizeof(field), "%d", group->ext_id); - purple_roomlist_room_add_field(qd->roomlist, room, field); - g_snprintf(field, sizeof(field), "%d", group->creator_uid); - purple_roomlist_room_add_field(qd->roomlist, room, field); - purple_roomlist_room_add_field(qd->roomlist, room, group->desc_utf8); - g_snprintf(field, sizeof(field), "%d", group->id); - purple_roomlist_room_add_field(qd->roomlist, room, field); - g_snprintf(field, sizeof(field), "%d", group->type8); - purple_roomlist_room_add_field(qd->roomlist, room, field); - g_snprintf(field, sizeof(field), "%d", group->auth_type); - purple_roomlist_room_add_field(qd->roomlist, room, field); - g_snprintf(field, sizeof(field), "%d", group->category); - purple_roomlist_room_add_field(qd->roomlist, room, field); - purple_roomlist_room_add_field(qd->roomlist, room, group->title_utf8); - purple_roomlist_room_add(qd->roomlist, room); - - purple_roomlist_set_in_progress(qd->roomlist, FALSE); -} - -/* process group cmd reply "search group" */ -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; - - g_return_if_fail(data != NULL && len > 0); - qd = (qq_data *) gc->proto_data; - - bytes = 0; - bytes += qq_get8(&search_type, data + bytes); - - /* now it starts with group_info_entry */ - bytes += qq_get32(&(group.id), data + bytes); - bytes += qq_get32(&(group.ext_id), data + bytes); - bytes += qq_get8(&(group.type8), data + bytes); - bytes += qq_get16(&(unknown), data + bytes); - bytes += qq_get16(&(unknown), data + bytes); - bytes += qq_get32(&(group.creator_uid), data + bytes); - bytes += qq_get16(&(unknown), data + bytes); - bytes += qq_get16(&(unknown), data + bytes); - bytes += qq_get16(&(unknown), data + bytes); - bytes += qq_get32(&(group.category), data + bytes); - bytes += qq_get_vstr(&(group.title_utf8), QQ_CHARSET_DEFAULT, data + bytes); - bytes += qq_get16(&(unknown), data + bytes); - bytes += qq_get8(&(group.auth_type), data + bytes); - bytes += qq_get_vstr(&(group.desc_utf8), QQ_CHARSET_DEFAULT, data + bytes); - /* end of one qq_group */ - if(bytes != len) { - purple_debug_error("QQ", - "group_cmd_search_group: Dangerous error! maybe protocol changed, notify developers!"); - } - - 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 { - add_to_roomlist(qd, &group); - } -} diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/group_search.h --- a/libpurple/protocols/qq/group_search.h Tue Oct 28 16:35:06 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/** - * @file group_search.h - * - * purple - * - * Purple is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef _QQ_GROUP_SEARCH_H_ -#define _QQ_GROUP_SEARCH_H_ - -#include -#include "connection.h" - -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 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/qq.c --- a/libpurple/protocols/qq/qq.c Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/qq.c Tue Oct 28 16:38:16 2008 +0000 @@ -39,7 +39,6 @@ #include "buddy_list.h" #include "char_conv.h" #include "group.h" -#include "group_find.h" #include "group_im.h" #include "group_info.h" #include "group_join.h" @@ -777,7 +776,7 @@ g_return_if_fail(room_id != 0); qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_INFO, room_id, NULL, 0, - QQ_CMD_CLASS_UPDATE_ROOM, QQ_ROOM_INFO_DISPLAY); + 0, QQ_ROOM_INFO_DISPLAY); } #if 0 diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/qq_network.c --- a/libpurple/protocols/qq/qq_network.c Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/qq_network.c Tue Oct 28 16:38:16 2008 +0000 @@ -28,7 +28,7 @@ #include "buddy_info.h" #include "group_info.h" -#include "group_free.h" +#include "group_internal.h" #include "qq_crypt.h" #include "qq_define.h" #include "qq_base.h" @@ -1039,7 +1039,7 @@ qd->my_ip.s_addr = 0; qd->my_port = 0; - qq_group_free_all(gc); + qq_room_data_free_all(gc); qq_buddy_data_free_all(gc); } diff -r 147f1b17b6ce -r 1ee91ff0d5fe libpurple/protocols/qq/qq_process.c --- a/libpurple/protocols/qq/qq_process.c Tue Oct 28 16:35:06 2008 +0000 +++ b/libpurple/protocols/qq/qq_process.c Tue Oct 28 16:38:16 2008 +0000 @@ -33,8 +33,6 @@ #include "char_conv.h" #include "qq_crypt.h" -#include "group_search.h" -#include "group_find.h" #include "group_internal.h" #include "group_im.h" #include "group_info.h" @@ -529,36 +527,25 @@ void qq_update_room(PurpleConnection *gc, guint8 room_cmd, guint32 room_id) { qq_data *qd; - qq_group *group; gint ret; g_return_if_fail (gc != NULL && gc->proto_data != NULL); qd = (qq_data *) gc->proto_data; - group = qq_room_search_id(gc, room_id); - if (group == NULL && room_id <= 0) { - purple_debug_info("QQ", "No room, nothing update\n"); - return; - } - if (group == NULL ) { - purple_debug_warning("QQ", "Failed search room id [%d]\n", room_id); - return; - } - switch (room_cmd) { case 0: - qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_INFO, group->id, NULL, 0, + qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_INFO, room_id, NULL, 0, QQ_CMD_CLASS_UPDATE_ROOM, 0); break; case QQ_ROOM_CMD_GET_INFO: - ret = qq_request_room_get_buddies(gc, group, QQ_CMD_CLASS_UPDATE_ROOM); + ret = qq_request_room_get_buddies(gc, room_id, QQ_CMD_CLASS_UPDATE_ROOM); if (ret <= 0) { - qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_ONLINES, group->id, NULL, 0, + qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_ONLINES, room_id, NULL, 0, QQ_CMD_CLASS_UPDATE_ROOM, 0); } break; case QQ_ROOM_CMD_GET_BUDDIES: - qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_ONLINES, group->id, NULL, 0, + qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_ONLINES, room_id, NULL, 0, QQ_CMD_CLASS_UPDATE_ROOM, 0); break; case QQ_ROOM_CMD_GET_ONLINES: @@ -572,39 +559,42 @@ { qq_data *qd; gboolean is_new_turn = FALSE; - qq_group *next_group; + guint32 next_id; g_return_if_fail (gc != NULL && gc->proto_data != NULL); qd = (qq_data *) gc->proto_data; - next_group = qq_room_get_next(gc, room_id); - if (next_group == NULL && room_id <= 0) { - purple_debug_info("QQ", "No room. Finished update\n"); - return; - } - if (next_group == NULL ) { - is_new_turn = TRUE; - next_group = qq_room_get_next(gc, 0); - g_return_if_fail(next_group != NULL); + next_id = qq_room_get_next(gc, room_id); + purple_debug_info("QQ", "Update rooms, next id %d, prev id %d\n", next_id, room_id); + + if (next_id <= 0) { + if (room_id > 0) { + is_new_turn = TRUE; + next_id = qq_room_get_next(gc, 0); + purple_debug_info("QQ", "new turn, id %d\n", next_id); + } else { + purple_debug_info("QQ", "No room. Finished update\n"); + return; + } } switch (room_cmd) { case 0: - qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_INFO, next_group->id, NULL, 0, + qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_INFO, next_id, NULL, 0, QQ_CMD_CLASS_UPDATE_ALL, 0); break; case QQ_ROOM_CMD_GET_INFO: if (!is_new_turn) { - qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_INFO, next_group->id, NULL, 0, + qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_INFO, next_id, NULL, 0, QQ_CMD_CLASS_UPDATE_ALL, 0); } else { - qq_request_room_get_buddies(gc, next_group, QQ_CMD_CLASS_UPDATE_ALL); + qq_request_room_get_buddies(gc, next_id, QQ_CMD_CLASS_UPDATE_ALL); } break; case QQ_ROOM_CMD_GET_BUDDIES: /* last command */ if (!is_new_turn) { - qq_request_room_get_buddies(gc, next_group, QQ_CMD_CLASS_UPDATE_ALL); + qq_request_room_get_buddies(gc, next_id, QQ_CMD_CLASS_UPDATE_ALL); } else { purple_debug_info("QQ", "Finished update\n"); } @@ -658,28 +648,28 @@ static void update_all_rooms_online(PurpleConnection *gc, guint8 room_cmd, guint32 room_id) { qq_data *qd; - qq_group *next_group; + guint32 next_id; g_return_if_fail (gc != NULL && gc->proto_data != NULL); qd = (qq_data *) gc->proto_data; - next_group = qq_room_get_next_conv(gc, room_id); - if (next_group == NULL && room_id <= 0) { + next_id = qq_room_get_next_conv(gc, room_id); + if (next_id <= 0 && room_id <= 0) { purple_debug_info("QQ", "No room in conversation, no update online buddies\n"); return; } - if (next_group == NULL ) { + if (next_id <= 0 ) { purple_debug_info("QQ", "finished update rooms' online buddies\n"); return; } switch (room_cmd) { case 0: - qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_ONLINES, next_group->id, NULL, 0, + qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_ONLINES, next_id, NULL, 0, QQ_CMD_CLASS_UPDATE_ALL, 0); break; case QQ_ROOM_CMD_GET_ONLINES: - qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_ONLINES, next_group->id, NULL, 0, + qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_ONLINES, next_id, NULL, 0, QQ_CMD_CLASS_UPDATE_ALL, 0); break; default: @@ -714,7 +704,7 @@ qq_data *qd; guint8 *data; gint data_len; - qq_group *group; + qq_room_data *rmd; gint bytes; guint8 reply_cmd, reply; @@ -760,16 +750,15 @@ if (reply != QQ_ROOM_CMD_REPLY_OK) { switch (reply) { /* this should be all errors */ case QQ_ROOM_CMD_REPLY_NOT_MEMBER: - group = qq_room_search_id(gc, room_id); - if (group == NULL) { + rmd = qq_room_data_find(gc, room_id); + if (rmd == 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; - qq_group_refresh(gc, group); + _("Not a member of room \"%s\"\n"), rmd->title_utf8); + rmd->my_role = QQ_ROOM_ROLE_NO; } break; case QQ_ROOM_CMD_REPLY_SEARCH_ERROR: @@ -972,7 +961,7 @@ qd->is_login = TRUE; /* must be defined after sev_finish_login */ /* now initiate QQ Qun, do it first as it may take longer to finish */ - qq_group_init(gc); + qq_room_data_initial(gc); /* is_login, but we have packets before login */ qq_trans_process_remained(gc);