From 10bb0b67bc22a3f8dfef1c65809a9035143ba51a Mon Sep 17 00:00:00 2001 From: Tiago R Date: Sun, 26 Nov 2023 14:53:54 +0000 Subject: [PATCH] some more patches thanks to ruby Signed-off-by: GitHub --- .../plugins/Automod/triggers/threadArchive.ts | 4 ++-- .../plugins/Automod/triggers/threadCreate.ts | 3 ++- .../plugins/Automod/triggers/threadDelete.ts | 3 ++- .../Automod/triggers/threadUnarchive.ts | 4 ++-- .../plugins/BotControl/commands/ServersCmd.ts | 6 +++-- .../src/plugins/Cases/functions/createCase.ts | 8 +++---- .../plugins/Cases/functions/createCaseNote.ts | 4 ++-- .../InternalPoster/functions/sendMessage.ts | 2 +- .../ModActions/commands/CasesModCmd.ts | 12 +++++----- .../ModActions/commands/CasesUserCmd.ts | 22 ++++++++++++++----- .../src/plugins/Post/util/actualPostCmd.ts | 4 ++-- .../util/createStarboardEmbedFromMessage.ts | 6 ++--- .../src/plugins/Utility/commands/AboutCmd.ts | 4 ++-- .../src/plugins/Utility/commands/AvatarCmd.ts | 8 +++---- .../Utility/functions/getUserInfoEmbed.ts | 5 +---- backend/src/plugins/Utility/search.ts | 10 ++++----- backend/src/utils.ts | 9 +++++--- backend/src/utils/templateSafeObjects.ts | 7 +++--- 18 files changed, 69 insertions(+), 52 deletions(-) diff --git a/backend/src/plugins/Automod/triggers/threadArchive.ts b/backend/src/plugins/Automod/triggers/threadArchive.ts index 0e65b10a..8a692f6d 100644 --- a/backend/src/plugins/Automod/triggers/threadArchive.ts +++ b/backend/src/plugins/Automod/triggers/threadArchive.ts @@ -1,6 +1,6 @@ import { User, escapeBold, type Snowflake } from "discord.js"; import * as t from "io-ts"; -import { tNullable } from "../../../utils"; +import { renderUsername, tNullable } from "../../../utils"; import { automodTrigger } from "../helpers"; interface ThreadArchiveResult { @@ -48,7 +48,7 @@ export const ThreadArchiveTrigger = automodTrigger()({ const parentName = matchResult.extra.matchedThreadParentName; const base = `Thread **#${threadName}** (\`${threadId}\`) has been archived in the **#${parentName}** (\`${parentId}\`) channel`; if (threadOwner) { - return `${base} by **${escapeBold(threadOwner.tag)}** (\`${threadOwner.id}\`)`; + return `${base} by **${escapeBold(renderUsername(threadOwner.tag))}** (\`${threadOwner.id}\`)`; } return base; }, diff --git a/backend/src/plugins/Automod/triggers/threadCreate.ts b/backend/src/plugins/Automod/triggers/threadCreate.ts index 7b8aca71..dc613068 100644 --- a/backend/src/plugins/Automod/triggers/threadCreate.ts +++ b/backend/src/plugins/Automod/triggers/threadCreate.ts @@ -1,5 +1,6 @@ import { User, escapeBold, type Snowflake } from "discord.js"; import * as t from "io-ts"; +import { renderUsername } from "../../../utils.js"; import { automodTrigger } from "../helpers"; interface ThreadCreateResult { @@ -40,7 +41,7 @@ export const ThreadCreateTrigger = automodTrigger()({ const parentName = matchResult.extra.matchedThreadParentName; const base = `Thread **#${threadName}** (\`${threadId}\`) has been created in the **#${parentName}** (\`${parentId}\`) channel`; if (threadOwner) { - return `${base} by **${escapeBold(threadOwner.tag)}** (\`${threadOwner.id}\`)`; + return `${base} by **${escapeBold(renderUsername(threadOwner.tag))}** (\`${threadOwner.id}\`)`; } return base; }, diff --git a/backend/src/plugins/Automod/triggers/threadDelete.ts b/backend/src/plugins/Automod/triggers/threadDelete.ts index 489b5b4c..f27a1d0b 100644 --- a/backend/src/plugins/Automod/triggers/threadDelete.ts +++ b/backend/src/plugins/Automod/triggers/threadDelete.ts @@ -1,5 +1,6 @@ import { User, escapeBold, type Snowflake } from "discord.js"; import * as t from "io-ts"; +import { renderUsername } from "../../../utils.js"; import { automodTrigger } from "../helpers"; interface ThreadDeleteResult { @@ -40,7 +41,7 @@ export const ThreadDeleteTrigger = automodTrigger()({ const parentName = matchResult.extra.matchedThreadParentName; if (threadOwner) { return `Thread **#${threadName ?? "Unknown"}** (\`${threadId}\`) created by **${escapeBold( - threadOwner.tag, + renderUsername(threadOwner.tag), )}** (\`${threadOwner.id}\`) in the **#${parentName}** (\`${parentId}\`) channel has been deleted`; } return `Thread **#${ diff --git a/backend/src/plugins/Automod/triggers/threadUnarchive.ts b/backend/src/plugins/Automod/triggers/threadUnarchive.ts index f6047f48..94c69ace 100644 --- a/backend/src/plugins/Automod/triggers/threadUnarchive.ts +++ b/backend/src/plugins/Automod/triggers/threadUnarchive.ts @@ -1,6 +1,6 @@ import { User, escapeBold, type Snowflake } from "discord.js"; import * as t from "io-ts"; -import { tNullable } from "../../../utils"; +import { renderUsername, tNullable } from "../../../utils"; import { automodTrigger } from "../helpers"; interface ThreadUnarchiveResult { @@ -48,7 +48,7 @@ export const ThreadUnarchiveTrigger = automodTrigger()({ const parentName = matchResult.extra.matchedThreadParentName; const base = `Thread **#${threadName}** (\`${threadId}\`) has been unarchived in the **#${parentName}** (\`${parentId}\`) channel`; if (threadOwner) { - return `${base} by **${escapeBold(threadOwner.tag)}** (\`${threadOwner.id}\`)`; + return `${base} by **${escapeBold(renderUsername(threadOwner.tag))}** (\`${threadOwner.id}\`)`; } return base; }, diff --git a/backend/src/plugins/BotControl/commands/ServersCmd.ts b/backend/src/plugins/BotControl/commands/ServersCmd.ts index 23146d21..5cb62433 100644 --- a/backend/src/plugins/BotControl/commands/ServersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ServersCmd.ts @@ -1,7 +1,7 @@ import escapeStringRegexp from "escape-string-regexp"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isStaffPreFilter } from "../../../pluginUtils"; -import { createChunkedMessage, getUser, sorter } from "../../../utils"; +import { createChunkedMessage, getUser, renderUsername, sorter } from "../../../utils"; import { botControlCmd } from "../types"; export const ServersCmd = botControlCmd({ @@ -48,7 +48,9 @@ export const ServersCmd = botControlCmd({ const lines = filteredGuilds.map((g) => { const paddedId = g.id.padEnd(longestId, " "); const owner = getUser(pluginData.client, g.ownerId); - return `\`${paddedId}\` **${g.name}** (${g.memberCount} members) (owner **${owner.tag}** \`${owner.id}\`)`; + return `\`${paddedId}\` **${g.name}** (${g.memberCount} members) (owner **${renderUsername(owner.tag)}** \`${ + owner.id + }\`)`; }); createChunkedMessage(msg.channel, lines.join("\n")); } else { diff --git a/backend/src/plugins/Cases/functions/createCase.ts b/backend/src/plugins/Cases/functions/createCase.ts index c16d937b..70717f51 100644 --- a/backend/src/plugins/Cases/functions/createCase.ts +++ b/backend/src/plugins/Cases/functions/createCase.ts @@ -1,23 +1,23 @@ import type { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { logger } from "../../../logger"; -import { renderUserUsername, resolveUser } from "../../../utils"; +import { renderUsername, resolveUser } from "../../../utils"; import { CaseArgs, CasesPluginType } from "../types"; import { createCaseNote } from "./createCaseNote"; import { postCaseToCaseLogChannel } from "./postToCaseLogChannel"; export async function createCase(pluginData: GuildPluginData, args: CaseArgs) { const user = await resolveUser(pluginData.client, args.userId); - const userName = renderUserUsername(user); + const userName = renderUsername(user.username, user.discriminator); const mod = await resolveUser(pluginData.client, args.modId); - const modName = mod.tag; + const modName = renderUsername(mod.username, mod.discriminator); let ppName: string | null = null; let ppId: Snowflake | null = null; if (args.ppId) { const pp = await resolveUser(pluginData.client, args.ppId); - ppName = pp.tag; + ppName = renderUsername(pp.username, pp.discriminator); ppId = pp.id; } diff --git a/backend/src/plugins/Cases/functions/createCaseNote.ts b/backend/src/plugins/Cases/functions/createCaseNote.ts index 92520b7d..71b11302 100644 --- a/backend/src/plugins/Cases/functions/createCaseNote.ts +++ b/backend/src/plugins/Cases/functions/createCaseNote.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import { UnknownUser, resolveUser } from "../../../utils"; +import { UnknownUser, renderUsername, resolveUser } from "../../../utils"; import { CaseNoteArgs, CasesPluginType } from "../types"; import { postCaseToCaseLogChannel } from "./postToCaseLogChannel"; import { resolveCaseId } from "./resolveCaseId"; @@ -16,7 +16,7 @@ export async function createCaseNote(pluginData: GuildPluginData ({ diff --git a/backend/src/plugins/ModActions/commands/CasesModCmd.ts b/backend/src/plugins/ModActions/commands/CasesModCmd.ts index 5b0e3273..a911091d 100644 --- a/backend/src/plugins/ModActions/commands/CasesModCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesModCmd.ts @@ -1,7 +1,7 @@ -import { APIEmbed, User } from "discord.js"; +import { APIEmbed, GuildMember, User } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; -import { emptyEmbedValue, resolveUser, trimLines } from "../../../utils"; +import { emptyEmbedValue, renderUsername, resolveMember, resolveUser, trimLines } from "../../../utils"; import { asyncMap } from "../../../utils/async"; import { createPaginatedMessage } from "../../../utils/createPaginatedMessage"; import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; @@ -28,8 +28,10 @@ export const CasesModCmd = modActionsCmd({ async run({ pluginData, message: msg, args }) { const modId = args.mod || msg.author.id; - const mod = await resolveUser(pluginData.client, modId); - const modName = mod instanceof User ? mod.tag : modId; + const mod = + (await resolveMember(pluginData.client, pluginData.guild, modId)) || + (await resolveUser(pluginData.client, modId)); + const modName = mod instanceof User ? renderUsername(mod) : modId; const casesPlugin = pluginData.getPlugin(CasesPlugin); const totalCases = await casesPlugin.getTotalCasesByMod(modId); @@ -57,7 +59,7 @@ export const CasesModCmd = modActionsCmd({ const embed = { author: { name: title, - icon_url: mod instanceof User ? mod.displayAvatarURL() : undefined, + icon_url: mod instanceof User || mod instanceof GuildMember ? mod.displayAvatarURL() : undefined, }, fields: [ ...getChunkedEmbedFields(emptyEmbedValue, lines.join("\n")), diff --git a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts index 069ad31f..05ab65eb 100644 --- a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts @@ -1,9 +1,17 @@ -import { APIEmbed, User } from "discord.js"; +import { APIEmbed } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; -import { UnknownUser, chunkArray, emptyEmbedValue, renderUserUsername, resolveUser, trimLines } from "../../../utils"; +import { + UnknownUser, + chunkArray, + emptyEmbedValue, + renderUsername, + resolveMember, + resolveUser, + trimLines, +} from "../../../utils"; import { asyncMap } from "../../../utils/async"; import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; import { getGuildPrefix } from "../../../utils/getGuildPrefix"; @@ -35,8 +43,10 @@ export const CasesUserCmd = modActionsCmd({ ], async run({ pluginData, message: msg, args }) { - const user = await resolveUser(pluginData.client, args.user); - if (!user.id) { + const user = + (await resolveMember(pluginData.client, pluginData.guild, args.user)) || + (await resolveUser(pluginData.client, args.user)); + if (!user.id || user instanceof UnknownUser) { sendErrorMessage(pluginData, msg.channel, `User not found`); return; } @@ -62,7 +72,7 @@ export const CasesUserCmd = modActionsCmd({ const hiddenCases = cases.filter((c) => c.is_hidden); const userName = - user instanceof UnknownUser && cases.length ? cases[cases.length - 1].user_name : renderUserUsername(user); + user instanceof UnknownUser && cases.length ? cases[cases.length - 1].user_name : renderUsername(user); if (cases.length === 0) { msg.channel.send(`No cases found for **${userName}**`); @@ -123,7 +133,7 @@ export const CasesUserCmd = modActionsCmd({ lineChunks.length === 1 ? `Cases for ${userName} (${lines.length} total)` : `Cases ${chunkStart}–${chunkEnd} of ${lines.length} for ${userName}`, - icon_url: user instanceof User ? user.displayAvatarURL() : undefined, + icon_url: user.displayAvatarURL(), }, fields: [ ...getChunkedEmbedFields(emptyEmbedValue, linesInChunk.join("\n")), diff --git a/backend/src/plugins/Post/util/actualPostCmd.ts b/backend/src/plugins/Post/util/actualPostCmd.ts index c73a672b..29c3d5ec 100644 --- a/backend/src/plugins/Post/util/actualPostCmd.ts +++ b/backend/src/plugins/Post/util/actualPostCmd.ts @@ -4,7 +4,7 @@ import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { registerUpcomingScheduledPost } from "../../../data/loops/upcomingScheduledPostsLoop"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { DBDateFormat, MINUTES, StrictMessageContent, errorMessage } from "../../../utils"; +import { DBDateFormat, MINUTES, StrictMessageContent, errorMessage, renderUsername } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { PostPluginType } from "../types"; @@ -122,7 +122,7 @@ export async function actualPostCmd( const post = await pluginData.state.scheduledPosts.create({ author_id: msg.author.id, - author_name: msg.author.tag, + author_name: renderUsername(msg.author), channel_id: targetChannel.id, content, attachments: [...msg.attachments.values()], diff --git a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts index 5f028c0a..5126f20f 100644 --- a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts +++ b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts @@ -1,6 +1,6 @@ import { GuildChannel, Message } from "discord.js"; import path from "path"; -import { EMPTY_CHAR, EmbedWith } from "../../../utils"; +import { EMPTY_CHAR, EmbedWith, renderUsername } from "../../../utils"; const imageAttachmentExtensions = ["jpeg", "jpg", "png", "gif", "webp"]; const audioAttachmentExtensions = ["wav", "mp3", "m4a"]; @@ -18,7 +18,7 @@ export function createStarboardEmbedFromMessage( text: `#${(msg.channel as GuildChannel).name}`, }, author: { - name: msg.author.tag, + name: renderUsername(msg.author), }, fields: [], timestamp: msg.createdAt.toISOString(), @@ -28,7 +28,7 @@ export function createStarboardEmbedFromMessage( embed.color = color; } - embed.author.icon_url = msg.author.displayAvatarURL(); + embed.author.icon_url = (msg.member || msg.author).displayAvatarURL(); // The second condition here checks for messages with only an image link that is then embedded. // The message content in that case is hidden by the Discord client, so we hide it here too. diff --git a/backend/src/plugins/Utility/commands/AboutCmd.ts b/backend/src/plugins/Utility/commands/AboutCmd.ts index 53408d71..d4188ad7 100644 --- a/backend/src/plugins/Utility/commands/AboutCmd.ts +++ b/backend/src/plugins/Utility/commands/AboutCmd.ts @@ -100,8 +100,8 @@ export const AboutCmd = utilityCmd({ } // Use the bot avatar as the embed image - if (pluginData.client.user!.avatarURL()) { - aboutEmbed.thumbnail = { url: pluginData.client.user!.avatarURL()! }; + if (pluginData.client.user!.displayAvatarURL()) { + aboutEmbed.thumbnail = { url: pluginData.client.user!.displayAvatarURL()! }; } msg.channel.send({ embeds: [aboutEmbed] }); diff --git a/backend/src/plugins/Utility/commands/AvatarCmd.ts b/backend/src/plugins/Utility/commands/AvatarCmd.ts index ef44a2cb..b1215df6 100644 --- a/backend/src/plugins/Utility/commands/AvatarCmd.ts +++ b/backend/src/plugins/Utility/commands/AvatarCmd.ts @@ -1,7 +1,7 @@ import { APIEmbed, ImageFormat } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; -import { UnknownUser, renderUserUsername } from "../../../utils"; +import { UnknownUser, renderUsername } from "../../../utils"; import { utilityCmd } from "../types"; export const AvatarCmd = utilityCmd({ @@ -10,17 +10,17 @@ export const AvatarCmd = utilityCmd({ permission: "can_avatar", signature: { - user: ct.resolvedUserLoose({ required: false }), + user: ct.resolvedMember({ required: false }) || ct.resolvedUserLoose({ required: false }), }, async run({ message: msg, args, pluginData }) { - const user = args.user || msg.author; + const user = args.user || msg.member || msg.author; if (!(user instanceof UnknownUser)) { const embed: APIEmbed = { image: { url: user.displayAvatarURL({ extension: ImageFormat.PNG, size: 2048 }), }, - title: `Avatar of ${renderUserUsername(user)}:`, + title: `Avatar of ${renderUsername(user)}:`, }; msg.channel.send({ embeds: [embed] }); } else { diff --git a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts index 2de8b4db..58d34d56 100644 --- a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts @@ -13,7 +13,6 @@ import { trimLines, UnknownUser, } from "../../../utils"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { UtilityPluginType } from "../types"; const MAX_ROLES_TO_DISPLAY = 15; @@ -40,13 +39,11 @@ export async function getUserInfoEmbed( fields: [], }; - const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin); - embed.author = { name: `${user.bot ? "Bot" : "User"}: ${renderUsername(user)}`, }; - const avatarURL = user.displayAvatarURL(); + const avatarURL = (member || user).displayAvatarURL(); embed.author.icon_url = avatarURL; if (compact) { diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index 19710b58..632a85a7 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -14,7 +14,7 @@ import { ArgsFromSignatureOrArray, GuildPluginData } from "knub"; import moment from "moment-timezone"; import { RegExpRunner, allowTimeout } from "../../RegExpRunner"; import { getBaseUrl, sendErrorMessage } from "../../pluginUtils"; -import { MINUTES, multiSorter, renderUserUsername, sorter, trimLines } from "../../utils"; +import { MINUTES, multiSorter, renderUsername, sorter, trimLines } from "../../utils"; import { asyncFilter } from "../../utils/async"; import { hasDiscordPermissions } from "../../utils/hasDiscordPermissions"; import { InvalidRegexError, inputPatternToRegExp } from "../../validatorUtils"; @@ -381,7 +381,7 @@ async function performMemberSearch( return true; } - const fullUsername = renderUserUsername(member.user); + const fullUsername = renderUsername(member.user); if (await execRegExp(queryRegex, fullUsername).catch(allowTimeout)) return true; return false; @@ -448,7 +448,7 @@ async function performBanSearch( const execRegExp = getOptimizedRegExpRunner(pluginData, isSafeRegex); matchingBans = await asyncFilter(matchingBans, async (user) => { - const fullUsername = renderUserUsername(user); + const fullUsername = renderUsername(user); if (await execRegExp(queryRegex, fullUsername).catch(allowTimeout)) return true; return false; }); @@ -492,10 +492,10 @@ function formatSearchResultList(members: Array): string { const paddedId = member.id.padEnd(longestId, " "); let line; if (member instanceof GuildMember) { - line = `${paddedId} ${renderUserUsername(member.user)}`; + line = `${paddedId} ${renderUsername(member.user)}`; if (member.nickname) line += ` (${member.nickname})`; } else { - line = `${paddedId} ${member.tag}`; + line = `${paddedId} ${renderUsername(member)}`; } return line; }); diff --git a/backend/src/utils.ts b/backend/src/utils.ts index ee6b556c..5c795072 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -1603,9 +1603,12 @@ export function isTruthy(value: T): value is Exclude) { @@ -261,7 +261,7 @@ export function userToTemplateSafeUser(user: User | UnknownUser): TemplateSafeUs globalName: user.globalName, mention: `<@${user.id}>`, tag: user.tag, - avatarURL: user.displayAvatarURL?.(), + avatarURL: user.displayAvatarURL(), bot: user.bot, createdAt: user.createdTimestamp, renderedUsername: renderUserUsername(user), @@ -287,6 +287,7 @@ export function memberToTemplateSafeMember(member: GuildMember | PartialGuildMem nick: member.nickname ?? "*None*", roles: [...member.roles.cache.mapValues((r) => roleToTemplateSafeRole(r)).values()], joinedAt: member.joinedTimestamp ?? undefined, + guildAvatarURL: member.displayAvatarURL(), guildName: member.guild.name, }); }