diff --git a/src/index.ts b/src/index.ts index 823ba0b..0f3e3ea 100644 --- a/src/index.ts +++ b/src/index.ts @@ -59,4 +59,8 @@ bot.on(Events.MessageDelete, (msg) => { console.log(`${msg.content}`); }); +process.on('uncaughtException', err => { + console.error(err); +}); + bot.login(token); diff --git a/src/lib/game.ts b/src/lib/game.ts index 2c72b05..b1f3ff3 100644 --- a/src/lib/game.ts +++ b/src/lib/game.ts @@ -19,12 +19,13 @@ const BAD_EMOJI = '👎'; const DEFAULT_EMOJI = 'đŸĒ™'; const STOP_EMOJI = '⏚ī¸'; +const CANCEL_EMOJI = '❌'; -function formatMessage(users: User[], time: number, name: string, ended = false) { +function formatMessage(users: User[], time: number, name: string, ended = false, cancelled = false) { return `Starting a **${name}** game (${users.length} player${users.length !== 1 ? 's' : ''})\n` + users.map(user => `- ${user.toString()}`).join('\n') + '\n' + (time <= 0 ? - (ended ? '**Already ended!**' : '**Already started**') : + (cancelled ? ('**Game was cancelled**') : (ended ? '**Already ended!**' : '**Already started**')) : `Starting in **${Math.ceil(time / 1000)}s** - react ${STOP_EMOJI} to begin now` ); } @@ -54,8 +55,6 @@ export async function startGame(interaction: Interaction, startingUser: User, na if (!(m instanceof Message)) return; const emoji = m.guild?.emojis.cache.random(); - await m.react(emoji || DEFAULT_EMOJI); - await m.react(STOP_EMOJI); const started = Date.now(); const collector = m.createReactionCollector({ @@ -65,19 +64,29 @@ export async function startGame(interaction: Interaction, startingUser: User, na (emoji ? reaction.emoji.id === emoji.id : reaction.emoji.name === DEFAULT_EMOJI) && !participants.find(u => user.id === u.id) && !membersInGame.includes(user.id) - ) || (reaction.emoji.name === STOP_EMOJI && user.id === startingUser.id) + ) + || (reaction.emoji.name === STOP_EMOJI && user.id === startingUser.id) + || (reaction.emoji.name === CANCEL_EMOJI && user.id === startingUser.id) ), time: duration, dispose: true }); + await Promise.all([ + m.react(emoji || DEFAULT_EMOJI), + m.react(STOP_EMOJI), + m.react(CANCEL_EMOJI), + ]); + const updateInterval = setInterval(() => { m.edit(formatMessage(participants, duration - (Date.now() - started), name)); }, 3_000); collector.on('collect', (reaction, user) => { if (reaction.emoji.name === STOP_EMOJI) { - collector.stop(); + collector.stop('force-started'); + } else if (reaction.emoji.name === CANCEL_EMOJI) { + collector.stop('cancelled'); } else { participants.push(user); membersInGame.push(user.id); @@ -91,13 +100,17 @@ export async function startGame(interaction: Interaction, startingUser: User, na m.edit(formatMessage(participants, duration - (Date.now() - started), name)); }); - collector.on('end', async () => { + collector.on('end', async (_, reason) => { clearInterval(updateInterval); - m.edit(formatMessage(participants, 0, name)); + await m.reactions.removeAll().catch(error => console.error(error)); - await callback(participants, m.channel); - - m.edit(formatMessage(participants, 0, name, true)); + if (reason === 'cancelled') { + m.edit(formatMessage(participants, 0, name, false, true)); + } else { + m.edit(formatMessage(participants, 0, name)); + await callback(participants, m.channel); + m.edit(formatMessage(participants, 0, name, true)); + } membersInGame = membersInGame.filter(id => !participants.find(u => u.id === id)); }); }