void qq_update_room(PurpleConnection *gc, guint8 room_cmd, guint32 room_id) { gint ret; g_return_if_fail (gc != NULL); switch (room_cmd) { case 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_members_info(gc, room_id, QQ_CMD_CLASS_UPDATE_ROOM, 0); if (ret <= 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_MEMBERS_INFO: 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: /* last command */ default: break; } }
static void update_all_rooms_online(PurpleConnection *gc, guint8 room_cmd, guint32 room_id) { guint32 next_id; g_return_if_fail (gc != NULL); 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_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_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_id, NULL, 0, QQ_CMD_CLASS_UPDATE_ALL, 0); break; default: break; } }
void qq_update_all_rooms(PurpleConnection *gc, guint8 room_cmd, guint32 room_id) { qq_data * qd; gboolean is_new_turn = FALSE; guint32 next_id; g_return_if_fail (gc != NULL && gc->proto_data != NULL); qd = (qq_data *) gc->proto_data; next_id = qq_room_get_next(gc, room_id); purple_debug_info("QQ", "Update rooms, next id %u, prev id %u\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 %u\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_QUN_LIST, 0, NULL, g_slist_length(qd->rooms) * 16, QQ_CMD_CLASS_UPDATE_ALL, 0); break; case QQ_ROOM_CMD_GET_QUN_LIST: case QQ_ROOM_CMD_GET_INFO: if (!is_new_turn) { 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_members_info(gc, next_id, QQ_CMD_CLASS_UPDATE_ALL, 0); } break; case QQ_ROOM_CMD_GET_MEMBERS_INFO: /* last command */ if (!is_new_turn) { qq_request_room_get_members_info(gc, next_id, QQ_CMD_CLASS_UPDATE_ALL, 0); } else { purple_debug_info("QQ", "Finished update\n"); } break; default: break; } }
static void action_chat_get_info(PurpleBlistNode * node) { PurpleChat *chat = (PurpleChat *)node; PurpleAccount *account = purple_chat_get_account(chat); PurpleConnection *gc = purple_account_get_connection(account); GHashTable *components = purple_chat_get_components(chat); gchar *num_str; guint32 room_id; g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); g_return_if_fail(components != NULL); num_str = g_hash_table_lookup(components, QQ_ROOM_KEY_INTERNAL_ID); if (!num_str) { purple_debug_error("QQ", "Cannot find Room! Wait and Retry"); return; } room_id = strtoul(num_str, NULL, 10); g_return_if_fail(room_id != 0); qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_INFO, room_id, NULL, 0, 0, QQ_ROOM_INFO_DISPLAY); }
/* send packet to get info for each group member */ gint qq_request_room_get_members_info( PurpleConnection *gc, guint32 room_id, guint32 update_class, guint32 index ) { guint8 *raw_data; gint bytes, num; GList *list; qq_room_data *rmd; qq_buddy_data *bd; guint32 i = 0; 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++; } if (num <= 0) { purple_debug_info("QQ", "No group member info needs to be updated now.\n"); return 0; } raw_data = g_newa(guint8, 4 * num); bytes = 0; list = rmd->members; /* index shipped from last request send 30 uids one time */ while (list != NULL) { if (i>=index) { bd = (qq_buddy_data *) list->data; if (check_update_interval(bd)) bytes += qq_put32(raw_data + bytes, bd->uid); } i++; if (i==index+30) break; list = list->next; } /* if reach the end */ if (list == NULL) i=0; qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_MEMBERS_INFO, rmd->id, raw_data, bytes, update_class, i); return num; }
/* 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 %u\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); }
void qq_process_room_cmd_get_info(guint8 *data, gint data_len, guint32 action, PurpleConnection *gc) { qq_data *qd; qq_room_data *rmd; qq_buddy_data *bd; PurpleChat *chat; PurpleConversation *conv; guint8 organization, role; guint16 max_members; guint32 resend_flag, member_uid, id, qun_id, last_uid; gint bytes; guint num=0; guint8 has_more=0; gchar *topic; g_return_if_fail(data != NULL && data_len > 0); qd = (qq_data *) gc->proto_data; /* qq_show_packet("Room Info", data, data_len); */ bytes = 0; bytes += qq_get32(&id, data + bytes); g_return_if_fail(id > 0); bytes += qq_get32(&qun_id, data + bytes); g_return_if_fail(qun_id > 0); chat = qq_room_find_or_new(gc, id, qun_id); g_return_if_fail(chat != NULL); rmd = qq_room_data_find(gc, id); g_return_if_fail(rmd != NULL); bytes += qq_get32(&resend_flag, data + bytes); //first 00 00 00 03, then 00 00 00 02 if (resend_flag == 0x00000003) { bytes += qq_get8(&(rmd->type8), data + bytes); bytes += 4; //maybe vip sign bytes += qq_get32(&(rmd->creator_uid), data + bytes); if (rmd->creator_uid == qd->uid) rmd->my_role = QQ_ROOM_ROLE_ADMIN; bytes += qq_get8(&(rmd->auth_type), data + bytes); bytes += 4 ; /* oldCategory */ bytes += 2; // 00 00 bytes += qq_get32(&(rmd->category), data + bytes); bytes += qq_get16(&max_members, data + bytes); bytes += 1; bytes += 8; purple_debug_info("QQ", "type: %u creator: %u category: %u max_members: %u\n", rmd->type8, rmd->creator_uid, rmd->category, max_members); bytes += qq_get_vstr(&(rmd->name), NULL, sizeof(guint8), data + bytes); bytes += 2; /* 0x0000 */ bytes += qq_get_vstr(&(rmd->bulletin), NULL, sizeof(guint8), data + bytes); bytes += qq_get_vstr(&(rmd->intro), NULL, sizeof(guint8), data + bytes); bytes += qq_get_vstr(&(rmd->token), NULL, sizeof(guint16), data + bytes); purple_debug_info("QQ", "room [%s] bulletin [%s] intro [%s] \n", rmd->name, rmd->bulletin, rmd->intro); bytes += 2; //Unknown bytes += qq_get32(&last_uid, data + bytes); /* last_uid of this recv, request more with it */ bytes += qq_get8(&has_more, data + bytes); /* if there are more, request again */ /* now comes the member list separated by 0x00 */ } else { /* resend_flag 00 00 00 02 is special, start with random one only 5 bytes */ bytes += qq_get32(&member_uid, data + bytes); num++; bytes += qq_get8(&organization, data + bytes); bd = qq_room_buddy_find_or_new(gc, rmd, member_uid); } while (bytes < data_len) { bytes += qq_get32(&member_uid, data + bytes); num++; bytes += qq_get8(&organization, data + bytes); bytes += qq_get8(&role, data + bytes); #if 0 if(organization != 0 || role != 0) { purple_debug_info("QQ", "%u, organization=%d, role=%d\n", member_uid, organization, role); } #endif bd = qq_room_buddy_find_or_new(gc, rmd, member_uid); if (bd != NULL) bd->role = role; } purple_debug_info("QQ", "Qun \"%s\" has received %d members\n", rmd->name, num); if (has_more) { qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_INFO, id, NULL, 0, 0, last_uid); } else { qq_room_update_chat_info(chat, rmd); if (action == QQ_ROOM_INFO_DISPLAY) { room_info_display(gc, rmd); } conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, rmd->name, purple_connection_get_account(gc)); if(NULL == conv) { purple_debug_warning("QQ", "Conversation \"%s\" is not opened\n", rmd->name); return; } topic = g_strdup_printf("%u %s", rmd->qun_id, rmd->bulletin); purple_debug_info("QQ", "Set chat topic to %s\n", topic); purple_conv_chat_set_topic(PURPLE_CONV_CHAT(conv), NULL, topic); g_free(topic); } }