/* 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(chat, &rmd);
		qq_request_room_join(gc, &rmd);
	} else {
		add_to_roomlist(qd, &rmd);
	}
}
Exemple #2
0
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);
	}
}