From 426d0b03353906ecbd3d27ad25b9268e82ea2ab9 Mon Sep 17 00:00:00 2001 From: Max Isom Date: Mon, 16 Mar 2020 22:12:02 -0500 Subject: [PATCH] Add help command --- src/commands/clear.ts | 5 ++++- src/commands/config.ts | 5 ++++- src/commands/fseek.ts | 5 ++++- src/commands/help.ts | 47 +++++++++++++++++++++++++++++++++++++++ src/commands/index.ts | 2 +- src/commands/pause.ts | 5 ++++- src/commands/play.ts | 11 ++++++++- src/commands/queue.ts | 5 ++++- src/commands/seek.ts | 6 ++++- src/commands/shortcuts.ts | 14 ++++++++++-- src/commands/shuffle.ts | 5 ++++- src/commands/skip.ts | 5 ++++- src/commands/unskip.ts | 5 ++++- src/inversify.config.ts | 2 ++ 14 files changed, 109 insertions(+), 13 deletions(-) create mode 100644 src/commands/help.ts diff --git a/src/commands/clear.ts b/src/commands/clear.ts index 4c0539f..18f6807 100644 --- a/src/commands/clear.ts +++ b/src/commands/clear.ts @@ -7,7 +7,10 @@ import Command from '.'; @injectable() export default class implements Command { public name = 'clear'; - public description = 'clears all songs in queue (except currently playing)'; + public examples = [ + ['clear', 'clears all songs in queue except currently playing'] + ]; + private readonly queueManager: QueueManager; constructor(@inject(TYPES.Managers.Queue) queueManager: QueueManager) { diff --git a/src/commands/config.ts b/src/commands/config.ts index 52950fc..e584d1d 100644 --- a/src/commands/config.ts +++ b/src/commands/config.ts @@ -6,7 +6,10 @@ import Command from '.'; @injectable() export default class implements Command { public name = 'config'; - public description = 'changes various bot settings'; + public examples = [ + ['config prefix !', 'set the prefix to !'], + ['config channel music-commands', 'bind the bot to the music-commands channel'] + ]; public async execute(msg: Message, args: string []): Promise { if (args.length === 0) { diff --git a/src/commands/fseek.ts b/src/commands/fseek.ts index e442612..fb32adf 100644 --- a/src/commands/fseek.ts +++ b/src/commands/fseek.ts @@ -9,7 +9,10 @@ import Command from '.'; @injectable() export default class implements Command { public name = 'fseek'; - public description = 'forward seek position in currently playing song'; + public examples = [ + ['fseek 10', 'skips forward in current song by 10 seconds'] + ]; + private readonly playerManager: PlayerManager; private readonly queueManager: QueueManager; diff --git a/src/commands/help.ts b/src/commands/help.ts new file mode 100644 index 0000000..97cafa4 --- /dev/null +++ b/src/commands/help.ts @@ -0,0 +1,47 @@ +import {Message} from 'discord.js'; +import {injectable} from 'inversify'; +import Command from '.'; +import {TYPES} from '../types'; +import {Settings} from '../models'; +import container from '../inversify.config'; + +@injectable() +export default class implements Command { + public name = 'help'; + public examples = [ + ['help', 'you don\'t need a description'] + ]; + + private commands: Command[] = []; + + public async execute(msg: Message, _: string []): Promise { + if (this.commands.length === 0) { + // Lazy load to avoid circular dependencies + this.commands = container.getAll(TYPES.Command); + } + + const settings = await Settings.findOne({where: {guildId: msg.guild!.id}}); + + if (!settings) { + return; + } + + const {prefix} = settings; + + const res = this.commands.sort((a, b) => a.name.localeCompare(b.name)).reduce((content, command) => { + content += `**${command.name}**:\n`; + + command.examples.forEach(example => { + content += `- \`${prefix}${example[0]}\`: ${example[1]}\n`; + }); + + content += '\n'; + + return content; + }, ''); + + await msg.author.send(res); + await msg.react('🇩'); + await msg.react('🇲'); + } +} diff --git a/src/commands/index.ts b/src/commands/index.ts index 1a6d686..160253c 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -2,6 +2,6 @@ import {Message} from 'discord.js'; export default interface Command { name: string; - description: string; + examples: string[][]; execute: (msg: Message, args: string[]) => Promise; } diff --git a/src/commands/pause.ts b/src/commands/pause.ts index 54855e0..48933f2 100644 --- a/src/commands/pause.ts +++ b/src/commands/pause.ts @@ -8,7 +8,10 @@ import Command from '.'; @injectable() export default class implements Command { public name = 'pause'; - public description = 'pause currently playing song'; + public examples = [ + ['pause', 'pauses currently playing song'] + ]; + private readonly playerManager: PlayerManager; constructor(@inject(TYPES.Managers.Player) playerManager: PlayerManager) { diff --git a/src/commands/play.ts b/src/commands/play.ts index 4ba04bd..cdfc9fe 100644 --- a/src/commands/play.ts +++ b/src/commands/play.ts @@ -20,7 +20,16 @@ import Command from '.'; @injectable() export default class implements Command { public name = 'play'; - public description = 'plays a song'; + public examples = [ + ['play', 'resume paused playback'], + ['play https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'plays a YouTube video'], + ['play cool music', 'plays the first search result for "cool music" from YouTube'], + ['play https://www.youtube.com/watch?list=PLi9drqWffJ9FWBo7ZVOiaVy0UQQEm4IbP', 'adds the playlist to the queue'], + ['play https://open.spotify.com/track/3ebXMykcMXOcLeJ9xZ17XH?si=tioqSuyMRBWxhThhAW51Ig', 'plays a song from Spotify'], + ['play https://open.spotify.com/album/5dv1oLETxdsYOkS2Sic00z?si=bDa7PaloRx6bMIfKdnvYQw', 'adds all songs from album to the queue'], + ['play https://open.spotify.com/playlist/37i9dQZF1DX94qaYRnkufr?si=r2fOVL_QQjGxFM5MWb84Xw', 'adds all songs from playlist to the queue'] + ]; + private readonly queueManager: QueueManager; private readonly playerManager: PlayerManager; private readonly youtube: YouTube; diff --git a/src/commands/queue.ts b/src/commands/queue.ts index dfa48d4..e77cbcb 100644 --- a/src/commands/queue.ts +++ b/src/commands/queue.ts @@ -7,7 +7,10 @@ import Command from '.'; @injectable() export default class implements Command { public name = 'queue'; - public description = 'shows current queue'; + public examples = [ + ['queue', 'shows current queue'] + ]; + private readonly queueManager: QueueManager; constructor(@inject(TYPES.Managers.Queue) queueManager: QueueManager) { diff --git a/src/commands/seek.ts b/src/commands/seek.ts index ec8f0d7..d73eb88 100644 --- a/src/commands/seek.ts +++ b/src/commands/seek.ts @@ -9,7 +9,11 @@ import Command from '.'; @injectable() export default class implements Command { public name = 'seek'; - public description = 'seeks position in currently playing song'; + public examples = [ + ['seek 10', 'seeks to 10 seconds from begining of song'], + ['seek 1:30', 'seeks to 1 minute and 30 seconds from begining of song'] + ]; + private readonly playerManager: PlayerManager; private readonly queueManager: QueueManager; diff --git a/src/commands/shortcuts.ts b/src/commands/shortcuts.ts index 2d62370..240b10e 100644 --- a/src/commands/shortcuts.ts +++ b/src/commands/shortcuts.ts @@ -6,7 +6,11 @@ import Command from '.'; @injectable() export default class implements Command { public name = 'shortcuts'; - public description = 'edit shortcuts'; + public examples = [ + ['shortcuts set s skip', 'aliases `s` to `skip`'], + ['shortcuts set party play https://www.youtube.com/watch?v=zK6oOJ1wz8k', 'aliases `party` to a specific play command'], + ['shortcuts delete party', 'removes the `party` shortcut'] + ]; public async execute(msg: Message, args: string []): Promise { if (args.length === 0) { @@ -19,7 +23,13 @@ export default class implements Command { } // Get prefix for guild - const {prefix} = await Settings.findOne({where: {guildId: msg.guild!.id}}) as Settings; + const settings = await Settings.findOne({where: {guildId: msg.guild!.id}}); + + if (!settings) { + return; + } + + const {prefix} = settings; const res = shortcuts.reduce((accum, shortcut) => { accum += `${prefix}${shortcut.shortcut}: ${shortcut.command}\n`; diff --git a/src/commands/shuffle.ts b/src/commands/shuffle.ts index e91b695..ae5724a 100644 --- a/src/commands/shuffle.ts +++ b/src/commands/shuffle.ts @@ -7,7 +7,10 @@ import Command from '.'; @injectable() export default class implements Command { public name = 'shuffle'; - public description = 'shuffle current queue'; + public examples = [ + ['shuffle', 'shuffles the current queue'] + ]; + private readonly queueManager: QueueManager; constructor(@inject(TYPES.Managers.Queue) queueManager: QueueManager) { diff --git a/src/commands/skip.ts b/src/commands/skip.ts index ec0e83e..b06a3a9 100644 --- a/src/commands/skip.ts +++ b/src/commands/skip.ts @@ -8,7 +8,10 @@ import Command from '.'; @injectable() export default class implements Command { public name = 'skip'; - public description = 'skips current song'; + public examples = [ + ['skip', 'skips the current song'] + ]; + private readonly queueManager: QueueManager; private readonly playerManager: PlayerManager; diff --git a/src/commands/unskip.ts b/src/commands/unskip.ts index 01fef7a..fd49e92 100644 --- a/src/commands/unskip.ts +++ b/src/commands/unskip.ts @@ -8,7 +8,10 @@ import Command from '.'; @injectable() export default class implements Command { public name = 'unskip'; - public description = 'go back in the queue'; + public examples = [ + ['unskip', 'goes back in the queue by one song'] + ]; + private readonly queueManager: QueueManager; private readonly playerManager: PlayerManager; diff --git a/src/inversify.config.ts b/src/inversify.config.ts index 5c17572..c25d32b 100644 --- a/src/inversify.config.ts +++ b/src/inversify.config.ts @@ -24,6 +24,7 @@ import Command from './commands'; import Clear from './commands/clear'; import Config from './commands/config'; import ForwardSeek from './commands/fseek'; +import Help from './commands/help'; import Pause from './commands/pause'; import Play from './commands/play'; import QueueCommad from './commands/queue'; @@ -47,6 +48,7 @@ container.bind(TYPES.Managers.Queue).to(QueueManager).inSingletonS container.bind(TYPES.Command).to(Clear).inSingletonScope(); container.bind(TYPES.Command).to(Config).inSingletonScope(); container.bind(TYPES.Command).to(ForwardSeek).inSingletonScope(); +container.bind(TYPES.Command).to(Help).inSingletonScope(); container.bind(TYPES.Command).to(Pause).inSingletonScope(); container.bind(TYPES.Command).to(Play).inSingletonScope(); container.bind(TYPES.Command).to(QueueCommad).inSingletonScope();