Exemplo n.º 1
0
static gint send_room_cmd(PurpleConnection *gc, guint8 room_cmd, guint32 room_id,
		guint8 *data, gint data_len, UPDCLS update_class, guint32 ship32)
{
	qq_data *qd;
	guint8 *buf;
	gint buf_len;
	guint8 *encrypted;
	gint encrypted_len;
	gint bytes_sent;
	guint16 seq;

	g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1);
	qd = (qq_data *) gc->proto_data;

	buf = g_newa(guint8, MAX_PACKET_SIZE);
	memset(buf, 0, MAX_PACKET_SIZE);

	/* encap room_cmd and room id to buf*/
	buf_len = 0;
	buf_len += qq_put8(buf + buf_len, room_cmd);
	if (room_id != 0) {
		/* id 0 is for QQ Demo Group, now they are closed*/
		buf_len += qq_put32(buf + buf_len, room_id);
	}
	if (data != NULL && data_len > 0) {
		buf_len += qq_putdata(buf + buf_len, data, data_len);
	}

	qd->send_seq++;
	seq = qd->send_seq;

	/* Encrypt to encrypted with session_key */
	/* at most 17 bytes more */
	encrypted = g_newa(guint8, buf_len + 17);
	encrypted_len = qq_encrypt(encrypted, buf, buf_len, qd->session_key);
	if (encrypted_len < 16) {
		purple_debug_error("QQ_ENCRYPT", "Error len %d: [%05d] %s (0x%02X)\n",
				encrypted_len, seq, qq_get_room_cmd_desc(room_cmd), room_cmd);
		return -1;
	}

	bytes_sent = packet_send_out(gc, QQ_CMD_ROOM, seq, encrypted, encrypted_len);
#if 1
		/* qq_show_packet("send_room_cmd", buf, buf_len); */
		purple_debug_info("QQ",
				"<== [%05d] %s (0x%02X) to room %d, datalen %d\n",
				seq, qq_get_room_cmd_desc(room_cmd), room_cmd, room_id, buf_len);
#endif

	qq_trans_add_room_cmd(gc, seq, room_cmd, room_id, encrypted, encrypted_len,
			update_class, ship32);
	return bytes_sent;
}
Exemplo n.º 2
0
static void process_room_cmd_notify(PurpleConnection *gc,
	guint8 room_cmd, guint8 room_id, guint8 reply, guint8 *data, gint data_len)
{
	gchar *prim;
	gchar *msg, *msg_utf8;
	g_return_if_fail(data != NULL && data_len > 0);

	msg = g_strndup((gchar *) data, data_len);	/* it will append 0x00 */
	msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT);
	g_free(msg);

	prim = g_strdup_printf(_("Error reply of %s(0x%02X)\nRoom %u, reply 0x%02X"),
		qq_get_room_cmd_desc(room_cmd), room_cmd, room_id, reply);

	purple_notify_error(gc, _("QQ Qun Command"), prim, msg_utf8);

	g_free(prim);
	g_free(msg_utf8);
}
Exemplo n.º 3
0
void qq_proc_room_cmds(PurpleConnection *gc, guint16 seq,
		guint8 room_cmd, guint32 room_id, guint8 *rcved, gint rcved_len,
		guint32 update_class, guintptr ship_value)
{
	qq_data *qd;
	guint8 *data;
	gint data_len;
	qq_room_data *rmd;
	gint bytes;
	guint8 reply_cmd, reply;

	g_return_if_fail (gc != NULL && gc->proto_data != NULL);
	qd = (qq_data *) gc->proto_data;

	data = g_newa(guint8, rcved_len);
	data_len = qq_decrypt(data, rcved, rcved_len, qd->session_key);
	if (data_len < 0) {
		purple_debug_warning("QQ",
			"Can not decrypt room cmd by session key, [%05d], 0x%02X %s for %d, len %d\n",
			seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, rcved_len);
		qq_show_packet("Can not decrypted", rcved, rcved_len);
		return;
	}

	if (room_id <= 0) {
		purple_debug_warning("QQ",
			"room id is 0, [%05d], 0x%02X %s for %d, len %d\n",
			seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, rcved_len);
		/* Some room cmd has no room id, like QQ_ROOM_CMD_SEARCH */
	}

	if (data_len <= 2) {
		purple_debug_warning("QQ",
			"Invaild len of room cmd decrypted, [%05d], 0x%02X %s for %d, len %d\n",
			seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, rcved_len);
		return;
	}

	bytes = 0;
	bytes += qq_get8(&reply_cmd, data + bytes);
	bytes += qq_get8(&reply, data + bytes);

	if (reply_cmd != room_cmd) {
		purple_debug_warning("QQ",
			"Missing room cmd in reply 0x%02X %s, [%05d], 0x%02X %s for %d, len %d\n",
			reply_cmd, qq_get_room_cmd_desc(reply_cmd),
			seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, rcved_len);
	}

	/* now process the packet */
	if (reply != QQ_ROOM_CMD_REPLY_OK) {
		switch (reply) {	/* this should be all errors */
		case QQ_ROOM_CMD_REPLY_NOT_MEMBER:
			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",
					   "Not a member of room \"%s\"\n", rmd->name);
				rmd->my_role = QQ_ROOM_ROLE_NO;
			}
			break;
		case QQ_ROOM_CMD_REPLY_SEARCH_ERROR:
			if (qd->roomlist != NULL) {
				if (purple_roomlist_get_in_progress(qd->roomlist))
					purple_roomlist_set_in_progress(qd->roomlist, FALSE);
			}
		default:
			process_room_cmd_notify(gc, reply_cmd, room_id, reply, data + bytes, data_len - bytes);
		}
		return;
	}

	/* seems ok so far, so we process the reply according to sub_cmd */
	switch (reply_cmd) {
	case QQ_ROOM_CMD_GET_QUN_LIST:
		qq_process_room_cmd_get_qun_list(data + bytes, data_len - bytes, gc);
		break;
	case QQ_ROOM_CMD_GET_INFO:
		qq_process_room_cmd_get_info(data + bytes, data_len - bytes, ship_value, gc);
		break;
	case QQ_ROOM_CMD_CREATE:
		qq_group_process_create_group_reply(data + bytes, data_len - bytes, gc);
		break;
	case QQ_ROOM_CMD_CHANGE_INFO:
		qq_group_process_modify_info_reply(data + bytes, data_len - bytes, gc);
		break;
	case QQ_ROOM_CMD_MEMBER_OPT:
		qq_group_process_modify_members_reply(data + bytes, data_len - bytes, gc);
		break;
	case QQ_ROOM_CMD_ACTIVATE:
		qq_group_process_activate_group_reply(data + bytes, data_len - bytes, gc);
		break;
	case QQ_ROOM_CMD_SEARCH:
		qq_process_room_search(gc, data + bytes, data_len - bytes, ship_value);
		break;
	case QQ_ROOM_CMD_JOIN:
		qq_process_group_cmd_join_group(data + bytes, data_len - bytes, gc);
		break;
	case QQ_ROOM_CMD_AUTH:
		qq_process_group_cmd_join_group_auth(data + bytes, data_len - bytes, gc);
		break;
	case QQ_ROOM_CMD_QUIT:
		qq_process_group_cmd_exit_group(data + bytes, data_len - bytes, gc);
		break;
	case QQ_ROOM_CMD_SEND_IM:
		qq_process_room_send_im(gc, data + bytes, data_len - bytes);
		break;
	case QQ_ROOM_CMD_GET_ONLINES:
		qq_process_room_cmd_get_onlines(data + bytes, data_len - bytes, gc);
		break;
	case QQ_ROOM_CMD_GET_MEMBERS_INFO:
		qq_process_room_cmd_get_members_info(data + bytes, data_len - bytes, ship_value, gc);
		break;
	default:
		purple_debug_warning("QQ", "Unknown room cmd 0x%02X %s\n",
			   reply_cmd, qq_get_room_cmd_desc(reply_cmd));
	}

	if (update_class == QQ_CMD_CLASS_NONE)
		return;

	if (update_class == QQ_CMD_CLASS_UPDATE_ALL) {
		qq_update_all_rooms(gc, room_cmd, room_id);
		return;
	}
	if (update_class == QQ_CMD_CLASS_UPDATE_ONLINE) {
		update_all_rooms_online(gc, room_cmd, room_id);
		return;
	}
	if (update_class == QQ_CMD_CLASS_UPDATE_ROOM) {
		qq_update_room(gc, room_cmd, room_id);
	}
}