Update djs & knub (#395)
* update pkgs Signed-off-by: GitHub <noreply@github.com> * new knub typings Signed-off-by: GitHub <noreply@github.com> * more pkg updates Signed-off-by: GitHub <noreply@github.com> * more fixes Signed-off-by: GitHub <noreply@github.com> * channel typings Signed-off-by: GitHub <noreply@github.com> * more message utils typings fixes Signed-off-by: GitHub <noreply@github.com> * migrate permissions Signed-off-by: GitHub <noreply@github.com> * fix: InternalPoster webhookables Signed-off-by: GitHub <noreply@github.com> * djs typings: Attachment & Util Signed-off-by: GitHub <noreply@github.com> * more typings Signed-off-by: GitHub <noreply@github.com> * fix: rename permissionNames Signed-off-by: GitHub <noreply@github.com> * more fixes Signed-off-by: GitHub <noreply@github.com> * half the number of errors * knub commands => messageCommands Signed-off-by: GitHub <noreply@github.com> * configPreprocessor => configParser Signed-off-by: GitHub <noreply@github.com> * fix channel.messages Signed-off-by: GitHub <noreply@github.com> * revert automod any typing Signed-off-by: GitHub <noreply@github.com> * more configParser typings Signed-off-by: GitHub <noreply@github.com> * revert Signed-off-by: GitHub <noreply@github.com> * remove knub type params Signed-off-by: GitHub <noreply@github.com> * fix more MessageEmbed / MessageOptions Signed-off-by: GitHub <noreply@github.com> * dumb commit for @almeidx to see why this is stupid Signed-off-by: GitHub <noreply@github.com> * temp disable custom_events Signed-off-by: GitHub <noreply@github.com> * more minor typings fixes - 23 err left Signed-off-by: GitHub <noreply@github.com> * update djs dep * +debug build method (revert this) Signed-off-by: GitHub <noreply@github.com> * Revert "+debug build method (revert this)" This reverts commit a80af1e729b742d1aad1097df538d224fbd32ce7. * Redo +debug build (Revert this) Signed-off-by: GitHub <noreply@github.com> * uniform before/after Load shorthands Signed-off-by: GitHub <noreply@github.com> * remove unused imports & add prettier plugin Signed-off-by: GitHub <noreply@github.com> * env fixes for web platform hosting Signed-off-by: GitHub <noreply@github.com> * feat: knub v32-next; related fixes * fix: allow legacy keys in change_perms action * fix: request Message Content intent * fix: use Knub's config validation logic in API * fix(dashboard): fix error when there are no message and/or slash commands in a plugin * fix(automod): start_thread action thread options * fix(CustomEvents): message command types * chore: remove unneeded type annotation * feat: add forum channel icon; use thread icon for news threads * chore: make tslint happy * chore: fix formatting --------- Signed-off-by: GitHub <noreply@github.com> Co-authored-by: almeidx <almeidx@pm.me> Co-authored-by: Dragory <2606411+Dragory@users.noreply.github.com>
This commit is contained in:
parent
293115af22
commit
06877e90cc
476 changed files with 2965 additions and 3251 deletions
|
@ -1,5 +1,5 @@
|
|||
import * as t from "io-ts";
|
||||
import { configUtils, CooldownManager } from "knub";
|
||||
import { ConfigPreprocessorFn } from "knub/dist/config/configTypes";
|
||||
import { GuildAntiraidLevels } from "../../data/GuildAntiraidLevels";
|
||||
import { GuildArchives } from "../../data/GuildArchives";
|
||||
import { GuildLogs } from "../../data/GuildLogs";
|
||||
|
@ -9,11 +9,13 @@ import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners";
|
|||
import { MINUTES, SECONDS } from "../../utils";
|
||||
import { registerEventListenersFromMap } from "../../utils/registerEventListenersFromMap";
|
||||
import { unregisterEventListenersFromMap } from "../../utils/unregisterEventListenersFromMap";
|
||||
import { StrictValidationError } from "../../validatorUtils";
|
||||
import { StrictValidationError, validate } from "../../validatorUtils";
|
||||
import { CountersPlugin } from "../Counters/CountersPlugin";
|
||||
import { InternalPosterPlugin } from "../InternalPoster/InternalPosterPlugin";
|
||||
import { LogsPlugin } from "../Logs/LogsPlugin";
|
||||
import { ModActionsPlugin } from "../ModActions/ModActionsPlugin";
|
||||
import { MutesPlugin } from "../Mutes/MutesPlugin";
|
||||
import { PhishermanPlugin } from "../Phisherman/PhishermanPlugin";
|
||||
import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
|
||||
import { availableActions } from "./actions/availableActions";
|
||||
import { AntiraidClearCmd } from "./commands/AntiraidClearCmd";
|
||||
|
@ -35,8 +37,6 @@ import { clearOldRecentSpam } from "./functions/clearOldRecentSpam";
|
|||
import { pluginInfo } from "./info";
|
||||
import { availableTriggers } from "./triggers/availableTriggers";
|
||||
import { AutomodPluginType, ConfigSchema } from "./types";
|
||||
import { PhishermanPlugin } from "../Phisherman/PhishermanPlugin";
|
||||
import { InternalPosterPlugin } from "../InternalPoster/InternalPosterPlugin";
|
||||
|
||||
const defaultOptions = {
|
||||
config: {
|
||||
|
@ -63,13 +63,15 @@ const defaultOptions = {
|
|||
|
||||
/**
|
||||
* Config preprocessor to set default values for triggers and perform extra validation
|
||||
* TODO: Separate input and output types
|
||||
*/
|
||||
const configPreprocessor: ConfigPreprocessorFn<AutomodPluginType> = (options) => {
|
||||
if (options.config?.rules) {
|
||||
const configParser = (input: unknown) => {
|
||||
const rules = (input as any).rules;
|
||||
if (rules) {
|
||||
// Loop through each rule
|
||||
for (const [name, rule] of Object.entries(options.config.rules)) {
|
||||
for (const [name, rule] of Object.entries(rules)) {
|
||||
if (rule == null) {
|
||||
delete options.config.rules[name];
|
||||
delete rules[name];
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -97,7 +99,7 @@ const configPreprocessor: ConfigPreprocessorFn<AutomodPluginType> = (options) =>
|
|||
for (const triggerObj of rule["triggers"]) {
|
||||
for (const triggerName in triggerObj) {
|
||||
if (!availableTriggers[triggerName]) {
|
||||
throw new StrictValidationError([`Unknown trigger '${triggerName}' in rule '${rule.name}'`]);
|
||||
throw new StrictValidationError([`Unknown trigger '${triggerName}' in rule '${rule["name"]}'`]);
|
||||
}
|
||||
|
||||
const triggerBlueprint = availableTriggers[triggerName];
|
||||
|
@ -117,11 +119,11 @@ const configPreprocessor: ConfigPreprocessorFn<AutomodPluginType> = (options) =>
|
|||
|
||||
if (white && black) {
|
||||
throw new StrictValidationError([
|
||||
`Cannot have both blacklist and whitelist enabled at rule <${rule.name}/match_attachment_type>`,
|
||||
`Cannot have both blacklist and whitelist enabled at rule <${rule["name"]}/match_attachment_type>`,
|
||||
]);
|
||||
} else if (!white && !black) {
|
||||
throw new StrictValidationError([
|
||||
`Must have either blacklist or whitelist enabled at rule <${rule.name}/match_attachment_type>`,
|
||||
`Must have either blacklist or whitelist enabled at rule <${rule["name"]}/match_attachment_type>`,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -132,11 +134,11 @@ const configPreprocessor: ConfigPreprocessorFn<AutomodPluginType> = (options) =>
|
|||
|
||||
if (white && black) {
|
||||
throw new StrictValidationError([
|
||||
`Cannot have both blacklist and whitelist enabled at rule <${rule.name}/match_mime_type>`,
|
||||
`Cannot have both blacklist and whitelist enabled at rule <${rule["name"]}/match_mime_type>`,
|
||||
]);
|
||||
} else if (!white && !black) {
|
||||
throw new StrictValidationError([
|
||||
`Must have either blacklist or whitelist enabled at rule <${rule.name}/match_mime_type>`,
|
||||
`Must have either blacklist or whitelist enabled at rule <${rule["name"]}/match_mime_type>`,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +149,7 @@ const configPreprocessor: ConfigPreprocessorFn<AutomodPluginType> = (options) =>
|
|||
if (rule["actions"]) {
|
||||
for (const actionName in rule["actions"]) {
|
||||
if (!availableActions[actionName]) {
|
||||
throw new StrictValidationError([`Unknown action '${actionName}' in rule '${rule.name}'`]);
|
||||
throw new StrictValidationError([`Unknown action '${actionName}' in rule '${rule["name"]}'`]);
|
||||
}
|
||||
|
||||
const actionBlueprint = availableActions[actionName];
|
||||
|
@ -163,9 +165,9 @@ const configPreprocessor: ConfigPreprocessorFn<AutomodPluginType> = (options) =>
|
|||
|
||||
// Enable logging of automod actions by default
|
||||
if (rule["actions"]) {
|
||||
for (const actionName in rule.actions) {
|
||||
for (const actionName in rule["actions"]) {
|
||||
if (!availableActions[actionName]) {
|
||||
throw new StrictValidationError([`Unknown action '${actionName}' in rule '${rule.name}'`]);
|
||||
throw new StrictValidationError([`Unknown action '${actionName}' in rule '${rule["name"]}'`]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,13 +175,18 @@ const configPreprocessor: ConfigPreprocessorFn<AutomodPluginType> = (options) =>
|
|||
rule["actions"]["log"] = true;
|
||||
}
|
||||
if (rule["actions"]["clean"] && rule["actions"]["start_thread"]) {
|
||||
throw new StrictValidationError([`Cannot have both clean and start_thread at rule '${rule.name}'`]);
|
||||
throw new StrictValidationError([`Cannot have both clean and start_thread at rule '${rule["name"]}'`]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
const error = validate(ConfigSchema, input);
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return input as t.TypeOf<typeof ConfigSchema>;
|
||||
};
|
||||
|
||||
export const AutomodPlugin = zeppelinGuildPlugin<AutomodPluginType>()({
|
||||
|
@ -197,9 +204,8 @@ export const AutomodPlugin = zeppelinGuildPlugin<AutomodPluginType>()({
|
|||
InternalPosterPlugin,
|
||||
],
|
||||
|
||||
configSchema: ConfigSchema,
|
||||
defaultOptions,
|
||||
configPreprocessor,
|
||||
configParser,
|
||||
|
||||
customOverrideCriteriaFunctions: {
|
||||
antiraid_level: (pluginData, matchParams, value) => {
|
||||
|
@ -218,136 +224,126 @@ export const AutomodPlugin = zeppelinGuildPlugin<AutomodPluginType>()({
|
|||
// Messages use message events from SavedMessages, see onLoad below
|
||||
],
|
||||
|
||||
commands: [AntiraidClearCmd, SetAntiraidCmd, ViewAntiraidCmd],
|
||||
messageCommands: [AntiraidClearCmd, SetAntiraidCmd, ViewAntiraidCmd],
|
||||
|
||||
async beforeLoad(pluginData) {
|
||||
pluginData.state.queue = new Queue();
|
||||
const { state, guild } = pluginData;
|
||||
|
||||
pluginData.state.regexRunner = getRegExpRunner(`guild-${pluginData.guild.id}`);
|
||||
state.queue = new Queue();
|
||||
|
||||
pluginData.state.recentActions = [];
|
||||
state.regexRunner = getRegExpRunner(`guild-${guild.id}`);
|
||||
|
||||
pluginData.state.recentSpam = [];
|
||||
state.recentActions = [];
|
||||
|
||||
pluginData.state.recentNicknameChanges = new Map();
|
||||
state.recentSpam = [];
|
||||
|
||||
pluginData.state.ignoredRoleChanges = new Set();
|
||||
state.recentNicknameChanges = new Map();
|
||||
|
||||
pluginData.state.cooldownManager = new CooldownManager();
|
||||
state.ignoredRoleChanges = new Set();
|
||||
|
||||
pluginData.state.logs = new GuildLogs(pluginData.guild.id);
|
||||
pluginData.state.savedMessages = GuildSavedMessages.getGuildInstance(pluginData.guild.id);
|
||||
pluginData.state.antiraidLevels = GuildAntiraidLevels.getGuildInstance(pluginData.guild.id);
|
||||
pluginData.state.archives = GuildArchives.getGuildInstance(pluginData.guild.id);
|
||||
state.cooldownManager = new CooldownManager();
|
||||
|
||||
pluginData.state.cachedAntiraidLevel = await pluginData.state.antiraidLevels.get();
|
||||
state.logs = new GuildLogs(guild.id);
|
||||
state.savedMessages = GuildSavedMessages.getGuildInstance(guild.id);
|
||||
state.antiraidLevels = GuildAntiraidLevels.getGuildInstance(guild.id);
|
||||
state.archives = GuildArchives.getGuildInstance(guild.id);
|
||||
|
||||
state.cachedAntiraidLevel = await state.antiraidLevels.get();
|
||||
},
|
||||
|
||||
async afterLoad(pluginData) {
|
||||
pluginData.state.clearRecentActionsInterval = setInterval(() => clearOldRecentActions(pluginData), 1 * MINUTES);
|
||||
pluginData.state.clearRecentSpamInterval = setInterval(() => clearOldRecentSpam(pluginData), 1 * SECONDS);
|
||||
pluginData.state.clearRecentNicknameChangesInterval = setInterval(
|
||||
const { state, guild } = pluginData;
|
||||
|
||||
state.clearRecentActionsInterval = setInterval(() => clearOldRecentActions(pluginData), 1 * MINUTES);
|
||||
state.clearRecentSpamInterval = setInterval(() => clearOldRecentSpam(pluginData), 1 * SECONDS);
|
||||
state.clearRecentNicknameChangesInterval = setInterval(
|
||||
() => clearOldRecentNicknameChanges(pluginData),
|
||||
30 * SECONDS,
|
||||
);
|
||||
|
||||
pluginData.state.onMessageCreateFn = (message) => runAutomodOnMessage(pluginData, message, false);
|
||||
pluginData.state.savedMessages.events.on("create", pluginData.state.onMessageCreateFn);
|
||||
|
||||
pluginData.state.onMessageUpdateFn = (message) => runAutomodOnMessage(pluginData, message, true);
|
||||
pluginData.state.savedMessages.events.on("update", pluginData.state.onMessageUpdateFn);
|
||||
state.onMessageCreateFn = (message) => runAutomodOnMessage(pluginData, message, false);
|
||||
state.savedMessages.events.on("create", state.onMessageCreateFn);
|
||||
|
||||
state.onMessageUpdateFn = (message) => runAutomodOnMessage(pluginData, message, true);
|
||||
state.savedMessages.events.on("update", state.onMessageUpdateFn);
|
||||
const countersPlugin = pluginData.getPlugin(CountersPlugin);
|
||||
|
||||
pluginData.state.onCounterTrigger = (name, triggerName, channelId, userId) => {
|
||||
state.onCounterTrigger = (name, triggerName, channelId, userId) => {
|
||||
runAutomodOnCounterTrigger(pluginData, name, triggerName, channelId, userId, false);
|
||||
};
|
||||
|
||||
pluginData.state.onCounterReverseTrigger = (name, triggerName, channelId, userId) => {
|
||||
state.onCounterReverseTrigger = (name, triggerName, channelId, userId) => {
|
||||
runAutomodOnCounterTrigger(pluginData, name, triggerName, channelId, userId, true);
|
||||
};
|
||||
|
||||
countersPlugin.onCounterEvent("trigger", pluginData.state.onCounterTrigger);
|
||||
countersPlugin.onCounterEvent("reverseTrigger", pluginData.state.onCounterReverseTrigger);
|
||||
countersPlugin.onCounterEvent("trigger", state.onCounterTrigger);
|
||||
countersPlugin.onCounterEvent("reverseTrigger", state.onCounterReverseTrigger);
|
||||
|
||||
const modActionsEvents = pluginData.getPlugin(ModActionsPlugin).getEventEmitter();
|
||||
pluginData.state.modActionsListeners = new Map();
|
||||
pluginData.state.modActionsListeners.set("note", (userId: string) =>
|
||||
runAutomodOnModAction(pluginData, "note", userId),
|
||||
state.modActionsListeners = new Map();
|
||||
state.modActionsListeners.set("note", (userId: string) => runAutomodOnModAction(pluginData, "note", userId));
|
||||
state.modActionsListeners.set("warn", (userId: string, reason: string | undefined, isAutomodAction: boolean) =>
|
||||
runAutomodOnModAction(pluginData, "warn", userId, reason, isAutomodAction),
|
||||
);
|
||||
pluginData.state.modActionsListeners.set(
|
||||
"warn",
|
||||
(userId: string, reason: string | undefined, isAutomodAction: boolean) =>
|
||||
runAutomodOnModAction(pluginData, "warn", userId, reason, isAutomodAction),
|
||||
state.modActionsListeners.set("kick", (userId: string, reason: string | undefined, isAutomodAction: boolean) =>
|
||||
runAutomodOnModAction(pluginData, "kick", userId, reason, isAutomodAction),
|
||||
);
|
||||
pluginData.state.modActionsListeners.set(
|
||||
"kick",
|
||||
(userId: string, reason: string | undefined, isAutomodAction: boolean) =>
|
||||
runAutomodOnModAction(pluginData, "kick", userId, reason, isAutomodAction),
|
||||
state.modActionsListeners.set("ban", (userId: string, reason: string | undefined, isAutomodAction: boolean) =>
|
||||
runAutomodOnModAction(pluginData, "ban", userId, reason, isAutomodAction),
|
||||
);
|
||||
pluginData.state.modActionsListeners.set(
|
||||
"ban",
|
||||
(userId: string, reason: string | undefined, isAutomodAction: boolean) =>
|
||||
runAutomodOnModAction(pluginData, "ban", userId, reason, isAutomodAction),
|
||||
);
|
||||
pluginData.state.modActionsListeners.set("unban", (userId: string) =>
|
||||
runAutomodOnModAction(pluginData, "unban", userId),
|
||||
);
|
||||
registerEventListenersFromMap(modActionsEvents, pluginData.state.modActionsListeners);
|
||||
state.modActionsListeners.set("unban", (userId: string) => runAutomodOnModAction(pluginData, "unban", userId));
|
||||
registerEventListenersFromMap(modActionsEvents, state.modActionsListeners);
|
||||
|
||||
const mutesEvents = pluginData.getPlugin(MutesPlugin).getEventEmitter();
|
||||
pluginData.state.mutesListeners = new Map();
|
||||
pluginData.state.mutesListeners.set(
|
||||
"mute",
|
||||
(userId: string, reason: string | undefined, isAutomodAction: boolean) =>
|
||||
runAutomodOnModAction(pluginData, "mute", userId, reason, isAutomodAction),
|
||||
state.mutesListeners = new Map();
|
||||
state.mutesListeners.set("mute", (userId: string, reason: string | undefined, isAutomodAction: boolean) =>
|
||||
runAutomodOnModAction(pluginData, "mute", userId, reason, isAutomodAction),
|
||||
);
|
||||
pluginData.state.mutesListeners.set("unmute", (userId: string) =>
|
||||
runAutomodOnModAction(pluginData, "unmute", userId),
|
||||
);
|
||||
registerEventListenersFromMap(mutesEvents, pluginData.state.mutesListeners);
|
||||
state.mutesListeners.set("unmute", (userId: string) => runAutomodOnModAction(pluginData, "unmute", userId));
|
||||
registerEventListenersFromMap(mutesEvents, state.mutesListeners);
|
||||
},
|
||||
|
||||
async beforeUnload(pluginData) {
|
||||
const { state, guild } = pluginData;
|
||||
|
||||
const countersPlugin = pluginData.getPlugin(CountersPlugin);
|
||||
if (pluginData.state.onCounterTrigger) {
|
||||
countersPlugin.offCounterEvent("trigger", pluginData.state.onCounterTrigger);
|
||||
if (state.onCounterTrigger) {
|
||||
countersPlugin.offCounterEvent("trigger", state.onCounterTrigger);
|
||||
}
|
||||
if (pluginData.state.onCounterReverseTrigger) {
|
||||
countersPlugin.offCounterEvent("reverseTrigger", pluginData.state.onCounterReverseTrigger);
|
||||
if (state.onCounterReverseTrigger) {
|
||||
countersPlugin.offCounterEvent("reverseTrigger", state.onCounterReverseTrigger);
|
||||
}
|
||||
|
||||
const modActionsEvents = pluginData.getPlugin(ModActionsPlugin).getEventEmitter();
|
||||
if (pluginData.state.modActionsListeners) {
|
||||
unregisterEventListenersFromMap(modActionsEvents, pluginData.state.modActionsListeners);
|
||||
if (state.modActionsListeners) {
|
||||
unregisterEventListenersFromMap(modActionsEvents, state.modActionsListeners);
|
||||
}
|
||||
|
||||
const mutesEvents = pluginData.getPlugin(MutesPlugin).getEventEmitter();
|
||||
if (pluginData.state.mutesListeners) {
|
||||
unregisterEventListenersFromMap(mutesEvents, pluginData.state.mutesListeners);
|
||||
if (state.mutesListeners) {
|
||||
unregisterEventListenersFromMap(mutesEvents, state.mutesListeners);
|
||||
}
|
||||
|
||||
pluginData.state.queue.clear();
|
||||
state.queue.clear();
|
||||
|
||||
discardRegExpRunner(`guild-${pluginData.guild.id}`);
|
||||
discardRegExpRunner(`guild-${guild.id}`);
|
||||
|
||||
if (pluginData.state.clearRecentActionsInterval) {
|
||||
clearInterval(pluginData.state.clearRecentActionsInterval);
|
||||
if (state.clearRecentActionsInterval) {
|
||||
clearInterval(state.clearRecentActionsInterval);
|
||||
}
|
||||
|
||||
if (pluginData.state.clearRecentSpamInterval) {
|
||||
clearInterval(pluginData.state.clearRecentSpamInterval);
|
||||
if (state.clearRecentSpamInterval) {
|
||||
clearInterval(state.clearRecentSpamInterval);
|
||||
}
|
||||
|
||||
if (pluginData.state.clearRecentNicknameChangesInterval) {
|
||||
clearInterval(pluginData.state.clearRecentNicknameChangesInterval);
|
||||
if (state.clearRecentNicknameChangesInterval) {
|
||||
clearInterval(state.clearRecentNicknameChangesInterval);
|
||||
}
|
||||
|
||||
if (pluginData.state.onMessageCreateFn) {
|
||||
pluginData.state.savedMessages.events.off("create", pluginData.state.onMessageCreateFn);
|
||||
if (state.onMessageCreateFn) {
|
||||
state.savedMessages.events.off("create", state.onMessageCreateFn);
|
||||
}
|
||||
if (pluginData.state.onMessageUpdateFn) {
|
||||
pluginData.state.savedMessages.events.off("update", pluginData.state.onMessageUpdateFn);
|
||||
if (state.onMessageUpdateFn) {
|
||||
state.savedMessages.events.off("update", state.onMessageUpdateFn);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue