00001
00023
00024
00025 #include "debug.h"
00026 #include "conversation.h"
00027
00028 #include "buddy_status.h"
00029 #include "char_conv.h"
00030 #include "group_find.h"
00031 #include "group_hash.h"
00032 #include "group_info.h"
00033 #include "buddy_status.h"
00034 #include "group_network.h"
00035
00036
00037
00038 #define QQ_GROUP_CHAT_REFRESH_NICKNAME_INTERNAL 180
00039
00040
00041 gboolean _is_group_member_need_update_info(qq_buddy * member)
00042 {
00043 g_return_val_if_fail(member != NULL, FALSE);
00044 return (member->nickname == NULL) ||
00045 (time(NULL) - member->last_refresh) > QQ_GROUP_CHAT_REFRESH_NICKNAME_INTERNAL;
00046 }
00047
00048
00049
00050
00051 void _qq_group_set_members_all_offline(qq_group * group)
00052 {
00053 GList *list;
00054 qq_buddy *member;
00055 g_return_if_fail(group != NULL);
00056
00057 list = group->members;
00058 while (list != NULL) {
00059 member = (qq_buddy *) list->data;
00060 member->status = QQ_BUDDY_ONLINE_OFFLINE;
00061 list = list->next;
00062 }
00063 }
00064
00065
00066
00067 void qq_send_cmd_group_get_group_info(GaimConnection * gc, qq_group * group)
00068 {
00069 guint8 *raw_data, *cursor;
00070 gint bytes, data_len;
00071
00072 g_return_if_fail(gc != NULL && group != NULL);
00073
00074 data_len = 5;
00075 raw_data = g_newa(guint8, data_len);
00076 cursor = raw_data;
00077
00078 bytes = 0;
00079 bytes += create_packet_b(raw_data, &cursor, QQ_GROUP_CMD_GET_GROUP_INFO);
00080 bytes += create_packet_dw(raw_data, &cursor, group->internal_group_id);
00081
00082 if (bytes != data_len)
00083 gaim_debug(GAIM_DEBUG_ERROR, "QQ",
00084 "Fail create packet for %s\n", qq_group_cmd_get_desc(QQ_GROUP_CMD_GET_GROUP_INFO));
00085 else
00086 qq_send_group_cmd(gc, group, raw_data, data_len);
00087 }
00088
00089
00090
00091 void qq_send_cmd_group_get_online_member(GaimConnection * gc, qq_group * group) {
00092 guint8 *raw_data, *cursor;
00093 gint bytes, data_len;
00094
00095 g_return_if_fail(gc != NULL && group != NULL);
00096
00097
00098 if (NULL == gaim_find_conversation_with_account(group->group_name_utf8, gaim_connection_get_account(gc))) {
00099 gaim_debug(GAIM_DEBUG_WARNING, "QQ",
00100 "Conv windows for \"%s\" is not on, do not get online members\n", group->group_name_utf8);
00101 return;
00102 }
00103
00104 data_len = 5;
00105 raw_data = g_newa(guint8, data_len);
00106 cursor = raw_data;
00107
00108 bytes = 0;
00109 bytes += create_packet_b(raw_data, &cursor, QQ_GROUP_CMD_GET_ONLINE_MEMBER);
00110 bytes += create_packet_dw(raw_data, &cursor, group->internal_group_id);
00111
00112 if (bytes != data_len)
00113 gaim_debug(GAIM_DEBUG_ERROR, "QQ",
00114 "Fail create packet for %s\n", qq_group_cmd_get_desc(QQ_GROUP_CMD_GET_ONLINE_MEMBER));
00115 else
00116 qq_send_group_cmd(gc, group, raw_data, data_len);
00117 }
00118
00119
00120
00121 void qq_send_cmd_group_get_member_info(GaimConnection * gc, qq_group * group) {
00122 guint8 *raw_data, *cursor;
00123 gint bytes, data_len, i;
00124 GList *list;
00125 qq_buddy *member;
00126
00127 g_return_if_fail(gc != NULL && group != NULL);
00128 for (i = 0, list = group->members; list != NULL; list = list->next) {
00129 member = (qq_buddy *) list->data;
00130 if (_is_group_member_need_update_info(member))
00131 i++;
00132 }
00133
00134 if (i <= 0) {
00135 gaim_debug(GAIM_DEBUG_INFO, "QQ", "No group member needs to to update info now.\n");
00136 return;
00137 }
00138
00139 data_len = 5 + 4 * i;
00140 raw_data = g_newa(guint8, data_len);
00141 cursor = raw_data;
00142
00143 bytes = 0;
00144 bytes += create_packet_b(raw_data, &cursor, QQ_GROUP_CMD_GET_MEMBER_INFO);
00145 bytes += create_packet_dw(raw_data, &cursor, group->internal_group_id);
00146
00147 list = group->members;
00148 while (list != NULL) {
00149 member = (qq_buddy *) list->data;
00150 if (_is_group_member_need_update_info(member))
00151 bytes += create_packet_dw(raw_data, &cursor, member->uid);
00152 list = list->next;
00153 }
00154
00155 if (bytes != data_len)
00156 gaim_debug(GAIM_DEBUG_ERROR, "QQ",
00157 "Fail create packet for %s\n", qq_group_cmd_get_desc(QQ_GROUP_CMD_GET_MEMBER_INFO));
00158 else
00159 qq_send_group_cmd(gc, group, raw_data, data_len);
00160 }
00161
00162
00163 void qq_process_group_cmd_get_group_info(guint8 * data, guint8 ** cursor, gint len, GaimConnection * gc) {
00164 qq_group *group;
00165 qq_data *qd;
00166 guint8 bar, orgnization;
00167 guint16 unknown;
00168 guint32 member_uid, internal_group_id;
00169 gint pascal_len, i;
00170 guint32 unknown4;
00171 guint8 unknown1;
00172
00173 g_return_if_fail(gc != NULL && gc->proto_data != NULL);
00174 g_return_if_fail(data != NULL && len > 0);
00175 qd = (qq_data *) gc->proto_data;
00176
00177 read_packet_dw(data, cursor, len, &(internal_group_id));
00178 g_return_if_fail(internal_group_id > 0);
00179
00180 group = qq_group_find_by_internal_group_id(gc, internal_group_id);
00181 g_return_if_fail(group != NULL);
00182
00183 read_packet_dw(data, cursor, len, &(group->external_group_id));
00184 read_packet_b(data, cursor, len, &(group->group_type));
00185 read_packet_dw(data, cursor, len, &unknown4);
00186 read_packet_dw(data, cursor, len, &(group->creator_uid));
00187 read_packet_b(data, cursor, len, &(group->auth_type));
00188 read_packet_dw(data, cursor, len, &unknown4);
00189 read_packet_w(data, cursor, len, &(unknown));
00190 read_packet_dw(data, cursor, len, &(group->group_category));
00191 read_packet_w(data, cursor, len, &(unknown));
00192 read_packet_b(data, cursor, len, &unknown1);
00193 read_packet_dw(data, cursor, len, &(unknown4));
00194
00195 pascal_len = convert_as_pascal_string(*cursor, &(group->group_name_utf8), QQ_CHARSET_DEFAULT);
00196 *cursor += pascal_len;
00197 read_packet_w(data, cursor, len, &(unknown));
00198 pascal_len = convert_as_pascal_string(*cursor, &(group->notice_utf8), QQ_CHARSET_DEFAULT);
00199 *cursor += pascal_len;
00200 pascal_len = convert_as_pascal_string(*cursor, &(group->group_desc_utf8), QQ_CHARSET_DEFAULT);
00201 *cursor += pascal_len;
00202
00203 i = 0;
00204
00205 while (*cursor < data + len) {
00206 read_packet_dw(data, cursor, len, &member_uid);
00207 i++;
00208 read_packet_b(data, cursor, len, &orgnization);
00209 read_packet_b(data, cursor, len, &bar);
00210 qq_group_find_or_add_member(gc, group, member_uid);
00211 }
00212
00213 gaim_debug(GAIM_DEBUG_INFO, "QQ", "group \"%s\" has %d members\n", group->group_name_utf8, i);
00214
00215 if (group->creator_uid == qd->uid)
00216 group->my_status = QQ_GROUP_MEMBER_STATUS_IS_ADMIN;
00217
00218 qq_group_refresh(gc, group);
00219
00220 }
00221
00222
00223 void qq_process_group_cmd_get_online_member(guint8 * data, guint8 ** cursor, gint len, GaimConnection * gc) {
00224 guint32 internal_group_id, member_uid;
00225 guint8 unknown;
00226 gint bytes, i;
00227 qq_group *group;
00228 qq_buddy *member;
00229
00230 g_return_if_fail(gc != NULL && data != NULL && len > 0);
00231
00232 if (data + len - *cursor < 4) {
00233 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Invalid group online member reply, discard it!\n");
00234 return;
00235 }
00236
00237 bytes = 0;
00238 i = 0;
00239 bytes += read_packet_dw(data, cursor, len, &internal_group_id);
00240 bytes += read_packet_b(data, cursor, len, &unknown);
00241 g_return_if_fail(internal_group_id > 0);
00242
00243 group = qq_group_find_by_internal_group_id(gc, internal_group_id);
00244 if (group == NULL) {
00245 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "We have no group info for internal id [%d]\n", internal_group_id);
00246 return;
00247 }
00248
00249
00250 _qq_group_set_members_all_offline(group);
00251 while (*cursor < data + len) {
00252 bytes += read_packet_dw(data, cursor, len, &member_uid);
00253 i++;
00254 member = qq_group_find_or_add_member(gc, group, member_uid);
00255 if (member != NULL)
00256 member->status = QQ_BUDDY_ONLINE_NORMAL;
00257 }
00258
00259 gaim_debug(GAIM_DEBUG_INFO, "QQ", "Group \"%s\" has %d online members\n", group->group_name_utf8, i);
00260
00261 }
00262
00263
00264
00265 void qq_process_group_cmd_get_member_info(guint8 * data, guint8 ** cursor, gint len, GaimConnection * gc) {
00266 guint32 internal_group_id, member_uid;
00267 guint16 unknown;
00268 guint8 bar;
00269 gint pascal_len, i;
00270 qq_group *group;
00271 qq_buddy *member;
00272
00273 g_return_if_fail(gc != NULL && data != NULL && len > 0);
00274
00275 read_packet_dw(data, cursor, len, &internal_group_id);
00276 g_return_if_fail(internal_group_id > 0);
00277
00278 group = qq_group_find_by_internal_group_id(gc, internal_group_id);
00279 g_return_if_fail(group != NULL);
00280
00281 i = 0;
00282
00283 while (*cursor < data + len) {
00284 read_packet_dw(data, cursor, len, &member_uid);
00285 g_return_if_fail(member_uid > 0);
00286 member = qq_group_find_member_by_uid(group, member_uid);
00287 g_return_if_fail(member != NULL);
00288
00289 i++;
00290 read_packet_b(data, cursor, len, &bar);
00291 read_packet_b(data, cursor, len, &(member->icon));
00292 read_packet_b(data, cursor, len, &(member->age));
00293 read_packet_b(data, cursor, len, &(member->gender));
00294 pascal_len = convert_as_pascal_string(*cursor, &(member->nickname), QQ_CHARSET_DEFAULT);
00295 *cursor += pascal_len;
00296 read_packet_w(data, cursor, len, &unknown);
00297 read_packet_b(data, cursor, len, &(member->flag1));
00298 read_packet_b(data, cursor, len, &(member->comm_flag));
00299
00300 member->last_refresh = time(NULL);
00301 }
00302
00303 gaim_debug(GAIM_DEBUG_INFO, "QQ", "Group \"%s\" obtained %d member info\n", group->group_name_utf8, i);
00304
00305 }
00306
00307
00308