diff --git a/backend/src/api/start.ts b/backend/src/api/start.ts index 088c8ba9..e009e393 100644 --- a/backend/src/api/start.ts +++ b/backend/src/api/start.ts @@ -28,10 +28,10 @@ app.use(multer().none()); const rootRouter = express.Router(); -initAuth(app); -initGuildsAPI(app); -initArchives(app); -initDocs(app); +initAuth(rootRouter); +initGuildsAPI(rootRouter); +initArchives(rootRouter); +initDocs(rootRouter); // Default route rootRouter.get("/", (req, res) => { diff --git a/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts b/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts index 6c24b296..df5ebd3a 100644 --- a/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts +++ b/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts @@ -6,6 +6,7 @@ import { DisableAutoReactionsCmd } from "./commands/DisableAutoReactionsCmd"; import { NewAutoReactionsCmd } from "./commands/NewAutoReactionsCmd"; import { AddReactionsEvt } from "./events/AddReactionsEvt"; import { AutoReactionsPluginType, zAutoReactionsConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -50,4 +51,8 @@ export const AutoReactionsPlugin = guildPlugin()({ state.autoReactions = GuildAutoReactions.getGuildInstance(guild.id); state.cache = new Map(); }, + + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + } }); diff --git a/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts index ec3417d4..f6539174 100644 --- a/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts +++ b/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts @@ -14,12 +14,12 @@ export const DisableAutoReactionsCmd = autoReactionsCmd({ async run({ message: msg, args, pluginData }) { const autoReaction = await pluginData.state.autoReactions.getForChannel(args.channelId); if (!autoReaction) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Auto-reactions aren't enabled in <#${args.channelId}>`); + void pluginData.state.common.sendErrorMessage(msg, `Auto-reactions aren't enabled in <#${args.channelId}>`); return; } await pluginData.state.autoReactions.removeFromChannel(args.channelId); pluginData.state.cache.delete(args.channelId); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Auto-reactions disabled in <#${args.channelId}>`); + void pluginData.state.common.sendSuccessMessage(msg, `Auto-reactions disabled in <#${args.channelId}>`); }, }); diff --git a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts index 250df4f0..7f3355fb 100644 --- a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts +++ b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts @@ -25,20 +25,16 @@ export const NewAutoReactionsCmd = autoReactionsCmd({ const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; const missingPermissions = getMissingChannelPermissions(me, args.channel, requiredPermissions); if (missingPermissions) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( - msg, - `Cannot set auto-reactions for that channel. ${missingPermissionError(missingPermissions)}`, - ); + pluginData.state.common.sendErrorMessage( + msg, + `Cannot set auto-reactions for that channel. ${missingPermissionError(missingPermissions)}`, + ); return; } for (const reaction of args.reactions) { if (!isEmoji(reaction)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "One or more of the specified reactions were invalid!"); + void pluginData.state.common.sendErrorMessage(msg, "One or more of the specified reactions were invalid!"); return; } @@ -48,9 +44,7 @@ export const NewAutoReactionsCmd = autoReactionsCmd({ if (customEmojiMatch) { // Custom emoji if (!canUseEmoji(pluginData.client, customEmojiMatch[2])) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "I can only use regular emojis and custom emojis from this server"); + pluginData.state.common.sendErrorMessage(msg, "I can only use regular emojis and custom emojis from this server"); return; } @@ -65,6 +59,6 @@ export const NewAutoReactionsCmd = autoReactionsCmd({ await pluginData.state.autoReactions.set(args.channel.id, finalReactions); pluginData.state.cache.delete(args.channel.id); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Auto-reactions set for <#${args.channel.id}>`); + void pluginData.state.common.sendSuccessMessage(msg, `Auto-reactions set for <#${args.channel.id}>`); }, }); diff --git a/backend/src/plugins/AutoReactions/types.ts b/backend/src/plugins/AutoReactions/types.ts index 996fba8d..d060d59a 100644 --- a/backend/src/plugins/AutoReactions/types.ts +++ b/backend/src/plugins/AutoReactions/types.ts @@ -1,9 +1,10 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildAutoReactions } from "../../data/GuildAutoReactions"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { AutoReaction } from "../../data/entities/AutoReaction"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zAutoReactionsConfig = z.strictObject({ can_manage: z.boolean(), @@ -16,6 +17,7 @@ export interface AutoReactionsPluginType extends BasePluginType { savedMessages: GuildSavedMessages; autoReactions: GuildAutoReactions; cache: Map; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/Automod/AutomodPlugin.ts b/backend/src/plugins/Automod/AutomodPlugin.ts index 33956590..5da233a1 100644 --- a/backend/src/plugins/Automod/AutomodPlugin.ts +++ b/backend/src/plugins/Automod/AutomodPlugin.ts @@ -32,6 +32,7 @@ import { clearOldRecentNicknameChanges } from "./functions/clearOldNicknameChang import { clearOldRecentActions } from "./functions/clearOldRecentActions"; import { clearOldRecentSpam } from "./functions/clearOldRecentSpam"; import { AutomodPluginType, zAutomodConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions = { config: { @@ -117,6 +118,10 @@ export const AutomodPlugin = guildPlugin()({ state.cachedAntiraidLevel = await state.antiraidLevels.get(); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + async afterLoad(pluginData) { const { state } = pluginData; diff --git a/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts b/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts index 983a1f99..85f9bbcb 100644 --- a/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts +++ b/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts @@ -1,5 +1,4 @@ import { guildPluginMessageCommand } from "knub"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { setAntiraidLevel } from "../functions/setAntiraidLevel"; import { AutomodPluginType } from "../types"; @@ -9,6 +8,6 @@ export const AntiraidClearCmd = guildPluginMessageCommand()({ async run({ pluginData, message }) { await setAntiraidLevel(pluginData, null, message.author); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(message, "Anti-raid turned **off**"); + void pluginData.state.common.sendSuccessMessage(message, "Anti-raid turned **off**"); }, }); diff --git a/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts b/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts index 91cbacd6..46c2106f 100644 --- a/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts +++ b/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts @@ -1,6 +1,5 @@ import { guildPluginMessageCommand } from "knub"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { setAntiraidLevel } from "../functions/setAntiraidLevel"; import { AutomodPluginType } from "../types"; @@ -15,11 +14,11 @@ export const SetAntiraidCmd = guildPluginMessageCommand()({ async run({ pluginData, message, args }) { const config = pluginData.config.get(); if (!config.antiraid_levels.includes(args.level)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown anti-raid level"); + pluginData.state.common.sendErrorMessage(message, "Unknown anti-raid level"); return; } await setAntiraidLevel(pluginData, args.level, message.author); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(message, `Anti-raid level set to **${args.level}**`); + pluginData.state.common.sendSuccessMessage(message, `Anti-raid level set to **${args.level}**`); }, }); diff --git a/backend/src/plugins/Automod/types.ts b/backend/src/plugins/Automod/types.ts index 6cf88ad6..75cd8daa 100644 --- a/backend/src/plugins/Automod/types.ts +++ b/backend/src/plugins/Automod/types.ts @@ -1,5 +1,5 @@ import { GuildMember, GuildTextBasedChannel, PartialGuildMember, ThreadChannel, User } from "discord.js"; -import { BasePluginType, CooldownManager } from "knub"; +import { BasePluginType, CooldownManager, pluginUtils } from "knub"; import z from "zod"; import { Queue } from "../../Queue"; import { RegExpRunner } from "../../RegExpRunner"; @@ -17,6 +17,7 @@ import { RecentActionType } from "./constants"; import { availableTriggers } from "./triggers/availableTriggers"; import Timeout = NodeJS.Timeout; +import { CommonPlugin } from "../Common/CommonPlugin"; export type ZTriggersMapHelper = { [TriggerName in keyof typeof availableTriggers]: (typeof availableTriggers)[TriggerName]["configSchema"]; @@ -139,6 +140,8 @@ export interface AutomodPluginType extends BasePluginType { modActionsListeners: Map; mutesListeners: Map; + + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/BotControl/BotControlPlugin.ts b/backend/src/plugins/BotControl/BotControlPlugin.ts index b3812e02..c1a94888 100644 --- a/backend/src/plugins/BotControl/BotControlPlugin.ts +++ b/backend/src/plugins/BotControl/BotControlPlugin.ts @@ -4,7 +4,6 @@ import { AllowedGuilds } from "../../data/AllowedGuilds"; import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments"; import { Configs } from "../../data/Configs"; import { GuildArchives } from "../../data/GuildArchives"; -import { CommonPlugin } from "../Common/CommonPlugin"; import { getActiveReload, resetActiveReload } from "./activeReload"; import { AddDashboardUserCmd } from "./commands/AddDashboardUserCmd"; import { AddServerFromInviteCmd } from "./commands/AddServerFromInviteCmd"; @@ -77,7 +76,7 @@ export const BotControlPlugin = globalPlugin()({ if (guild) { const channel = guild.channels.cache.get(channelId as Snowflake); if (channel instanceof TextChannel) { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(channel, "Global plugins reloaded!"); + void channel.send("Global plugins reloaded!"); } } } diff --git a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts index 5a50d1b0..8e97cf56 100644 --- a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts @@ -20,7 +20,7 @@ export const AddDashboardUserCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is not using Zeppelin"); + void msg.channel.send("Server is not using Zeppelin"); return; } @@ -38,11 +38,6 @@ export const AddDashboardUserCmd = botControlCmd({ const userNameList = args.users.map((user) => `<@!${user.id}> (**${renderUsername(user)}**, \`${user.id}\`)`); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - msg, - `The following users were given dashboard access for **${guild.name}**:\n\n${userNameList}`, - ); + msg.channel.send(`The following users were given dashboard access for **${guild.name}**:\n\n${userNameList}`); }, }); diff --git a/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts b/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts index aaeb7147..e5245bb3 100644 --- a/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts +++ b/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts @@ -18,21 +18,19 @@ export const AddServerFromInviteCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const invite = await resolveInvite(pluginData.client, args.inviteCode, true); if (!invite || !isGuildInvite(invite)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Could not resolve invite"); // :D + void msg.channel.send("Could not resolve invite"); // :D return; } const existing = await pluginData.state.allowedGuilds.find(invite.guild.id); if (existing) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is already allowed!"); + void msg.channel.send("Server is already allowed!"); return; } const { result, explanation } = await isEligible(pluginData, args.user, invite); if (!result) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Could not add server because it's not eligible: ${explanation}`); + msg.channel.send(`Could not add server because it's not eligible: ${explanation}`); return; } @@ -53,8 +51,6 @@ export const AddServerFromInviteCmd = botControlCmd({ ); } - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, "Server was eligible and is now allowed to use Zeppelin!"); + msg.channel.send("Server was eligible and is now allowed to use Zeppelin!"); }, }); diff --git a/backend/src/plugins/BotControl/commands/AllowServerCmd.ts b/backend/src/plugins/BotControl/commands/AllowServerCmd.ts index ac843867..9d0a6cea 100644 --- a/backend/src/plugins/BotControl/commands/AllowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/AllowServerCmd.ts @@ -21,17 +21,17 @@ export const AllowServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const existing = await pluginData.state.allowedGuilds.find(args.guildId); if (existing) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is already allowed!"); + void msg.channel.send("Server is already allowed!"); return; } if (!isSnowflake(args.guildId)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid server ID!"); + void msg.channel.send("Invalid server ID!"); return; } if (args.userId && !isSnowflake(args.userId)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid user ID!"); + void msg.channel.send("Invalid user ID!"); return; } @@ -52,6 +52,6 @@ export const AllowServerCmd = botControlCmd({ ); } - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Server is now allowed to use Zeppelin!"); + void msg.channel.send("Server is now allowed to use Zeppelin!"); }, }); diff --git a/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts b/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts index 939077e2..f19a41c9 100644 --- a/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts @@ -17,7 +17,7 @@ export const ChannelToServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const channel = pluginData.client.channels.cache.get(args.channelId); if (!channel) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Channel not found in cache!"); + void msg.channel.send("Channel not found in cache!"); return; } diff --git a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts index 69ba0b4c..8a31ddf5 100644 --- a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts @@ -19,7 +19,7 @@ export const DisallowServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const existing = await pluginData.state.allowedGuilds.find(args.guildId); if (!existing) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "That server is not allowed in the first place!"); + void msg.channel.send("That server is not allowed in the first place!"); return; } @@ -28,6 +28,6 @@ export const DisallowServerCmd = botControlCmd({ .get(args.guildId as Snowflake) ?.leave() .catch(noop); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Server removed!"); + void msg.channel.send("Server removed!"); }, }); diff --git a/backend/src/plugins/BotControl/commands/EligibleCmd.ts b/backend/src/plugins/BotControl/commands/EligibleCmd.ts index bbcd5c5d..60adcea2 100644 --- a/backend/src/plugins/BotControl/commands/EligibleCmd.ts +++ b/backend/src/plugins/BotControl/commands/EligibleCmd.ts @@ -16,17 +16,17 @@ export const EligibleCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const invite = await resolveInvite(pluginData.client, args.inviteCode, true); if (!invite || !isGuildInvite(invite)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Could not resolve invite"); + void msg.channel.send("Could not resolve invite"); return; } const { result, explanation } = await isEligible(pluginData, args.user, invite); if (result) { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Server is eligible: ${explanation}`); + void msg.channel.send(`Server is eligible: ${explanation}`); return; } - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Server is **NOT** eligible: ${explanation}`); + void msg.channel.send(`Server is **NOT** eligible: ${explanation}`); }, }); diff --git a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts index 0066a916..c22a885f 100644 --- a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts @@ -17,7 +17,7 @@ export const LeaveServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { if (!pluginData.client.guilds.cache.has(args.guildId as Snowflake)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "I am not in that guild"); + void msg.channel.send("I am not in that guild"); return; } @@ -27,10 +27,10 @@ export const LeaveServerCmd = botControlCmd({ try { await pluginData.client.guilds.cache.get(args.guildId as Snowflake)?.leave(); } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Failed to leave guild: ${e.message}`); + void msg.channel.send(`Failed to leave guild: ${e.message}`); return; } - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Left guild **${guildName}**`); + void msg.channel.send(`Left guild **${guildName}**`); }, }); diff --git a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts index 0de1ff26..83f0cc37 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts @@ -16,7 +16,7 @@ export const ListDashboardPermsCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { if (!args.user && !args.guildId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Must specify at least guildId, user, or both."); + void msg.channel.send("Must specify at least guildId, user, or both."); return; } @@ -24,7 +24,7 @@ export const ListDashboardPermsCmd = botControlCmd({ if (args.guildId) { guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is not using Zeppelin"); + void msg.channel.send("Server is not using Zeppelin"); return; } } @@ -33,7 +33,7 @@ export const ListDashboardPermsCmd = botControlCmd({ if (args.user) { existingUserAssignment = await pluginData.state.apiPermissionAssignments.getByUserId(args.user.id); if (existingUserAssignment.length === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "The user has no assigned permissions."); + void msg.channel.send("The user has no assigned permissions."); return; } } @@ -54,9 +54,7 @@ export const ListDashboardPermsCmd = botControlCmd({ } if (finalMessage === "") { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `The user ${userInfo} has no assigned permissions on the specified server.`); + msg.channel.send(`The user ${userInfo} has no assigned permissions on the specified server.`); return; } // Else display all users that have permissions on the specified guild @@ -65,9 +63,7 @@ export const ListDashboardPermsCmd = botControlCmd({ const existingGuildAssignment = await pluginData.state.apiPermissionAssignments.getByGuildId(guild.id); if (existingGuildAssignment.length === 0) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `The server ${guildInfo} has no assigned permissions.`); + msg.channel.send(`The server ${guildInfo} has no assigned permissions.`); return; } @@ -80,6 +76,9 @@ export const ListDashboardPermsCmd = botControlCmd({ } } - await pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, finalMessage.trim(), {}); + await msg.channel.send({ + content: finalMessage.trim(), + allowedMentions: {}, + }); }, }); diff --git a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts index b835dfed..2892e6e6 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts @@ -14,7 +14,7 @@ export const ListDashboardUsersCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is not using Zeppelin"); + void msg.channel.send("Server is not using Zeppelin"); return; } @@ -30,12 +30,9 @@ export const ListDashboardUsersCmd = botControlCmd({ `<@!${user.id}> (**${renderUsername(user)}**, \`${user.id}\`): ${permission.permissions.join(", ")}`, ); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - msg, - `The following users have dashboard access for **${guild.name}**:\n\n${userNameList.join("\n")}`, - {}, - ); + msg.channel.send({ + content: `The following users have dashboard access for **${guild.name}**:\n\n${userNameList.join("\n")}`, + allowedMentions: {}, + }); }, }); diff --git a/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts b/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts index 9ac5499d..9ba9d23c 100644 --- a/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts +++ b/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts @@ -14,7 +14,7 @@ export const RateLimitPerformanceCmd = botControlCmd({ async run({ pluginData, message: msg }) { const logItems = getRateLimitStats(); if (logItems.length === 0) { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `No rate limits hit`); + void msg.channel.send(`No rate limits hit`); return; } diff --git a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts index ea51dc00..957fca95 100644 --- a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts @@ -15,7 +15,7 @@ export const ReloadGlobalPluginsCmd = botControlCmd({ const guildId = "guild" in message.channel ? message.channel.guild.id : null; if (!guildId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "This command can only be used in a server"); + void message.channel.send("This command can only be used in a server"); return; } diff --git a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts index 8481682e..a171af5f 100644 --- a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts @@ -17,18 +17,18 @@ export const ReloadServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { if (!pluginData.client.guilds.cache.has(args.guildId as Snowflake)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "I am not in that guild"); + void msg.channel.send("I am not in that guild"); return; } try { await pluginData.getKnubInstance().reloadGuild(args.guildId); } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Failed to reload guild: ${e.message}`); + void msg.channel.send(`Failed to reload guild: ${e.message}`); return; } const guild = await pluginData.client.guilds.fetch(args.guildId as Snowflake); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Reloaded guild **${guild?.name || "???"}**`); + void msg.channel.send(`Reloaded guild **${guild?.name || "???"}**`); }, }); diff --git a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts index 90927a2a..502570a7 100644 --- a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts @@ -19,7 +19,7 @@ export const RemoveDashboardUserCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is not using Zeppelin"); + void msg.channel.send("Server is not using Zeppelin"); return; } @@ -37,11 +37,8 @@ export const RemoveDashboardUserCmd = botControlCmd({ const userNameList = args.users.map((user) => `<@!${user.id}> (**${renderUsername(user)}**, \`${user.id}\`)`); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - msg, - `The following users were removed from the dashboard for **${guild.name}**:\n\n${userNameList}`, - ); + msg.channel.send( + `The following users were removed from the dashboard for **${guild.name}**:\n\n${userNameList}`, + ); }, }); diff --git a/backend/src/plugins/BotControl/types.ts b/backend/src/plugins/BotControl/types.ts index 1c1ccea6..592189c1 100644 --- a/backend/src/plugins/BotControl/types.ts +++ b/backend/src/plugins/BotControl/types.ts @@ -1,4 +1,4 @@ -import { BasePluginType, globalPluginEventListener, globalPluginMessageCommand } from "knub"; +import { BasePluginType, globalPluginEventListener, globalPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { AllowedGuilds } from "../../data/AllowedGuilds"; import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments"; diff --git a/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts b/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts index c8373aeb..b9c310d7 100644 --- a/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts +++ b/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts @@ -3,6 +3,7 @@ import z from "zod"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; import { ArchiveChannelCmd } from "./commands/ArchiveChannelCmd"; import { ChannelArchiverPluginType } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const ChannelArchiverPlugin = guildPlugin()({ name: "channel_archiver", @@ -14,4 +15,8 @@ export const ChannelArchiverPlugin = guildPlugin()({ messageCommands: [ ArchiveChannelCmd, ], + + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + } }); diff --git a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts index 327c6956..34bdeef7 100644 --- a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts +++ b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts @@ -38,7 +38,7 @@ export const ArchiveChannelCmd = channelArchiverCmd({ "No `-attachment-channel` specified. Continue? Attachments will not be available in the log if their message is deleted.", }); if (!confirmed) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Canceled"); + void pluginData.state.common.sendErrorMessage(msg, "Canceled"); return; } } diff --git a/backend/src/plugins/ChannelArchiver/types.ts b/backend/src/plugins/ChannelArchiver/types.ts index 024edf3d..a560af39 100644 --- a/backend/src/plugins/ChannelArchiver/types.ts +++ b/backend/src/plugins/ChannelArchiver/types.ts @@ -1,5 +1,10 @@ -import { BasePluginType, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginMessageCommand, pluginUtils } from "knub"; +import { CommonPlugin } from "../Common/CommonPlugin"; -export interface ChannelArchiverPluginType extends BasePluginType {} +export interface ChannelArchiverPluginType extends BasePluginType { + state: { + common: pluginUtils.PluginPublicInterface; + } +} export const channelArchiverCmd = guildPluginMessageCommand(); diff --git a/backend/src/plugins/Common/CommonPlugin.ts b/backend/src/plugins/Common/CommonPlugin.ts index 92c58b63..144c355c 100644 --- a/backend/src/plugins/Common/CommonPlugin.ts +++ b/backend/src/plugins/Common/CommonPlugin.ts @@ -1,4 +1,5 @@ import { + Attachment, ChatInputCommandInteraction, Message, MessageCreateOptions, @@ -7,11 +8,10 @@ import { TextBasedChannel, User, } from "discord.js"; -import { PluginOptions } from "knub"; +import { PluginOptions, guildPlugin } from "knub"; import { logger } from "../../logger"; import { isContextInteraction, sendContextResponse } from "../../pluginUtils"; import { errorMessage, successMessage } from "../../utils"; -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { getErrorEmoji, getSuccessEmoji } from "./functions/getEmoji"; import { CommonPluginType, zCommonConfig } from "./types"; @@ -19,30 +19,21 @@ const defaultOptions: PluginOptions = { config: { success_emoji: "✅", error_emoji: "❌", + attachment_storing_channel: null, }, }; -export const CommonPlugin = zeppelinGuildPlugin()({ +export const CommonPlugin = guildPlugin()({ name: "common", - showInDocs: false, - info: { - prettyName: "Common", - }, - dependencies: () => [], configParser: (input) => zCommonConfig.parse(input), defaultOptions, - public: { - getSuccessEmoji(pluginData) { - return () => getSuccessEmoji(pluginData); - }, + public(pluginData) { + return { + getSuccessEmoji, + getErrorEmoji, - getErrorEmoji(pluginData) { - return () => getErrorEmoji(pluginData); - }, - - sendSuccessMessage(pluginData) { - return async ( + sendSuccessMessage: async ( context: TextBasedChannel | Message | User | ChatInputCommandInteraction, body: string, allowedMentions?: MessageMentionOptions, @@ -89,11 +80,9 @@ export const CommonPlugin = zeppelinGuildPlugin()({ return undefined; }) as Promise; - }; - }, + }, - sendErrorMessage(pluginData) { - return async ( + sendErrorMessage: async ( context: TextBasedChannel | Message | User | ChatInputCommandInteraction, body: string, allowedMentions?: MessageMentionOptions, @@ -140,7 +129,25 @@ export const CommonPlugin = zeppelinGuildPlugin()({ return undefined; }) as Promise; - }; - }, + }, + + storeAttachmentsAsMessage: async (attachments: Attachment[], backupChannel?: TextBasedChannel | null) => { + const attachmentChannelId = pluginData.config.get().attachment_storing_channel; + const channel = attachmentChannelId + ? (pluginData.guild.channels.cache.get(attachmentChannelId) as TextBasedChannel) ?? backupChannel + : backupChannel; + + if (!channel) { + throw new Error( + 'Cannot store attachments: no attachment storing channel configured, and no backup channel passed' + ); + } + + return channel!.send({ + content: `Storing ${attachments.length} attachment${attachments.length === 1 ? "" : "s"}`, + files: attachments.map((a) => a.url), + }); + }, + } }, }); diff --git a/backend/src/plugins/Common/info.ts b/backend/src/plugins/Common/info.ts new file mode 100644 index 00000000..666ac502 --- /dev/null +++ b/backend/src/plugins/Common/info.ts @@ -0,0 +1,8 @@ +import { ZeppelinPluginInfo } from "../../types"; +import { zCommonConfig } from "./types"; + +export const contextMenuPluginInfo: ZeppelinPluginInfo = { + showInDocs: false, + prettyName: "Common", + configSchema: zCommonConfig, +}; diff --git a/backend/src/plugins/Common/types.ts b/backend/src/plugins/Common/types.ts index 965046aa..87a342f5 100644 --- a/backend/src/plugins/Common/types.ts +++ b/backend/src/plugins/Common/types.ts @@ -4,6 +4,7 @@ import z from "zod"; export const zCommonConfig = z.strictObject({ success_emoji: z.string(), error_emoji: z.string(), + attachment_storing_channel: z.nullable(z.string()), }); export interface CommonPluginType extends BasePluginType { diff --git a/backend/src/plugins/ContextMenus/actions/ban.ts b/backend/src/plugins/ContextMenus/actions/ban.ts index 9848f5d5..9f7114c6 100644 --- a/backend/src/plugins/ContextMenus/actions/ban.ts +++ b/backend/src/plugins/ContextMenus/actions/ban.ts @@ -9,8 +9,8 @@ import { } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { canActOn } from "src/pluginUtils"; -import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; +import { canActOn } from "../../../pluginUtils"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { logger } from "../../../logger"; import { convertDelayStringToMS, renderUserUsername } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; @@ -36,17 +36,13 @@ async function banAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasBanPermission(executingMember, interaction.channelId))) { - await interactionToReply - .editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }) - .catch((err) => logger.error(`Ban interaction reply failed: ${err}`)); + await interactionToReply.editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }); return; } const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interactionToReply - .editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }) - .catch((err) => logger.error(`Ban interaction reply failed: ${err}`)); + await interactionToReply.editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }); return; } @@ -57,9 +53,7 @@ async function banAction( const durationMs = duration ? convertDelayStringToMS(duration)! : undefined; const result = await modactions.banUserId(target, reason, reason, { caseArgs }, durationMs); if (result.status === "failed") { - await interactionToReply - .editReply({ content: "Error: Failed to ban user", embeds: [], components: [] }) - .catch((err) => logger.error(`Ban interaction reply failed: ${err}`)); + await interactionToReply.editReply({ content: "Error: Failed to ban user", embeds: [], components: [] }); return; } @@ -73,9 +67,7 @@ async function banAction( await updateAction(pluginData, executingMember, result.case, evidence); } - await interactionToReply - .editReply({ content: banMessage, embeds: [], components: [] }) - .catch((err) => logger.error(`Ban interaction reply failed: ${err}`)); + await interactionToReply.editReply({ content: banMessage, embeds: [], components: [] }); } export async function launchBanActionModal( @@ -112,9 +104,7 @@ export async function launchBanActionModal( if (interaction.isButton()) { await submitted.deferUpdate().catch((err) => logger.error(`Ban interaction defer failed: ${err}`)); } else if (interaction.isContextMenuCommand()) { - await submitted - .deferReply({ ephemeral: true }) - .catch((err) => logger.error(`Ban interaction defer failed: ${err}`)); + await submitted.deferReply({ ephemeral: true }); } const duration = submitted.fields.getTextInputValue("duration"); @@ -122,6 +112,5 @@ export async function launchBanActionModal( const evidence = submitted.fields.getTextInputValue("evidence"); await banAction(pluginData, duration, reason, evidence, target, interaction, submitted); - }) - .catch((err) => logger.error(`Ban modal interaction failed: ${err}`)); + }); } diff --git a/backend/src/plugins/ContextMenus/actions/clean.ts b/backend/src/plugins/ContextMenus/actions/clean.ts index c5125721..8dee27b1 100644 --- a/backend/src/plugins/ContextMenus/actions/clean.ts +++ b/backend/src/plugins/ContextMenus/actions/clean.ts @@ -61,15 +61,11 @@ export async function launchCleanActionModal( await interaction .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) .then(async (submitted) => { - await submitted - .deferReply({ ephemeral: true }) - .catch((err) => logger.error(`Clean interaction defer failed: ${err}`)); + await submitted.deferReply({ ephemeral: true }); const amount = submitted.fields.getTextInputValue("amount"); if (isNaN(Number(amount))) { - interaction - .editReply({ content: `Error: Amount '${amount}' is invalid`, embeds: [], components: [] }) - .catch((err) => logger.error(`Clean interaction reply failed: ${err}`)); + interaction.editReply({ content: `Error: Amount '${amount}' is invalid`, embeds: [], components: [] }); return; } @@ -81,6 +77,5 @@ export async function launchCleanActionModal( interaction.channelId, submitted, ); - }) - .catch((err) => logger.error(`Clean modal interaction failed: ${err}`)); + }); } diff --git a/backend/src/plugins/ContextMenus/actions/mute.ts b/backend/src/plugins/ContextMenus/actions/mute.ts index 6e69b16f..6d7ec1e1 100644 --- a/backend/src/plugins/ContextMenus/actions/mute.ts +++ b/backend/src/plugins/ContextMenus/actions/mute.ts @@ -39,25 +39,21 @@ async function muteAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasMutePermission(executingMember, interaction.channelId))) { - await interactionToReply - .editReply({ - content: "Cannot mute: insufficient permissions", - embeds: [], - components: [], - }) - .catch((err) => logger.error(`Mute interaction reply failed: ${err}`)); + await interactionToReply.editReply({ + content: "Cannot mute: insufficient permissions", + embeds: [], + components: [], + }); return; } const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interactionToReply - .editReply({ - content: "Cannot mute: insufficient permissions", - embeds: [], - components: [], - }) - .catch((err) => logger.error(`Mute interaction reply failed: ${err}`)); + await interactionToReply.editReply({ + content: "Cannot mute: insufficient permissions", + embeds: [], + components: [], + }); return; } @@ -78,17 +74,13 @@ async function muteAction( await updateAction(pluginData, executingMember, result.case!, evidence); } - await interactionToReply - .editReply({ content: muteMessage, embeds: [], components: [] }) - .catch((err) => logger.error(`Mute interaction reply failed: ${err}`)); + await interactionToReply.editReply({ content: muteMessage, embeds: [], components: [] }); } catch (e) { - await interactionToReply - .editReply({ - content: "Plugin error, please check your BOT_ALERTs", - embeds: [], - components: [], - }) - .catch((err) => logger.error(`Mute interaction reply failed: ${err}`)); + await interactionToReply.editReply({ + content: "Plugin error, please check your BOT_ALERTs", + embeds: [], + components: [], + }); if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { pluginData.getPlugin(LogsPlugin).logBotAlert({ @@ -134,9 +126,7 @@ export async function launchMuteActionModal( if (interaction.isButton()) { await submitted.deferUpdate().catch((err) => logger.error(`Mute interaction defer failed: ${err}`)); } else if (interaction.isContextMenuCommand()) { - await submitted - .deferReply({ ephemeral: true }) - .catch((err) => logger.error(`Mute interaction defer failed: ${err}`)); + await submitted.deferReply({ ephemeral: true }); } const duration = submitted.fields.getTextInputValue("duration"); @@ -144,6 +134,5 @@ export async function launchMuteActionModal( const evidence = submitted.fields.getTextInputValue("evidence"); await muteAction(pluginData, duration, reason, evidence, target, interaction, submitted); - }) - .catch((err) => logger.error(`Mute modal interaction failed: ${err}`)); + }); } diff --git a/backend/src/plugins/ContextMenus/actions/note.ts b/backend/src/plugins/ContextMenus/actions/note.ts index b6911274..bbdc6a8e 100644 --- a/backend/src/plugins/ContextMenus/actions/note.ts +++ b/backend/src/plugins/ContextMenus/actions/note.ts @@ -8,8 +8,8 @@ import { TextInputStyle, } from "discord.js"; import { GuildPluginData } from "knub"; -import { canActOn } from "src/pluginUtils"; -import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; +import { canActOn } from "../../../pluginUtils"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { CaseTypes } from "../../../data/CaseTypes"; import { logger } from "../../../logger"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; @@ -34,25 +34,21 @@ async function noteAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasNotePermission(executingMember, interaction.channelId))) { - await interactionToReply - .editReply({ - content: "Cannot note: insufficient permissions", - embeds: [], - components: [], - }) - .catch((err) => logger.error(`Note interaction reply failed: ${err}`)); + await interactionToReply.editReply({ + content: "Cannot note: insufficient permissions", + embeds: [], + components: [], + }); return; } const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interactionToReply - .editReply({ - content: "Cannot note: insufficient permissions", - embeds: [], - components: [], - }) - .catch((err) => logger.error(`Note interaction reply failed: ${err}`)); + await interactionToReply.editReply({ + content: "Cannot note: insufficient permissions", + embeds: [], + components: [], + }); return; } @@ -72,13 +68,11 @@ async function noteAction( }); const userName = renderUserUsername(targetMember.user); - await interactionToReply - .editReply({ - content: `Note added on **${userName}** (Case #${createdCase.case_number})`, - embeds: [], - components: [], - }) - .catch((err) => logger.error(`Note interaction reply failed: ${err}`)); + await interactionToReply.editReply({ + content: `Note added on **${userName}** (Case #${createdCase.case_number})`, + embeds: [], + components: [], + }); } export async function launchNoteActionModal( @@ -99,14 +93,11 @@ export async function launchNoteActionModal( if (interaction.isButton()) { await submitted.deferUpdate().catch((err) => logger.error(`Note interaction defer failed: ${err}`)); } else if (interaction.isContextMenuCommand()) { - await submitted - .deferReply({ ephemeral: true }) - .catch((err) => logger.error(`Note interaction defer failed: ${err}`)); + await submitted.deferReply({ ephemeral: true }); } const reason = submitted.fields.getTextInputValue("reason"); await noteAction(pluginData, reason, target, interaction, submitted); - }) - .catch((err) => logger.error(`Note modal interaction failed: ${err}`)); + }); } diff --git a/backend/src/plugins/ContextMenus/actions/update.ts b/backend/src/plugins/ContextMenus/actions/update.ts index 3365f293..d534930d 100644 --- a/backend/src/plugins/ContextMenus/actions/update.ts +++ b/backend/src/plugins/ContextMenus/actions/update.ts @@ -2,8 +2,8 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; -import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; import { ContextMenuPluginType } from "../types"; export async function updateAction( @@ -19,7 +19,7 @@ export async function updateAction( body: value, }); - pluginData.getPlugin(LogsPlugin).logCaseUpdate({ + void pluginData.getPlugin(LogsPlugin).logCaseUpdate({ mod: executingMember.user, caseNumber: theCase.case_number, caseType: CaseTypes[theCase.type], diff --git a/backend/src/plugins/ContextMenus/actions/warn.ts b/backend/src/plugins/ContextMenus/actions/warn.ts index b467ed61..1e93f42d 100644 --- a/backend/src/plugins/ContextMenus/actions/warn.ts +++ b/backend/src/plugins/ContextMenus/actions/warn.ts @@ -8,8 +8,8 @@ import { TextInputStyle, } from "discord.js"; import { GuildPluginData } from "knub"; -import { canActOn } from "src/pluginUtils"; -import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; +import { canActOn } from "../../../pluginUtils"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { logger } from "../../../logger"; import { renderUserUsername } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; @@ -34,25 +34,21 @@ async function warnAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasWarnPermission(executingMember, interaction.channelId))) { - await interactionToReply - .editReply({ - content: "Cannot warn: insufficient permissions", - embeds: [], - components: [], - }) - .catch((err) => logger.error(`Warn interaction reply failed: ${err}`)); + await interactionToReply.editReply({ + content: "Cannot warn: insufficient permissions", + embeds: [], + components: [], + }); return; } const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interactionToReply - .editReply({ - content: "Cannot warn: insufficient permissions", - embeds: [], - components: [], - }) - .catch((err) => logger.error(`Warn interaction reply failed: ${err}`)); + await interactionToReply.editReply({ + content: "Cannot warn: insufficient permissions", + embeds: [], + components: [], + }); return; } @@ -62,9 +58,7 @@ async function warnAction( const result = await modactions.warnMember(targetMember, reason, reason, { caseArgs }); if (result.status === "failed") { - await interactionToReply - .editReply({ content: "Error: Failed to warn user", embeds: [], components: [] }) - .catch((err) => logger.error(`Warn interaction reply failed: ${err}`)); + await interactionToReply.editReply({ content: "Error: Failed to warn user", embeds: [], components: [] }); return; } @@ -76,9 +70,7 @@ async function warnAction( await updateAction(pluginData, executingMember, result.case, evidence); } - await interactionToReply - .editReply({ content: muteMessage, embeds: [], components: [] }) - .catch((err) => logger.error(`Warn interaction reply failed: ${err}`)); + await interactionToReply.editReply({ content: muteMessage, embeds: [], components: [] }); } export async function launchWarnActionModal( @@ -105,15 +97,12 @@ export async function launchWarnActionModal( if (interaction.isButton()) { await submitted.deferUpdate().catch((err) => logger.error(`Warn interaction defer failed: ${err}`)); } else if (interaction.isContextMenuCommand()) { - await submitted - .deferReply({ ephemeral: true }) - .catch((err) => logger.error(`Warn interaction defer failed: ${err}`)); + await submitted.deferReply({ ephemeral: true }); } const reason = submitted.fields.getTextInputValue("reason"); const evidence = submitted.fields.getTextInputValue("evidence"); await warnAction(pluginData, reason, evidence, target, interaction, submitted); - }) - .catch((err) => logger.error(`Warn modal interaction failed: ${err}`)); + }); } diff --git a/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts index 9cb40f14..fd538997 100644 --- a/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts @@ -12,7 +12,7 @@ import { import { GuildPluginData, guildPluginUserContextMenuCommand } from "knub"; import { Case } from "../../../data/entities/Case"; import { logger } from "../../../logger"; -import { ModActionsPlugin } from "../../../plugins/ModActions/ModActionsPlugin"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { SECONDS, UnknownUser, emptyEmbedValue, renderUserUsername, resolveUser, trimLines } from "../../../utils"; import { asyncMap } from "../../../utils/async"; import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; @@ -40,9 +40,7 @@ export const ModMenuCmd = guildPluginUserContextMenuCommand({ name: "Mod Menu", defaultMemberPermissions: PermissionFlagsBits.ViewAuditLog.toString(), async run({ pluginData, interaction }) { - await interaction - .deferReply({ ephemeral: true }) - .catch((err) => logger.error(`Mod menu interaction defer failed: ${err}`)); + await interaction.deferReply({ ephemeral: true }); // Run permission checks for executing user. const executingMember = await pluginData.guild.members.fetch(interaction.user.id); @@ -50,22 +48,14 @@ export const ModMenuCmd = guildPluginUserContextMenuCommand({ channelId: interaction.channelId, member: executingMember, }); - const utility = pluginData.getPlugin(UtilityPlugin); - if ( - !userCfg.can_use || - (await !utility.hasPermission(executingMember, interaction.channelId, "can_open_mod_menu")) - ) { - await interaction - .followUp({ content: "Error: Insufficient Permissions" }) - .catch((err) => logger.error(`Mod menu interaction follow up failed: ${err}`)); + if (!userCfg.can_use || !userCfg.can_open_mod_menu) { + await interaction.followUp({ content: "Error: Insufficient Permissions" }); return; } const user = await resolveUser(pluginData.client, interaction.targetId); if (!user.id) { - await interaction - .followUp("Error: User not found") - .catch((err) => logger.error(`Mod menu interaction follow up failed: ${err}`)); + await interaction.followUp("Error: User not found"); return; } diff --git a/backend/src/plugins/Counters/CountersPlugin.ts b/backend/src/plugins/Counters/CountersPlugin.ts index ed1b2d8a..dd226865 100644 --- a/backend/src/plugins/Counters/CountersPlugin.ts +++ b/backend/src/plugins/Counters/CountersPlugin.ts @@ -19,6 +19,7 @@ import { offCounterEvent } from "./functions/offCounterEvent"; import { onCounterEvent } from "./functions/onCounterEvent"; import { setCounterValue } from "./functions/setCounterValue"; import { CountersPluginType, zCountersConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const DECAY_APPLY_INTERVAL = 5 * MINUTES; @@ -127,6 +128,10 @@ export const CountersPlugin = guildPlugin()({ await state.counters.markUnusedTriggersToBeDeleted(activeTriggerIds); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + async afterLoad(pluginData) { const { state } = pluginData; diff --git a/backend/src/plugins/Counters/commands/AddCounterCmd.ts b/backend/src/plugins/Counters/commands/AddCounterCmd.ts index 0eb68f2b..558c23de 100644 --- a/backend/src/plugins/Counters/commands/AddCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/AddCounterCmd.ts @@ -45,22 +45,22 @@ export const AddCounterCmd = guildPluginMessageCommand()({ const counter = config.counters[args.counterName]; const counterId = pluginData.state.counterIds[args.counterName]; if (!counter || !counterId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Unknown counter: ${args.counterName}`); + void pluginData.state.common.sendErrorMessage(message, `Unknown counter: ${args.counterName}`); return; } if (counter.can_edit === false) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Missing permissions to edit this counter's value`); + void pluginData.state.common.sendErrorMessage(message, `Missing permissions to edit this counter's value`); return; } if (args.channel && !counter.per_channel) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-channel`); + void pluginData.state.common.sendErrorMessage(message, `This counter is not per-channel`); return; } if (args.user && !counter.per_user) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-user`); + void pluginData.state.common.sendErrorMessage(message, `This counter is not per-user`); return; } @@ -69,13 +69,13 @@ export const AddCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which channel's counter value would you like to add to?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Channel is not a text channel, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Channel is not a text channel, cancelling"); return; } @@ -87,13 +87,13 @@ export const AddCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which user's counter value would you like to add to?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialUser = await resolveUser(pluginData.client, reply.content); if (!potentialUser || potentialUser instanceof UnknownUser) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown user, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Unknown user, cancelling"); return; } @@ -105,13 +105,13 @@ export const AddCounterCmd = guildPluginMessageCommand()({ message.channel.send("How much would you like to add to the counter's value?"); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialAmount = parseInt(reply.content, 10); if (!potentialAmount) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Not a number, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Not a number, cancelling"); return; } diff --git a/backend/src/plugins/Counters/commands/CountersListCmd.ts b/backend/src/plugins/Counters/commands/CountersListCmd.ts index db83812e..fc79b62c 100644 --- a/backend/src/plugins/Counters/commands/CountersListCmd.ts +++ b/backend/src/plugins/Counters/commands/CountersListCmd.ts @@ -15,7 +15,7 @@ export const CountersListCmd = guildPluginMessageCommand()({ const countersToShow = Array.from(Object.values(config.counters)).filter((c) => c.can_view !== false); if (!countersToShow.length) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "No counters are configured for this server"); + void pluginData.state.common.sendErrorMessage(message, "No counters are configured for this server"); return; } diff --git a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts index e413cf21..5f7aa5d4 100644 --- a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts @@ -18,14 +18,12 @@ export const ResetAllCounterValuesCmd = guildPluginMessageCommand()({ const counter = config.counters[args.counterName]; const counterId = pluginData.state.counterIds[args.counterName]; if (!counter || !counterId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Unknown counter: ${args.counterName}`); + void pluginData.state.common.sendErrorMessage(message, `Unknown counter: ${args.counterName}`); return; } if (counter.can_edit === false) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Missing permissions to reset this counter's value`); + void pluginData.state.common.sendErrorMessage(message, `Missing permissions to reset this counter's value`); return; } if (args.channel && !counter.per_channel) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-channel`); + void pluginData.state.common.sendErrorMessage(message, `This counter is not per-channel`); return; } if (args.user && !counter.per_user) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-user`); + void pluginData.state.common.sendErrorMessage(message, `This counter is not per-user`); return; } @@ -64,13 +64,13 @@ export const ResetCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which channel's counter value would you like to reset?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Channel is not a text channel, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Channel is not a text channel, cancelling"); return; } @@ -82,13 +82,13 @@ export const ResetCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which user's counter value would you like to reset?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialUser = await resolveUser(pluginData.client, reply.content); if (!potentialUser || potentialUser instanceof UnknownUser) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown user, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Unknown user, cancelling"); return; } diff --git a/backend/src/plugins/Counters/commands/SetCounterCmd.ts b/backend/src/plugins/Counters/commands/SetCounterCmd.ts index 3cc62c54..da055ee0 100644 --- a/backend/src/plugins/Counters/commands/SetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/SetCounterCmd.ts @@ -45,22 +45,22 @@ export const SetCounterCmd = guildPluginMessageCommand()({ const counter = config.counters[args.counterName]; const counterId = pluginData.state.counterIds[args.counterName]; if (!counter || !counterId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Unknown counter: ${args.counterName}`); + void pluginData.state.common.sendErrorMessage(message, `Unknown counter: ${args.counterName}`); return; } if (counter.can_edit === false) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Missing permissions to edit this counter's value`); + void pluginData.state.common.sendErrorMessage(message, `Missing permissions to edit this counter's value`); return; } if (args.channel && !counter.per_channel) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-channel`); + void pluginData.state.common.sendErrorMessage(message, `This counter is not per-channel`); return; } if (args.user && !counter.per_user) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-user`); + void pluginData.state.common.sendErrorMessage(message, `This counter is not per-user`); return; } @@ -69,13 +69,13 @@ export const SetCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which channel's counter value would you like to change?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Channel is not a text channel, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Channel is not a text channel, cancelling"); return; } @@ -87,13 +87,13 @@ export const SetCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which user's counter value would you like to change?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialUser = await resolveUser(pluginData.client, reply.content); if (!potentialUser || potentialUser instanceof UnknownUser) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown user, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Unknown user, cancelling"); return; } @@ -105,13 +105,13 @@ export const SetCounterCmd = guildPluginMessageCommand()({ message.channel.send("What would you like to set the counter's value to?"); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialValue = parseInt(reply.content, 10); if (Number.isNaN(potentialValue)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Not a number, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Not a number, cancelling"); return; } @@ -119,7 +119,7 @@ export const SetCounterCmd = guildPluginMessageCommand()({ } if (value < 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cannot set counter value below 0"); + void pluginData.state.common.sendErrorMessage(message, "Cannot set counter value below 0"); return; } diff --git a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts index 1c037e69..d91de3f3 100644 --- a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts @@ -39,22 +39,22 @@ export const ViewCounterCmd = guildPluginMessageCommand()({ const counter = config.counters[args.counterName]; const counterId = pluginData.state.counterIds[args.counterName]; if (!counter || !counterId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Unknown counter: ${args.counterName}`); + void pluginData.state.common.sendErrorMessage(message, `Unknown counter: ${args.counterName}`); return; } if (counter.can_view === false) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Missing permissions to view this counter's value`); + void pluginData.state.common.sendErrorMessage(message, `Missing permissions to view this counter's value`); return; } if (args.channel && !counter.per_channel) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-channel`); + void pluginData.state.common.sendErrorMessage(message, `This counter is not per-channel`); return; } if (args.user && !counter.per_user) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-user`); + void pluginData.state.common.sendErrorMessage(message, `This counter is not per-user`); return; } @@ -63,13 +63,13 @@ export const ViewCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which channel's counter value would you like to view?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); if (!potentialChannel?.isTextBased()) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Channel is not a text channel, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Channel is not a text channel, cancelling"); return; } @@ -81,13 +81,13 @@ export const ViewCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which user's counter value would you like to view?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialUser = await resolveUser(pluginData.client, reply.content); if (!potentialUser || potentialUser instanceof UnknownUser) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown user, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Unknown user, cancelling"); return; } diff --git a/backend/src/plugins/Counters/types.ts b/backend/src/plugins/Counters/types.ts index ef322e7b..c75046eb 100644 --- a/backend/src/plugins/Counters/types.ts +++ b/backend/src/plugins/Counters/types.ts @@ -1,5 +1,5 @@ import { EventEmitter } from "events"; -import { BasePluginType } from "knub"; +import { BasePluginType, pluginUtils } from "knub"; import z from "zod"; import { GuildCounters, MAX_COUNTER_VALUE, MIN_COUNTER_VALUE } from "../../data/GuildCounters"; import { @@ -10,6 +10,7 @@ import { } from "../../data/entities/CounterTrigger"; import { zBoundedCharacters, zBoundedRecord, zDelayString } from "../../utils"; import Timeout = NodeJS.Timeout; +import { CommonPlugin } from "../Common/CommonPlugin"; const MAX_COUNTERS = 5; const MAX_TRIGGERS_PER_COUNTER = 5; @@ -132,5 +133,6 @@ export interface CountersPluginType extends BasePluginType { decayTimers: Timeout[]; events: CounterEventEmitter; counterTriggersByCounterId: Map; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts b/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts index f85036a1..cdb9aae7 100644 --- a/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts +++ b/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts @@ -14,6 +14,7 @@ import { import { LogsPlugin } from "../Logs/LogsPlugin"; import { runEvent } from "./functions/runEvent"; import { CustomEventsPluginType, zCustomEventsConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions = { config: { @@ -28,6 +29,10 @@ export const CustomEventsPlugin = guildPlugin()({ configParser: (input) => zCustomEventsConfig.parse(input), defaultOptions, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const config = pluginData.config.get(); for (const [key, event] of Object.entries(config.events)) { diff --git a/backend/src/plugins/CustomEvents/functions/runEvent.ts b/backend/src/plugins/CustomEvents/functions/runEvent.ts index 5ea3ceca..3f75b894 100644 --- a/backend/src/plugins/CustomEvents/functions/runEvent.ts +++ b/backend/src/plugins/CustomEvents/functions/runEvent.ts @@ -39,7 +39,7 @@ export async function runEvent( } catch (e) { if (e instanceof ActionError) { if (event.trigger.type === "command") { - pluginData.getPlugin(CommonPlugin).sendErrorMessage((eventData.msg as Message).channel, e.message); + void pluginData.state.common.sendErrorMessage((eventData.msg as Message).channel, e.message); } else { // TODO: Where to log action errors from other kinds of triggers? } diff --git a/backend/src/plugins/CustomEvents/types.ts b/backend/src/plugins/CustomEvents/types.ts index 6433b6d0..0372fd16 100644 --- a/backend/src/plugins/CustomEvents/types.ts +++ b/backend/src/plugins/CustomEvents/types.ts @@ -1,4 +1,4 @@ -import { BasePluginType } from "knub"; +import { BasePluginType, pluginUtils } from "knub"; import z from "zod"; import { zBoundedCharacters, zBoundedRecord } from "../../utils"; import { zAddRoleAction } from "./actions/addRoleAction"; @@ -8,6 +8,7 @@ import { zMakeRoleUnmentionableAction } from "./actions/makeRoleUnmentionableAct import { zMessageAction } from "./actions/messageAction"; import { zMoveToVoiceChannelAction } from "./actions/moveToVoiceChannelAction"; import { zSetChannelPermissionOverridesAction } from "./actions/setChannelPermissionOverrides"; +import { CommonPlugin } from "../Common/CommonPlugin"; const zCommandTrigger = z.strictObject({ type: z.literal("command"), @@ -43,5 +44,6 @@ export interface CustomEventsPluginType extends BasePluginType { config: z.infer; state: { clearTriggers: () => void; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/LocateUser/LocateUserPlugin.ts b/backend/src/plugins/LocateUser/LocateUserPlugin.ts index 3fb8f841..39057b00 100644 --- a/backend/src/plugins/LocateUser/LocateUserPlugin.ts +++ b/backend/src/plugins/LocateUser/LocateUserPlugin.ts @@ -9,6 +9,7 @@ import { VoiceStateUpdateAlertEvt } from "./events/SendAlertsEvts"; import { LocateUserPluginType, zLocateUserConfig } from "./types"; import { clearExpiredAlert } from "./utils/clearExpiredAlert"; import { fillActiveAlertsList } from "./utils/fillAlertsList"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -53,6 +54,10 @@ export const LocateUserPlugin = guildPlugin()({ state.usersWithAlerts = []; }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { state, guild } = pluginData; diff --git a/backend/src/plugins/LocateUser/commands/FollowCmd.ts b/backend/src/plugins/LocateUser/commands/FollowCmd.ts index a214241b..921ec47f 100644 --- a/backend/src/plugins/LocateUser/commands/FollowCmd.ts +++ b/backend/src/plugins/LocateUser/commands/FollowCmd.ts @@ -27,9 +27,7 @@ export const FollowCmd = locateUserCmd({ const active = args.active || false; if (time < 30 * SECONDS) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "Sorry, but the minimum duration for an alert is 30 seconds!"); + void pluginData.state.common.sendErrorMessage(msg, "Sorry, but the minimum duration for an alert is 30 seconds!"); return; } @@ -48,18 +46,14 @@ export const FollowCmd = locateUserCmd({ } if (active) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + void pluginData.state.common.sendSuccessMessage( msg, `Every time <@${args.member.id}> joins or switches VC in the next ${humanizeDuration( time, )} i will notify and move you.\nPlease make sure to be in a voice channel, otherwise i cannot move you!`, ); } else { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + void pluginData.state.common.sendSuccessMessage( msg, `Every time <@${args.member.id}> joins or switches VC in the next ${humanizeDuration( time, diff --git a/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts b/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts index 271b401d..c993c5c7 100644 --- a/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts +++ b/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts @@ -13,7 +13,7 @@ export const ListFollowCmd = locateUserCmd({ async run({ message: msg, pluginData }) { const alerts = await pluginData.state.alerts.getAlertsByRequestorId(msg.member.id); if (alerts.length === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You have no active alerts!"); + void pluginData.state.common.sendErrorMessage(msg, "You have no active alerts!"); return; } @@ -46,7 +46,7 @@ export const DeleteFollowCmd = locateUserCmd({ alerts.sort(sorter("expires_at")); if (args.num > alerts.length || args.num <= 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown alert!"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown alert!"); return; } @@ -54,6 +54,6 @@ export const DeleteFollowCmd = locateUserCmd({ clearExpiringVCAlert(toDelete); await pluginData.state.alerts.delete(toDelete.id); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Alert deleted"); + void pluginData.state.common.sendSuccessMessage(msg, "Alert deleted"); }, }); diff --git a/backend/src/plugins/LocateUser/types.ts b/backend/src/plugins/LocateUser/types.ts index 4139f465..90695a6d 100644 --- a/backend/src/plugins/LocateUser/types.ts +++ b/backend/src/plugins/LocateUser/types.ts @@ -1,6 +1,7 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildVCAlerts } from "../../data/GuildVCAlerts"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zLocateUserConfig = z.strictObject({ can_where: z.boolean(), @@ -13,6 +14,7 @@ export interface LocateUserPluginType extends BasePluginType { alerts: GuildVCAlerts; usersWithAlerts: string[]; unregisterGuildEventListener: () => void; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/LocateUser/utils/moveMember.ts b/backend/src/plugins/LocateUser/utils/moveMember.ts index f6dbd96b..f562fe30 100644 --- a/backend/src/plugins/LocateUser/utils/moveMember.ts +++ b/backend/src/plugins/LocateUser/utils/moveMember.ts @@ -16,14 +16,10 @@ export async function moveMember( channel: target.voice.channelId, }); } catch { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(errorChannel, "Failed to move you. Are you in a voice channel?"); + void pluginData.state.common.sendErrorMessage(errorChannel, "Failed to move you. Are you in a voice channel?"); return; } } else { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(errorChannel, "Failed to move you. Are you in a voice channel?"); + void pluginData.state.common.sendErrorMessage(errorChannel, "Failed to move you. Are you in a voice channel?"); } } diff --git a/backend/src/plugins/LocateUser/utils/sendWhere.ts b/backend/src/plugins/LocateUser/utils/sendWhere.ts index 8d40e99c..78172509 100644 --- a/backend/src/plugins/LocateUser/utils/sendWhere.ts +++ b/backend/src/plugins/LocateUser/utils/sendWhere.ts @@ -22,7 +22,7 @@ export async function sendWhere( try { invite = await createOrReuseInvite(voice); } catch { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(channel, "Cannot create an invite to that channel!"); + void pluginData.state.common.sendErrorMessage(channel, "Cannot create an invite to that channel!"); return; } channel.send({ diff --git a/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts b/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts index 4c960904..9d62c2c7 100644 --- a/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts +++ b/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts @@ -4,6 +4,7 @@ import { SaveMessagesToDBCmd } from "./commands/SaveMessagesToDB"; import { SavePinsToDBCmd } from "./commands/SavePinsToDB"; import { MessageCreateEvt, MessageDeleteBulkEvt, MessageDeleteEvt, MessageUpdateEvt } from "./events/SaveMessagesEvts"; import { MessageSaverPluginType, zMessageSaverConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -43,4 +44,8 @@ export const MessageSaverPlugin = guildPlugin()({ const { state, guild } = pluginData; state.savedMessages = GuildSavedMessages.getGuildInstance(guild.id); }, + + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, }); diff --git a/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts b/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts index 6b9211f1..a34b103e 100644 --- a/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts +++ b/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts @@ -18,14 +18,12 @@ export const SaveMessagesToDBCmd = messageSaverCmd({ const { savedCount, failed } = await saveMessagesToDB(pluginData, args.channel, args.ids.trim().split(" ")); if (failed.length) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + void pluginData.state.common.sendSuccessMessage( msg, `Saved ${savedCount} messages. The following messages could not be saved: ${failed.join(", ")}`, ); } else { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Saved ${savedCount} messages!`); + void pluginData.state.common.sendSuccessMessage(msg, `Saved ${savedCount} messages!`); } }, }); diff --git a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts index 92c5393d..d2910525 100644 --- a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts +++ b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts @@ -19,14 +19,12 @@ export const SavePinsToDBCmd = messageSaverCmd({ const { savedCount, failed } = await saveMessagesToDB(pluginData, args.channel, [...pins.keys()]); if (failed.length) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + void pluginData.state.common.sendSuccessMessage( msg, `Saved ${savedCount} messages. The following messages could not be saved: ${failed.join(", ")}`, ); } else { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Saved ${savedCount} messages!`); + void pluginData.state.common.sendSuccessMessage(msg, `Saved ${savedCount} messages!`); } }, }); diff --git a/backend/src/plugins/MessageSaver/types.ts b/backend/src/plugins/MessageSaver/types.ts index f42fa2c3..671eb9d9 100644 --- a/backend/src/plugins/MessageSaver/types.ts +++ b/backend/src/plugins/MessageSaver/types.ts @@ -1,6 +1,7 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zMessageSaverConfig = z.strictObject({ can_manage: z.boolean(), @@ -10,6 +11,7 @@ export interface MessageSaverPluginType extends BasePluginType { config: z.infer; state: { savedMessages: GuildSavedMessages; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts index 953e245d..bd6aa0c7 100644 --- a/backend/src/plugins/ModActions/ModActionsPlugin.ts +++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts @@ -72,6 +72,7 @@ import { onModActionsEvent } from "./functions/onModActionsEvent"; import { updateCase } from "./functions/updateCase"; import { warnMember } from "./functions/warnMember"; import { AttachmentLinkReactionType, ModActionsPluginType, modActionsSlashGroup, zModActionsConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions = { config: { @@ -94,7 +95,6 @@ const defaultOptions = { "The user already has **{priorWarnings}** warnings!\n Please check their prior cases and assess whether or not to warn anyways.\n Proceed with the warning?", ban_delete_message_days: 1, attachment_link_reaction: "warn" as AttachmentLinkReactionType, - attachment_storing_channel: null, can_note: false, can_warn: false, @@ -236,6 +236,10 @@ export const ModActionsPlugin = guildPlugin()({ state.events = new EventEmitter(); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { state, guild } = pluginData; diff --git a/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts index beb4cc3d..9f1b819b 100644 --- a/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts @@ -2,8 +2,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { CaseTypes } from "../../../../data/CaseTypes"; import { hasPermission } from "../../../../pluginUtils"; import { resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualAddCaseCmd } from "../../functions/actualCommands/actualAddCaseCmd"; +import { actualAddCaseCmd } from "./actualAddCaseCmd"; import { modActionsMsgCmd } from "../../types"; const opts = { @@ -28,7 +27,7 @@ export const AddCaseMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } @@ -36,7 +35,7 @@ export const AddCaseMsgCmd = modActionsMsgCmd({ let mod = msg.member; if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -46,7 +45,7 @@ export const AddCaseMsgCmd = modActionsMsgCmd({ // Verify the case type is valid const type: string = args.type[0].toUpperCase() + args.type.slice(1).toLowerCase(); if (!CaseTypes[type]) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot add case: invalid case type"); + pluginData.state.common.sendErrorMessage(msg, "Cannot add case: invalid case type"); return; } diff --git a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts index 5f427686..828ec742 100644 --- a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts @@ -4,8 +4,7 @@ import { CaseTypes } from "../../../../data/CaseTypes"; import { hasPermission } from "../../../../pluginUtils"; import { resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualAddCaseCmd } from "../../functions/actualCommands/actualAddCaseCmd"; +import { actualAddCaseCmd } from "./actualAddCaseCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -49,9 +48,10 @@ export const AddCaseSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualAddCaseCmd.ts b/backend/src/plugins/ModActions/commands/addcase/actualAddCaseCmd.ts similarity index 76% rename from backend/src/plugins/ModActions/functions/actualCommands/actualAddCaseCmd.ts rename to backend/src/plugins/ModActions/commands/addcase/actualAddCaseCmd.ts index e65fe8d3..2c67dc2f 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualAddCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/actualAddCaseCmd.ts @@ -5,11 +5,10 @@ import { Case } from "../../../../data/entities/Case"; import { canActOn } from "../../../../pluginUtils"; import { UnknownUser, renderUsername, resolveMember } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; export async function actualAddCaseCmd( pluginData: GuildPluginData, @@ -28,9 +27,10 @@ export async function actualAddCaseCmd( // If the user exists as a guild member, make sure we can act on them first const member = await resolveMember(pluginData.client, pluginData.guild, user.id); if (member && !canActOn(pluginData, author, member)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "Cannot add case on this user: insufficient permissions"); + pluginData.state.common.sendErrorMessage( + context, + "Cannot add case on this user: insufficient permissions" + ); return; } @@ -47,11 +47,12 @@ export async function actualAddCaseCmd( }); if (user) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(context, `Case #${theCase.case_number} created for **${renderUsername(user)}**`); + pluginData.state.common.sendSuccessMessage( + context, + `Case #${theCase.case_number} created for **${renderUsername(user)}**` + ); } else { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, `Case #${theCase.case_number} created`); + pluginData.state.common.sendSuccessMessage(context, `Case #${theCase.case_number} created`); } // Log the action diff --git a/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts b/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts index 10b4344c..35b9f737 100644 --- a/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts @@ -1,8 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualBanCmd } from "../../functions/actualCommands/actualBanCmd"; +import { actualBanCmd } from "./actualBanCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; @@ -38,7 +37,7 @@ export const BanMsgCmd = modActionsMsgCmd({ const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } @@ -46,7 +45,7 @@ export const BanMsgCmd = modActionsMsgCmd({ let mod = msg.member; if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -57,7 +56,7 @@ export const BanMsgCmd = modActionsMsgCmd({ try { contactMethods = readContactMethodsFromArgs(args) ?? undefined; } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + pluginData.state.common.sendErrorMessage(msg, e.message); return; } diff --git a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts index 21b5558a..16bda55b 100644 --- a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts @@ -3,8 +3,7 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualBanCmd } from "../../functions/actualCommands/actualBanCmd"; +import { actualBanCmd } from "./actualBanCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -52,9 +51,13 @@ export const BanSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } @@ -67,9 +70,10 @@ export const BanSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } @@ -80,13 +84,13 @@ export const BanSlashCmd = modActionsSlashCmd({ try { contactMethods = readContactMethodsFromArgs(options) ?? undefined; } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); + pluginData.state.common.sendErrorMessage(interaction, e.message); return; } const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; if (options.time && !convertedTime) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); + pluginData.state.common.sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts b/backend/src/plugins/ModActions/commands/ban/actualBanCmd.ts similarity index 85% rename from backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts rename to backend/src/plugins/ModActions/commands/ban/actualBanCmd.ts index e4bf5ff9..0b442239 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/actualBanCmd.ts @@ -9,13 +9,12 @@ import { UnknownUser, UserNotificationMethod, renderUsername, resolveMember } fr import { banLock } from "../../../../utils/lockNameHelpers"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { banUserId } from "../banUserId"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; -import { isBanned } from "../isBanned"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { banUserId } from "../../functions/banUserId"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { isBanned } from "../../functions/isBanned"; export async function actualBanCmd( pluginData: GuildPluginData, @@ -54,7 +53,7 @@ export async function actualBanCmd( ); if (!reply) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "User not on server, ban cancelled by moderator"); + pluginData.state.common.sendErrorMessage(context, "User not on server, ban cancelled by moderator"); lock.unlock(); return; } else { @@ -63,7 +62,7 @@ export async function actualBanCmd( } else { // Abort if trying to ban user indefinitely if they are already banned indefinitely if (!existingTempban && !time) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `User is already banned indefinitely.`); + pluginData.state.common.sendErrorMessage(context, `User is already banned indefinitely.`); return; } @@ -75,9 +74,10 @@ export async function actualBanCmd( ); if (!reply) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "User already banned, update cancelled by moderator"); + pluginData.state.common.sendErrorMessage( + context, + "User already banned, update cancelled by moderator" + ); lock.unlock(); return; } @@ -122,9 +122,7 @@ export async function actualBanCmd( }); } - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + pluginData.state.common.sendSuccessMessage( context, `Ban updated to ${time ? "expire in " + humanizeDuration(time) + " from now" : "indefinite"}`, ); @@ -137,11 +135,9 @@ export async function actualBanCmd( if (!forceban && !canActOn(pluginData, author, memberToBan!)) { const ourLevel = getMemberLevel(pluginData, author); const targetLevel = getMemberLevel(pluginData, memberToBan!); - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( - context, - `Cannot ban: target permission level is equal or higher to yours, ${targetLevel} >= ${ourLevel}`, + pluginData.state.common.sendErrorMessage( + context, + `Cannot ban: target permission level is equal or higher to yours, ${targetLevel} >= ${ourLevel}`, ); lock.unlock(); return; @@ -170,7 +166,7 @@ export async function actualBanCmd( ); if (banResult.status === "failed") { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Failed to ban member: ${banResult.error}`); + pluginData.state.common.sendErrorMessage(context, `Failed to ban member: ${banResult.error}`); lock.unlock(); return; } @@ -190,5 +186,5 @@ export async function actualBanCmd( } lock.unlock(); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, response); + pluginData.state.common.sendSuccessMessage(context, response); } diff --git a/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts index 4e278e23..6c727e45 100644 --- a/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { actualCaseCmd } from "../../functions/actualCommands/actualCaseCmd"; +import { actualCaseCmd } from "./actualCaseCmd"; import { modActionsMsgCmd } from "../../types"; const opts = { diff --git a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts index 15f2d03f..b86bfb01 100644 --- a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts @@ -1,5 +1,5 @@ import { slashOptions } from "knub"; -import { actualCaseCmd } from "../../functions/actualCommands/actualCaseCmd"; +import { actualCaseCmd } from "./actualCaseCmd"; import { modActionsSlashCmd } from "../../types"; const opts = [ diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts b/backend/src/plugins/ModActions/commands/case/actualCaseCmd.ts similarity index 74% rename from backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts rename to backend/src/plugins/ModActions/commands/case/actualCaseCmd.ts index 92b27199..5be37726 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/actualCaseCmd.ts @@ -2,7 +2,6 @@ import { ChatInputCommandInteraction, Message } from "discord.js"; import { GuildPluginData } from "knub"; import { sendContextResponse } from "../../../../pluginUtils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { ModActionsPluginType } from "../../types"; export async function actualCaseCmd( @@ -15,12 +14,12 @@ export async function actualCaseCmd( const theCase = await pluginData.state.cases.findByCaseNumber(caseNumber); if (!theCase) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Case not found", undefined, undefined, show !== true); + void pluginData.state.common.sendErrorMessage(context, "Case not found", undefined, undefined, show !== true); return; } const casesPlugin = pluginData.getPlugin(CasesPlugin); const embed = await casesPlugin.getCaseEmbed(theCase.id, authorId); - sendContextResponse(context, { ...embed, ephemeral: show !== true }); + void sendContextResponse(context, { ...embed, ephemeral: show !== true }); } diff --git a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts index 57f45c74..d5f5f7fe 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { actualCasesCmd } from "../../functions/actualCommands/actualCasesCmd"; +import { actualCasesCmd } from "./actualCasesCmd"; import { modActionsMsgCmd } from "../../types"; const opts = { diff --git a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts index 8e885d1a..fe932311 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts @@ -1,6 +1,6 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { actualCasesCmd } from "../../functions/actualCommands/actualCasesCmd"; +import { actualCasesCmd } from "./actualCasesCmd"; import { modActionsSlashCmd } from "../../types"; const opts = [ diff --git a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts index c65226a6..b36b39c7 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts @@ -1,7 +1,6 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { resolveMember, resolveUser, UnknownUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualCasesCmd } from "../../functions/actualCommands/actualCasesCmd"; +import { actualCasesCmd } from "./actualCasesCmd"; import { modActionsMsgCmd } from "../../types"; const opts = { @@ -38,7 +37,7 @@ export const CasesUserMsgCmd = modActionsMsgCmd({ (await resolveUser(pluginData.client, args.user)); if (user instanceof UnknownUser) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts b/backend/src/plugins/ModActions/commands/cases/actualCasesCmd.ts similarity index 97% rename from backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts rename to backend/src/plugins/ModActions/commands/cases/actualCasesCmd.ts index 23c091a1..5973bcdb 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/actualCasesCmd.ts @@ -18,7 +18,6 @@ import { asyncMap } from "../../../../utils/async"; import { createPaginatedMessage } from "../../../../utils/createPaginatedMessage"; import { getGuildPrefix } from "../../../../utils/getGuildPrefix"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { ModActionsPluginType } from "../../types"; const casesPerPage = 5; @@ -160,9 +159,13 @@ async function casesModCmd( const totalCases = await casesPlugin.getTotalCasesByMod(modId ?? author.id, casesFilters); if (totalCases === 0) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, `No cases by **${modName}**`, undefined, undefined, !show); + pluginData.state.common.sendErrorMessage( + context, + `No cases by **${modName}**`, + undefined, + undefined, + !show + ); return; } diff --git a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts index b4c96a68..dad54847 100644 --- a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { trimLines } from "../../../../utils"; -import { actualDeleteCaseCmd } from "../../functions/actualCommands/actualDeleteCaseCmd"; +import { actualDeleteCaseCmd } from "./actualDeleteCaseCmd"; import { modActionsMsgCmd } from "../../types"; export const DeleteCaseMsgCmd = modActionsMsgCmd({ diff --git a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts index f852b666..c9038c74 100644 --- a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts @@ -1,6 +1,6 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { actualDeleteCaseCmd } from "../../functions/actualCommands/actualDeleteCaseCmd"; +import { actualDeleteCaseCmd } from "./actualDeleteCaseCmd"; import { modActionsSlashCmd } from "../../types"; const opts = [slashOptions.boolean({ name: "force", description: "Whether or not to force delete", required: false })]; diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualDeleteCaseCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/actualDeleteCaseCmd.ts similarity index 85% rename from backend/src/plugins/ModActions/functions/actualCommands/actualDeleteCaseCmd.ts rename to backend/src/plugins/ModActions/commands/deletecase/actualDeleteCaseCmd.ts index cedd03c6..707332e4 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualDeleteCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/deletecase/actualDeleteCaseCmd.ts @@ -4,7 +4,6 @@ import { Case } from "../../../../data/entities/Case"; import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; import { SECONDS, renderUsername } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { TimeAndDatePlugin } from "../../../TimeAndDate/TimeAndDatePlugin"; import { ModActionsPluginType } from "../../types"; @@ -31,7 +30,7 @@ export async function actualDeleteCaseCmd( } if (failed.length === caseNumbers.length) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "None of the cases were found!"); + pluginData.state.common.sendErrorMessage(context, "None of the cases were found!"); return; } @@ -83,13 +82,15 @@ export async function actualDeleteCaseCmd( : ""; const amt = validCases.length - cancelled; if (amt === 0) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "All deletions were cancelled, no cases were deleted."); + pluginData.state.common.sendErrorMessage( + context, + "All deletions were cancelled, no cases were deleted." + ); return; } - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(context, `${amt} case${amt === 1 ? " was" : "s were"} deleted!${failedAddendum}`); + pluginData.state.common.sendSuccessMessage( + context, + `${amt} case${amt === 1 ? " was" : "s were"} deleted!${failedAddendum}` + ); } diff --git a/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts b/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts index e15f3c13..5224e905 100644 --- a/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts @@ -1,8 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualForceBanCmd } from "../../functions/actualCommands/actualForceBanCmd"; +import { actualForceBanCmd } from "./actualForceBanCmd"; import { isBanned } from "../../functions/isBanned"; import { modActionsMsgCmd } from "../../types"; @@ -27,21 +26,21 @@ export const ForceBanMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } // If the user exists as a guild member, make sure we can act on them first const member = await resolveMember(pluginData.client, pluginData.guild, user.id); if (member && !canActOn(pluginData, msg.member, member)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot forceban this user: insufficient permissions"); + pluginData.state.common.sendErrorMessage(msg, "Cannot forceban this user: insufficient permissions"); return; } // Make sure the user isn't already banned const banned = await isBanned(pluginData, user.id); if (banned) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User is already banned`); + pluginData.state.common.sendErrorMessage(msg, `User is already banned`); return; } @@ -49,7 +48,7 @@ export const ForceBanMsgCmd = modActionsMsgCmd({ let mod = msg.member; if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } diff --git a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts index 7f7e824c..8389233b 100644 --- a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts @@ -3,8 +3,7 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualForceBanCmd } from "../../functions/actualCommands/actualForceBanCmd"; +import { actualForceBanCmd } from "./actualForceBanCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -30,9 +29,13 @@ export const ForceBanSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } @@ -45,9 +48,10 @@ export const ForceBanSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } @@ -56,7 +60,7 @@ export const ForceBanSlashCmd = modActionsSlashCmd({ const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; if (options.time && !convertedTime) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); + pluginData.state.common.sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualForceBanCmd.ts b/backend/src/plugins/ModActions/commands/forceban/actualForceBanCmd.ts similarity index 83% rename from backend/src/plugins/ModActions/functions/actualCommands/actualForceBanCmd.ts rename to backend/src/plugins/ModActions/commands/forceban/actualForceBanCmd.ts index c093306f..448f4134 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualForceBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/actualForceBanCmd.ts @@ -4,12 +4,11 @@ import { CaseTypes } from "../../../../data/CaseTypes"; import { LogType } from "../../../../data/LogType"; import { DAYS, MINUTES, UnknownUser } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; -import { ignoreEvent } from "../ignoreEvent"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { ignoreEvent } from "../../functions/ignoreEvent"; export async function actualForceBanCmd( pluginData: GuildPluginData, @@ -37,7 +36,7 @@ export async function actualForceBanCmd( reason: formattedReasonWithAttachments ?? undefined, }); } catch { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Failed to forceban member"); + pluginData.state.common.sendErrorMessage(context, "Failed to forceban member"); return; } @@ -52,9 +51,7 @@ export async function actualForceBanCmd( }); // Confirm the action - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(context, `Member forcebanned (Case #${createdCase.case_number})`); + pluginData.state.common.sendSuccessMessage(context, `Member forcebanned (Case #${createdCase.case_number})`); // Log the action pluginData.getPlugin(LogsPlugin).logMemberForceban({ diff --git a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts index 9c2a9cbb..833fb181 100644 --- a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts @@ -1,8 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; +import { actualMuteCmd } from "../mute/actualMuteCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; @@ -36,7 +35,7 @@ export const ForceMuteMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } @@ -44,7 +43,7 @@ export const ForceMuteMsgCmd = modActionsMsgCmd({ // Make sure we're allowed to mute this user if (memberToMute && !canActOn(pluginData, msg.member, memberToMute)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot mute: insufficient permissions"); + pluginData.state.common.sendErrorMessage(msg, "Cannot mute: insufficient permissions"); return; } @@ -54,7 +53,7 @@ export const ForceMuteMsgCmd = modActionsMsgCmd({ if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -66,7 +65,7 @@ export const ForceMuteMsgCmd = modActionsMsgCmd({ try { contactMethods = readContactMethodsFromArgs(args); } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + pluginData.state.common.sendErrorMessage(msg, e.message); return; } diff --git a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts index 348ff047..ba262835 100644 --- a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts @@ -3,8 +3,7 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; +import { actualMuteCmd } from "../mute/actualMuteCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -47,9 +46,13 @@ export const ForceMuteSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } @@ -63,9 +66,10 @@ export const ForceMuteSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } @@ -75,7 +79,7 @@ export const ForceMuteSlashCmd = modActionsSlashCmd({ const convertedTime = options.time ? convertDelayStringToMS(options.time) ?? undefined : undefined; if (options.time && !convertedTime) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); + pluginData.state.common.sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } @@ -83,7 +87,7 @@ export const ForceMuteSlashCmd = modActionsSlashCmd({ try { contactMethods = readContactMethodsFromArgs(options) ?? undefined; } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); + pluginData.state.common.sendErrorMessage(interaction, e.message); return; } diff --git a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts index f9351d8f..396052fd 100644 --- a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts @@ -1,8 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; +import { actualUnmuteCmd } from "../unmute/actualUnmuteCmd"; import { modActionsMsgCmd } from "../../types"; const opts = { @@ -33,13 +32,13 @@ export const ForceUnmuteMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } // Check if they're muted in the first place if (!(await pluginData.state.mutes.isMuted(user.id))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot unmute: member is not muted"); + pluginData.state.common.sendErrorMessage(msg, "Cannot unmute: member is not muted"); return; } @@ -48,7 +47,7 @@ export const ForceUnmuteMsgCmd = modActionsMsgCmd({ // Make sure we're allowed to unmute this member if (memberToUnmute && !canActOn(pluginData, msg.member, memberToUnmute)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot unmute: insufficient permissions"); + pluginData.state.common.sendErrorMessage(msg, "Cannot unmute: insufficient permissions"); return; } @@ -58,7 +57,7 @@ export const ForceUnmuteMsgCmd = modActionsMsgCmd({ if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } diff --git a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts index 326d5b73..bb03ee89 100644 --- a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts @@ -3,8 +3,7 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; +import { actualUnmuteCmd } from "../unmute/actualUnmuteCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -31,9 +30,13 @@ export const ForceUnmuteSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } @@ -47,9 +50,10 @@ export const ForceUnmuteSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } @@ -59,7 +63,7 @@ export const ForceUnmuteSlashCmd = modActionsSlashCmd({ const convertedTime = options.time ? convertDelayStringToMS(options.time) ?? undefined : undefined; if (options.time && !convertedTime) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); + pluginData.state.common.sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } diff --git a/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts index 3d160d5f..c04bf9a1 100644 --- a/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { actualHideCaseCmd } from "../../functions/actualCommands/actualHideCaseCmd"; +import { actualHideCaseCmd } from "./actualHideCaseCmd"; import { modActionsMsgCmd } from "../../types"; export const HideCaseMsgCmd = modActionsMsgCmd({ diff --git a/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts index a501a5b1..b6261d73 100644 --- a/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts @@ -1,5 +1,5 @@ import { slashOptions } from "knub"; -import { actualHideCaseCmd } from "../../functions/actualCommands/actualHideCaseCmd"; +import { actualHideCaseCmd } from "./actualHideCaseCmd"; import { modActionsSlashCmd } from "../../types"; export const HideCaseSlashCmd = modActionsSlashCmd({ diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualHideCaseCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/actualHideCaseCmd.ts similarity index 81% rename from backend/src/plugins/ModActions/functions/actualCommands/actualHideCaseCmd.ts rename to backend/src/plugins/ModActions/commands/hidecase/actualHideCaseCmd.ts index 28527b4d..49bee81b 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualHideCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/hidecase/actualHideCaseCmd.ts @@ -1,6 +1,5 @@ import { ChatInputCommandInteraction, Message } from "discord.js"; import { GuildPluginData } from "knub"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { ModActionsPluginType } from "../../types"; export async function actualHideCaseCmd( @@ -21,7 +20,7 @@ export async function actualHideCaseCmd( } if (failed.length === caseNumbers.length) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "None of the cases were found!"); + pluginData.state.common.sendErrorMessage(context, "None of the cases were found!"); return; } const failedAddendum = @@ -30,9 +29,7 @@ export async function actualHideCaseCmd( : ""; const amt = caseNumbers.length - failed.length; - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + pluginData.state.common.sendSuccessMessage( context, `${amt} case${amt === 1 ? " is" : "s are"} now hidden! Use \`unhidecase\` to unhide them.${failedAddendum}`, ); diff --git a/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts b/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts index fb2754e0..c494a7c7 100644 --- a/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts @@ -1,8 +1,7 @@ import { hasPermission } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualKickCmd } from "../../functions/actualCommands/actualKickCmd"; +import { actualKickCmd } from "./actualKickCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; @@ -30,7 +29,7 @@ export const KickMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } @@ -38,7 +37,7 @@ export const KickMsgCmd = modActionsMsgCmd({ let mod = msg.member; if (args.mod) { if (!(await hasPermission(await pluginData.config.getForMessage(msg), "can_act_as_other"))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -49,7 +48,7 @@ export const KickMsgCmd = modActionsMsgCmd({ try { contactMethods = readContactMethodsFromArgs(args); } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + pluginData.state.common.sendErrorMessage(msg, e.message); return; } diff --git a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts index 4776d093..5bd94f30 100644 --- a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts @@ -3,8 +3,7 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualKickCmd } from "../../functions/actualCommands/actualKickCmd"; +import { actualKickCmd } from "./actualKickCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -51,9 +50,13 @@ export const KickSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } @@ -66,9 +69,10 @@ export const KickSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } @@ -79,7 +83,7 @@ export const KickSlashCmd = modActionsSlashCmd({ try { contactMethods = readContactMethodsFromArgs(options) ?? undefined; } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); + pluginData.state.common.sendErrorMessage(interaction, e.message); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts b/backend/src/plugins/ModActions/commands/kick/actualKickCmd.ts similarity index 72% rename from backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts rename to backend/src/plugins/ModActions/commands/kick/actualKickCmd.ts index f8ad0158..4a6b22a4 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/actualKickCmd.ts @@ -3,13 +3,12 @@ import { GuildPluginData } from "knub"; import { LogType } from "../../../../data/LogType"; import { canActOn } from "../../../../pluginUtils"; import { DAYS, SECONDS, UnknownUser, UserNotificationMethod, renderUsername, resolveMember } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; -import { ignoreEvent } from "../ignoreEvent"; -import { isBanned } from "../isBanned"; -import { kickMember } from "../kickMember"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { ignoreEvent } from "../../functions/ignoreEvent"; +import { isBanned } from "../../functions/isBanned"; +import { kickMember } from "../../functions/kickMember"; export async function actualKickCmd( pluginData: GuildPluginData, @@ -31,9 +30,9 @@ export async function actualKickCmd( if (!memberToKick) { const banned = await isBanned(pluginData, user.id); if (banned) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `User is banned`); + pluginData.state.common.sendErrorMessage(context, `User is banned`); } else { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `User not found on the server`); + pluginData.state.common.sendErrorMessage(context, `User not found on the server`); } return; @@ -41,7 +40,7 @@ export async function actualKickCmd( // Make sure we're allowed to kick this member if (!canActOn(pluginData, author, memberToKick)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Cannot kick: insufficient permissions"); + pluginData.state.common.sendErrorMessage(context, "Cannot kick: insufficient permissions"); return; } @@ -63,7 +62,7 @@ export async function actualKickCmd( try { await memberToKick.ban({ deleteMessageSeconds: (1 * DAYS) / SECONDS, reason: "kick -clean" }); } catch { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Failed to ban the user to clean messages (-clean)"); + pluginData.state.common.sendErrorMessage(context, "Failed to ban the user to clean messages (-clean)"); } pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_UNBAN, memberToKick.id); @@ -72,14 +71,14 @@ export async function actualKickCmd( try { await pluginData.guild.bans.remove(memberToKick.id, "kick -clean"); } catch { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "Failed to unban the user after banning them (-clean)"); + pluginData.state.common.sendErrorMessage( + context, + "Failed to unban the user after banning them (-clean)"); } } if (kickResult.status === "failed") { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Failed to kick user`); + pluginData.state.common.sendErrorMessage(context, `Failed to kick user`); return; } @@ -87,5 +86,5 @@ export async function actualKickCmd( let response = `Kicked **${renderUsername(memberToKick.user)}** (Case #${kickResult.case.case_number})`; if (kickResult.notifyResult.text) response += ` (${kickResult.notifyResult.text})`; - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, response); + pluginData.state.common.sendSuccessMessage(context, response); } diff --git a/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts b/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts index d2f72c70..d47c61d5 100644 --- a/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts @@ -1,8 +1,7 @@ import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMassBanCmd } from "../../functions/actualCommands/actualMassBanCmd"; +import { actualMassBanCmd } from "./actualMassBanCmd"; import { modActionsMsgCmd } from "../../types"; export const MassBanMsgCmd = modActionsMsgCmd({ @@ -22,7 +21,7 @@ export const MassBanMsgCmd = modActionsMsgCmd({ const banReasonReply = await waitForReply(pluginData.client, await getContextChannel(msg), msg.author.id); if (!banReasonReply || !banReasonReply.content || banReasonReply.content.toLowerCase().trim() === "cancel") { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cancelled"); + pluginData.state.common.sendErrorMessage(msg, "Cancelled"); return; } diff --git a/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts index de374434..a358893e 100644 --- a/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts @@ -1,8 +1,7 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMassBanCmd } from "../../functions/actualCommands/actualMassBanCmd"; +import { actualMassBanCmd } from "./actualMassBanCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -31,9 +30,13 @@ export const MassBanSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts b/backend/src/plugins/ModActions/commands/massban/actualMassBanCmd.ts similarity index 85% rename from backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts rename to backend/src/plugins/ModActions/commands/massban/actualMassBanCmd.ts index fcb9610d..207194df 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/actualMassBanCmd.ts @@ -6,12 +6,11 @@ import { humanizeDurationShort } from "../../../../humanizeDurationShort"; import { canActOn, getContextChannel, isContextInteraction, sendContextResponse } from "../../../../pluginUtils"; import { DAYS, MINUTES, SECONDS, noop } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; -import { ignoreEvent } from "../ignoreEvent"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { ignoreEvent } from "../../functions/ignoreEvent"; export async function actualMassBanCmd( pluginData: GuildPluginData, @@ -23,7 +22,7 @@ export async function actualMassBanCmd( ) { // Limit to 100 users at once (arbitrary?) if (userIds.length > 100) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Can only massban max 100 users at once`); + pluginData.state.common.sendErrorMessage(context, `Can only massban max 100 users at once`); return; } @@ -38,9 +37,9 @@ export async function actualMassBanCmd( for (const userId of userIds) { const member = pluginData.guild.members.cache.get(userId as Snowflake); // TODO: Get members on demand? if (member && !canActOn(pluginData, author, member)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "Cannot massban one or more users: insufficient permissions"); + pluginData.state.common.sendErrorMessage( + context, + "Cannot massban one or more users: insufficient permissions"); return; } } @@ -146,7 +145,7 @@ export async function actualMassBanCmd( const successfulBanCount = userIds.length - failedBans.length; if (successfulBanCount === 0) { // All bans failed - don't create a log entry and notify the user - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "All bans failed. Make sure the IDs are valid."); + pluginData.state.common.sendErrorMessage(context, "All bans failed. Make sure the IDs are valid."); } else { // Some or all bans were successful. Create a log entry for the mass ban and notify the user. pluginData.getPlugin(LogsPlugin).logMassBan({ @@ -156,18 +155,17 @@ export async function actualMassBanCmd( }); if (failedBans.length) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - context, - `Banned ${successfulBanCount} users in ${formattedTimeTaken}, ${ - failedBans.length - } failed: ${failedBans.join(" ")}`, - ); + pluginData.state.common.sendSuccessMessage( + context, + `Banned ${successfulBanCount} users in ${formattedTimeTaken}, ${ + failedBans.length + } failed: ${failedBans.join(" ")}`, + ); } else { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(context, `Banned ${successfulBanCount} users successfully in ${formattedTimeTaken}`); + pluginData.state.common.sendSuccessMessage( + context, + `Banned ${successfulBanCount} users successfully in ${formattedTimeTaken}` + ); } } }); diff --git a/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts index 713e89dd..bbcfd715 100644 --- a/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts @@ -1,8 +1,7 @@ import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMassMuteCmd } from "../../functions/actualCommands/actualMassMuteCmd"; +import { actualMassMuteCmd } from "./actualMassMuteCmd"; import { modActionsMsgCmd } from "../../types"; export const MassMuteMsgCmd = modActionsMsgCmd({ @@ -25,7 +24,7 @@ export const MassMuteMsgCmd = modActionsMsgCmd({ !muteReasonReceived.content || muteReasonReceived.content.toLowerCase().trim() === "cancel" ) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cancelled"); + pluginData.state.common.sendErrorMessage(msg, "Cancelled"); return; } diff --git a/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts index ecdadbc7..d7ad927a 100644 --- a/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts @@ -1,8 +1,7 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMassMuteCmd } from "../../functions/actualCommands/actualMassMuteCmd"; +import { actualMassMuteCmd } from "./actualMassMuteCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -31,9 +30,13 @@ export const MassMuteSlashSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts b/backend/src/plugins/ModActions/commands/massmute/actualMassMuteCmd.ts similarity index 80% rename from backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts rename to backend/src/plugins/ModActions/commands/massmute/actualMassMuteCmd.ts index 53a82421..e8ed7111 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/actualMassMuteCmd.ts @@ -3,12 +3,11 @@ import { GuildPluginData } from "knub"; import { LogType } from "../../../../data/LogType"; import { logger } from "../../../../logger"; import { canActOn, isContextInteraction, sendContextResponse } from "../../../../pluginUtils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; import { ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; export async function actualMassMuteCmd( pluginData: GuildPluginData, @@ -20,7 +19,7 @@ export async function actualMassMuteCmd( ) { // Limit to 100 users at once (arbitrary?) if (userIds.length > 100) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Can only massmute max 100 users at once`); + pluginData.state.common.sendErrorMessage(context, `Can only massmute max 100 users at once`); return; } @@ -35,9 +34,10 @@ export async function actualMassMuteCmd( for (const userId of userIds) { const member = pluginData.guild.members.cache.get(userId as Snowflake); if (member && !canActOn(pluginData, author, member)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "Cannot massmute one or more users: insufficient permissions"); + pluginData.state.common.sendErrorMessage( + context, + "Cannot massmute one or more users: insufficient permissions" + ); return; } } @@ -77,7 +77,7 @@ export async function actualMassMuteCmd( const successfulMuteCount = userIds.length - failedMutes.length; if (successfulMuteCount === 0) { // All mutes failed - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "All mutes failed. Make sure the IDs are valid."); + pluginData.state.common.sendErrorMessage(context, "All mutes failed. Make sure the IDs are valid."); } else { // Success on all or some mutes pluginData.getPlugin(LogsPlugin).logMassMute({ @@ -86,14 +86,12 @@ export async function actualMassMuteCmd( }); if (failedMutes.length) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + pluginData.state.common.sendSuccessMessage( context, `Muted ${successfulMuteCount} users, ${failedMutes.length} failed: ${failedMutes.join(" ")}`, ); } else { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, `Muted ${successfulMuteCount} users successfully`); + pluginData.state.common.sendSuccessMessage(context, `Muted ${successfulMuteCount} users successfully`); } } } diff --git a/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts b/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts index 121be1cb..c10df41f 100644 --- a/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts @@ -1,8 +1,7 @@ import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMassUnbanCmd } from "../../functions/actualCommands/actualMassUnbanCmd"; +import { actualMassUnbanCmd } from "./actualMassUnbanCmd"; import { modActionsMsgCmd } from "../../types"; export const MassUnbanMsgCmd = modActionsMsgCmd({ @@ -21,7 +20,7 @@ export const MassUnbanMsgCmd = modActionsMsgCmd({ sendContextResponse(msg, "Unban reason? `cancel` to cancel"); const unbanReasonReply = await waitForReply(pluginData.client, await getContextChannel(msg), msg.author.id); if (!unbanReasonReply || !unbanReasonReply.content || unbanReasonReply.content.toLowerCase().trim() === "cancel") { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cancelled"); + pluginData.state.common.sendErrorMessage(msg, "Cancelled"); return; } diff --git a/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts index 1a2cf558..4a733552 100644 --- a/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts @@ -1,8 +1,7 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMassUnbanCmd } from "../../functions/actualCommands/actualMassUnbanCmd"; +import { actualMassUnbanCmd } from "./actualMassUnbanCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -31,9 +30,13 @@ export const MassUnbanSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/massunban/actualMassUnbanCmd.ts similarity index 84% rename from backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts rename to backend/src/plugins/ModActions/commands/massunban/actualMassUnbanCmd.ts index 8cf1b4ac..6f4a0ebf 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/actualMassUnbanCmd.ts @@ -5,13 +5,12 @@ import { LogType } from "../../../../data/LogType"; import { isContextInteraction, sendContextResponse } from "../../../../pluginUtils"; import { MINUTES, noop } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; -import { ignoreEvent } from "../ignoreEvent"; -import { isBanned } from "../isBanned"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { ignoreEvent } from "../../functions/ignoreEvent"; +import { isBanned } from "../../functions/isBanned"; export async function actualMassUnbanCmd( pluginData: GuildPluginData, @@ -23,7 +22,7 @@ export async function actualMassUnbanCmd( ) { // Limit to 100 users at once (arbitrary?) if (userIds.length > 100) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Can only mass-unban max 100 users at once`); + pluginData.state.common.sendErrorMessage(context, `Can only mass-unban max 100 users at once`); return; } @@ -76,9 +75,10 @@ export async function actualMassUnbanCmd( const successfulUnbanCount = userIds.length - failedUnbans.length; if (successfulUnbanCount === 0) { // All unbans failed - don't create a log entry and notify the user - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "All unbans failed. Make sure the IDs are valid and banned."); + pluginData.state.common.sendErrorMessage( + context, + "All unbans failed. Make sure the IDs are valid and banned." + ); } else { // Some or all unbans were successful. Create a log entry for the mass unban and notify the user. pluginData.getPlugin(LogsPlugin).logMassUnban({ @@ -105,16 +105,12 @@ export async function actualMassUnbanCmd( }); } - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + pluginData.state.common.sendSuccessMessage( context, `Unbanned ${successfulUnbanCount} users, ${failedUnbans.length} failed:\n${failedMsg}`, ); } else { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(context, `Unbanned ${successfulUnbanCount} users successfully`); + pluginData.state.common.sendSuccessMessage(context, `Unbanned ${successfulUnbanCount} users successfully`); } } } diff --git a/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts index 469d7162..d6aeb284 100644 --- a/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts @@ -2,8 +2,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; +import { actualMuteCmd } from "./actualMuteCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; @@ -38,7 +37,7 @@ export const MuteMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } @@ -48,9 +47,10 @@ export const MuteMsgCmd = modActionsMsgCmd({ const _isBanned = await isBanned(pluginData, user.id); const prefix = pluginData.fullConfig.prefix; if (_isBanned) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.`); + pluginData.state.common.sendErrorMessage( + msg, + `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.` + ); return; } else { // Ask the mod if we should upgrade to a forcemute as the user is not on the server @@ -61,7 +61,7 @@ export const MuteMsgCmd = modActionsMsgCmd({ ); if (!reply) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "User not on server, mute cancelled by moderator"); + pluginData.state.common.sendErrorMessage(msg, "User not on server, mute cancelled by moderator"); return; } } @@ -69,7 +69,7 @@ export const MuteMsgCmd = modActionsMsgCmd({ // Make sure we're allowed to mute this member if (memberToMute && !canActOn(pluginData, msg.member, memberToMute)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot mute: insufficient permissions"); + pluginData.state.common.sendErrorMessage(msg, "Cannot mute: insufficient permissions"); return; } @@ -79,7 +79,7 @@ export const MuteMsgCmd = modActionsMsgCmd({ if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -91,7 +91,7 @@ export const MuteMsgCmd = modActionsMsgCmd({ try { contactMethods = readContactMethodsFromArgs(args); } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + pluginData.state.common.sendErrorMessage(msg, e.message); return; } diff --git a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts index 5913d67e..b662b33d 100644 --- a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts @@ -4,8 +4,7 @@ import { canActOn, hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; +import { actualMuteCmd } from "./actualMuteCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsSlashCmd } from "../../types"; @@ -53,9 +52,10 @@ export const MuteSlashCmd = modActionsSlashCmd({ const _isBanned = await isBanned(pluginData, options.user.id); const prefix = pluginData.fullConfig.prefix; if (_isBanned) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.`); + pluginData.state.common.sendErrorMessage( + interaction, + `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.` + ); return; } else { // Ask the mod if we should upgrade to a forcemute as the user is not on the server @@ -66,9 +66,10 @@ export const MuteSlashCmd = modActionsSlashCmd({ ); if (!reply) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "User not on server, mute cancelled by moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "User not on server, mute cancelled by moderator" + ); return; } } @@ -76,7 +77,7 @@ export const MuteSlashCmd = modActionsSlashCmd({ // Make sure we're allowed to mute this member if (memberToMute && !canActOn(pluginData, interaction.member as GuildMember, memberToMute)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot mute: insufficient permissions"); + pluginData.state.common.sendErrorMessage(interaction, "Cannot mute: insufficient permissions"); return; } @@ -89,9 +90,10 @@ export const MuteSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } @@ -101,7 +103,7 @@ export const MuteSlashCmd = modActionsSlashCmd({ const convertedTime = options.time ? convertDelayStringToMS(options.time) ?? undefined : undefined; if (options.time && !convertedTime) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); + pluginData.state.common.sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } @@ -109,7 +111,7 @@ export const MuteSlashCmd = modActionsSlashCmd({ try { contactMethods = readContactMethodsFromArgs(options) ?? undefined; } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); + pluginData.state.common.sendErrorMessage(interaction, e.message); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts b/backend/src/plugins/ModActions/commands/mute/actualMuteCmd.ts similarity index 85% rename from backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts rename to backend/src/plugins/ModActions/commands/mute/actualMuteCmd.ts index 2cff62ff..6500d072 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/actualMuteCmd.ts @@ -10,12 +10,11 @@ import { isDiscordAPIError, renderUsername, } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; import { MuteResult } from "../../../Mutes/types"; import { ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; /** * The actual function run by both !mute and !forcemute. @@ -57,11 +56,12 @@ export async function actualMuteCmd( }); } catch (e) { if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "Could not mute the user: no mute role set in config"); + pluginData.state.common.sendErrorMessage( + context, + "Could not mute the user: no mute role set in config" + ); } else if (isDiscordAPIError(e) && e.code === 10007) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Could not mute the user: unknown member"); + pluginData.state.common.sendErrorMessage(context, "Could not mute the user: unknown member"); } else { logger.error(`Failed to mute user ${user.id}: ${e.stack}`); if (user.id == null) { @@ -69,7 +69,7 @@ export async function actualMuteCmd( // tslint:disable-next-line:no-console console.trace("[DEBUG] Null user.id for mute"); } - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Could not mute the user"); + pluginData.state.common.sendErrorMessage(context, "Could not mute the user"); } return; @@ -104,5 +104,5 @@ export async function actualMuteCmd( } if (muteResult.notifyResult.text) response += ` (${muteResult.notifyResult.text})`; - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, response); + pluginData.state.common.sendSuccessMessage(context, response); } diff --git a/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts b/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts index 9861702f..2cccbd6d 100644 --- a/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts @@ -1,7 +1,6 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualNoteCmd } from "../../functions/actualCommands/actualNoteCmd"; +import { actualNoteCmd } from "./actualNoteCmd"; import { modActionsMsgCmd } from "../../types"; export const NoteMsgCmd = modActionsMsgCmd({ @@ -17,12 +16,12 @@ export const NoteMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } if (!args.note && msg.attachments.size === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Text or attachment required"); + pluginData.state.common.sendErrorMessage(msg, "Text or attachment required"); return; } diff --git a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts index 8962be11..c13bbb60 100644 --- a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts @@ -1,7 +1,6 @@ import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualNoteCmd } from "../../functions/actualCommands/actualNoteCmd"; +import { actualNoteCmd } from "./actualNoteCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -26,9 +25,13 @@ export const NoteSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.note || options.note.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualNoteCmd.ts b/backend/src/plugins/ModActions/commands/note/actualNoteCmd.ts similarity index 85% rename from backend/src/plugins/ModActions/functions/actualCommands/actualNoteCmd.ts rename to backend/src/plugins/ModActions/commands/note/actualNoteCmd.ts index 06772113..5c70cb04 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualNoteCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/actualNoteCmd.ts @@ -3,11 +3,10 @@ import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../../data/CaseTypes"; import { UnknownUser, renderUsername } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; export async function actualNoteCmd( pluginData: GuildPluginData, @@ -39,9 +38,7 @@ export async function actualNoteCmd( reason, }); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + pluginData.state.common.sendSuccessMessage( context, `Note added on **${userName}** (Case #${createdCase.case_number})`, undefined, diff --git a/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts b/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts index 531efc4a..ec346acc 100644 --- a/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts @@ -1,8 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { hasPermission } from "../../../../pluginUtils"; import { resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualUnbanCmd } from "../../functions/actualCommands/actualUnbanCmd"; +import { actualUnbanCmd } from "./actualUnbanCmd"; import { modActionsMsgCmd } from "../../types"; const opts = { @@ -26,7 +25,7 @@ export const UnbanMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } @@ -34,7 +33,7 @@ export const UnbanMsgCmd = modActionsMsgCmd({ let mod = msg.member; if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg, channelId: msg.channel.id }))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } diff --git a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts index 954a90ae..a5b0124b 100644 --- a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts @@ -3,8 +3,7 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualUnbanCmd } from "../../functions/actualCommands/actualUnbanCmd"; +import { actualUnbanCmd } from "./actualUnbanCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -30,9 +29,13 @@ export const UnbanSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } @@ -45,9 +48,10 @@ export const UnbanSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualUnbanCmd.ts b/backend/src/plugins/ModActions/commands/unban/actualUnbanCmd.ts similarity index 81% rename from backend/src/plugins/ModActions/functions/actualCommands/actualUnbanCmd.ts rename to backend/src/plugins/ModActions/commands/unban/actualUnbanCmd.ts index 85f9abba..e49b5b21 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/actualUnbanCmd.ts @@ -5,12 +5,11 @@ import { LogType } from "../../../../data/LogType"; import { clearExpiringTempban } from "../../../../data/loops/expiringTempbansLoop"; import { UnknownUser } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; -import { ignoreEvent } from "../ignoreEvent"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { ignoreEvent } from "../../functions/ignoreEvent"; export async function actualUnbanCmd( pluginData: GuildPluginData, @@ -32,9 +31,10 @@ export async function actualUnbanCmd( ignoreEvent(pluginData, IgnoredEventType.Unban, user.id); await pluginData.guild.bans.remove(user.id as Snowflake, formattedReason ?? undefined); } catch { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "Failed to unban member; are you sure they're banned?"); + pluginData.state.common.sendErrorMessage( + context, + "Failed to unban member; are you sure they're banned?" + ); return; } @@ -56,7 +56,7 @@ export async function actualUnbanCmd( } // Confirm the action - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, `Member unbanned (Case #${createdCase.case_number})`); + pluginData.state.common.sendSuccessMessage(context, `Member unbanned (Case #${createdCase.case_number})`); // Log the action pluginData.getPlugin(LogsPlugin).logMemberUnban({ diff --git a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts index 8e71c8e3..308c34f2 100644 --- a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { actualHideCaseCmd } from "../../functions/actualCommands/actualHideCaseCmd"; +import { actualHideCaseCmd } from "../hidecase/actualHideCaseCmd"; import { modActionsMsgCmd } from "../../types"; export const UnhideCaseMsgCmd = modActionsMsgCmd({ diff --git a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts index 2dbdc309..f4b4b80f 100644 --- a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts @@ -1,5 +1,5 @@ import { slashOptions } from "knub"; -import { actualUnhideCaseCmd } from "../../functions/actualCommands/actualUnhideCaseCmd"; +import { actualUnhideCaseCmd } from "./actualUnhideCaseCmd"; import { modActionsSlashCmd } from "../../types"; export const UnhideCaseSlashCmd = modActionsSlashCmd({ diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualUnhideCaseCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/actualUnhideCaseCmd.ts similarity index 73% rename from backend/src/plugins/ModActions/functions/actualCommands/actualUnhideCaseCmd.ts rename to backend/src/plugins/ModActions/commands/unhidecase/actualUnhideCaseCmd.ts index 313261ee..f1e8405e 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualUnhideCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/unhidecase/actualUnhideCaseCmd.ts @@ -1,6 +1,5 @@ import { ChatInputCommandInteraction, Message } from "discord.js"; import { GuildPluginData } from "knub"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { ModActionsPluginType } from "../../types"; export async function actualUnhideCaseCmd( @@ -21,7 +20,7 @@ export async function actualUnhideCaseCmd( } if (failed.length === caseNumbers.length) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "None of the cases were found!"); + pluginData.state.common.sendErrorMessage(context, "None of the cases were found!"); return; } @@ -31,7 +30,8 @@ export async function actualUnhideCaseCmd( : ""; const amt = caseNumbers.length - failed.length; - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(context, `${amt} case${amt === 1 ? " is" : "s are"} no longer hidden!${failedAddendum}`); + pluginData.state.common.sendSuccessMessage( + context, + `${amt} case${amt === 1 ? " is" : "s are"} no longer hidden!${failedAddendum}` + ); } diff --git a/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts index b917d83b..a0654d13 100644 --- a/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts @@ -2,9 +2,8 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; -import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; +import { actualUnmuteCmd } from "./actualUnmuteCmd"; import { isBanned } from "../../functions/isBanned"; import { modActionsMsgCmd } from "../../types"; @@ -36,7 +35,7 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } @@ -50,7 +49,7 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ !hasMuteRole && !memberToUnmute?.isCommunicationDisabled() ) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot unmute: member is not muted"); + pluginData.state.common.sendErrorMessage(msg, "Cannot unmute: member is not muted"); return; } @@ -58,9 +57,10 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ const banned = await isBanned(pluginData, user.id); const prefix = pluginData.fullConfig.prefix; if (banned) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.`); + pluginData.state.common.sendErrorMessage( + msg, + `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.` + ); return; } else { // Ask the mod if we should upgrade to a forceunmute as the user is not on the server @@ -71,7 +71,7 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ ); if (!reply) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "User not on server, unmute cancelled by moderator"); + pluginData.state.common.sendErrorMessage(msg, "User not on server, unmute cancelled by moderator"); return; } } @@ -79,7 +79,7 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ // Make sure we're allowed to unmute this member if (memberToUnmute && !canActOn(pluginData, msg.member, memberToUnmute)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot unmute: insufficient permissions"); + pluginData.state.common.sendErrorMessage(msg, "Cannot unmute: insufficient permissions"); return; } @@ -89,7 +89,7 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } diff --git a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts index b3ab730c..609c7451 100644 --- a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts @@ -4,9 +4,8 @@ import { canActOn, hasPermission } from "../../../../pluginUtils"; import { convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; -import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; +import { actualUnmuteCmd } from "./actualUnmuteCmd"; import { isBanned } from "../../functions/isBanned"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -34,9 +33,13 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } @@ -51,7 +54,7 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ !hasMuteRole && !memberToUnmute?.isCommunicationDisabled() ) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot unmute: member is not muted"); + pluginData.state.common.sendErrorMessage(interaction, "Cannot unmute: member is not muted"); return; } @@ -59,9 +62,10 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ const banned = await isBanned(pluginData, options.user.id); const prefix = pluginData.fullConfig.prefix; if (banned) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.`); + pluginData.state.common.sendErrorMessage( + interaction, + `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.` + ); return; } else { // Ask the mod if we should upgrade to a forceunmute as the user is not on the server @@ -72,9 +76,10 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ ); if (!reply) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "User not on server, unmute cancelled by moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "User not on server, unmute cancelled by moderator" + ); return; } } @@ -82,7 +87,7 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ // Make sure we're allowed to unmute this member if (memberToUnmute && !canActOn(pluginData, interaction.member as GuildMember, memberToUnmute)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot unmute: insufficient permissions"); + pluginData.state.common.sendErrorMessage(interaction, "Cannot unmute: insufficient permissions"); return; } @@ -95,9 +100,10 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } @@ -107,7 +113,7 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ const convertedTime = options.time ? convertDelayStringToMS(options.time) ?? undefined : undefined; if (options.time && !convertedTime) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); + pluginData.state.common.sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts b/backend/src/plugins/ModActions/commands/unmute/actualUnmuteCmd.ts similarity index 81% rename from backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts rename to backend/src/plugins/ModActions/commands/unmute/actualUnmuteCmd.ts index 11a668b4..3e3be312 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/actualUnmuteCmd.ts @@ -2,11 +2,10 @@ import { Attachment, ChatInputCommandInteraction, GuildMember, Message, User } f import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { UnknownUser, asSingleLine, renderUsername } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; import { ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; export async function actualUnmuteCmd( pluginData: GuildPluginData, @@ -35,14 +34,14 @@ export async function actualUnmuteCmd( }); if (!result) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "User is not muted!"); + pluginData.state.common.sendErrorMessage(context, "User is not muted!"); return; } // Confirm the action to the moderator if (time) { const timeUntilUnmute = time && humanizeDuration(time); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage( + pluginData.state.common.sendSuccessMessage( context, asSingleLine(` Unmuting **${renderUsername(user)}** @@ -50,7 +49,7 @@ export async function actualUnmuteCmd( `), ); } else { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage( + pluginData.state.common.sendSuccessMessage( context, asSingleLine(` Unmuted **${renderUsername(user)}** diff --git a/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts index d6175356..1d9e331f 100644 --- a/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts @@ -1,8 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { errorMessage, resolveMember, resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualWarnCmd } from "../../functions/actualCommands/actualWarnCmd"; +import { actualWarnCmd } from "./actualWarnCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; @@ -24,7 +23,7 @@ export const WarnMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + await pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } @@ -33,9 +32,9 @@ export const WarnMsgCmd = modActionsMsgCmd({ if (!memberToWarn) { const _isBanned = await isBanned(pluginData, user.id); if (_isBanned) { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User is banned`); + await pluginData.state.common.sendErrorMessage(msg, `User is banned`); } else { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found on the server`); + await pluginData.state.common.sendErrorMessage(msg, `User not found on the server`); } return; @@ -43,7 +42,7 @@ export const WarnMsgCmd = modActionsMsgCmd({ // Make sure we're allowed to warn this member if (!canActOn(pluginData, msg.member, memberToWarn)) { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot warn: insufficient permissions"); + await pluginData.state.common.sendErrorMessage(msg, "Cannot warn: insufficient permissions"); return; } @@ -62,7 +61,7 @@ export const WarnMsgCmd = modActionsMsgCmd({ try { contactMethods = readContactMethodsFromArgs(args); } catch (e) { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + await pluginData.state.common.sendErrorMessage(msg, e.message); return; } diff --git a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts index 180d52c8..82f80ba0 100644 --- a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts @@ -3,8 +3,7 @@ import { slashOptions } from "knub"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualWarnCmd } from "../../functions/actualCommands/actualWarnCmd"; +import { actualWarnCmd } from "./actualWarnCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsSlashCmd } from "../../types"; @@ -47,9 +46,13 @@ export const WarnSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - await pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + await pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } @@ -59,9 +62,9 @@ export const WarnSlashCmd = modActionsSlashCmd({ if (!memberToWarn) { const _isBanned = await isBanned(pluginData, options.user.id); if (_isBanned) { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `User is banned`); + await pluginData.state.common.sendErrorMessage(interaction, `User is banned`); } else { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `User not found on the server`); + await pluginData.state.common.sendErrorMessage(interaction, `User not found on the server`); } return; @@ -69,7 +72,7 @@ export const WarnSlashCmd = modActionsSlashCmd({ // Make sure we're allowed to warn this member if (!canActOn(pluginData, interaction.member as GuildMember, memberToWarn)) { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot warn: insufficient permissions"); + await pluginData.state.common.sendErrorMessage(interaction, "Cannot warn: insufficient permissions"); return; } @@ -81,9 +84,10 @@ export const WarnSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - await pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + await pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } @@ -94,7 +98,7 @@ export const WarnSlashCmd = modActionsSlashCmd({ try { contactMethods = readContactMethodsFromArgs(options) ?? undefined; } catch (e) { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); + await pluginData.state.common.sendErrorMessage(interaction, e.message); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts b/backend/src/plugins/ModActions/commands/warn/actualWarnCmd.ts similarity index 83% rename from backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts rename to backend/src/plugins/ModActions/commands/warn/actualWarnCmd.ts index ac43d8df..c764d29d 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/actualWarnCmd.ts @@ -4,11 +4,10 @@ import { CaseTypes } from "../../../../data/CaseTypes"; import { UserNotificationMethod, renderUsername } from "../../../../utils"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; -import { warnMember } from "../warnMember"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { warnMember } from "../../functions/warnMember"; export async function actualWarnCmd( pluginData: GuildPluginData, @@ -37,7 +36,7 @@ export async function actualWarnCmd( { confirmText: "Yes", cancelText: "No", restrictToId: authorId }, ); if (!reply) { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Warn cancelled by moderator"); + await pluginData.state.common.sendErrorMessage(context, "Warn cancelled by moderator"); return; } } @@ -55,16 +54,14 @@ export async function actualWarnCmd( if (warnResult.status === "failed") { const failReason = warnResult.error ? `: ${warnResult.error}` : ""; - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Failed to warn user${failReason}`); + await pluginData.state.common.sendErrorMessage(context, `Failed to warn user${failReason}`); return; } const messageResultText = warnResult.notifyResult.text ? ` (${warnResult.notifyResult.text})` : ""; - await pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + await pluginData.state.common.sendSuccessMessage( context, `Warned **${renderUsername(memberToWarn.user)}** (Case #${warnResult.case.case_number})${messageResultText}`, ); diff --git a/backend/src/plugins/ModActions/functions/attachmentLinkReaction.ts b/backend/src/plugins/ModActions/functions/attachmentLinkReaction.ts index 868786ed..b10e063e 100644 --- a/backend/src/plugins/ModActions/functions/attachmentLinkReaction.ts +++ b/backend/src/plugins/ModActions/functions/attachmentLinkReaction.ts @@ -1,6 +1,5 @@ import { ChatInputCommandInteraction, Message, TextBasedChannel } from "discord.js"; import { AnyPluginData, GuildPluginData } from "knub"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { ModActionsPluginType } from "../types"; export function shouldReactToAttachmentLink(pluginData: GuildPluginData) { @@ -22,16 +21,14 @@ export function sendAttachmentLinkDetectionErrorMessage( context: TextBasedChannel | Message | ChatInputCommandInteraction, restricted = false, ) { - const emoji = pluginData.getPlugin(CommonPlugin).getErrorEmoji(); + const emoji = pluginData.state.common.getErrorEmoji(); - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( - context, - "You manually added a Discord attachment link to the reason. This link will only work for a limited time.\n" + - "You should instead **re-upload** the attachment with the command, in the same message.\n\n" + - (restricted ? `${emoji} **Command canceled.** ${emoji}` : "").trim(), - ); + pluginData.state.common.sendErrorMessage( + context, + "You manually added a Discord attachment link to the reason. This link will only work for a limited time.\n" + + "You should instead **re-upload** the attachment with the command, in the same message.\n\n" + + (restricted ? `${emoji} **Command canceled.** ${emoji}` : "").trim(), + ); } export async function handleAttachmentLinkDetectionAndGetRestriction( diff --git a/backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts b/backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts index 4cb16e82..8932aa26 100644 --- a/backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts +++ b/backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts @@ -1,4 +1,4 @@ -import { Attachment, ChatInputCommandInteraction, Message, TextBasedChannel } from "discord.js"; +import { Attachment, ChatInputCommandInteraction, Message } from "discord.js"; import { GuildPluginData } from "knub"; import { isContextMessage } from "../../../pluginUtils"; import { ModActionsPluginType } from "../types"; @@ -19,17 +19,9 @@ export async function formatReasonWithMessageLinkForAttachments( return reason; } - const attachmentChannelId = pluginData.config.get().attachment_storing_channel; - const channel = attachmentChannelId - ? (pluginData.guild.channels.cache.get(attachmentChannelId) as TextBasedChannel) ?? context.channel - : context.channel; + const attachmentsMessage = await pluginData.state.common.storeAttachmentsAsMessage(attachments, context.channel); - const message = await channel!.send({ - content: `Storing ${attachments.length} attachment${attachments.length === 1 ? "" : "s"}`, - files: attachments.map((a) => a.url), - }); - - return ((reason || "") + " " + message.url).trim(); + return ((reason || "") + " " + attachmentsMessage.url).trim(); } export function formatReasonWithAttachments(reason: string, attachments: Attachment[]) { diff --git a/backend/src/plugins/ModActions/functions/updateCase.ts b/backend/src/plugins/ModActions/functions/updateCase.ts index e4011fb7..8cfffa98 100644 --- a/backend/src/plugins/ModActions/functions/updateCase.ts +++ b/backend/src/plugins/ModActions/functions/updateCase.ts @@ -3,7 +3,6 @@ import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { ModActionsPluginType } from "../types"; import { handleAttachmentLinkDetectionAndGetRestriction } from "./attachmentLinkReaction"; @@ -25,12 +24,12 @@ export async function updateCase( } if (!theCase) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Case not found"); + pluginData.state.common.sendErrorMessage(context, "Case not found"); return; } if (note.length === 0 && attachments.length === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Text or attachment required"); + pluginData.state.common.sendErrorMessage(context, "Text or attachment required"); return; } @@ -54,5 +53,5 @@ export async function updateCase( note: formattedNote, }); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, `Case \`#${theCase.case_number}\` updated`); + pluginData.state.common.sendSuccessMessage(context, `Case \`#${theCase.case_number}\` updated`); } diff --git a/backend/src/plugins/ModActions/types.ts b/backend/src/plugins/ModActions/types.ts index ee128986..a3f36c11 100644 --- a/backend/src/plugins/ModActions/types.ts +++ b/backend/src/plugins/ModActions/types.ts @@ -1,11 +1,11 @@ import { ChatInputCommandInteraction, Message } from "discord.js"; import { EventEmitter } from "events"; import { - BasePluginType, + BasePluginType, pluginUtils, guildPluginEventListener, guildPluginMessageCommand, guildPluginSlashCommand, - guildPluginSlashGroup, + guildPluginSlashGroup } from "knub"; import z from "zod"; import { Queue } from "../../Queue"; @@ -16,6 +16,7 @@ import { GuildTempbans } from "../../data/GuildTempbans"; import { Case } from "../../data/entities/Case"; import { UserNotificationMethod, UserNotificationResult } from "../../utils"; import { CaseArgs } from "../Cases/types"; +import { CommonPlugin } from "../Common/CommonPlugin"; export type AttachmentLinkReactionType = "none" | "warn" | "restrict" | null; @@ -38,7 +39,6 @@ export const zModActionsConfig = z.strictObject({ warn_notify_message: z.string(), ban_delete_message_days: z.number(), attachment_link_reaction: z.nullable(z.union([z.literal("none"), z.literal("warn"), z.literal("restrict")])), - attachment_storing_channel: z.nullable(z.string()), can_note: z.boolean(), can_warn: z.boolean(), can_mute: z.boolean(), @@ -84,6 +84,8 @@ export interface ModActionsPluginType extends BasePluginType { massbanQueue: Queue; events: ModActionsEventEmitter; + + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/Mutes/MutesPlugin.ts b/backend/src/plugins/Mutes/MutesPlugin.ts index db8548be..c1a8c84b 100644 --- a/backend/src/plugins/Mutes/MutesPlugin.ts +++ b/backend/src/plugins/Mutes/MutesPlugin.ts @@ -24,6 +24,7 @@ import { onMutesEvent } from "./functions/onMutesEvent"; import { renewTimeoutMute } from "./functions/renewTimeoutMute"; import { unmuteUser } from "./functions/unmuteUser"; import { MutesPluginType, zMutesConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions = { config: { @@ -109,6 +110,10 @@ export const MutesPlugin = guildPlugin()({ state.events = new EventEmitter(); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { state, guild } = pluginData; diff --git a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts index 3884ae89..64b77233 100644 --- a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts @@ -25,6 +25,6 @@ export const ClearBannedMutesCmd = mutesCmd({ } } - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Cleared ${cleared} mutes from banned users!`); + void pluginData.state.common.sendSuccessMessage(msg, `Cleared ${cleared} mutes from banned users!`); }, }); diff --git a/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts index a71dc402..b8f75022 100644 --- a/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts @@ -23,15 +23,11 @@ export const ClearMutesCmd = mutesCmd({ } if (failed.length !== args.userIds.length) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `**${args.userIds.length - failed.length} active mute(s) cleared**`); + void pluginData.state.common.sendSuccessMessage(msg, `**${args.userIds.length - failed.length} active mute(s) cleared**`); } if (failed.length) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( + void pluginData.state.common.sendErrorMessage( msg, `**${failed.length}/${args.userIds.length} IDs failed**, they are not muted: ${failed.join(" ")}`, ); diff --git a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts index 1e52f6b3..c5f7be13 100644 --- a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts @@ -26,8 +26,6 @@ export const ClearMutesWithoutRoleCmd = mutesCmd({ } } - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `Cleared ${cleared} mutes from members that don't have the mute role`); + void pluginData.state.common.sendSuccessMessage(msg, `Cleared ${cleared} mutes from members that don't have the mute role`); }, }); diff --git a/backend/src/plugins/Mutes/types.ts b/backend/src/plugins/Mutes/types.ts index e1f266a9..59790782 100644 --- a/backend/src/plugins/Mutes/types.ts +++ b/backend/src/plugins/Mutes/types.ts @@ -1,6 +1,6 @@ import { GuildMember } from "discord.js"; import { EventEmitter } from "events"; -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildArchives } from "../../data/GuildArchives"; import { GuildCases } from "../../data/GuildCases"; @@ -10,6 +10,7 @@ import { Case } from "../../data/entities/Case"; import { Mute } from "../../data/entities/Mute"; import { UserNotificationMethod, UserNotificationResult, zSnowflake } from "../../utils"; import { CaseArgs } from "../Cases/types"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zMutesConfig = z.strictObject({ mute_role: zSnowflake.nullable(), @@ -53,6 +54,8 @@ export interface MutesPluginType extends BasePluginType { unregisterTimeoutMuteToRenewListener: () => void; events: MutesEventEmitter; + + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/NameHistory/NameHistoryPlugin.ts b/backend/src/plugins/NameHistory/NameHistoryPlugin.ts index ee226f3e..f8d5f990 100644 --- a/backend/src/plugins/NameHistory/NameHistoryPlugin.ts +++ b/backend/src/plugins/NameHistory/NameHistoryPlugin.ts @@ -4,6 +4,7 @@ import { GuildNicknameHistory } from "../../data/GuildNicknameHistory"; import { UsernameHistory } from "../../data/UsernameHistory"; import { NamesCmd } from "./commands/NamesCmd"; import { NameHistoryPluginType, zNameHistoryConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -44,4 +45,8 @@ export const NameHistoryPlugin = guildPlugin()({ state.usernameHistory = new UsernameHistory(); state.updateQueue = new Queue(); }, + + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, }); diff --git a/backend/src/plugins/NameHistory/commands/NamesCmd.ts b/backend/src/plugins/NameHistory/commands/NamesCmd.ts index f584857f..9f3bb418 100644 --- a/backend/src/plugins/NameHistory/commands/NamesCmd.ts +++ b/backend/src/plugins/NameHistory/commands/NamesCmd.ts @@ -21,7 +21,7 @@ export const NamesCmd = nameHistoryCmd({ const usernames = await pluginData.state.usernameHistory.getByUserId(args.userId); if (nicknames.length === 0 && usernames.length === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No name history found"); + void pluginData.state.common.sendErrorMessage(msg, "No name history found"); return; } diff --git a/backend/src/plugins/NameHistory/types.ts b/backend/src/plugins/NameHistory/types.ts index 70101b53..df96a56b 100644 --- a/backend/src/plugins/NameHistory/types.ts +++ b/backend/src/plugins/NameHistory/types.ts @@ -1,8 +1,9 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { Queue } from "../../Queue"; import { GuildNicknameHistory } from "../../data/GuildNicknameHistory"; import { UsernameHistory } from "../../data/UsernameHistory"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zNameHistoryConfig = z.strictObject({ can_view: z.boolean(), @@ -14,6 +15,7 @@ export interface NameHistoryPluginType extends BasePluginType { nicknameHistory: GuildNicknameHistory; usernameHistory: UsernameHistory; updateQueue: Queue; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts b/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts index 68dbcd2e..118cf044 100644 --- a/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts +++ b/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts @@ -3,6 +3,7 @@ import { GuildPingableRoles } from "../../data/GuildPingableRoles"; import { PingableRoleDisableCmd } from "./commands/PingableRoleDisableCmd"; import { PingableRoleEnableCmd } from "./commands/PingableRoleEnableCmd"; import { PingableRolesPluginType, zPingableRolesConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -44,4 +45,8 @@ export const PingableRolesPlugin = guildPlugin()({ state.cache = new Map(); state.timeouts = new Map(); }, + + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, }); diff --git a/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts b/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts index 00006cee..3bc1ad58 100644 --- a/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts +++ b/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts @@ -14,17 +14,13 @@ export const PingableRoleDisableCmd = pingableRolesCmd({ async run({ message: msg, args, pluginData }) { const pingableRole = await pluginData.state.pingableRoles.getByChannelAndRoleId(args.channelId, args.role.id); if (!pingableRole) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `**${args.role.name}** is not set as pingable in <#${args.channelId}>`); + void pluginData.state.common.sendErrorMessage(msg, `**${args.role.name}** is not set as pingable in <#${args.channelId}>`); return; } await pluginData.state.pingableRoles.delete(args.channelId, args.role.id); pluginData.state.cache.delete(args.channelId); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `**${args.role.name}** is no longer set as pingable in <#${args.channelId}>`); + void pluginData.state.common.sendSuccessMessage(msg, `**${args.role.name}** is no longer set as pingable in <#${args.channelId}>`); }, }); diff --git a/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts b/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts index 7a93990f..004c0741 100644 --- a/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts +++ b/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts @@ -17,17 +17,13 @@ export const PingableRoleEnableCmd = pingableRolesCmd({ args.role.id, ); if (existingPingableRole) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `**${args.role.name}** is already set as pingable in <#${args.channelId}>`); + void pluginData.state.common.sendErrorMessage(msg, `**${args.role.name}** is already set as pingable in <#${args.channelId}>`); return; } await pluginData.state.pingableRoles.add(args.channelId, args.role.id); pluginData.state.cache.delete(args.channelId); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `**${args.role.name}** has been set as pingable in <#${args.channelId}>`); + void pluginData.state.common.sendSuccessMessage(msg, `**${args.role.name}** has been set as pingable in <#${args.channelId}>`); }, }); diff --git a/backend/src/plugins/PingableRoles/types.ts b/backend/src/plugins/PingableRoles/types.ts index 3bd6faa8..55edd97c 100644 --- a/backend/src/plugins/PingableRoles/types.ts +++ b/backend/src/plugins/PingableRoles/types.ts @@ -1,7 +1,8 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildPingableRoles } from "../../data/GuildPingableRoles"; import { PingableRole } from "../../data/entities/PingableRole"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zPingableRolesConfig = z.strictObject({ can_manage: z.boolean(), @@ -14,6 +15,7 @@ export interface PingableRolesPluginType extends BasePluginType { pingableRoles: GuildPingableRoles; cache: Map; timeouts: Map; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/Post/PostPlugin.ts b/backend/src/plugins/Post/PostPlugin.ts index 0deb881b..93376dcf 100644 --- a/backend/src/plugins/Post/PostPlugin.ts +++ b/backend/src/plugins/Post/PostPlugin.ts @@ -14,6 +14,7 @@ import { ScheduledPostsListCmd } from "./commands/ScheduledPostsListCmd"; import { ScheduledPostsShowCmd } from "./commands/ScheduledPostsShowCmd"; import { PostPluginType, zPostConfig } from "./types"; import { postScheduledPost } from "./util/postScheduledPost"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -55,6 +56,10 @@ export const PostPlugin = guildPlugin()({ state.logs = new GuildLogs(guild.id); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { state, guild } = pluginData; diff --git a/backend/src/plugins/Post/commands/EditCmd.ts b/backend/src/plugins/Post/commands/EditCmd.ts index cd607aa6..fb785929 100644 --- a/backend/src/plugins/Post/commands/EditCmd.ts +++ b/backend/src/plugins/Post/commands/EditCmd.ts @@ -15,18 +15,18 @@ export const EditCmd = postCmd({ async run({ message: msg, args, pluginData }) { const targetMessage = await args.message.channel.messages.fetch(args.message.messageId); if (!targetMessage) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown message"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown message"); return; } if (targetMessage.author.id !== pluginData.client.user!.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Message wasn't posted by me"); + void pluginData.state.common.sendErrorMessage(msg, "Message wasn't posted by me"); return; } targetMessage.channel.messages.edit(targetMessage.id, { content: formatContent(args.content), }); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Message edited"); + void pluginData.state.common.sendSuccessMessage(msg, "Message edited"); }, }); diff --git a/backend/src/plugins/Post/commands/EditEmbedCmd.ts b/backend/src/plugins/Post/commands/EditEmbedCmd.ts index 7d42c040..4cdfdd8b 100644 --- a/backend/src/plugins/Post/commands/EditEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/EditEmbedCmd.ts @@ -30,14 +30,14 @@ export const EditEmbedCmd = postCmd({ if (colorRgb) { color = rgbToInt(colorRgb); } else { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid color specified"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid color specified"); return; } } const targetMessage = await args.message.channel.messages.fetch(args.message.messageId); if (!targetMessage) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown message"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown message"); return; } @@ -51,12 +51,12 @@ export const EditEmbedCmd = postCmd({ try { parsed = JSON.parse(content); } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Syntax error in embed JSON: ${e.message}`); + void pluginData.state.common.sendErrorMessage(msg, `Syntax error in embed JSON: ${e.message}`); return; } if (!isValidEmbed(parsed)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Embed is not valid"); + void pluginData.state.common.sendErrorMessage(msg, "Embed is not valid"); return; } @@ -69,7 +69,7 @@ export const EditEmbedCmd = postCmd({ args.message.channel.messages.edit(targetMessage.id, { embeds: [embed], }); - await pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Embed edited"); + await pluginData.state.common.sendSuccessMessage(msg, "Embed edited"); if (args.content) { const prefix = pluginData.fullConfig.prefix || "!"; diff --git a/backend/src/plugins/Post/commands/PostEmbedCmd.ts b/backend/src/plugins/Post/commands/PostEmbedCmd.ts index a78abacb..e54649e6 100644 --- a/backend/src/plugins/Post/commands/PostEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/PostEmbedCmd.ts @@ -31,7 +31,7 @@ export const PostEmbedCmd = postCmd({ const content = args.content || args.maincontent; if (!args.title && !content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Title or content required"); + void pluginData.state.common.sendErrorMessage(msg, "Title or content required"); return; } @@ -41,7 +41,7 @@ export const PostEmbedCmd = postCmd({ if (colorRgb) { color = rgbToInt(colorRgb); } else { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid color specified"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid color specified"); return; } } @@ -56,12 +56,12 @@ export const PostEmbedCmd = postCmd({ try { parsed = JSON.parse(content); } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Syntax error in embed JSON: ${e.message}`); + void pluginData.state.common.sendErrorMessage(msg, `Syntax error in embed JSON: ${e.message}`); return; } if (!isValidEmbed(parsed)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Embed is not valid"); + void pluginData.state.common.sendErrorMessage(msg, "Embed is not valid"); return; } diff --git a/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts index 565135e6..d3c6063a 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts @@ -17,12 +17,12 @@ export const ScheduledPostsDeleteCmd = postCmd({ scheduledPosts.sort(sorter("post_at")); const post = scheduledPosts[args.num - 1]; if (!post) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Scheduled post not found"); + void pluginData.state.common.sendErrorMessage(msg, "Scheduled post not found"); return; } clearUpcomingScheduledPost(post); await pluginData.state.scheduledPosts.delete(post.id); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Scheduled post deleted!"); + void pluginData.state.common.sendSuccessMessage(msg, "Scheduled post deleted!"); }, }); diff --git a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts index 2895cc68..a990e6d9 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts @@ -17,7 +17,7 @@ export const ScheduledPostsShowCmd = postCmd({ scheduledPosts.sort(sorter("post_at")); const post = scheduledPosts[args.num - 1]; if (!post) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Scheduled post not found"); + void pluginData.state.common.sendErrorMessage(msg, "Scheduled post not found"); return; } diff --git a/backend/src/plugins/Post/types.ts b/backend/src/plugins/Post/types.ts index e0ec7d2c..7a0a1db7 100644 --- a/backend/src/plugins/Post/types.ts +++ b/backend/src/plugins/Post/types.ts @@ -1,8 +1,9 @@ -import { BasePluginType, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildScheduledPosts } from "../../data/GuildScheduledPosts"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zPostConfig = z.strictObject({ can_post: z.boolean(), @@ -14,6 +15,7 @@ export interface PostPluginType extends BasePluginType { savedMessages: GuildSavedMessages; scheduledPosts: GuildScheduledPosts; logs: GuildLogs; + common: pluginUtils.PluginPublicInterface; unregisterGuildEventListener: () => void; }; diff --git a/backend/src/plugins/Post/util/actualPostCmd.ts b/backend/src/plugins/Post/util/actualPostCmd.ts index 537d469f..b75bcc53 100644 --- a/backend/src/plugins/Post/util/actualPostCmd.ts +++ b/backend/src/plugins/Post/util/actualPostCmd.ts @@ -40,15 +40,11 @@ export async function actualPostCmd( if (opts.repeat) { if (opts.repeat < MIN_REPEAT_TIME) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Minimum time for -repeat is ${humanizeDuration(MIN_REPEAT_TIME)}`); + void pluginData.state.common.sendErrorMessage(msg, `Minimum time for -repeat is ${humanizeDuration(MIN_REPEAT_TIME)}`); return; } if (opts.repeat > MAX_REPEAT_TIME) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Max time for -repeat is ${humanizeDuration(MAX_REPEAT_TIME)}`); + void pluginData.state.common.sendErrorMessage(msg, `Max time for -repeat is ${humanizeDuration(MAX_REPEAT_TIME)}`); return; } } @@ -59,7 +55,7 @@ export async function actualPostCmd( // Schedule the post to be posted later postAt = await parseScheduleTime(pluginData, msg.author.id, opts.schedule); if (!postAt) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid schedule time"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid schedule time"); return; } } else if (opts.repeat) { @@ -76,41 +72,35 @@ export async function actualPostCmd( // Invalid time if (!repeatUntil) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid time specified for -repeat-until"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid time specified for -repeat-until"); return; } if (repeatUntil.isBefore(moment.utc())) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You can't set -repeat-until in the past"); + void pluginData.state.common.sendErrorMessage(msg, "You can't set -repeat-until in the past"); return; } if (repeatUntil.isAfter(MAX_REPEAT_UNTIL)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( - msg, - "Unfortunately, -repeat-until can only be at most 100 years into the future. Maybe 99 years would be enough?", - ); + void pluginData.state.common.sendErrorMessage( + msg, + "Unfortunately, -repeat-until can only be at most 100 years into the future. Maybe 99 years would be enough?", + ); return; } } else if (opts["repeat-times"]) { repeatTimes = opts["repeat-times"]; if (repeatTimes <= 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "-repeat-times must be 1 or more"); + void pluginData.state.common.sendErrorMessage(msg, "-repeat-times must be 1 or more"); return; } } if (repeatUntil && repeatTimes) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "You can only use one of -repeat-until or -repeat-times at once"); + void pluginData.state.common.sendErrorMessage(msg, "You can only use one of -repeat-until or -repeat-times at once"); return; } if (opts.repeat && !repeatUntil && !repeatTimes) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "You must specify -repeat-until or -repeat-times for repeated messages"); + void pluginData.state.common.sendErrorMessage(msg, "You must specify -repeat-until or -repeat-times for repeated messages"); return; } @@ -125,7 +115,7 @@ export async function actualPostCmd( // Save schedule/repeat information in DB if (postAt) { if (postAt < moment.utc()) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Post can't be scheduled to be posted in the past"); + void pluginData.state.common.sendErrorMessage(msg, "Post can't be scheduled to be posted in the past"); return; } @@ -201,6 +191,6 @@ export async function actualPostCmd( } if (targetChannel.id !== msg.channel.id || opts.schedule || opts.repeat) { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, successMessage); + void pluginData.state.common.sendSuccessMessage(msg, successMessage); } } diff --git a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts index 8622b3b9..1848e663 100644 --- a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts +++ b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts @@ -9,6 +9,7 @@ import { RefreshReactionRolesCmd } from "./commands/RefreshReactionRolesCmd"; import { AddReactionRoleEvt } from "./events/AddReactionRoleEvt"; import { MessageDeletedEvt } from "./events/MessageDeletedEvt"; import { ReactionRolesPluginType, zReactionRolesConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const MIN_AUTO_REFRESH = 1000 * 60 * 15; // 15min minimum, let's not abuse the API @@ -63,6 +64,10 @@ export const ReactionRolesPlugin = guildPlugin()({ state.pendingRefreshes = new Set(); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const config = pluginData.config.get(); if (config.button_groups) { diff --git a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts index 1dc632a7..18baef48 100644 --- a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts @@ -15,7 +15,7 @@ export const ClearReactionRolesCmd = reactionRolesCmd({ async run({ message: msg, args, pluginData }) { const existingReactionRoles = pluginData.state.reactionRoles.getForMessage(args.message.messageId); if (!existingReactionRoles) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Message doesn't have reaction roles on it"); + void pluginData.state.common.sendErrorMessage(msg, "Message doesn't have reaction roles on it"); return; } @@ -26,7 +26,7 @@ export const ClearReactionRolesCmd = reactionRolesCmd({ targetMessage = await args.message.channel.messages.fetch(args.message.messageId); } catch (err) { if (isDiscordAPIError(err) && err.code === 50001) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Missing access to the specified message"); + void pluginData.state.common.sendErrorMessage(msg, "Missing access to the specified message"); return; } @@ -35,6 +35,6 @@ export const ClearReactionRolesCmd = reactionRolesCmd({ await targetMessage.reactions.removeAll(); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Reaction roles cleared"); + void pluginData.state.common.sendSuccessMessage(msg, "Reaction roles cleared"); }, }); diff --git a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts index 26d49039..1c166039 100644 --- a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts @@ -34,9 +34,7 @@ export const InitReactionRolesCmd = reactionRolesCmd({ async run({ message: msg, args, pluginData }) { if (!canReadChannel(args.message.channel, msg.member)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "You can't add reaction roles to channels you can't see yourself"); + void pluginData.state.common.sendErrorMessage(msg, "You can't add reaction roles to channels you can't see yourself"); return; } @@ -45,7 +43,7 @@ export const InitReactionRolesCmd = reactionRolesCmd({ targetMessage = await args.message.channel.messages.fetch(args.message.messageId); } catch (e) { if (isDiscordAPIError(e)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Error ${e.code} while getting message: ${e.message}`); + void pluginData.state.common.sendErrorMessage(msg, `Error ${e.code} while getting message: ${e.message}`); return; } @@ -73,26 +71,22 @@ export const InitReactionRolesCmd = reactionRolesCmd({ // Verify the specified emojis and roles are valid and usable for (const pair of emojiRolePairs) { if (pair[0] === CLEAR_ROLES_EMOJI) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `The emoji for clearing roles (${CLEAR_ROLES_EMOJI}) is reserved and cannot be used`); + void pluginData.state.common.sendErrorMessage(msg, `The emoji for clearing roles (${CLEAR_ROLES_EMOJI}) is reserved and cannot be used`); return; } if (!isValidEmoji(pair[0])) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Invalid emoji: ${pair[0]}`); + void pluginData.state.common.sendErrorMessage(msg, `Invalid emoji: ${pair[0]}`); return; } if (!canUseEmoji(pluginData.client, pair[0])) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "I can only use regular emojis and custom emojis from servers I'm on"); + void pluginData.state.common.sendErrorMessage(msg, "I can only use regular emojis and custom emojis from servers I'm on"); return; } if (!pluginData.guild.roles.cache.has(pair[1] as Snowflake)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Unknown role ${pair[1]}`); + void pluginData.state.common.sendErrorMessage(msg, `Unknown role ${pair[1]}`); return; } } @@ -123,11 +117,9 @@ export const InitReactionRolesCmd = reactionRolesCmd({ ); if (errors?.length) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Errors while adding reaction roles:\n${errors.join("\n")}`); + void pluginData.state.common.sendErrorMessage(msg, `Errors while adding reaction roles:\n${errors.join("\n")}`); } else { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Reaction roles added"); + void pluginData.state.common.sendSuccessMessage(msg, "Reaction roles added"); } (await progressMessage).delete().catch(noop); diff --git a/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts index 6d26ff48..fa0e8ac1 100644 --- a/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts @@ -13,12 +13,12 @@ export const RefreshReactionRolesCmd = reactionRolesCmd({ async run({ message: msg, args, pluginData }) { if (pluginData.state.pendingRefreshes.has(`${args.message.channel.id}-${args.message.messageId}`)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Another refresh in progress"); + void pluginData.state.common.sendErrorMessage(msg, "Another refresh in progress"); return; } await refreshReactionRoles(pluginData, args.message.channel.id, args.message.messageId); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Reaction roles refreshed"); + void pluginData.state.common.sendSuccessMessage(msg, "Reaction roles refreshed"); }, }); diff --git a/backend/src/plugins/ReactionRoles/types.ts b/backend/src/plugins/ReactionRoles/types.ts index b955c6fa..c985ece4 100644 --- a/backend/src/plugins/ReactionRoles/types.ts +++ b/backend/src/plugins/ReactionRoles/types.ts @@ -1,8 +1,9 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { Queue } from "../../Queue"; import { GuildReactionRoles } from "../../data/GuildReactionRoles"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zReactionRolesConfig = z.strictObject({ auto_refresh_interval: z.number(), @@ -37,6 +38,8 @@ export interface ReactionRolesPluginType extends BasePluginType { pendingRefreshes: Set; autoRefreshTimeout: NodeJS.Timeout; + + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/Reminders/RemindersPlugin.ts b/backend/src/plugins/Reminders/RemindersPlugin.ts index d43961c3..a6070112 100644 --- a/backend/src/plugins/Reminders/RemindersPlugin.ts +++ b/backend/src/plugins/Reminders/RemindersPlugin.ts @@ -7,6 +7,7 @@ import { RemindersCmd } from "./commands/RemindersCmd"; import { RemindersDeleteCmd } from "./commands/RemindersDeleteCmd"; import { postReminder } from "./functions/postReminder"; import { RemindersPluginType, zRemindersConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -44,6 +45,10 @@ export const RemindersPlugin = guildPlugin()({ state.unloaded = false; }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { state, guild } = pluginData; diff --git a/backend/src/plugins/Reminders/commands/RemindCmd.ts b/backend/src/plugins/Reminders/commands/RemindCmd.ts index 88ceeaa3..d0fb4eb0 100644 --- a/backend/src/plugins/Reminders/commands/RemindCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindCmd.ts @@ -38,7 +38,7 @@ export const RemindCmd = remindersCmd({ // "Delay string" i.e. e.g. "2h30m" const ms = convertDelayStringToMS(args.time); if (ms === null) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid reminder time"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid reminder time"); return; } @@ -46,7 +46,7 @@ export const RemindCmd = remindersCmd({ } if (!reminderTime.isValid() || reminderTime.isBefore(now)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid reminder time"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid reminder time"); return; } @@ -67,8 +67,6 @@ export const RemindCmd = remindersCmd({ pluginData.getPlugin(TimeAndDatePlugin).getDateFormat("pretty_datetime"), ); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `I will remind you in **${timeUntilReminder}** at **${prettyReminderTime}**`); + void pluginData.state.common.sendSuccessMessage(msg, `I will remind you in **${timeUntilReminder}** at **${prettyReminderTime}**`); }, }); diff --git a/backend/src/plugins/Reminders/commands/RemindersCmd.ts b/backend/src/plugins/Reminders/commands/RemindersCmd.ts index 7b2da150..9f6dacc7 100644 --- a/backend/src/plugins/Reminders/commands/RemindersCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindersCmd.ts @@ -12,7 +12,7 @@ export const RemindersCmd = remindersCmd({ async run({ message: msg, pluginData }) { const reminders = await pluginData.state.reminders.getRemindersByUserId(msg.author.id); if (reminders.length === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No reminders"); + void pluginData.state.common.sendErrorMessage(msg, "No reminders"); return; } diff --git a/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts b/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts index 5566a133..7a57f79b 100644 --- a/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts @@ -17,7 +17,7 @@ export const RemindersDeleteCmd = remindersCmd({ reminders.sort(sorter("remind_at")); if (args.num > reminders.length || args.num <= 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown reminder"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown reminder"); return; } @@ -25,6 +25,6 @@ export const RemindersDeleteCmd = remindersCmd({ clearUpcomingReminder(toDelete); await pluginData.state.reminders.delete(toDelete.id); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Reminder deleted"); + void pluginData.state.common.sendSuccessMessage(msg, "Reminder deleted"); }, }); diff --git a/backend/src/plugins/Reminders/types.ts b/backend/src/plugins/Reminders/types.ts index 4356fac0..ee2ad9bb 100644 --- a/backend/src/plugins/Reminders/types.ts +++ b/backend/src/plugins/Reminders/types.ts @@ -1,6 +1,7 @@ -import { BasePluginType, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildReminders } from "../../data/GuildReminders"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zRemindersConfig = z.strictObject({ can_use: z.boolean(), @@ -12,6 +13,7 @@ export interface RemindersPluginType extends BasePluginType { state: { reminders: GuildReminders; tries: Map; + common: pluginUtils.PluginPublicInterface; unregisterGuildEventListener: () => void; diff --git a/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts b/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts index d7f9111a..ecd25e8d 100644 --- a/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts +++ b/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts @@ -6,6 +6,7 @@ import { resetButtonsCmd } from "./commands/resetButtons"; import { onButtonInteraction } from "./events/buttonInteraction"; import { applyAllRoleButtons } from "./functions/applyAllRoleButtons"; import { RoleButtonsPluginType, zRoleButtonsConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const RoleButtonsPlugin = guildPlugin()({ name: "role_buttons", @@ -37,6 +38,10 @@ export const RoleButtonsPlugin = guildPlugin()({ pluginData.state.roleButtons = GuildRoleButtons.getGuildInstance(pluginData.guild.id); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + async afterLoad(pluginData) { await applyAllRoleButtons(pluginData); }, diff --git a/backend/src/plugins/RoleButtons/commands/resetButtons.ts b/backend/src/plugins/RoleButtons/commands/resetButtons.ts index edd99eb0..78b3e6a2 100644 --- a/backend/src/plugins/RoleButtons/commands/resetButtons.ts +++ b/backend/src/plugins/RoleButtons/commands/resetButtons.ts @@ -16,14 +16,12 @@ export const resetButtonsCmd = guildPluginMessageCommand( async run({ pluginData, args, message }) { const config = pluginData.config.get(); if (!config.buttons[args.name]) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(message, `Can't find role buttons with the name "${args.name}"`); + void pluginData.state.common.sendErrorMessage(message, `Can't find role buttons with the name "${args.name}"`); return; } await pluginData.state.roleButtons.deleteRoleButtonItem(args.name); await applyAllRoleButtons(pluginData); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(message, "Done!"); + void pluginData.state.common.sendSuccessMessage(message, "Done!"); }, }); diff --git a/backend/src/plugins/RoleButtons/types.ts b/backend/src/plugins/RoleButtons/types.ts index 95e46f79..42fa6bf9 100644 --- a/backend/src/plugins/RoleButtons/types.ts +++ b/backend/src/plugins/RoleButtons/types.ts @@ -1,10 +1,11 @@ import { ButtonStyle } from "discord.js"; -import { BasePluginType } from "knub"; +import { BasePluginType, pluginUtils } from "knub"; import z from "zod"; import { GuildRoleButtons } from "../../data/GuildRoleButtons"; import { zBoundedCharacters, zBoundedRecord, zMessageContent, zSnowflake } from "../../utils"; import { TooManyComponentsError } from "./functions/TooManyComponentsError"; import { createButtonComponents } from "./functions/createButtonComponents"; +import { CommonPlugin } from "../Common/CommonPlugin"; const zRoleButtonOption = z.strictObject({ role_id: zSnowflake, @@ -109,5 +110,6 @@ export interface RoleButtonsPluginType extends BasePluginType { config: z.infer; state: { roleButtons: GuildRoleButtons; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/Roles/RolesPlugin.ts b/backend/src/plugins/Roles/RolesPlugin.ts index 89b3b6c9..4d4bdbb9 100644 --- a/backend/src/plugins/Roles/RolesPlugin.ts +++ b/backend/src/plugins/Roles/RolesPlugin.ts @@ -7,6 +7,7 @@ import { MassAddRoleCmd } from "./commands/MassAddRoleCmd"; import { MassRemoveRoleCmd } from "./commands/MassRemoveRoleCmd"; import { RemoveRoleCmd } from "./commands/RemoveRoleCmd"; import { RolesPluginType, zRolesConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -50,4 +51,8 @@ export const RolesPlugin = guildPlugin()({ state.logs = new GuildLogs(guild.id); }, + + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, }); diff --git a/backend/src/plugins/Roles/commands/AddRoleCmd.ts b/backend/src/plugins/Roles/commands/AddRoleCmd.ts index a66ff365..66506c9e 100644 --- a/backend/src/plugins/Roles/commands/AddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/AddRoleCmd.ts @@ -19,21 +19,19 @@ export const AddRoleCmd = rolesCmd({ async run({ message: msg, args, pluginData }) { if (!canActOn(pluginData, msg.member, args.member, true)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "Cannot add roles to this user: insufficient permissions"); + void pluginData.state.common.sendErrorMessage(msg, "Cannot add roles to this user: insufficient permissions"); return; } const roleId = await resolveRoleId(pluginData.client, pluginData.guild.id, args.role); if (!roleId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid role id"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid role id"); return; } const config = await pluginData.config.getForMessage(msg); if (!config.assignable_roles.includes(roleId)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot assign that role"); + void pluginData.state.common.sendErrorMessage(msg, "You cannot assign that role"); return; } @@ -43,12 +41,12 @@ export const AddRoleCmd = rolesCmd({ pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unknown role configured for 'roles' plugin: ${roleId}`, }); - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot assign that role"); + void pluginData.state.common.sendErrorMessage(msg, "You cannot assign that role"); return; } if (args.member.roles.cache.has(roleId)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Member already has that role"); + void pluginData.state.common.sendErrorMessage(msg, "Member already has that role"); return; } @@ -60,8 +58,6 @@ export const AddRoleCmd = rolesCmd({ roles: [role], }); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `Added role **${role.name}** to ${verboseUserMention(args.member.user)}!`); + void pluginData.state.common.sendSuccessMessage(msg, `Added role **${role.name}** to ${verboseUserMention(args.member.user)}!`); }, }); diff --git a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts index 05db86ba..991cdcdb 100644 --- a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts @@ -30,22 +30,20 @@ export const MassAddRoleCmd = rolesCmd({ for (const member of members) { if (!canActOn(pluginData, msg.member, member, true)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "Cannot add roles to 1 or more specified members: insufficient permissions"); + void pluginData.state.common.sendErrorMessage(msg, "Cannot add roles to 1 or more specified members: insufficient permissions"); return; } } const roleId = await resolveRoleId(pluginData.client, pluginData.guild.id, args.role); if (!roleId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid role id"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid role id"); return; } const config = await pluginData.config.getForMessage(msg); if (!config.assignable_roles.includes(roleId)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot assign that role"); + void pluginData.state.common.sendErrorMessage(msg, "You cannot assign that role"); return; } @@ -54,7 +52,7 @@ export const MassAddRoleCmd = rolesCmd({ pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unknown role configured for 'roles' plugin: ${roleId}`, }); - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot assign that role"); + void pluginData.state.common.sendErrorMessage(msg, "You cannot assign that role"); return; } diff --git a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts index 06a5337d..6ba75d53 100644 --- a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts @@ -29,22 +29,20 @@ export const MassRemoveRoleCmd = rolesCmd({ for (const member of members) { if (!canActOn(pluginData, msg.member, member, true)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "Cannot add roles to 1 or more specified members: insufficient permissions"); + void pluginData.state.common.sendErrorMessage(msg, "Cannot add roles to 1 or more specified members: insufficient permissions"); return; } } const roleId = await resolveRoleId(pluginData.client, pluginData.guild.id, args.role); if (!roleId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid role id"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid role id"); return; } const config = await pluginData.config.getForMessage(msg); if (!config.assignable_roles.includes(roleId)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot remove that role"); + void pluginData.state.common.sendErrorMessage(msg, "You cannot remove that role"); return; } @@ -53,7 +51,7 @@ export const MassRemoveRoleCmd = rolesCmd({ pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unknown role configured for 'roles' plugin: ${roleId}`, }); - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot remove that role"); + void pluginData.state.common.sendErrorMessage(msg, "You cannot remove that role"); return; } diff --git a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts index e3dc979d..d1b8a7fa 100644 --- a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts @@ -19,21 +19,19 @@ export const RemoveRoleCmd = rolesCmd({ async run({ message: msg, args, pluginData }) { if (!canActOn(pluginData, msg.member, args.member, true)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "Cannot remove roles from this user: insufficient permissions"); + void pluginData.state.common.sendErrorMessage(msg, "Cannot remove roles from this user: insufficient permissions"); return; } const roleId = await resolveRoleId(pluginData.client, pluginData.guild.id, args.role); if (!roleId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid role id"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid role id"); return; } const config = await pluginData.config.getForMessage(msg); if (!config.assignable_roles.includes(roleId)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot remove that role"); + void pluginData.state.common.sendErrorMessage(msg, "You cannot remove that role"); return; } @@ -43,12 +41,12 @@ export const RemoveRoleCmd = rolesCmd({ pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unknown role configured for 'roles' plugin: ${roleId}`, }); - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot remove that role"); + void pluginData.state.common.sendErrorMessage(msg, "You cannot remove that role"); return; } if (!args.member.roles.cache.has(roleId)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Member doesn't have that role"); + void pluginData.state.common.sendErrorMessage(msg, "Member doesn't have that role"); return; } @@ -59,8 +57,6 @@ export const RemoveRoleCmd = rolesCmd({ roles: [role], }); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `Removed role **${role.name}** from ${verboseUserMention(args.member.user)}!`); + void pluginData.state.common.sendSuccessMessage(msg, `Removed role **${role.name}** from ${verboseUserMention(args.member.user)}!`); }, }); diff --git a/backend/src/plugins/Roles/types.ts b/backend/src/plugins/Roles/types.ts index caf55b76..c3f48670 100644 --- a/backend/src/plugins/Roles/types.ts +++ b/backend/src/plugins/Roles/types.ts @@ -1,6 +1,7 @@ -import { BasePluginType, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildLogs } from "../../data/GuildLogs"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zRolesConfig = z.strictObject({ can_assign: z.boolean(), @@ -12,6 +13,7 @@ export interface RolesPluginType extends BasePluginType { config: z.infer; state: { logs: GuildLogs; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts b/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts index 9a9e770c..a6a823d8 100644 --- a/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts +++ b/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts @@ -3,6 +3,7 @@ import { RoleAddCmd } from "./commands/RoleAddCmd"; import { RoleHelpCmd } from "./commands/RoleHelpCmd"; import { RoleRemoveCmd } from "./commands/RoleRemoveCmd"; import { SelfGrantableRolesPluginType, zSelfGrantableRolesConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -27,4 +28,8 @@ export const SelfGrantableRolesPlugin = guildPlugin Unknown ${args.roleNames.length === 1 ? "role" : "roles"}`, { - users: [msg.author.id], - }); + void pluginData.state.common.sendErrorMessage(msg, `<@!${msg.author.id}> Unknown ${args.roleNames.length === 1 ? "role" : "roles"}`, { + users: [msg.author.id], + }); lock.unlock(); return; } @@ -83,11 +81,9 @@ export const RoleAddCmd = selfGrantableRolesCmd({ roles: Array.from(newRoleIds) as Snowflake[], }); } catch { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `<@!${msg.author.id}> Got an error while trying to grant you the roles`, { - users: [msg.author.id], - }); + void pluginData.state.common.sendErrorMessage(msg, `<@!${msg.author.id}> Got an error while trying to grant you the roles`, { + users: [msg.author.id], + }); return; } @@ -118,7 +114,7 @@ export const RoleAddCmd = selfGrantableRolesCmd({ messageParts.push("couldn't recognize some of the roles"); } - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `<@!${msg.author.id}> ${messageParts.join("; ")}`, { + void pluginData.state.common.sendSuccessMessage(msg, `<@!${msg.author.id}> ${messageParts.join("; ")}`, { users: [msg.author.id], }); diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts index b688203f..11e4a4cd 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts @@ -46,34 +46,26 @@ export const RoleRemoveCmd = selfGrantableRolesCmd({ const removedRolesWord = rolesToRemove.length === 1 ? "role" : "roles"; if (rolesToRemove.length !== roleNames.length) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - msg, - `<@!${msg.author.id}> Removed ${removedRolesStr.join(", ")} ${removedRolesWord};` + - ` couldn't recognize the other roles you mentioned`, - { users: [msg.author.id] }, - ); + void pluginData.state.common.sendSuccessMessage( + msg, + `<@!${msg.author.id}> Removed ${removedRolesStr.join(", ")} ${removedRolesWord};` + + ` couldn't recognize the other roles you mentioned`, + { users: [msg.author.id] }, + ); } else { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `<@!${msg.author.id}> Removed ${removedRolesStr.join(", ")} ${removedRolesWord}`, { - users: [msg.author.id], - }); - } - } catch { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `<@!${msg.author.id}> Got an error while trying to remove the roles`, { + void pluginData.state.common.sendSuccessMessage(msg, `<@!${msg.author.id}> Removed ${removedRolesStr.join(", ")} ${removedRolesWord}`, { users: [msg.author.id], }); - } - } else { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `<@!${msg.author.id}> Unknown ${args.roleNames.length === 1 ? "role" : "roles"}`, { + } + } catch { + void pluginData.state.common.sendSuccessMessage(msg, `<@!${msg.author.id}> Got an error while trying to remove the roles`, { users: [msg.author.id], }); + } + } else { + void pluginData.state.common.sendErrorMessage(msg, `<@!${msg.author.id}> Unknown ${args.roleNames.length === 1 ? "role" : "roles"}`, { + users: [msg.author.id], + }); } lock.unlock(); diff --git a/backend/src/plugins/SelfGrantableRoles/types.ts b/backend/src/plugins/SelfGrantableRoles/types.ts index e3c7a786..7d8c4a0f 100644 --- a/backend/src/plugins/SelfGrantableRoles/types.ts +++ b/backend/src/plugins/SelfGrantableRoles/types.ts @@ -1,6 +1,7 @@ -import { BasePluginType, CooldownManager, guildPluginMessageCommand } from "knub"; +import { BasePluginType, CooldownManager, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { zBoundedCharacters, zBoundedRecord } from "../../utils"; +import { CommonPlugin } from "../Common/CommonPlugin"; const zRoleMap = z.record( zBoundedCharacters(1, 100), @@ -27,6 +28,7 @@ export interface SelfGrantableRolesPluginType extends BasePluginType { config: z.infer; state: { cooldowns: CooldownManager; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/Slowmode/SlowmodePlugin.ts b/backend/src/plugins/Slowmode/SlowmodePlugin.ts index 8e97adb1..8a0b7de9 100644 --- a/backend/src/plugins/Slowmode/SlowmodePlugin.ts +++ b/backend/src/plugins/Slowmode/SlowmodePlugin.ts @@ -12,6 +12,7 @@ import { SlowmodeSetCmd } from "./commands/SlowmodeSetCmd"; import { SlowmodePluginType, zSlowmodeConfig } from "./types"; import { clearExpiredSlowmodes } from "./util/clearExpiredSlowmodes"; import { onMessageCreate } from "./util/onMessageCreate"; +import { CommonPlugin } from "../Common/CommonPlugin"; const BOT_SLOWMODE_CLEAR_INTERVAL = 60 * SECONDS; @@ -63,6 +64,10 @@ export const SlowmodePlugin = guildPlugin()({ state.channelSlowmodeCache = new Map(); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { state } = pluginData; diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts index d3c8cedb..29465e79 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts @@ -22,16 +22,14 @@ export const SlowmodeClearCmd = slowmodeCmd({ async run({ message: msg, args, pluginData }) { const channelSlowmode = await pluginData.state.slowmodes.getChannelSlowmode(args.channel.id); if (!channelSlowmode) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Channel doesn't have slowmode!"); + void pluginData.state.common.sendErrorMessage(msg, "Channel doesn't have slowmode!"); return; } const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; const missingPermissions = getMissingChannelPermissions(me, args.channel, BOT_SLOWMODE_CLEAR_PERMISSIONS); if (missingPermissions) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Unable to clear slowmode. ${missingPermissionError(missingPermissions)}`); + void pluginData.state.common.sendErrorMessage(msg, `Unable to clear slowmode. ${missingPermissionError(missingPermissions)}`); return; } @@ -39,7 +37,7 @@ export const SlowmodeClearCmd = slowmodeCmd({ if (args.channel.type === ChannelType.GuildText) { await clearBotSlowmodeFromUserId(pluginData, args.channel, args.user.id, args.force); } else { - pluginData.getPlugin(CommonPlugin).sendErrorMessage( + void pluginData.state.common.sendErrorMessage( msg, asSingleLine(` Failed to clear slowmode from **${renderUsername(args.user)}** in <#${args.channel.id}>: @@ -49,7 +47,7 @@ export const SlowmodeClearCmd = slowmodeCmd({ return; } } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage( + void pluginData.state.common.sendErrorMessage( msg, asSingleLine(` Failed to clear slowmode from **${renderUsername(args.user)}** in <#${args.channel.id}>: @@ -59,8 +57,6 @@ export const SlowmodeClearCmd = slowmodeCmd({ return; } - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `Slowmode cleared from **${renderUsername(args.user)}** in <#${args.channel.id}>`); + void pluginData.state.common.sendSuccessMessage(msg, `Slowmode cleared from **${renderUsername(args.user)}** in <#${args.channel.id}>`); }, }); diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts index 0d088b43..6f951084 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts @@ -40,9 +40,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ const channel = args.channel || msg.channel; if (!channel.isTextBased() || channel.isThread()) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "Slowmode can only be set on non-thread text-based channels"); + void pluginData.state.common.sendErrorMessage(msg, "Slowmode can only be set on non-thread text-based channels"); return; } @@ -58,25 +56,23 @@ export const SlowmodeSetCmd = slowmodeCmd({ const mode = (args.mode as TMode) || defaultMode; if (!validModes.includes(mode)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "--mode must be 'bot' or 'native'"); + void pluginData.state.common.sendErrorMessage(msg, "--mode must be 'bot' or 'native'"); return; } // Validate durations if (mode === "native" && args.time > MAX_NATIVE_SLOWMODE) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Native slowmode can only be set to 6h or less"); + void pluginData.state.common.sendErrorMessage(msg, "Native slowmode can only be set to 6h or less"); return; } if (mode === "bot" && args.time > MAX_BOT_SLOWMODE) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Sorry, bot managed slowmodes can be at most 100 years long. Maybe 99 would be enough?`); + void pluginData.state.common.sendErrorMessage(msg, `Sorry, bot managed slowmodes can be at most 100 years long. Maybe 99 would be enough?`); return; } if (mode === "bot" && args.time < MIN_BOT_SLOWMODE) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage( + void pluginData.state.common.sendErrorMessage( msg, asSingleLine(` Bot managed slowmode must be 15min or more. @@ -95,9 +91,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ NATIVE_SLOWMODE_PERMISSIONS, ); if (missingPermissions) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Unable to set native slowmode. ${missingPermissionError(missingPermissions)}`); + void pluginData.state.common.sendErrorMessage(msg, `Unable to set native slowmode. ${missingPermissionError(missingPermissions)}`); return; } } @@ -108,9 +102,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ BOT_SLOWMODE_PERMISSIONS, ); if (missingPermissions) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Unable to set bot managed slowmode. ${missingPermissionError(missingPermissions)}`); + void pluginData.state.common.sendErrorMessage(msg, `Unable to set bot managed slowmode. ${missingPermissionError(missingPermissions)}`); return; } } @@ -129,9 +121,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ try { await channel.setRateLimitPerUser(rateLimitSeconds); } catch (e) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Failed to set native slowmode: ${escapeInlineCode(e.message)}`); + void pluginData.state.common.sendErrorMessage(msg, `Failed to set native slowmode: ${escapeInlineCode(e.message)}`); return; } } else { @@ -150,8 +140,6 @@ export const SlowmodeSetCmd = slowmodeCmd({ const humanizedSlowmodeTime = humanizeDuration(args.time); const slowmodeType = mode === "native" ? "native slowmode" : "bot-maintained slowmode"; - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `Set ${humanizedSlowmodeTime} slowmode for <#${channel.id}> (${slowmodeType})`); + void pluginData.state.common.sendSuccessMessage(msg, `Set ${humanizedSlowmodeTime} slowmode for <#${channel.id}> (${slowmodeType})`); }, }); diff --git a/backend/src/plugins/Slowmode/types.ts b/backend/src/plugins/Slowmode/types.ts index 7c8d5b56..73bd3cb8 100644 --- a/backend/src/plugins/Slowmode/types.ts +++ b/backend/src/plugins/Slowmode/types.ts @@ -1,9 +1,10 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildSlowmodes } from "../../data/GuildSlowmodes"; import { SlowmodeChannel } from "../../data/entities/SlowmodeChannel"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zSlowmodeConfig = z.strictObject({ use_native_slowmode: z.boolean(), @@ -21,6 +22,7 @@ export interface SlowmodePluginType extends BasePluginType { clearInterval: NodeJS.Timeout; serverLogs: GuildLogs; channelSlowmodeCache: Map; + common: pluginUtils.PluginPublicInterface; onMessageCreateFn; }; diff --git a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts index 72c86a04..da245eb4 100644 --- a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts +++ b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts @@ -11,16 +11,14 @@ export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) { const hasNativeSlowmode = args.channel.rateLimitPerUser; if (!botSlowmode && hasNativeSlowmode === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Channel is not on slowmode!"); + void pluginData.state.common.sendErrorMessage(msg, "Channel is not on slowmode!"); return; } const me = pluginData.guild.members.cache.get(pluginData.client.user!.id); const missingPermissions = getMissingChannelPermissions(me, args.channel, BOT_SLOWMODE_DISABLE_PERMISSIONS); if (missingPermissions) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Unable to disable slowmode. ${missingPermissionError(missingPermissions)}`); + void pluginData.state.common.sendErrorMessage(msg, `Unable to disable slowmode. ${missingPermissionError(missingPermissions)}`); return; } @@ -39,14 +37,12 @@ export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) { } if (failedUsers.length) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - msg, - `Slowmode disabled! Failed to clear slowmode from the following users:\n\n<@!${failedUsers.join(">\n<@!")}>`, - ); + void pluginData.state.common.sendSuccessMessage( + msg, + `Slowmode disabled! Failed to clear slowmode from the following users:\n\n<@!${failedUsers.join(">\n<@!")}>`, + ); } else { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Slowmode disabled!"); + void pluginData.state.common.sendSuccessMessage(msg, "Slowmode disabled!"); initMsg.delete().catch(noop); } } diff --git a/backend/src/plugins/Starboard/StarboardPlugin.ts b/backend/src/plugins/Starboard/StarboardPlugin.ts index 7e12102c..9888b013 100644 --- a/backend/src/plugins/Starboard/StarboardPlugin.ts +++ b/backend/src/plugins/Starboard/StarboardPlugin.ts @@ -7,6 +7,7 @@ import { StarboardReactionAddEvt } from "./events/StarboardReactionAddEvt"; import { StarboardReactionRemoveAllEvt, StarboardReactionRemoveEvt } from "./events/StarboardReactionRemoveEvts"; import { StarboardPluginType, zStarboardConfig } from "./types"; import { onMessageDelete } from "./util/onMessageDelete"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -50,6 +51,10 @@ export const StarboardPlugin = guildPlugin()({ state.starboardReactions = GuildStarboardReactions.getGuildInstance(guild.id); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { state } = pluginData; diff --git a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts index d074c948..114b293f 100644 --- a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts +++ b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts @@ -19,13 +19,13 @@ export const MigratePinsCmd = starboardCmd({ const config = await pluginData.config.get(); const starboard = config.boards[args.starboardName]; if (!starboard) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown starboard specified"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown starboard specified"); return; } const starboardChannel = pluginData.guild.channels.cache.get(starboard.channel_id as Snowflake); if (!starboardChannel || !(starboardChannel instanceof TextChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Starboard has an unknown/invalid channel id"); + void pluginData.state.common.sendErrorMessage(msg, "Starboard has an unknown/invalid channel id"); return; } @@ -43,8 +43,6 @@ export const MigratePinsCmd = starboardCmd({ await saveMessageToStarboard(pluginData, pin, starboard); } - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `Pins migrated from <#${args.pinChannel.id}> to <#${starboardChannel.id}>!`); + void pluginData.state.common.sendSuccessMessage(msg, `Pins migrated from <#${args.pinChannel.id}> to <#${starboardChannel.id}>!`); }, }); diff --git a/backend/src/plugins/Starboard/types.ts b/backend/src/plugins/Starboard/types.ts index bb8845fe..2e625d5a 100644 --- a/backend/src/plugins/Starboard/types.ts +++ b/backend/src/plugins/Starboard/types.ts @@ -1,9 +1,10 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildStarboardMessages } from "../../data/GuildStarboardMessages"; import { GuildStarboardReactions } from "../../data/GuildStarboardReactions"; import { zBoundedRecord, zSnowflake } from "../../utils"; +import { CommonPlugin } from "../Common/CommonPlugin"; const zStarboardOpts = z.strictObject({ channel_id: zSnowflake, @@ -29,6 +30,7 @@ export interface StarboardPluginType extends BasePluginType { savedMessages: GuildSavedMessages; starboardMessages: GuildStarboardMessages; starboardReactions: GuildStarboardReactions; + common: pluginUtils.PluginPublicInterface; onMessageDeleteFn; }; diff --git a/backend/src/plugins/Tags/TagsPlugin.ts b/backend/src/plugins/Tags/TagsPlugin.ts index 09379d6d..97d667c4 100644 --- a/backend/src/plugins/Tags/TagsPlugin.ts +++ b/backend/src/plugins/Tags/TagsPlugin.ts @@ -20,6 +20,7 @@ import { findTagByName } from "./util/findTagByName"; import { onMessageCreate } from "./util/onMessageCreate"; import { onMessageDelete } from "./util/onMessageDelete"; import { renderTagBody } from "./util/renderTagBody"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -91,6 +92,10 @@ export const TagsPlugin = guildPlugin()({ state.tagFunctions = {}; }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { state } = pluginData; diff --git a/backend/src/plugins/Tags/commands/TagCreateCmd.ts b/backend/src/plugins/Tags/commands/TagCreateCmd.ts index 0ee452f5..8aab9647 100644 --- a/backend/src/plugins/Tags/commands/TagCreateCmd.ts +++ b/backend/src/plugins/Tags/commands/TagCreateCmd.ts @@ -17,7 +17,7 @@ export const TagCreateCmd = tagsCmd({ parseTemplate(args.body); } catch (e) { if (e instanceof TemplateParseError) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Invalid tag syntax: ${e.message}`); + void pluginData.state.common.sendErrorMessage(msg, `Invalid tag syntax: ${e.message}`); return; } else { throw e; @@ -27,6 +27,6 @@ export const TagCreateCmd = tagsCmd({ await pluginData.state.tags.createOrUpdate(args.tag, args.body, msg.author.id); const prefix = pluginData.config.get().prefix; - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Tag set! Use it with: \`${prefix}${args.tag}\``); + void pluginData.state.common.sendSuccessMessage(msg, `Tag set! Use it with: \`${prefix}${args.tag}\``); }, }); diff --git a/backend/src/plugins/Tags/commands/TagDeleteCmd.ts b/backend/src/plugins/Tags/commands/TagDeleteCmd.ts index 174b7b64..618b6796 100644 --- a/backend/src/plugins/Tags/commands/TagDeleteCmd.ts +++ b/backend/src/plugins/Tags/commands/TagDeleteCmd.ts @@ -13,11 +13,11 @@ export const TagDeleteCmd = tagsCmd({ async run({ message: msg, args, pluginData }) { const tag = await pluginData.state.tags.find(args.tag); if (!tag) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No tag with that name"); + void pluginData.state.common.sendErrorMessage(msg, "No tag with that name"); return; } await pluginData.state.tags.delete(args.tag); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Tag deleted!"); + void pluginData.state.common.sendSuccessMessage(msg, "Tag deleted!"); }, }); diff --git a/backend/src/plugins/Tags/commands/TagEvalCmd.ts b/backend/src/plugins/Tags/commands/TagEvalCmd.ts index 580c938b..9cdab774 100644 --- a/backend/src/plugins/Tags/commands/TagEvalCmd.ts +++ b/backend/src/plugins/Tags/commands/TagEvalCmd.ts @@ -29,7 +29,7 @@ export const TagEvalCmd = tagsCmd({ )) as MessageCreateOptions; if (!rendered.content && !rendered.embeds?.length) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Evaluation resulted in an empty text"); + void pluginData.state.common.sendErrorMessage(msg, "Evaluation resulted in an empty text"); return; } @@ -37,7 +37,7 @@ export const TagEvalCmd = tagsCmd({ } catch (e) { const errorMessage = e instanceof TemplateParseError ? e.message : "Internal error"; - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Failed to render tag: ${errorMessage}`); + void pluginData.state.common.sendErrorMessage(msg, `Failed to render tag: ${errorMessage}`); if (!(e instanceof TemplateParseError)) { logger.warn(`Internal error evaluating tag in ${pluginData.guild.id}: ${e}`); diff --git a/backend/src/plugins/Tags/commands/TagSourceCmd.ts b/backend/src/plugins/Tags/commands/TagSourceCmd.ts index 6690f8f7..0a16c41b 100644 --- a/backend/src/plugins/Tags/commands/TagSourceCmd.ts +++ b/backend/src/plugins/Tags/commands/TagSourceCmd.ts @@ -18,18 +18,18 @@ export const TagSourceCmd = tagsCmd({ if (args.delete) { const actualTag = await pluginData.state.tags.find(args.tag); if (!actualTag) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No tag with that name"); + void pluginData.state.common.sendErrorMessage(msg, "No tag with that name"); return; } await pluginData.state.tags.delete(args.tag); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Tag deleted!"); + void pluginData.state.common.sendSuccessMessage(msg, "Tag deleted!"); return; } const tag = await pluginData.state.tags.find(args.tag); if (!tag) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No tag with that name"); + void pluginData.state.common.sendErrorMessage(msg, "No tag with that name"); return; } diff --git a/backend/src/plugins/Tags/types.ts b/backend/src/plugins/Tags/types.ts index 8b8b472b..c750edc8 100644 --- a/backend/src/plugins/Tags/types.ts +++ b/backend/src/plugins/Tags/types.ts @@ -1,10 +1,11 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildArchives } from "../../data/GuildArchives"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildTags } from "../../data/GuildTags"; import { zBoundedCharacters, zStrictMessageContent } from "../../utils"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zTag = z.union([zBoundedCharacters(0, 4000), zStrictMessageContent]); export type TTag = z.infer; @@ -59,6 +60,7 @@ export interface TagsPluginType extends BasePluginType { tags: GuildTags; savedMessages: GuildSavedMessages; logs: GuildLogs; + common: pluginUtils.PluginPublicInterface; onMessageCreateFn; diff --git a/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts b/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts index 78dd8fa0..4c84c4ff 100644 --- a/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts +++ b/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts @@ -11,6 +11,7 @@ import { getMemberTz } from "./functions/getMemberTz"; import { inGuildTz } from "./functions/inGuildTz"; import { inMemberTz } from "./functions/inMemberTz"; import { TimeAndDatePluginType, zTimeAndDateConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -57,4 +58,8 @@ export const TimeAndDatePlugin = guildPlugin()({ state.memberTimezones = GuildMemberTimezones.getGuildInstance(guild.id); }, + + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, }); diff --git a/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts index 2c39519e..88eddd18 100644 --- a/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts @@ -11,8 +11,6 @@ export const ResetTimezoneCmd = timeAndDateCmd({ async run({ pluginData, message }) { await pluginData.state.memberTimezones.reset(message.author.id); const serverTimezone = getGuildTz(pluginData); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(message, `Your timezone has been reset to server default, **${serverTimezone}**`); + void pluginData.state.common.sendSuccessMessage(message, `Your timezone has been reset to server default, **${serverTimezone}**`); }, }); diff --git a/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts index 70acf129..684f60f7 100644 --- a/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts @@ -16,7 +16,7 @@ export const SetTimezoneCmd = timeAndDateCmd({ async run({ pluginData, message, args }) { const parsedTz = parseFuzzyTimezone(args.timezone); if (!parsedTz) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage( + void pluginData.state.common.sendErrorMessage( message, trimLines(` Invalid timezone: \`${escapeInlineCode(args.timezone)}\` @@ -28,6 +28,6 @@ export const SetTimezoneCmd = timeAndDateCmd({ } await pluginData.state.memberTimezones.set(message.author.id, parsedTz); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(message, `Your timezone is now set to **${parsedTz}**`); + void pluginData.state.common.sendSuccessMessage(message, `Your timezone is now set to **${parsedTz}**`); }, }); diff --git a/backend/src/plugins/TimeAndDate/types.ts b/backend/src/plugins/TimeAndDate/types.ts index 7a942518..5bb5253d 100644 --- a/backend/src/plugins/TimeAndDate/types.ts +++ b/backend/src/plugins/TimeAndDate/types.ts @@ -1,10 +1,11 @@ -import { BasePluginType, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginMessageCommand, pluginUtils } from "knub"; import { U } from "ts-toolbelt"; import z from "zod"; import { GuildMemberTimezones } from "../../data/GuildMemberTimezones"; import { keys } from "../../utils"; import { zValidTimezone } from "../../utils/zValidTimezone"; import { defaultDateFormats } from "./defaultDateFormats"; +import { CommonPlugin } from "../Common/CommonPlugin"; const zDateFormatKeys = z.enum(keys(defaultDateFormats) as U.ListOf); @@ -18,6 +19,7 @@ export interface TimeAndDatePluginType extends BasePluginType { config: z.infer; state: { memberTimezones: GuildMemberTimezones; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/Utility/UtilityPlugin.ts b/backend/src/plugins/Utility/UtilityPlugin.ts index 59da3e97..bd35837e 100644 --- a/backend/src/plugins/Utility/UtilityPlugin.ts +++ b/backend/src/plugins/Utility/UtilityPlugin.ts @@ -193,11 +193,15 @@ export const UtilityPlugin = guildPlugin()({ } }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { guild } = pluginData; if (activeReloads.has(guild.id)) { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(activeReloads.get(guild.id)!, "Reloaded!"); + pluginData.state.common.sendSuccessMessage(activeReloads.get(guild.id)!, "Reloaded!"); activeReloads.delete(guild.id); } }, diff --git a/backend/src/plugins/Utility/commands/AvatarCmd.ts b/backend/src/plugins/Utility/commands/AvatarCmd.ts index e06c7d89..b0b7ce7e 100644 --- a/backend/src/plugins/Utility/commands/AvatarCmd.ts +++ b/backend/src/plugins/Utility/commands/AvatarCmd.ts @@ -24,7 +24,7 @@ export const AvatarCmd = utilityCmd({ }; msg.channel.send({ embeds: [embed] }); } else { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid user ID"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid user ID"); } }, }); diff --git a/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts b/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts index 5b4a70bb..dc0901bc 100644 --- a/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts @@ -16,7 +16,7 @@ export const ChannelInfoCmd = utilityCmd({ async run({ message, args, pluginData }) { const embed = await getChannelInfoEmbed(pluginData, args.channel); if (!embed) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown channel"); + void pluginData.state.common.sendErrorMessage(message, "Unknown channel"); return; } diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index 11e7bcfb..6eac645e 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -83,22 +83,18 @@ export interface CleanArgs { export async function cleanCmd(pluginData: GuildPluginData, args: CleanArgs | any, msg) { if (args.count > MAX_CLEAN_COUNT || args.count <= 0) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( - msg, - `Clean count must be between 1 and ${MAX_CLEAN_COUNT}`, - undefined, - args["response-interaction"], - ); + void pluginData.state.common.sendErrorMessage( + msg, + `Clean count must be between 1 and ${MAX_CLEAN_COUNT}`, + undefined, + args["response-interaction"], + ); return; } const targetChannel = args.channel ? pluginData.guild.channels.cache.get(args.channel as Snowflake) : msg.channel; if (!targetChannel?.isTextBased()) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Invalid channel specified`, undefined, args["response-interaction"]); + void pluginData.state.common.sendErrorMessage(msg, `Invalid channel specified`, undefined, args["response-interaction"]); return; } @@ -110,14 +106,12 @@ export async function cleanCmd(pluginData: GuildPluginData, a categoryId: targetChannel.parentId, }); if (configForTargetChannel.can_clean !== true) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( - msg, - `Missing permissions to use clean on that channel`, - undefined, - args["response-interaction"], - ); + void pluginData.state.common.sendErrorMessage( + msg, + `Missing permissions to use clean on that channel`, + undefined, + args["response-interaction"], + ); return; } } @@ -223,14 +217,10 @@ export async function cleanCmd(pluginData: GuildPluginData, a } } - responseMsg = await pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, responseText, undefined, args["response-interaction"]); + responseMsg = await pluginData.state.common.sendSuccessMessage(msg, responseText, undefined, args["response-interaction"]); } else { const responseText = `Found no messages to clean${note ? ` (${note})` : ""}!`; - responseMsg = await pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, responseText, undefined, args["response-interaction"]); + responseMsg = await pluginData.state.common.sendErrorMessage(msg, responseText, undefined, args["response-interaction"]); } cleaningMessage?.delete(); diff --git a/backend/src/plugins/Utility/commands/ContextCmd.ts b/backend/src/plugins/Utility/commands/ContextCmd.ts index eb613f57..9db76606 100644 --- a/backend/src/plugins/Utility/commands/ContextCmd.ts +++ b/backend/src/plugins/Utility/commands/ContextCmd.ts @@ -23,7 +23,7 @@ export const ContextCmd = utilityCmd({ async run({ message: msg, args, pluginData }) { if (args.channel && !(args.channel instanceof TextChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Channel must be a text channel"); + void pluginData.state.common.sendErrorMessage(msg, "Channel must be a text channel"); return; } @@ -31,7 +31,7 @@ export const ContextCmd = utilityCmd({ const messageId = args.messageId ?? args.message.messageId; if (!canReadChannel(channel, msg.member)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Message context not found"); + void pluginData.state.common.sendErrorMessage(msg, "Message context not found"); return; } @@ -42,7 +42,7 @@ export const ContextCmd = utilityCmd({ }) )[0]; if (!previousMessage) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Message context not found"); + void pluginData.state.common.sendErrorMessage(msg, "Message context not found"); return; } diff --git a/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts b/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts index 114652a9..e5806aec 100644 --- a/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts @@ -17,13 +17,13 @@ export const EmojiInfoCmd = utilityCmd({ async run({ message, args, pluginData }) { const emojiId = getCustomEmojiId(args.emoji); if (!emojiId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Emoji not found"); + void pluginData.state.common.sendErrorMessage(message, "Emoji not found"); return; } const embed = await getEmojiInfoEmbed(pluginData, emojiId); if (!embed) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Emoji not found"); + void pluginData.state.common.sendErrorMessage(message, "Emoji not found"); return; } diff --git a/backend/src/plugins/Utility/commands/InfoCmd.ts b/backend/src/plugins/Utility/commands/InfoCmd.ts index 23ffa8ac..9314dbce 100644 --- a/backend/src/plugins/Utility/commands/InfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InfoCmd.ts @@ -146,11 +146,9 @@ export const InfoCmd = utilityCmd({ } // 10. No can do - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( - message, - "Could not find anything with that value or you are lacking permission for the snowflake type", - ); + void pluginData.state.common.sendErrorMessage( + message, + "Could not find anything with that value or you are lacking permission for the snowflake type", + ); }, }); diff --git a/backend/src/plugins/Utility/commands/InviteInfoCmd.ts b/backend/src/plugins/Utility/commands/InviteInfoCmd.ts index 262ab94a..bbecd794 100644 --- a/backend/src/plugins/Utility/commands/InviteInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InviteInfoCmd.ts @@ -18,7 +18,7 @@ export const InviteInfoCmd = utilityCmd({ const inviteCode = parseInviteCodeInput(args.inviteCode); const embed = await getInviteInfoEmbed(pluginData, inviteCode); if (!embed) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown invite"); + void pluginData.state.common.sendErrorMessage(message, "Unknown invite"); return; } diff --git a/backend/src/plugins/Utility/commands/JumboCmd.ts b/backend/src/plugins/Utility/commands/JumboCmd.ts index a8cf8678..d29dc608 100644 --- a/backend/src/plugins/Utility/commands/JumboCmd.ts +++ b/backend/src/plugins/Utility/commands/JumboCmd.ts @@ -51,7 +51,7 @@ export const JumboCmd = utilityCmd({ let file: AttachmentBuilder | undefined; if (!isEmoji(args.emoji)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid emoji"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid emoji"); return; } @@ -87,7 +87,7 @@ export const JumboCmd = utilityCmd({ } } if (!image) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Error occurred while jumboing default emoji"); + void pluginData.state.common.sendErrorMessage(msg, "Error occurred while jumboing default emoji"); return; } diff --git a/backend/src/plugins/Utility/commands/MessageInfoCmd.ts b/backend/src/plugins/Utility/commands/MessageInfoCmd.ts index 88df8eff..4ea7da69 100644 --- a/backend/src/plugins/Utility/commands/MessageInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/MessageInfoCmd.ts @@ -16,13 +16,13 @@ export const MessageInfoCmd = utilityCmd({ async run({ message, args, pluginData }) { if (!canReadChannel(args.message.channel, message.member)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown message"); + void pluginData.state.common.sendErrorMessage(message, "Unknown message"); return; } const embed = await getMessageInfoEmbed(pluginData, args.message.channel.id, args.message.messageId); if (!embed) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown message"); + void pluginData.state.common.sendErrorMessage(message, "Unknown message"); return; } diff --git a/backend/src/plugins/Utility/commands/NicknameCmd.ts b/backend/src/plugins/Utility/commands/NicknameCmd.ts index 63d5eac8..fd33a755 100644 --- a/backend/src/plugins/Utility/commands/NicknameCmd.ts +++ b/backend/src/plugins/Utility/commands/NicknameCmd.ts @@ -46,11 +46,9 @@ export const NicknameCmd = utilityCmd({ return; } - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - msg, - `Changed nickname of <@!${args.member.id}> from **${oldNickname}** to **${args.nickname}**`, - ); + void pluginData.state.common.sendSuccessMessage( + msg, + `Changed nickname of <@!${args.member.id}> from **${oldNickname}** to **${args.nickname}**`, + ); }, }); diff --git a/backend/src/plugins/Utility/commands/NicknameResetCmd.ts b/backend/src/plugins/Utility/commands/NicknameResetCmd.ts index 61417419..8fd23c84 100644 --- a/backend/src/plugins/Utility/commands/NicknameResetCmd.ts +++ b/backend/src/plugins/Utility/commands/NicknameResetCmd.ts @@ -32,6 +32,6 @@ export const NicknameResetCmd = utilityCmd({ return; } - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `The nickname of <@!${args.member.id}> has been reset`); + void pluginData.state.common.sendSuccessMessage(msg, `The nickname of <@!${args.member.id}> has been reset`); }, }); diff --git a/backend/src/plugins/Utility/commands/RolesCmd.ts b/backend/src/plugins/Utility/commands/RolesCmd.ts index d04903f9..08ec5dc1 100644 --- a/backend/src/plugins/Utility/commands/RolesCmd.ts +++ b/backend/src/plugins/Utility/commands/RolesCmd.ts @@ -62,7 +62,7 @@ export const RolesCmd = utilityCmd({ } else if (sort === "name") { roles.sort(sorter((r) => r.name.toLowerCase(), sortDir)); } else { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown sorting method"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown sorting method"); return; } diff --git a/backend/src/plugins/Utility/commands/ServerInfoCmd.ts b/backend/src/plugins/Utility/commands/ServerInfoCmd.ts index 2e5d7ba5..0388d8cd 100644 --- a/backend/src/plugins/Utility/commands/ServerInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/ServerInfoCmd.ts @@ -17,7 +17,7 @@ export const ServerInfoCmd = utilityCmd({ const serverId = args.serverId || pluginData.guild.id; const serverInfoEmbed = await getServerInfoEmbed(pluginData, serverId); if (!serverInfoEmbed) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Could not find information for that server"); + void pluginData.state.common.sendErrorMessage(message, "Could not find information for that server"); return; } diff --git a/backend/src/plugins/Utility/commands/SourceCmd.ts b/backend/src/plugins/Utility/commands/SourceCmd.ts index be3a4bab..5fccc109 100644 --- a/backend/src/plugins/Utility/commands/SourceCmd.ts +++ b/backend/src/plugins/Utility/commands/SourceCmd.ts @@ -17,13 +17,13 @@ export const SourceCmd = utilityCmd({ async run({ message: cmdMessage, args, pluginData }) { if (!canReadChannel(args.message.channel, cmdMessage.member)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(cmdMessage, "Unknown message"); + void pluginData.state.common.sendErrorMessage(cmdMessage, "Unknown message"); return; } const message = await args.message.channel.messages.fetch(args.message.messageId); if (!message) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(cmdMessage, "Unknown message"); + void pluginData.state.common.sendErrorMessage(cmdMessage, "Unknown message"); return; } diff --git a/backend/src/plugins/Utility/commands/UserInfoCmd.ts b/backend/src/plugins/Utility/commands/UserInfoCmd.ts index 6ba99548..9f2698a9 100644 --- a/backend/src/plugins/Utility/commands/UserInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/UserInfoCmd.ts @@ -19,7 +19,7 @@ export const UserInfoCmd = utilityCmd({ const userId = args.user?.id || message.author.id; const embed = await getUserInfoEmbed(pluginData, userId, args.compact); if (!embed) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "User not found"); + void pluginData.state.common.sendErrorMessage(message, "User not found"); return; } diff --git a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts index 6ad01cdb..797f5dda 100644 --- a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts +++ b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts @@ -18,12 +18,12 @@ export const VcdisconnectCmd = utilityCmd({ async run({ message: msg, args, pluginData }) { if (!canActOn(pluginData, msg.member, args.member)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot move: insufficient permissions"); + void pluginData.state.common.sendErrorMessage(msg, "Cannot move: insufficient permissions"); return; } if (!args.member.voice?.channelId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Member is not in a voice channel"); + void pluginData.state.common.sendErrorMessage(msg, "Member is not in a voice channel"); return; } const channel = pluginData.guild.channels.cache.get(args.member.voice.channelId) as VoiceChannel; @@ -31,7 +31,7 @@ export const VcdisconnectCmd = utilityCmd({ try { await args.member.voice.disconnect(); } catch { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Failed to disconnect member"); + void pluginData.state.common.sendErrorMessage(msg, "Failed to disconnect member"); return; } @@ -41,8 +41,9 @@ export const VcdisconnectCmd = utilityCmd({ oldChannel: channel, }); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `**${renderUsername(args.member)}** disconnected from **${channel.name}**`); + pluginData.state.common.sendSuccessMessage( + msg, + `**${renderUsername(args.member)}** disconnected from **${channel.name}**` + ); }, }); diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index abf47bbb..eee432c7 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -24,7 +24,7 @@ export const VcmoveCmd = utilityCmd({ // Snowflake -> resolve channel directly const potentialChannel = pluginData.guild.channels.cache.get(args.channel as Snowflake); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown or non-voice channel"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown or non-voice channel"); return; } @@ -34,7 +34,7 @@ export const VcmoveCmd = utilityCmd({ const channelId = args.channel.match(channelMentionRegex)![1]; const potentialChannel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown or non-voice channel"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown or non-voice channel"); return; } @@ -46,7 +46,7 @@ export const VcmoveCmd = utilityCmd({ ); const closestMatch = simpleClosestStringMatch(args.channel, voiceChannels, (ch) => ch.name); if (!closestMatch) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No matching voice channels"); + void pluginData.state.common.sendErrorMessage(msg, "No matching voice channels"); return; } @@ -54,12 +54,12 @@ export const VcmoveCmd = utilityCmd({ } if (!args.member.voice?.channelId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Member is not in a voice channel"); + void pluginData.state.common.sendErrorMessage(msg, "Member is not in a voice channel"); return; } if (args.member.voice.channelId === channel.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Member is already on that channel!"); + void pluginData.state.common.sendErrorMessage(msg, "Member is already on that channel!"); return; } @@ -70,7 +70,7 @@ export const VcmoveCmd = utilityCmd({ channel: channel.id, }); } catch { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Failed to move member"); + void pluginData.state.common.sendErrorMessage(msg, "Failed to move member"); return; } @@ -81,9 +81,7 @@ export const VcmoveCmd = utilityCmd({ newChannel: channel, }); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `**${renderUsername(args.member)}** moved to **${channel.name}**`); + void pluginData.state.common.sendSuccessMessage(msg, `**${renderUsername(args.member)}** moved to **${channel.name}**`); }, }); @@ -105,7 +103,7 @@ export const VcmoveAllCmd = utilityCmd({ // Snowflake -> resolve channel directly const potentialChannel = pluginData.guild.channels.cache.get(args.channel as Snowflake); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown or non-voice channel"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown or non-voice channel"); return; } @@ -115,7 +113,7 @@ export const VcmoveAllCmd = utilityCmd({ const channelId = args.channel.match(channelMentionRegex)![1]; const potentialChannel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown or non-voice channel"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown or non-voice channel"); return; } @@ -127,7 +125,7 @@ export const VcmoveAllCmd = utilityCmd({ ); const closestMatch = simpleClosestStringMatch(args.channel, voiceChannels, (ch) => ch.name); if (!closestMatch) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No matching voice channels"); + void pluginData.state.common.sendErrorMessage(msg, "No matching voice channels"); return; } @@ -135,12 +133,12 @@ export const VcmoveAllCmd = utilityCmd({ } if (args.oldChannel.members.size === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Voice channel is empty"); + void pluginData.state.common.sendErrorMessage(msg, "Voice channel is empty"); return; } if (args.oldChannel.id === channel.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cant move from and to the same channel!"); + void pluginData.state.common.sendErrorMessage(msg, "Cant move from and to the same channel!"); return; } @@ -153,12 +151,10 @@ export const VcmoveAllCmd = utilityCmd({ // Check for permissions but allow self-moves if (currMember.id !== msg.member.id && !canActOn(pluginData, msg.member, currMember)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( - msg, - `Failed to move ${renderUsername(currMember)} (${currMember.id}): You cannot act on this member`, - ); + void pluginData.state.common.sendErrorMessage( + msg, + `Failed to move ${renderUsername(currMember)} (${currMember.id}): You cannot act on this member`, + ); errAmt++; continue; } @@ -169,12 +165,10 @@ export const VcmoveAllCmd = utilityCmd({ }); } catch { if (msg.member.id === currMember.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown error when trying to move members"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown error when trying to move members"); return; } - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Failed to move ${renderUsername(currMember)} (${currMember.id})`); + void pluginData.state.common.sendErrorMessage(msg, `Failed to move ${renderUsername(currMember)} (${currMember.id})`); errAmt++; continue; } @@ -188,14 +182,12 @@ export const VcmoveAllCmd = utilityCmd({ } if (moveAmt !== errAmt) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - msg, - `${moveAmt - errAmt} members from **${args.oldChannel.name}** moved to **${channel.name}**`, - ); + void pluginData.state.common.sendSuccessMessage( + msg, + `${moveAmt - errAmt} members from **${args.oldChannel.name}** moved to **${channel.name}**`, + ); } else { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Failed to move any members.`); + void pluginData.state.common.sendErrorMessage(msg, `Failed to move any members.`); } }, }); diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index 191ea1ca..4b50ab1f 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -25,7 +25,6 @@ import { } from "../../utils"; import { asyncFilter } from "../../utils/async"; import { hasDiscordPermissions } from "../../utils/hasDiscordPermissions"; -import { CommonPlugin } from "../Common/CommonPlugin"; import { banSearchSignature } from "./commands/BanSearchCmd"; import { searchCmdSignature } from "./commands/SearchCmd"; import { getUserInfoEmbed } from "./functions/getUserInfoEmbed"; @@ -123,12 +122,12 @@ export async function displaySearch( } } catch (e) { if (e instanceof SearchError) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + void pluginData.state.common.sendErrorMessage(msg, e.message); return; } if (e instanceof InvalidRegexError) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + void pluginData.state.common.sendErrorMessage(msg, e.message); return; } @@ -136,7 +135,7 @@ export async function displaySearch( } if (searchResult.totalResults === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No results found"); + void pluginData.state.common.sendErrorMessage(msg, "No results found"); return; } @@ -267,12 +266,12 @@ export async function archiveSearch( } } catch (e) { if (e instanceof SearchError) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + void pluginData.state.common.sendErrorMessage(msg, e.message); return; } if (e instanceof InvalidRegexError) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + void pluginData.state.common.sendErrorMessage(msg, e.message); return; } @@ -280,7 +279,7 @@ export async function archiveSearch( } if (results.totalResults === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No results found"); + void pluginData.state.common.sendErrorMessage(msg, "No results found"); return; } diff --git a/backend/src/plugins/Utility/types.ts b/backend/src/plugins/Utility/types.ts index 77b3d8ac..0bcb56dd 100644 --- a/backend/src/plugins/Utility/types.ts +++ b/backend/src/plugins/Utility/types.ts @@ -1,4 +1,4 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { RegExpRunner } from "../../RegExpRunner"; import { GuildArchives } from "../../data/GuildArchives"; @@ -6,6 +6,7 @@ import { GuildCases } from "../../data/GuildCases"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { Supporters } from "../../data/Supporters"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zUtilityConfig = z.strictObject({ can_roles: z.boolean(), @@ -48,6 +49,8 @@ export interface UtilityPluginType extends BasePluginType { regexRunner: RegExpRunner; lastReload: number; + + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/utils/loadYamlSafely.ts b/backend/src/utils/loadYamlSafely.ts index 8cc0d90c..6960a0bf 100644 --- a/backend/src/utils/loadYamlSafely.ts +++ b/backend/src/utils/loadYamlSafely.ts @@ -5,7 +5,7 @@ import { validateNoObjectAliases } from "./validateNoObjectAliases"; * Loads a YAML file safely while removing object anchors/aliases (including arrays) */ export function loadYamlSafely(yamlStr: string): any { - let loaded = yaml.safeLoad(yamlStr); + let loaded = yaml.load(yamlStr); if (loaded == null || typeof loaded !== "object") { loaded = {}; } diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts index 59054d72..1486bef3 100644 --- a/backend/src/utils/waitForInteraction.ts +++ b/backend/src/utils/waitForInteraction.ts @@ -34,13 +34,11 @@ export async function waitForButtonConfirm( .setCustomId(`cancelButton:${idMod}:${uuidv4()}`), ]); const sendMethod = () => { - return contextIsInteraction - ? context.replied - ? context.editReply.bind(context) - : context.reply.bind(context) - : "send" in context - ? context.send.bind(context) - : context.channel.send.bind(context.channel); + if (contextIsInteraction) { + return context.replied ? context.editReply.bind(context) : context.reply.bind(context); + } else { + return "send" in context ? context.send.bind(context) : context.channel.send.bind(context.channel); + } }; const extraParameters = contextIsInteraction ? { fetchReply: true, ephemeral: true } : {}; const message = (await sendMethod()({ ...toPost, components: [row], ...extraParameters })) as Message;