mpd/src/playlist.h
Eric Wong 688289b295 Revert the queue implementation and commands
It's too ugly and broken (both technically and usability-wise)
to be worth supporting in any stable release.

In one sentence: The queue is a very crippled version of the
playlist that takes precedence over the normal playlist.

How is it crippled?

* The "queueid" command only allows the queuing of songs
ALREADY IN THE PLAYLIST!  This promotes having the entire mpd
database of songs in the playlist, which is a stupid practice
to begin with.

* It doesn't allow for meaningful rearranging and movement
of songs within the queue.  To move a song, you'd need to
dequeue and requeue it (and other songs on the list).
Why?  The playlist already allows _all_ these features
and shows everything a client needs to know about the ordering
of songs in a _single_ command!

* Random was a stupid idea to begin with and unfortunately
we're stuck supporting it since we've always had it.  Users
should learn to use "shuffle" instead and not look at their
playlists.  Implementing queue because we have the problem of
random is just a bandage fix and digging ourselves a new hole.

This protocol addition was never in a stable release of mpd, so
reverting it will only break things for people following trunk;
which I'm not too worried about.  I am however worried about
long-term support of this misfeature, so I'm removing it.

Additionally, there are other points:

* It's trivially DoS-able:

(while true; do echo queueid $song_id; done) | nc $MPD_HOST $MPD_PORT

The above commands would cause the queue to become infinitely
expanding, taking up all available memory in the system.  The
mpd playlist was implemented as an array with a fixed (but
configurable) size limit for this reason.

* It's not backwards-compatible.  All clients would require
upgrades (and additional complexity) to even know what the
next song in the playlist is.  mpd is a shared architecture,
and we should not violate the principle of least astonishment
here.

This removes the following commands:
queueid, dequeue, queueinfo

Additionally, the status field of "playlistqueue: " is removed
from the status command.

While this DoS is trivial to fix, the design is simply too
broken to ever support in a real release.

The overloading of the "addid" command and the allowing of
negative numbers to be used as offsets is far more flexible.

This improved "addid" is completely backwards-compatible with
all clients, and does not require clients to have UI changes or
run additional commands to display the queue.

git-svn-id: https://svn.musicpd.org/mpd/trunk@7155 09075e82-0dd4-0310-85a5-a0d7c8717e4f
2008-01-26 20:21:07 +00:00

146 lines
3.5 KiB
C

/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PLAYLIST_H
#define PLAYLIST_H
#include "../config.h"
#include "dbUtils.h"
#include "os_compat.h"
#define PLAYLIST_FILE_SUFFIX "m3u"
#define PLAYLIST_COMMENT '#'
typedef struct _Playlist {
Song **songs;
/* holds version a song was modified on */
mpd_uint32 *songMod;
int *order;
int *positionToId;
int *idToPosition;
int length;
int current;
int queued;
int repeat;
int random;
mpd_uint32 version;
} Playlist;
extern int playlist_saveAbsolutePaths;
extern int playlist_max_length;
void initPlaylist(void);
void finishPlaylist(void);
void readPlaylistState(FILE *);
void savePlaylistState(FILE *);
int clearPlaylist(int fd);
int clearStoredPlaylist(int fd, char *utf8file);
int addToPlaylist(int fd, char *file, int *added_id);
int addToStoredPlaylist(int fd, char *file, char *utf8file);
int addSongToPlaylist(int fd, Song * song, int *added_id);
int showPlaylist(int fd);
int deleteFromPlaylist(int fd, int song);
int deleteFromPlaylistById(int fd, int song);
int playlistInfo(int fd, int song);
int playlistId(int fd, int song);
int stopPlaylist(int fd);
int playPlaylist(int fd, int song, int stopOnError);
int playPlaylistById(int fd, int song, int stopOnError);
int nextSongInPlaylist(int fd);
void syncPlayerAndPlaylist(void);
int previousSongInPlaylist(int fd);
int shufflePlaylist(int fd);
int savePlaylist(int fd, char *utf8file);
int deletePlaylist(int fd, char *utf8file);
int deletePlaylistById(int fd, char *utf8file);
void deleteASongFromPlaylist(Song * song);
int moveSongInPlaylist(int fd, int from, int to);
int moveSongInPlaylistById(int fd, int id, int to);
int swapSongsInPlaylist(int fd, int song1, int song2);
int swapSongsInPlaylistById(int fd, int id1, int id2);
int loadPlaylist(int fd, char *utf8file);
int getPlaylistRepeatStatus(void);
int setPlaylistRepeatStatus(int fd, int status);
int getPlaylistRandomStatus(void);
int setPlaylistRandomStatus(int fd, int status);
int getPlaylistCurrentSong(void);
int getPlaylistSongId(int song);
int getPlaylistLength(void);
unsigned long getPlaylistVersion(void);
void playPlaylistIfPlayerStopped(void);
int seekSongInPlaylist(int fd, int song, float time);
int seekSongInPlaylistById(int fd, int id, float time);
void playlistVersionChange(void);
int playlistChanges(int fd, mpd_uint32 version);
int playlistChangesPosId(int fd, mpd_uint32 version);
int PlaylistInfo(int fd, char *utf8file, int detail);
void searchForSongsInPlaylist(int fd, int numItems, LocateTagItem * items);
void findSongsInPlaylist(int fd, int numItems, LocateTagItem * items);
int valid_playlist_name(int err_fd, const char *utf8path);
#endif