📝 Update documentation

This commit is contained in:
Androz2091 2020-08-14 20:52:34 +02:00
parent f88e77170d
commit 5c784991ca
2 changed files with 302 additions and 170 deletions

View file

@ -114,6 +114,10 @@ class Player extends EventEmitter {
client.on('voiceStateUpdate', (oldState, newState) => this._handleVoiceStateUpdate(oldState, newState)) client.on('voiceStateUpdate', (oldState, newState) => this._handleVoiceStateUpdate(oldState, newState))
} }
/**
* @ignore
* @param {String} query
*/
resolveQueryType (query) { resolveQueryType (query) {
if (this.util.isSpotifyLink(query)) { if (this.util.isSpotifyLink(query)) {
return 'spotify-song' return 'spotify-song'
@ -129,9 +133,11 @@ class Player extends EventEmitter {
} }
/** /**
* * Search tracks
* @ignore
* @param {Discord.Message} message * @param {Discord.Message} message
* @param {string} query * @param {string} query
* @returns {Promise<Track>}
*/ */
_searchTracks (message, query) { _searchTracks (message, query) {
return new Promise(async (resolve) => { return new Promise(async (resolve) => {
@ -192,6 +198,15 @@ class Player extends EventEmitter {
}) })
} }
/**
* Change the filters.
* @param {Discord.Message} message
* @param {Partial<Filters>} newFilters The filters to update and their new status.
* @example
* client.player.setFilters(message, {
* bassboost: true
* });
*/
setFilters (message, newFilters) { setFilters (message, newFilters) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// Get guild queue // Get guild queue
@ -204,10 +219,21 @@ class Player extends EventEmitter {
}) })
} }
/**
* Check whether there is a music played in the server
* @param {Discord.Message} message
*/
isPlaying (message) { isPlaying (message) {
return this.queues.some((g) => g.guildID === message.guild.id) return this.queues.some((g) => g.guildID === message.guild.id)
} }
/**
* Add a track to the queue
* @ignore
* @param {Discord.Message} message
* @param {Track} track
* @returns {Queue}
*/
_addTrackToQueue (message, track) { _addTrackToQueue (message, track) {
const queue = this.getQueue(message) const queue = this.getQueue(message)
if (!queue) throw new Error('NotPlaying') if (!queue) throw new Error('NotPlaying')
@ -216,6 +242,13 @@ class Player extends EventEmitter {
return queue return queue
} }
/**
* Add multiple tracks to the queue
* @ignore
* @param {Discord.Message} message
* @param {Track[]} tracks
* @returns {Queue}
*/
_addTracksToQueue (message, tracks) { _addTracksToQueue (message, tracks) {
const queue = this.getQueue(message) const queue = this.getQueue(message)
if (!queue) throw new Error('Cannot add tracks to queue because no song is currently played on the server.') if (!queue) throw new Error('Cannot add tracks to queue because no song is currently played on the server.')
@ -223,6 +256,13 @@ class Player extends EventEmitter {
return queue return queue
} }
/**
* Create a new queue and play the first track
* @ignore
* @param {Discord.Message} message
* @param {Track} track
* @returns {Promise<Queue>}
*/
_createQueue (message, track) { _createQueue (message, track) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const channel = message.member.voice ? message.member.voice.channel : null const channel = message.member.voice ? message.member.voice.channel : null
@ -243,6 +283,12 @@ class Player extends EventEmitter {
}) })
} }
/**
* Handle playlist by fetching the tracks and adding them to the queue
* @ignore
* @param {Discord.Message} message
* @param {String} query
*/
async _handlePlaylist (message, query) { async _handlePlaylist (message, query) {
const playlist = await ytpl(query).catch(() => {}) const playlist = await ytpl(query).catch(() => {})
if (!playlist) return this.emit('noResults', message, query) if (!playlist) return this.emit('noResults', message, query)
@ -261,14 +307,15 @@ class Player extends EventEmitter {
} }
} }
async _resolveSong (message, query) { /**
* Play a track in the server. Supported query types are `keywords`, YouTube video links`, `YouTube playlists links`, Spotify track link` or `SoundCloud song link`.
} * @param {Discord.Message} message
* @param {String} query
async _handleSong (message, query) { * @returns {Promise<void>}
*
} * @example
* client.player.play(message, "Despacito");
*/
async play (message, query) { async play (message, query) {
const isPlaying = this.isPlaying(message) const isPlaying = this.isPlaying(message)
if (this.util.isYTPlaylistLink(query)) { if (this.util.isYTPlaylistLink(query)) {
@ -294,6 +341,12 @@ class Player extends EventEmitter {
} }
} }
/**
* Pause the music in the server.
* @param {Discord.Message} message
* @example
* client.player.pause(message);
*/
pause (message) { pause (message) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// Get guild queue // Get guild queue
@ -307,24 +360,34 @@ class Player extends EventEmitter {
}) })
} }
/**
* Resume the music in the server.
* @param {Discord.Message} message
* @returns {Queue}
* @example
* client.player.resume(message);
*/
resume (message) { resume (message) {
return new Promise((resolve, reject) => {
// Get guild queue // Get guild queue
const queue = this.queues.find((g) => g.guildID === message.guild.id) const queue = this.queues.find((g) => g.guildID === message.guild.id)
if (!queue) return reject(new Error('Not playing')) if (!queue) return this.emit('error', 'NotPlaying')
// Pause the dispatcher // Pause the dispatcher
queue.voiceConnection.dispatcher.resume() queue.voiceConnection.dispatcher.resume()
queue.paused = false queue.paused = false
// Resolve the guild queue // Resolve the guild queue
resolve(queue.playing) return queue
})
} }
/**
* Stop the music in the server.
* @param {Discord.Message} message
* @example
* client.player.stop(message);
*/
stop (message) { stop (message) {
return new Promise((resolve, reject) => {
// Get guild queue // Get guild queue
const queue = this.queues.find((g) => g.guildID === message.guild.id) const queue = this.queues.find((g) => g.guildID === message.guild.id)
if (!queue) return reject(new Error('Not playing')) if (!queue) return this.emit('error', 'NotPlaying')
// Stop the dispatcher // Stop the dispatcher
queue.stopped = true queue.stopped = true
queue.tracks = [] queue.tracks = []
@ -332,98 +395,127 @@ class Player extends EventEmitter {
queue.voiceConnection.dispatcher.end() queue.voiceConnection.dispatcher.end()
if (this.options.leaveOnStop) queue.voiceConnection.channel.leave() if (this.options.leaveOnStop) queue.voiceConnection.channel.leave()
this.queues.delete(message.guild.id) this.queues.delete(message.guild.id)
// Resolve
resolve()
})
} }
/**
* Change the server volume.
* @param {Discord.Message} message
* @param {number} percent
* @returns {Queue}
* @example
* client.player.setVolume(message, 90);
*/
setVolume (message, percent) { setVolume (message, percent) {
return new Promise((resolve, reject) => {
// Get guild queue // Get guild queue
const queue = this.queues.get(message.guild.id) const queue = this.queues.get(message.guild.id)
if (!queue) return reject(new Error('Not playing')) if (!queue) return this.emit('error', 'NotPlaying')
// Update volume // Update volume
queue.volume = percent queue.volume = percent
queue.voiceConnection.dispatcher.setVolumeLogarithmic(queue.calculatedVolume / 200) queue.voiceConnection.dispatcher.setVolumeLogarithmic(queue.calculatedVolume / 200)
// Resolve guild queue // Return the queue
resolve() return queue
})
} }
/**
* Get the server queue.
* @param {Discord.Message} message
* @returns {Queue}
*/
getQueue (message) { getQueue (message) {
// Gets guild queue // Gets guild queue
const queue = this.queues.get(message.guild.id) const queue = this.queues.get(message.guild.id)
return queue return queue
} }
/**
* Clears the server queue.
* @param {Discord.Message} message
* @returns {Queue}
*/
clearQueue (message) { clearQueue (message) {
return new Promise((resolve, reject) => {
// Get guild queue // Get guild queue
const queue = this.queues.get(message.guild.id) const queue = this.queues.get(message.guild.id)
if (!queue) return reject(new Error('Not playing')) if (!queue) return this.emit('error', 'NotPlaying')
// Clear queue // Clear queue
queue.tracks = [] queue.tracks = []
// Resolve guild queue // Return the queue
resolve(queue) return queue
})
} }
/**
* Skips to the next song.
* @param {Discord.Message} message
* @returns {Queue}
*/
skip (message) { skip (message) {
return new Promise((resolve, reject) => {
// Get guild queue // Get guild queue
const queue = this.queues.get(message.guild.id) const queue = this.queues.get(message.guild.id)
if (!queue) return reject(new Error('Not playing')) if (!queue) return this.emit('error', 'NotPlaying')
const currentTrack = queue.playing const currentTrack = queue.playing
// End the dispatcher // End the dispatcher
queue.voiceConnection.dispatcher.end() queue.voiceConnection.dispatcher.end()
queue.lastSkipped = true queue.lastSkipped = true
// Resolve the current track // Return the queue
resolve(currentTrack) return queue
})
} }
/**
* Get the played song in the server.
* @param {Discord.Message} message
* @returns {Track}
*/
nowPlaying (message) { nowPlaying (message) {
return new Promise((resolve, reject) => {
// Get guild queue // Get guild queue
const queue = this.queues.get(message.guild.id) const queue = this.queues.get(message.guild.id)
if (!queue) return reject(new Error('Not playing')) if (!queue) return this.emit('error', 'NotPlaying')
const currentTrack = queue.tracks[0] const currentTrack = queue.tracks[0]
// Resolve the current track // Return the current track
resolve(currentTrack) return currentTrack
})
} }
/**
* Enable or disable repeat mode in the server.
* @param {Discord.Message} message
* @param {boolean} enabled
* @returns {boolean} whether the repeat mode is now enabled.
*/
setRepeatMode (message, enabled) { setRepeatMode (message, enabled) {
return new Promise((resolve, reject) => {
// Get guild queue // Get guild queue
const queue = this.queues.get(message.guild.id) const queue = this.queues.get(message.guild.id)
if (!queue) return reject(new Error('Not playing')) if (!queue) return this.emit('error', 'NotPlaying')
// Enable/Disable repeat mode // Enable/Disable repeat mode
queue.repeatMode = enabled queue.repeatMode = enabled
// Resolve // Return the repeat mode
resolve() return queue.repeatMode
})
} }
/**
* Shuffle the queue of the server.
* @param {Discord.Message} message
* @returns {}
*/
shuffle (message) { shuffle (message) {
return new Promise((resolve, reject) => {
// Get guild queue // Get guild queue
const queue = this.queues.get(message.guild.id) const queue = this.queues.get(message.guild.id)
if (!queue) return reject(new Error('Not playing')) if (!queue) return this.emit('error', 'NotPlaying')
// Shuffle the queue (except the first track) // Shuffle the queue (except the first track)
const currentTrack = queue.tracks.shift() const currentTrack = queue.tracks.shift()
queue.tracks = queue.tracks.sort(() => Math.random() - 0.5) queue.tracks = queue.tracks.sort(() => Math.random() - 0.5)
queue.tracks.unshift(currentTrack) queue.tracks.unshift(currentTrack)
// Resolve // Return the queue
resolve(queue) return queue
})
} }
/**
* Remove a track from the queue of the server
* @param {Discord.Message} message
* @param {Track|number} track
* @returns {Track} the removed track
*/
remove (message, track) { remove (message, track) {
return new Promise((resolve, reject) => { // Get guild queue
// Gets guild queue
const queue = this.queues.get(message.guild.id) const queue = this.queues.get(message.guild.id)
if (!queue) return reject(new Error('Not playing')) if (!queue) return this.emit('error', 'NotPlaying')
// Remove the track from the queue // Remove the track from the queue
let trackFound = null let trackFound = null
if (typeof track === 'number') { if (typeof track === 'number') {
@ -438,10 +530,16 @@ class Player extends EventEmitter {
} }
} }
// Resolve // Resolve
resolve(trackFound) return trackFound
})
} }
/**
* Create a progress bar for the queue of the server.
* @param {Discord.Message} message
* @param {Object} options
* @param {boolean} options.timecodes
* @returns {string}
*/
createProgressBar (message, options) { createProgressBar (message, options) {
// Gets guild queue // Gets guild queue
const queue = this.queues.get(message.guild.id) const queue = this.queues.get(message.guild.id)
@ -489,7 +587,7 @@ class Player extends EventEmitter {
if (newState.member.id === this.client.user.id && !newState.channelID) { if (newState.member.id === this.client.user.id && !newState.channelID) {
queue.stream.destroy() queue.stream.destroy()
this.queues.delete(newState.guild.id) this.queues.delete(newState.guild.id)
this.emit('botDisconnect') this.emit('botDisconnect', queue.firstMessage)
} }
// process leaveOnEmpty checks // process leaveOnEmpty checks
@ -580,7 +678,7 @@ class Player extends EventEmitter {
return queue.emit('musicStopp') return queue.emit('musicStopp')
} }
// Emit end event // Emit end event
return queue.emit('queueEnd') return queue.emit('queueEnd', queue.firstMessage, queue)
} }
// if the track needs to be the next one // if the track needs to be the next one
if (!queue.repeatMode && !firstPlay) queue.tracks.shift() if (!queue.repeatMode && !firstPlay) queue.tracks.shift()
@ -594,3 +692,95 @@ class Player extends EventEmitter {
}; };
module.exports = Player module.exports = Player
/**
* Emitted when a track starts
* @event Player#trackStart
* @param {Discord.Message} message
* @param {Queue} queue
* @param {Track} track
*/
/**
* Emitted when a playlist is started
* @event Player#queueCreate
* @param {Discord.Message} message
* @param {Queue} queue
* @param {Object} playlist
* @param {Track} track
*/
/**
* Emitted when the bot is awaiting search results
* @event Player#searchResults
* @param {Discord.Message} message
* @param {string} query
* @param {Track[]} tracks
*/
/**
* Emitted when the user has sent an invalid response for search results
* @event Player#searchInvalidResponse
* @param {Discord.Message} message
* @param {string} query
* @param {Track[]} tracks
* @param {string} invalidResponse
*/
/**
* Emitted when the bot has stopped awaiting search results (timeout)
* @event Player#searchCancel
* @param {Discord.Message} message
* @param {string} query
* @param {Track[]} tracks
*/
/**
* Emitted when the bot can't find related results to the query
* @event Player#noResults
* @param {Discord.Message} message
* @param {string} query
*/
/**
* Emitted when the bot is disconnected from the channel
* @event Player#botDisconnect
* @param {Discord.Message} message
*/
/**
* Emitted when the channel of the bot is empty
* @event Player#channelEmpty
* @param {Discord.Message} message
* @param {Queue} queue
*/
/**
* Emitted when the queue of the server is ended
* @event Player#queueEnd
* @param {Discord.Message} message
* @param {Queue} queue
*/
/**
* Emitted when a track is added to the queue
* @event Player#trackAdd
* @param {Discord.Message} message
* @param {Queue} queue
* @param {Track} track
*/
/**
* Emitted when a playlist is added to the queue
* @event Player#playlistAdd
* @param {Discord.Message} message
* @param {Queue} queue
* @param {Object} playlist
*/
/**
* Emitted when an error is triggered
* @event Player#error
* @param {Discord.Message} message
* @param {string} error It can be `NotConnected`, `UnableToJoin` or `NotPlaying`.
*/

View file

@ -90,61 +90,3 @@ class Queue extends EventEmitter {
} }
module.exports = Queue module.exports = Queue
/**
* Emitted when the queue is empty.
* @event Queue#end
*
* @example
* client.on('message', (message) => {
*
* const args = message.content.slice(settings.prefix.length).trim().split(/ +/g);
* const command = args.shift().toLowerCase();
*
* if(command === 'play'){
*
* let track = await client.player.play(message.member.voice.channel, args[0]);
*
* track.queue.on('end', () => {
* message.channel.send('The queue is empty, please add new tracks!');
* });
*
* }
*
* });
*/
/**
* Emitted when the voice channel is empty.
* @event Queue#channelEmpty
*/
/**
* Emitted when the track changes.
* @event Queue#trackChanged
* @param {Track} oldTrack The old track (playing before)
* @param {Track} newTrack The new track (currently playing)
* @param {Boolean} skipped Whether the change is due to the skip() function
*
* @example
* client.on('message', (message) => {
*
* const args = message.content.slice(settings.prefix.length).trim().split(/ +/g);
* const command = args.shift().toLowerCase();
*
* if(command === 'play'){
*
* let track = await client.player.play(message.member.voice.channel, args[0]);
*
* track.queue.on('trackChanged', (oldTrack, newTrack, skipped, repeatMode) => {
* if(repeatMode){
* message.channel.send(`Playing ${newTrack} again...`);
* } else {
* message.channel.send(`Now playing ${newTrack}...`);
* }
* });
*
* }
*
* });
*/