parent
a425607a6b
commit
556c3a5e7f
@ -0,0 +1,178 @@
|
|||||||
|
play:
|
||||||
|
name: play
|
||||||
|
description: >
|
||||||
|
Adds the url to the YouTube video or YouTube playlist into the queue.
|
||||||
|
permission: all
|
||||||
|
category: Music
|
||||||
|
args:
|
||||||
|
- url
|
||||||
|
response:
|
||||||
|
success: >
|
||||||
|
Added URL to the media queue.
|
||||||
|
failure: >
|
||||||
|
Failed adding the URL to the media queue.
|
||||||
|
url_invalid: >
|
||||||
|
The URL you provided is not a valid YouTube video or Playlist URL.
|
||||||
|
no_url: >
|
||||||
|
You need to provide an URL to a YouTube viceo or Playlist.
|
||||||
|
no_voicechannel: >
|
||||||
|
You need to join a VoiceChannel to request media playback.
|
||||||
|
|
||||||
|
play_next:
|
||||||
|
name: playnext
|
||||||
|
description: >
|
||||||
|
Adds the url to the YouTube video or YouTube playlist into the queue as
|
||||||
|
next playing song.
|
||||||
|
permission: all
|
||||||
|
category: Music
|
||||||
|
args:
|
||||||
|
- url
|
||||||
|
response:
|
||||||
|
success: >
|
||||||
|
Added URL as next media to the media queue.
|
||||||
|
failure: >
|
||||||
|
Failed adding the URL to the media queue.
|
||||||
|
url_invalid: >
|
||||||
|
The URL you provided is not a valid YouTube video or Playlist URL.
|
||||||
|
no_url: >
|
||||||
|
You need to provide an URL to a YouTube viceo or Playlist.
|
||||||
|
no_voicechannel: >
|
||||||
|
You need to join a VoiceChannel to request media playback.
|
||||||
|
|
||||||
|
join:
|
||||||
|
name: join
|
||||||
|
description: >
|
||||||
|
Joins the VoiceChannel you are in.
|
||||||
|
permission: all
|
||||||
|
category: Music
|
||||||
|
response:
|
||||||
|
no_voicechannel: >
|
||||||
|
You need to join a VoiceChannel for me to join.
|
||||||
|
|
||||||
|
stop:
|
||||||
|
name: stop
|
||||||
|
description: >
|
||||||
|
Stops the media playback and leaves the VoiceChannel.
|
||||||
|
permission: dj
|
||||||
|
category: Music
|
||||||
|
response:
|
||||||
|
success: >
|
||||||
|
Stopped music playback.
|
||||||
|
not_playing: >
|
||||||
|
I'm not playing music at the moment. What do you want me to stop?
|
||||||
|
|
||||||
|
pause:
|
||||||
|
name: pause
|
||||||
|
description: >
|
||||||
|
Pauses the media playback.
|
||||||
|
permission: all
|
||||||
|
category: Music
|
||||||
|
response:
|
||||||
|
success: >
|
||||||
|
Paused playback.
|
||||||
|
not_playing: >
|
||||||
|
I'm not playing music at the moment.
|
||||||
|
|
||||||
|
resume:
|
||||||
|
name: resume
|
||||||
|
description: >
|
||||||
|
Resumes the media playback.
|
||||||
|
permission: all
|
||||||
|
category: Music
|
||||||
|
response:
|
||||||
|
success: >
|
||||||
|
Resumed playback.
|
||||||
|
not_playing: >
|
||||||
|
I'm not playing music at the moment.
|
||||||
|
|
||||||
|
skip:
|
||||||
|
name: skip
|
||||||
|
description: >
|
||||||
|
Skips the currently playing song.
|
||||||
|
permission: dj
|
||||||
|
category: Music
|
||||||
|
response:
|
||||||
|
success: >
|
||||||
|
Skipped to the next song.
|
||||||
|
not_playing: >
|
||||||
|
I'm not playing music at the moment.
|
||||||
|
|
||||||
|
clear:
|
||||||
|
name: clear
|
||||||
|
description: >
|
||||||
|
Clears the media queue.
|
||||||
|
permission: dj
|
||||||
|
category: Music
|
||||||
|
response:
|
||||||
|
success: >
|
||||||
|
The media queue has been cleared.
|
||||||
|
|
||||||
|
media_queue:
|
||||||
|
name: queue
|
||||||
|
descriptions: >
|
||||||
|
Shows the next ten songs in the media queue.
|
||||||
|
permission: all
|
||||||
|
category: Music
|
||||||
|
|
||||||
|
media_current:
|
||||||
|
name: np
|
||||||
|
description: >
|
||||||
|
Shows the currently playing song.
|
||||||
|
permission: all
|
||||||
|
category: Music
|
||||||
|
response:
|
||||||
|
not_playing: >
|
||||||
|
I'm not playing music at the moment.
|
||||||
|
|
||||||
|
shuffle:
|
||||||
|
name: shuffle
|
||||||
|
description: >
|
||||||
|
Shuffles the media queue
|
||||||
|
permission: all
|
||||||
|
category: Music
|
||||||
|
response:
|
||||||
|
success: >
|
||||||
|
The queue has been shuffled.
|
||||||
|
|
||||||
|
toggle_repeat:
|
||||||
|
name: repeat
|
||||||
|
description: >
|
||||||
|
Toggles listening o repeat.
|
||||||
|
permission: all
|
||||||
|
category: Music
|
||||||
|
response:
|
||||||
|
repeat_true: >
|
||||||
|
Listening on repeat now!
|
||||||
|
repeat_false: >
|
||||||
|
Not listening on repeat anymore.
|
||||||
|
|
||||||
|
save_media:
|
||||||
|
name: savemedia
|
||||||
|
description: >
|
||||||
|
Saves the YouTube URL with a specific name.
|
||||||
|
permission: dj
|
||||||
|
category: Music
|
||||||
|
args:
|
||||||
|
- url
|
||||||
|
usage: savemedia [url] [name...]
|
||||||
|
|
||||||
|
delete_media:
|
||||||
|
name: deletemedia
|
||||||
|
description: >
|
||||||
|
Deletes a saved YouTube URL from saved media.
|
||||||
|
permission: dj
|
||||||
|
category: Music
|
||||||
|
usage: deletemedia [name]
|
||||||
|
response:
|
||||||
|
no_name: >
|
||||||
|
You must provide a name for the media to delete.
|
||||||
|
|
||||||
|
saved_media:
|
||||||
|
name: savedmedia
|
||||||
|
description: >
|
||||||
|
Shows all saved YouTube URLs.
|
||||||
|
permission: all
|
||||||
|
category: Music
|
||||||
|
response:
|
||||||
|
no_saved: >
|
||||||
|
There are no saved YouTube URLs :(
|
@ -0,0 +1,285 @@
|
|||||||
|
const cmdLib = require('../../CommandLib'),
|
||||||
|
utils = require('../../utils'),
|
||||||
|
location = './lib/commands/MusicCommands';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Music commands provide commands to control the bots music functions.
|
||||||
|
* These commands are for server music functionalities.
|
||||||
|
*/
|
||||||
|
class MusicCommandModule extends cmdLib.CommandModule {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param opts {Object} properties:
|
||||||
|
* getGuildHandler - a function to get the guild handler for a guild.
|
||||||
|
* logger - the logger instance
|
||||||
|
*/
|
||||||
|
constructor(opts) {
|
||||||
|
super(cmdLib.CommandScopes.Guild);
|
||||||
|
this.templateFile = location + '/MusicCommandsTemplate.yaml';
|
||||||
|
this._getGuildHandler = opts.getGuildHandler;
|
||||||
|
this._logger = opts.logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects to a voice-channel if not connected and plays the url
|
||||||
|
* @param gh {guilding.GuildHandler}
|
||||||
|
* @param vc {Discord.VoiceChannel}
|
||||||
|
* @param url {String} The url to the YouTube media
|
||||||
|
* @param next {Boolean} Should the song be played next
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
async _connectAndPlay(gh, vc, url, next) {
|
||||||
|
if (!gh.dj.connected) {
|
||||||
|
await gh.dj.connect(vc);
|
||||||
|
await gh.dj.playYouTube(url, next);
|
||||||
|
} else {
|
||||||
|
await gh.dj.playYouTube(url, next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The play function for the music commands play and playnext
|
||||||
|
* @param m {Discord.Message}
|
||||||
|
* @param k {Object} kwargs
|
||||||
|
* @param s {String} argsString
|
||||||
|
* @param t {Object} template
|
||||||
|
* @param n {Boolean} play next
|
||||||
|
* @returns {Promise<*>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
async _playFunction(m, k, s, t, n) {
|
||||||
|
let gh = await this._getGuildHandler(m.guild);
|
||||||
|
let vc = gh.dj.voiceChannel || m.member.voiceChannel;
|
||||||
|
let url = k['url'];
|
||||||
|
if (!vc)
|
||||||
|
return t.response.no_voicechannel;
|
||||||
|
if (!url)
|
||||||
|
return t.response.no_url;
|
||||||
|
if (!utils.YouTube.isValidEntityUrl(url)) {
|
||||||
|
url = s;
|
||||||
|
let row = await gh.db.get('SELECT url FROM playlists WHERE name = ?', [url]);
|
||||||
|
if (!row) {
|
||||||
|
this._logger.debug('Got invalid url for play command.');
|
||||||
|
return t.response.url_invalid;
|
||||||
|
} else {
|
||||||
|
await this._connectAndPlay(gh, vc, row.url, n);
|
||||||
|
return t.response.success;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await this._connectAndPlay(gh, vc, url, n);
|
||||||
|
return t.response.success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async register(commandHandler) {
|
||||||
|
await this._loadTemplate();
|
||||||
|
|
||||||
|
let play = new cmdLib.Command(
|
||||||
|
this.template.play,
|
||||||
|
new cmdLib.Answer(async (m, k, s) => {
|
||||||
|
return await this._playFunction(m, k, s, this.template.play, false);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
let playNext = new cmdLib.Command(
|
||||||
|
this.template.play_next,
|
||||||
|
new cmdLib.Answer(async (m, k, s) => {
|
||||||
|
return await this._playFunction(m, k, s, this.template.play_next, true);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
let join = new cmdLib.Command(
|
||||||
|
this.template.join,
|
||||||
|
new cmdLib.Answer(async (m) => {
|
||||||
|
let gh = await this._getGuildHandler(m.guild);
|
||||||
|
if (m.member.voiceChannel)
|
||||||
|
await gh.dj.connect(m.member.voiceChannel);
|
||||||
|
else
|
||||||
|
return this.template.join.response.no_voicechannel;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
let stop = new cmdLib.Command(
|
||||||
|
this.template.stop,
|
||||||
|
new cmdLib.Answer(async (m) => {
|
||||||
|
let gh = await this._getGuildHandler(m.guild);
|
||||||
|
if (gh.dj.connected) {
|
||||||
|
gh.dj.stop();
|
||||||
|
return this.template.stop.success;
|
||||||
|
} else {
|
||||||
|
return this.template.stop.not_playing;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
let pause = new cmdLib.Command(
|
||||||
|
this.template.pause,
|
||||||
|
new cmdLib.Answer(async (m) => {
|
||||||
|
let gh = await this._getGuildHandler(m.guild);
|
||||||
|
if (gh.dj.playing) {
|
||||||
|
gh.dj.pause();
|
||||||
|
return this.template.pause.response.success;
|
||||||
|
} else {
|
||||||
|
return this.template.pause.response.not_playing;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
let resume = new cmdLib.Command(
|
||||||
|
this.template.resume,
|
||||||
|
new cmdLib.Answer(async (m) => {
|
||||||
|
let gh = await this._getGuildHandler(m.guild);
|
||||||
|
if (gh.dj.playing) {
|
||||||
|
gh.dj.resume();
|
||||||
|
return this.template.resume.response.success;
|
||||||
|
} else {
|
||||||
|
return this.template.resume.response.not_playing;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
let skip = new cmdLib.Command(
|
||||||
|
this.template.skip,
|
||||||
|
new cmdLib.Answer(async (m) => {
|
||||||
|
let gh = await this._getGuildHandler(m.guild);
|
||||||
|
if (gh.dj.playing) {
|
||||||
|
gh.dj.skip();
|
||||||
|
return this.template.skip.response.success;
|
||||||
|
} else {
|
||||||
|
return this.template.skip.response.not_playing;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
let clear = new cmdLib.Command(
|
||||||
|
this.template.clear,
|
||||||
|
new cmdLib.Answer(async (m) => {
|
||||||
|
let gh = await this._getGuildHandler(m.guild);
|
||||||
|
gh.dj.clear();
|
||||||
|
return this.template.clear.response.success;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
let mediaQueue = new cmdLib.Command(
|
||||||
|
this.template.media_queue,
|
||||||
|
new cmdLib.Answer(async (m) => {
|
||||||
|
let gh = await this._getGuildHandler(m.guild);
|
||||||
|
this._logger.debug(`Found ${gh.dj.queue.length} songs.`);
|
||||||
|
let description = '';
|
||||||
|
|
||||||
|
for (let i = 0; i < Math.min(gh.dj.queue.length, 9); i++) {
|
||||||
|
let entry = gh.dj.queue[i];
|
||||||
|
description += `[${entry.title}](${entry.url})\n`;
|
||||||
|
}
|
||||||
|
return new cmdLib.ExtendedRichEmbed(`${gh.dj.queue.length} songs in queue`)
|
||||||
|
.setDescription(description);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
let mediaCurrent = new cmdLib.Command(
|
||||||
|
this.template.media_current,
|
||||||
|
new cmdLib.Answer(async (m) => {
|
||||||
|
let gh = await this._getGuildHandler(m.guild);
|
||||||
|
let song = gh.dj.song;
|
||||||
|
if (song)
|
||||||
|
return new cmdLib.ExtendedRichEmbed('Now playing:')
|
||||||
|
.setDescription(`[${song.title}](${song.url})`)
|
||||||
|
.setImage(utils.YouTube.getVideoThumbnailUrlFromUrl(song.url))
|
||||||
|
.setColor(0x00aaff);
|
||||||
|
else
|
||||||
|
return this.template.media_current.response.not_playing;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
let shuffle = new cmdLib.Command(
|
||||||
|
this.template.shuffle,
|
||||||
|
new cmdLib.Answer(async (m) => {
|
||||||
|
let gh = await this._getGuildHandler(m.guild);
|
||||||
|
gh.dj.shuffle();
|
||||||
|
return this.template.shuffle.response.success;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
let toggleRepeat = new cmdLib.Command(
|
||||||
|
this.template.toggle_repeat,
|
||||||
|
new cmdLib.Answer(async (m) => {
|
||||||
|
let gh = await this._getGuildHandler(m.guild);
|
||||||
|
gh.dj.repeat = !gh.dj.repeat;
|
||||||
|
return gh.dj.repeat?
|
||||||
|
this.template.toggle_repeat.response.repeat_true :
|
||||||
|
this.template.toggle_repeat.response.repeat_false;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
let saveMedia = new cmdLib.Command(
|
||||||
|
this.template.save_media,
|
||||||
|
new cmdLib.Answer(async (m, k, s) => {
|
||||||
|
let gh = await this._getGuildHandler(m.guild);
|
||||||
|
let saveName = s.replace(k.url + ' ', '');
|
||||||
|
let row = await gh.db
|
||||||
|
.get('SELECT COUNT(*) count FROM playlists WHERE name = ?', [saveName]);
|
||||||
|
if (!row || row.count === 0)
|
||||||
|
await gh.db.run('INSERT INTO playlists (name, url) VALUES (?, ?)',
|
||||||
|
[saveName, k.url]);
|
||||||
|
else
|
||||||
|
await gh.db.run('UPDATE playlists SET url = ? WHERE name = ?',
|
||||||
|
[k.url, saveName]);
|
||||||
|
return `Saved song/playlist as ${saveName}`;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
let deleteMedia = new cmdLib.Command(
|
||||||
|
this.template.delete_media,
|
||||||
|
new cmdLib.Answer(async (m, k, s) => {
|
||||||
|
let gh = await this._getGuildHandler(m.guild);
|
||||||
|
if (!s) {
|
||||||
|
return this.template.delete_media.response.no_name;
|
||||||
|
} else {
|
||||||
|
await gh.db.run('DELETE FROM playlists WHERE name = ?', [s]);
|
||||||
|
return `Deleted ${s} from saved media`;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
let savedMedia = new cmdLib.Command(
|
||||||
|
this.template.saved_media,
|
||||||
|
new cmdLib.Answer(async (m) => {
|
||||||
|
let gh = await this._getGuildHandler(m.guild);
|
||||||
|
let response = '';
|
||||||
|
let rows = await gh.db.all('SELECT name, url FROM playlists');
|
||||||
|
for (let row of rows)
|
||||||
|
response += `[${row.name}](${row.url})\n`;
|
||||||
|
|
||||||
|
if (rows.length === 0)
|
||||||
|
return this.template.saved_media.response.no_saved;
|
||||||
|
else
|
||||||
|
return new cmdLib.ExtendedRichEmbed('Saved Songs and Playlists')
|
||||||
|
.setDescription(response)
|
||||||
|
.setFooter(`Play a saved entry with play [Entryname]`);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// register commands
|
||||||
|
commandHandler
|
||||||
|
.registerCommand(play)
|
||||||
|
.registerCommand(playNext)
|
||||||
|
.registerCommand(join)
|
||||||
|
.registerCommand(stop)
|
||||||
|
.registerCommand(pause)
|
||||||
|
.registerCommand(resume)
|
||||||
|
.registerCommand(skip)
|
||||||
|
.registerCommand(clear)
|
||||||
|
.registerCommand(mediaQueue)
|
||||||
|
.registerCommand(mediaCurrent)
|
||||||
|
.registerCommand(shuffle)
|
||||||
|
.registerCommand(toggleRepeat)
|
||||||
|
.registerCommand(saveMedia)
|
||||||
|
.registerCommand(deleteMedia)
|
||||||
|
.registerCommand(savedMedia);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(exports, {
|
||||||
|
'module': MusicCommandModule
|
||||||
|
});
|
Loading…
Reference in New Issue