From 0c3a42e5c725b66413e4be51e80adfde705881b1 Mon Sep 17 00:00:00 2001 From: liushuyu Date: Mon, 31 Oct 2022 01:11:52 -0600 Subject: [PATCH] tree-wide: await all the await-able functions --- generateExports.js | 4 ++-- src/commands/ban.ts | 6 +++--- src/commands/clearWarnings.ts | 8 ++++---- src/commands/game.ts | 2 +- src/commands/grantDeveloper.ts | 14 +++++++------- src/commands/info.ts | 8 ++++---- src/commands/quote.ts | 2 +- src/commands/status.ts | 10 +++++----- src/commands/warn.ts | 10 +++++----- src/commands/warnings.ts | 8 ++++---- src/models/interfaces.ts | 2 +- src/server.ts | 26 ++++++++++++++------------ src/triggers/pingBomb.ts | 2 +- 13 files changed, 52 insertions(+), 50 deletions(-) diff --git a/generateExports.js b/generateExports.js index e96df8a..71cba37 100644 --- a/generateExports.js +++ b/generateExports.js @@ -26,9 +26,9 @@ console.info('Generating module loader ...'); let modules = collectModules('commands', '.ts'); let loader_content = header; for (let mod of modules) { - loader_content += `import * as ${mod} from "./${mod}";\n`; + loader_content += `import * as ${mod} from './${mod}';\n`; } -let loader_map = modules.map((moduleName) => `${moduleName.toLowerCase()}: ${moduleName}`).join(', '); +let loader_map = modules.map((moduleName) => moduleName.toLowerCase() === moduleName ? moduleName : `${moduleName.toLowerCase()}: ${moduleName}`).join(', '); loader_content += `\nexport default { ${loader_map} };\n`; fs.writeFileSync("./src/commands/_.ts", loader_content); diff --git a/src/commands/ban.ts b/src/commands/ban.ts index 39602b9..acb2ad5 100644 --- a/src/commands/ban.ts +++ b/src/commands/ban.ts @@ -2,8 +2,8 @@ import { ban } from '../common'; import * as discord from 'discord.js'; export const roles = ['Admins', 'Moderators', 'CitraBot']; -export function command (message: discord.Message) { - message.mentions.users.map(async (user) => { +export async function command (message: discord.Message) { + return Promise.all(message.mentions.users.map(async (user) => { await ban(user, message.author, message.guild); - }); + })); } diff --git a/src/commands/clearWarnings.ts b/src/commands/clearWarnings.ts index 6baa8a9..948649e 100644 --- a/src/commands/clearWarnings.ts +++ b/src/commands/clearWarnings.ts @@ -4,8 +4,8 @@ import logger from '../logging'; import * as discord from 'discord.js'; export const roles = ['Admins', 'Moderators']; -export function command (message: discord.Message) { - message.mentions.users.map(async (user) => { +export async function command (message: discord.Message) { + return Promise.all(message.mentions.users.map(async (user) => { const count = state.warnings.filter(x => x.id === user.id && !x.cleared); if (count != null && count.length > 0) { count.forEach(warning => { warning.cleared = true; }); @@ -15,7 +15,7 @@ export function command (message: discord.Message) { await message.channel.send(`${user.toString()}, you have no warnings to clear.`); } - logger.info(`${message.author.username} has cleared all warnings for ${user} ${user.username} [${count?.length}].`); + logger.info(`${message.author.username} has cleared all warnings for ${user.toString()} ${user.username} [${count?.length}].`); await state.logChannel?.send(`${message.author.toString()} has cleared all warnings for ${user.toString()} [${count?.length}].`); - }); + })); } diff --git a/src/commands/game.ts b/src/commands/game.ts index 29bd5a6..0ad1daa 100644 --- a/src/commands/game.ts +++ b/src/commands/game.ts @@ -66,7 +66,7 @@ export async function command(message: discord.Message) { throw e; } finally { // We don't need this message anymore - waitMessage.then(async waitMessageResult => await waitMessageResult.delete()); + await waitMessage.then(async waitMessageResult => await waitMessageResult.delete()); } } diff --git a/src/commands/grantDeveloper.ts b/src/commands/grantDeveloper.ts index 45ddb49..d111190 100644 --- a/src/commands/grantDeveloper.ts +++ b/src/commands/grantDeveloper.ts @@ -3,16 +3,16 @@ import logger from '../logging'; import * as discord from 'discord.js'; export const roles = ['Admins', 'Moderators', 'CitraBot']; -export function command (message: discord.Message) { +export async function command (message: discord.Message) { const role = process.env.DISCORD_DEVELOPER_ROLE; if (!role) { logger.error('DISCORD_DEVELOPER_ROLE suddenly became undefined?!'); - return; + return Promise.resolve([]); } - message.mentions.users.map((user) => { - message.guild?.members.fetch(user).then((member) => { + return Promise.all(message.mentions.users.map(async (user) => { + return message.guild?.members.fetch(user).then((member) => { const alreadyJoined = member.roles.cache.has(role); if (alreadyJoined) { @@ -20,18 +20,18 @@ export function command (message: discord.Message) { await message.channel.send(`${user.toString()}'s speech has been revoked in the #development channel.`); }).catch(async () => { await state.logChannel?.send(`Error revoking ${user.toString()}'s developer speech...`); - logger.error(`Error revoking ${user} ${user.username}'s developer speech...`); + logger.error(`Error revoking ${user.toString()} ${user.username}'s developer speech...`); }); } else { member.roles.add(role).then(async () => { await message.channel.send(`${user.toString()} has been granted speech in the #development channel.`); }).catch(async () => { await state.logChannel?.send(`Error granting ${user.toString()}'s developer speech...`); - logger.error(`Error granting ${user} ${user.username}'s developer speech...`); + logger.error(`Error granting ${user.toString()} ${user.username}'s developer speech...`); }); } }).catch(async () => { await message.channel.send(`User ${user.toString()} was not found in the channel.`); }); - }); + })); } diff --git a/src/commands/info.ts b/src/commands/info.ts index 90a070d..5c99e6f 100644 --- a/src/commands/info.ts +++ b/src/commands/info.ts @@ -6,15 +6,15 @@ import * as discord from 'discord.js'; export const roles = ['Admins', 'Moderators']; function formatWarnings (warnings: UserWarning[]) { - return warnings.map(x => `[${x.date}] ${x.warnedByUsername} warned ${x.username} [${x.priorWarnings} + 1]. ${x.silent ? '(silent)' : ''} ${x.cleared ? '(cleared)' : ''}`); + return warnings.map(x => `[${x.date.toISOString()}] ${x.warnedByUsername} warned ${x.username} [${x.priorWarnings} + 1]. ${x.silent ? '(silent)' : ''} ${x.cleared ? '(cleared)' : ''}`); } function formatBans (bans: UserBan[]) { - return bans.map(x => `[${x.date}] ${x.warnedByUsername} banned ${x.username} [${x.priorWarnings} + 1].`); + return bans.map(x => `[${x.date.toISOString()}] ${x.warnedByUsername} banned ${x.username} [${x.priorWarnings} + 1].`); } export async function command (message: discord.Message) { - message.mentions.users.map(async (user) => { + return Promise.all(message.mentions.users.map(async (user) => { const totalWarnings = state.warnings.filter(x => x.id === user.id && x.cleared === false).length; const warns = state.warnings.filter(x => x.id === user.id); const bans = state.bans.filter(x => x.id === user.id); @@ -23,5 +23,5 @@ export async function command (message: discord.Message) { const bansString = `Bans: \`\`\`${formatBans(bans).join('\n')}\`\`\``; await message.channel.send(`\`${user.username} (${totalWarnings}) information:\`${warns.length !== 0 ? warnsString : '\n\n'}${bans.length !== 0 ? bansString : ''}`); - }); + })); } diff --git a/src/commands/quote.ts b/src/commands/quote.ts index ae554b1..04b3267 100644 --- a/src/commands/quote.ts +++ b/src/commands/quote.ts @@ -6,7 +6,7 @@ export async function command (message: discord.Message, reply: string | undefin if (reply == null) { replyMessage = message.content.substr(message.content.indexOf(' ') + 1); } else { - replyMessage = `${message.mentions.users.map(user => `${user.toString()}`)} ${reply}`; + replyMessage = `${message.mentions.users.map(user => `${user.toString()}`).join(' ')} ${reply}`; } await message.channel.send(replyMessage); diff --git a/src/commands/status.ts b/src/commands/status.ts index 72731b1..4c9cf30 100644 --- a/src/commands/status.ts +++ b/src/commands/status.ts @@ -7,16 +7,16 @@ const fetchOptions = { const repo = process.env.GITHUB_REPOSITORY || 'citra-emu/citra'; export const roles = ['Admins', 'Moderators', 'Developer']; -export function command(message: discord.Message) { - const pr_number = message.content.substr(message.content.indexOf(' ') + 1).replace(/\n/g, ''); - const url = `https://api.github.com/repos/${repo}/pulls/${pr_number}`; - fetch(url, fetchOptions).then(response => response.json()).then((pr: any) => { +export async function command(message: discord.Message) { + const prNumber = message.content.substr(message.content.indexOf(' ') + 1).replace(/\n/g, ''); + const url = `https://api.github.com/repos/${repo}/pulls/${prNumber}`; + return fetch(url, fetchOptions).then(response => response.json()).then((pr: any) => { if (!pr || pr.documentation_url || !pr.head) throw new Error('PR not found'); const headSHA = pr.head.sha; // use the new GitHub checks API fetch(`https://api.github.com/repos/${repo}/commits/${headSHA}/check-runs`, fetchOptions).then(response => response.json()).then(async (statuses: any) => { if (!statuses.check_runs || statuses.total_count < 1) throw new Error('No check runs'); - const msg = new discord.EmbedBuilder().setTitle(`Status for PR #${pr_number}`).setURL(pr.html_url); + const msg = new discord.EmbedBuilder().setTitle(`Status for PR #${prNumber}`).setURL(pr.html_url); let color = 'GREEN' as discord.ColorResolvable; statuses.check_runs.forEach((run: any) => { msg.addFields({ name: run.name, value: `**[${run.status} ${run.conclusion}](${run.html_url})**` }); diff --git a/src/commands/warn.ts b/src/commands/warn.ts index e641f5c..a91c6e2 100644 --- a/src/commands/warn.ts +++ b/src/commands/warn.ts @@ -5,13 +5,13 @@ import UserWarning from '../models/UserWarning'; import * as discord from 'discord.js'; export const roles = ['Admins', 'Moderators']; -export function command(message: discord.Message) { +export async function command(message: discord.Message) { const silent = message.content.includes('silent'); - message.mentions.users.map(async (user) => { + return Promise.all(message.mentions.users.map(async (user) => { const count = state.warnings.filter(x => x.id === user.id && !x.cleared).length || 0; - if (silent === false) { + if (!silent) { await message.channel.send(`${user.toString()} You have been warned. Additional infractions may result in a ban.`); } @@ -20,5 +20,5 @@ export function command(message: discord.Message) { state.warnings.push(new UserWarning(user.id, user.username, message.author.id, message.author.username, count, silent)); data.flushWarnings(); - }); -}; + })); +} diff --git a/src/commands/warnings.ts b/src/commands/warnings.ts index ad27918..676fe23 100644 --- a/src/commands/warnings.ts +++ b/src/commands/warnings.ts @@ -1,9 +1,9 @@ import state from '../state'; import * as discord from 'discord.js'; -export function command(message: discord.Message) { - message.mentions.users.map(async (user) => { +export async function command(message: discord.Message) { + return Promise.all(message.mentions.users.map(async (user) => { const warnings = state.warnings.filter(x => x.id === user.id && !x.cleared); await message.channel.send(`${user.toString()}, you have ${warnings.length} total warnings.`); - }); -}; + })); +} diff --git a/src/models/interfaces.ts b/src/models/interfaces.ts index 9370fef..5ff52d8 100644 --- a/src/models/interfaces.ts +++ b/src/models/interfaces.ts @@ -24,7 +24,7 @@ export interface IResponses { export interface IModule { readonly roles?: string[], - command: (message: Message, args?: string) => void | Promise + command: (message: Message, args?: string) => Promise | Promise } export interface ITrigger { diff --git a/src/server.ts b/src/server.ts index e2e18be..7f2ea9e 100644 --- a/src/server.ts +++ b/src/server.ts @@ -31,8 +31,8 @@ if (!rulesRole) { throw new Error('DISCORD_RULES_ROLE somehow became undefined.'); } -function findArray(haystack: string | any[], arr: any[]) { - return arr.some((v: any) => haystack.indexOf(v) >= 0); +function findArray(haystack: string | string[], arr: string[]) { + return arr.some((v: string) => haystack.indexOf(v) >= 0); } function IsIgnoredCategory(categoryName: string) { @@ -158,7 +158,7 @@ client.on('messageCreate', async (message) => { return; } if (!findArray(authorRoles, AllowedMediaRoles)) { - const urlRegex = new RegExp(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_+.~#?&\/=]*)/gi); + const urlRegex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)/gi; if (message.attachments.size > 0 || message.content.match(urlRegex)) { mediaUsers.set(message.author.id, true); } else if (mediaUsers.get(message.author.id)) { @@ -214,16 +214,18 @@ client.on('messageCreate', async (message) => { } catch (err) { logger.error(err); } } else if (message.author.bot === false) { // This is a normal channel message. - cachedTriggers.forEach(async function (trigger) { - if (!trigger.roles || authorRoles && findArray(authorRoles, trigger.roles)) { - if (trigger.trigger(message) === true) { - logger.debug(`${message.author.username} ${message.author} [Channel: ${message.channel}] triggered: ${message.content}`); - try { - await trigger.execute(message); - } catch (err) { logger.error(err); } + await Promise.all( + cachedTriggers.map(async function (trigger) { + if (!trigger.roles || (authorRoles && findArray(authorRoles, trigger.roles))) { + if (trigger.trigger(message)) { + logger.debug(`${message.author.username} ${message.author} [Channel: ${message.channel}] triggered: ${message.content}`); + try { + await trigger.execute(message); + } catch (err) { logger.error(err); } + } } - } - }); + }) + ); } }); diff --git a/src/triggers/pingBomb.ts b/src/triggers/pingBomb.ts index 3f5b4c2..8d29e8e 100644 --- a/src/triggers/pingBomb.ts +++ b/src/triggers/pingBomb.ts @@ -10,6 +10,6 @@ export function trigger (message: discord.Message) { export async function execute (message: discord.Message) { const count = message.mentions.users.size; logger.info(`${message.author.toString()} tagged ${count} users in ${message.channel.toString()}`); - state.logChannel?.send(`Ping bomb detected in ${message.channel.toString()} by ${message.author.toString()}`); + await state.logChannel?.send(`Ping bomb detected in ${message.channel.toString()} by ${message.author.toString()}`); await ban(message.author, message.author, message.guild); }