diff --git a/package.json b/package.json index 3fdc256..554c400 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,6 @@ "release-it": "^14.11.8", "ts-node": "^10.4.0", "type-fest": "^2.8.0", - "typed-emitter": "^1.4.0", "typescript": "^4.5.4" }, "eslintConfig": { diff --git a/src/commands/disconnect.ts b/src/commands/disconnect.ts index c63f9a2..4df76db 100644 --- a/src/commands/disconnect.ts +++ b/src/commands/disconnect.ts @@ -3,7 +3,6 @@ import {SlashCommandBuilder} from '@discordjs/builders'; import {TYPES} from '../types.js'; import {inject, injectable} from 'inversify'; import PlayerManager from '../managers/player.js'; -import errorMsg from '../utils/error-msg.js'; import Command from '.'; @injectable() @@ -24,12 +23,7 @@ export default class implements Command { const player = this.playerManager.get(interaction.guild!.id); if (!player.voiceConnection) { - await interaction.reply({ - content: errorMsg('not connected'), - ephemeral: true, - }); - - return; + throw new Error('not connected'); } player.disconnect(); diff --git a/src/commands/fseek.ts b/src/commands/fseek.ts index f4f1172..985a7c4 100644 --- a/src/commands/fseek.ts +++ b/src/commands/fseek.ts @@ -3,7 +3,6 @@ import {SlashCommandBuilder} from '@discordjs/builders'; import {TYPES} from '../types.js'; import {inject, injectable} from 'inversify'; import PlayerManager from '../managers/player.js'; -import errorMsg from '../utils/error-msg.js'; import Command from '.'; import {prettyTime} from '../utils/time.js'; @@ -31,41 +30,21 @@ export default class implements Command { const currentSong = player.getCurrent(); if (!currentSong) { - await interaction.reply({ - content: errorMsg('nothing is playing'), - ephemeral: true, - }); - - return; + throw new Error('nothing is playing'); } if (currentSong.isLive) { - await interaction.reply({ - content: errorMsg('can\'t seek in a livestream'), - ephemeral: true, - }); - - return; + throw new Error('can\'t seek in a livestream'); } const seekTime = interaction.options.getNumber('seconds'); if (!seekTime) { - await interaction.reply({ - content: errorMsg('missing number of seconds to seek'), - ephemeral: true, - }); - - return; + throw new Error('missing number of seconds to seek'); } if (seekTime + player.getPosition() > currentSong.length) { - await interaction.reply({ - content: errorMsg('can\'t seek past the end of the song'), - ephemeral: true, - }); - - return; + throw new Error('can\'t seek past the end of the song'); } await Promise.all([ diff --git a/src/commands/pause.ts b/src/commands/pause.ts index 5d87b87..fc98bdf 100644 --- a/src/commands/pause.ts +++ b/src/commands/pause.ts @@ -4,7 +4,6 @@ import {TYPES} from '../types.js'; import {inject, injectable} from 'inversify'; import PlayerManager from '../managers/player.js'; import {STATUS} from '../services/player.js'; -import errorMsg from '../utils/error-msg.js'; import Command from '.'; @injectable() @@ -25,11 +24,7 @@ export default class implements Command { const player = this.playerManager.get(interaction.guild!.id); if (player.status !== STATUS.PLAYING) { - await interaction.reply({ - content: errorMsg('not currently playing'), - ephemeral: true, - }); - return; + throw new Error('not currently playing'); } player.pause(); diff --git a/src/commands/remove.ts b/src/commands/remove.ts index c58fbdf..55c416f 100644 --- a/src/commands/remove.ts +++ b/src/commands/remove.ts @@ -3,7 +3,6 @@ import {inject, injectable} from 'inversify'; import {TYPES} from '../types.js'; import PlayerManager from '../managers/player.js'; import Command from '.'; -import errorMsg from '../utils/error-msg.js'; import {SlashCommandBuilder} from '@discordjs/builders'; @injectable() @@ -34,17 +33,11 @@ export default class implements Command { const range = interaction.options.getInteger('range') ?? 1; if (position < 1) { - await interaction.reply({ - content: errorMsg('position must be greater than 0'), - ephemeral: true, - }); + throw new Error('position must be at least 1'); } if (range < 1) { - await interaction.reply({ - content: errorMsg('range must be greater than 0'), - ephemeral: true, - }); + throw new Error('range must be at least 1'); } player.removeFromQueue(position, range); diff --git a/src/commands/seek.ts b/src/commands/seek.ts index ecfde64..07f6590 100644 --- a/src/commands/seek.ts +++ b/src/commands/seek.ts @@ -2,7 +2,6 @@ import {CommandInteraction} from 'discord.js'; import {TYPES} from '../types.js'; import {inject, injectable} from 'inversify'; import PlayerManager from '../managers/player.js'; -import errorMsg from '../utils/error-msg.js'; import Command from '.'; import {parseTime, prettyTime} from '../utils/time.js'; import {SlashCommandBuilder} from '@discordjs/builders'; @@ -32,19 +31,11 @@ export default class implements Command { const currentSong = player.getCurrent(); if (!currentSong) { - await interaction.reply({ - content: errorMsg('nothing is playing'), - ephemeral: true, - }); - return; + throw new Error('nothing is playing'); } if (currentSong.isLive) { - await interaction.reply({ - content: errorMsg('can\'t seek in a livestream'), - ephemeral: true, - }); - return; + throw new Error('can\'t seek in a livestream'); } const time = interaction.options.getString('time')!; @@ -58,11 +49,7 @@ export default class implements Command { } if (seekTime > currentSong.length) { - await interaction.reply({ - content: errorMsg('can\'t seek past the end of the song'), - ephemeral: true, - }); - return; + throw new Error('can\'t seek past the end of the song'); } await Promise.all([ diff --git a/src/commands/shuffle.ts b/src/commands/shuffle.ts index 9c0a664..e27f1e2 100644 --- a/src/commands/shuffle.ts +++ b/src/commands/shuffle.ts @@ -2,7 +2,6 @@ import {CommandInteraction} from 'discord.js'; import {TYPES} from '../types.js'; import {inject, injectable} from 'inversify'; import PlayerManager from '../managers/player.js'; -import errorMsg from '../utils/error-msg.js'; import Command from '.'; import {SlashCommandBuilder} from '@discordjs/builders'; @@ -24,11 +23,7 @@ export default class implements Command { const player = this.playerManager.get(interaction.guild!.id); if (player.isQueueEmpty()) { - await interaction.reply({ - content: errorMsg('not enough songs to shuffle'), - ephemeral: true, - }); - return; + throw new Error('not enough songs to shuffle'); } player.shuffle(); diff --git a/src/commands/skip.ts b/src/commands/skip.ts index cfcd605..4c51e77 100644 --- a/src/commands/skip.ts +++ b/src/commands/skip.ts @@ -3,7 +3,6 @@ import {TYPES} from '../types.js'; import {inject, injectable} from 'inversify'; import PlayerManager from '../managers/player.js'; import Command from '.'; -import errorMsg from '../utils/error-msg.js'; import {SlashCommandBuilder} from '@discordjs/builders'; import {buildPlayingMessageEmbed} from '../utils/build-embed.js'; @@ -29,7 +28,7 @@ export default class implements Command { const numToSkip = interaction.options.getInteger('skip') ?? 1; if (numToSkip < 1) { - await interaction.reply({content: errorMsg('invalid number of songs to skip'), ephemeral: true}); + throw new Error('invalid number of songs to skip'); } const player = this.playerManager.get(interaction.guild!.id); @@ -41,7 +40,7 @@ export default class implements Command { embeds: player.getCurrent() ? [buildPlayingMessageEmbed(player)] : [], }); } catch (_: unknown) { - await interaction.reply({content: errorMsg('no song to skip to'), ephemeral: true}); + throw new Error('no song to skip to'); } } } diff --git a/src/commands/unskip.ts b/src/commands/unskip.ts index b1947b8..17d6489 100644 --- a/src/commands/unskip.ts +++ b/src/commands/unskip.ts @@ -2,7 +2,6 @@ import {CommandInteraction} from 'discord.js'; import {TYPES} from '../types.js'; import {inject, injectable} from 'inversify'; import PlayerManager from '../managers/player.js'; -import errorMsg from '../utils/error-msg.js'; import Command from '.'; import {SlashCommandBuilder} from '@discordjs/builders'; import {buildPlayingMessageEmbed} from '../utils/build-embed.js'; @@ -31,10 +30,7 @@ export default class implements Command { embeds: player.getCurrent() ? [buildPlayingMessageEmbed(player)] : [], }); } catch (_: unknown) { - await interaction.reply({ - content: errorMsg('no song to go back to'), - ephemeral: true, - }); + throw new Error('no song to go back to'); } } } diff --git a/src/services/player.ts b/src/services/player.ts index 9257d98..871b1c1 100644 --- a/src/services/player.ts +++ b/src/services/player.ts @@ -1,7 +1,5 @@ import {VoiceChannel, Snowflake, Client, TextChannel} from 'discord.js'; import {Readable} from 'stream'; -import EventEmitter from 'events'; -import TypedEmitter from 'typed-emitter'; import hasha from 'hasha'; import ytdl from 'ytdl-core'; import {WriteStream} from 'fs-capacitor'; @@ -37,8 +35,10 @@ export interface PlayerEvents { statusChange: (oldStatus: STATUS, newStatus: STATUS) => void; } -export default class extends (EventEmitter as new () => TypedEmitter) { +export default class { public voiceConnection: VoiceConnection | null = null; + public status = STATUS.PAUSED; + private queue: QueuedSong[] = []; private queuePosition = 0; private audioPlayer: AudioPlayer | null = null; @@ -47,14 +47,11 @@ export default class extends (EventEmitter as new () => TypedEmitter TypedEmitter