3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-05-13 21:35:02 +00:00
zeppelin/backend/src/plugins/ModActions/ModActionsPlugin.ts

315 lines
11 KiB
TypeScript

import { GuildMember, Message, Snowflake } from "discord.js";
import { EventEmitter } from "events";
import { Queue } from "../../Queue";
import { GuildCases } from "../../data/GuildCases";
import { onGuildEvent } from "../../data/GuildEvents";
import { GuildLogs } from "../../data/GuildLogs";
import { GuildMutes } from "../../data/GuildMutes";
import { GuildTempbans } from "../../data/GuildTempbans";
import { mapToPublicFn } from "../../pluginUtils";
import { MINUTES, trimPluginDescription } from "../../utils";
import { CasesPlugin } from "../Cases/CasesPlugin";
import { LogsPlugin } from "../Logs/LogsPlugin";
import { MutesPlugin } from "../Mutes/MutesPlugin";
import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin";
import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
import { AddCaseMsgCmd } from "./commands/addcase/AddCaseMsgCmd";
import { AddCaseSlashCmd } from "./commands/addcase/AddCaseSlashCmd";
import { BanMsgCmd } from "./commands/ban/BanMsgCmd";
import { BanSlashCmd } from "./commands/ban/BanSlashCmd";
import { CaseMsgCmd } from "./commands/case/CaseMsgCmd";
import { CaseSlashCmd } from "./commands/case/CaseSlashCmd";
import { CasesModMsgCmd } from "./commands/cases/CasesModMsgCmd";
import { CasesSlashCmd } from "./commands/cases/CasesSlashCmd";
import { CasesUserMsgCmd } from "./commands/cases/CasesUserMsgCmd";
import { DeleteCaseMsgCmd } from "./commands/deletecase/DeleteCaseMsgCmd";
import { DeleteCaseSlashCmd } from "./commands/deletecase/DeleteCaseSlashCmd";
import { ForceBanMsgCmd } from "./commands/forceban/ForceBanMsgCmd";
import { ForceBanSlashCmd } from "./commands/forceban/ForceBanSlashCmd";
import { ForceMuteMsgCmd } from "./commands/forcemute/ForceMuteMsgCmd";
import { ForceMuteSlashCmd } from "./commands/forcemute/ForceMuteSlashCmd";
import { ForceUnmuteMsgCmd } from "./commands/forceunmute/ForceUnmuteMsgCmd";
import { ForceUnmuteSlashCmd } from "./commands/forceunmute/ForceUnmuteSlashCmd";
import { HideCaseMsgCmd } from "./commands/hidecase/HideCaseMsgCmd";
import { HideCaseSlashCmd } from "./commands/hidecase/HideCaseSlashCmd";
import { KickMsgCmd } from "./commands/kick/KickMsgCmd";
import { KickSlashCmd } from "./commands/kick/KickSlashCmd";
import { MassBanMsgCmd } from "./commands/massban/MassBanMsgCmd";
import { MassBanSlashCmd } from "./commands/massban/MassBanSlashCmd";
import { MassMuteMsgCmd } from "./commands/massmute/MassMuteMsgCmd";
import { MassMuteSlashSlashCmd } from "./commands/massmute/MassMuteSlashCmd";
import { MassUnbanMsgCmd } from "./commands/massunban/MassUnbanMsgCmd";
import { MassUnbanSlashCmd } from "./commands/massunban/MassUnbanSlashCmd";
import { MuteMsgCmd } from "./commands/mute/MuteMsgCmd";
import { MuteSlashCmd } from "./commands/mute/MuteSlashCmd";
import { NoteMsgCmd } from "./commands/note/NoteMsgCmd";
import { NoteSlashCmd } from "./commands/note/NoteSlashCmd";
import { UnbanMsgCmd } from "./commands/unban/UnbanMsgCmd";
import { UnbanSlashCmd } from "./commands/unban/UnbanSlashCmd";
import { UnhideCaseMsgCmd } from "./commands/unhidecase/UnhideCaseMsgCmd";
import { UnhideCaseSlashCmd } from "./commands/unhidecase/UnhideCaseSlashCmd";
import { UnmuteMsgCmd } from "./commands/unmute/UnmuteMsgCmd";
import { UnmuteSlashCmd } from "./commands/unmute/UnmuteSlashCmd";
import { UpdateMsgCmd } from "./commands/update/UpdateMsgCmd";
import { UpdateSlashCmd } from "./commands/update/UpdateSlashCmd";
import { WarnMsgCmd } from "./commands/warn/WarnMsgCmd";
import { WarnSlashCmd } from "./commands/warn/WarnSlashCmd";
import { AuditLogEvents } from "./events/AuditLogEvents";
import { CreateBanCaseOnManualBanEvt } from "./events/CreateBanCaseOnManualBanEvt";
import { CreateUnbanCaseOnManualUnbanEvt } from "./events/CreateUnbanCaseOnManualUnbanEvt";
import { PostAlertOnMemberJoinEvt } from "./events/PostAlertOnMemberJoinEvt";
import { banUserId } from "./functions/banUserId";
import { clearTempban } from "./functions/clearTempban";
import {
hasBanPermission,
hasMutePermission,
hasNotePermission,
hasWarnPermission,
} from "./functions/hasModActionPerm";
import { kickMember } from "./functions/kickMember";
import { offModActionsEvent } from "./functions/offModActionsEvent";
import { onModActionsEvent } from "./functions/onModActionsEvent";
import { updateCase } from "./functions/updateCase";
import { warnMember } from "./functions/warnMember";
import {
AttachmentLinkReactionType,
BanOptions,
KickOptions,
ModActionsPluginType,
WarnOptions,
modActionsSlashGroup,
zModActionsConfig,
} from "./types";
const defaultOptions = {
config: {
dm_on_warn: true,
dm_on_kick: false,
dm_on_ban: false,
message_on_warn: false,
message_on_kick: false,
message_on_ban: false,
message_channel: null,
warn_message: "You have received a warning on the {guildName} server: {reason}",
kick_message: "You have been kicked from the {guildName} server. Reason given: {reason}",
ban_message: "You have been banned from the {guildName} server. Reason given: {reason}",
tempban_message: "You have been banned from the {guildName} server for {banTime}. Reason given: {reason}",
alert_on_rejoin: false,
alert_channel: null,
warn_notify_enabled: false,
warn_notify_threshold: 5,
warn_notify_message:
"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,
can_mute: false,
can_kick: false,
can_ban: false,
can_unban: false,
can_view: false,
can_addcase: false,
can_massunban: false,
can_massban: false,
can_massmute: false,
can_hidecase: false,
can_deletecase: false,
can_act_as_other: false,
create_cases_for_manual_actions: true,
},
overrides: [
{
level: ">=50",
config: {
can_note: true,
can_warn: true,
can_mute: true,
can_kick: true,
can_ban: true,
can_unban: true,
can_view: true,
can_addcase: true,
},
},
{
level: ">=100",
config: {
can_massunban: true,
can_massban: true,
can_massmute: true,
can_hidecase: true,
can_act_as_other: true,
},
},
],
};
export const ModActionsPlugin = zeppelinGuildPlugin<ModActionsPluginType>()({
name: "mod_actions",
showInDocs: true,
info: {
prettyName: "Mod actions",
description: trimPluginDescription(`
This plugin contains the 'typical' mod actions such as warning, muting, kicking, banning, etc.
`),
configSchema: zModActionsConfig,
},
dependencies: () => [TimeAndDatePlugin, CasesPlugin, MutesPlugin, LogsPlugin],
configParser: (input) => zModActionsConfig.parse(input),
defaultOptions,
events: [CreateBanCaseOnManualBanEvt, CreateUnbanCaseOnManualUnbanEvt, PostAlertOnMemberJoinEvt, AuditLogEvents],
slashCommands: [
modActionsSlashGroup({
name: "mod",
description: "Moderation actions",
defaultMemberPermissions: "0",
subcommands: [
AddCaseSlashCmd,
BanSlashCmd,
CaseSlashCmd,
CasesSlashCmd,
DeleteCaseSlashCmd,
ForceBanSlashCmd,
ForceMuteSlashCmd,
ForceUnmuteSlashCmd,
HideCaseSlashCmd,
KickSlashCmd,
MassBanSlashCmd,
MassMuteSlashSlashCmd,
MassUnbanSlashCmd,
MuteSlashCmd,
NoteSlashCmd,
UnbanSlashCmd,
UnhideCaseSlashCmd,
UnmuteSlashCmd,
UpdateSlashCmd,
WarnSlashCmd,
],
}),
],
messageCommands: [
UpdateMsgCmd,
NoteMsgCmd,
WarnMsgCmd,
MuteMsgCmd,
ForceMuteMsgCmd,
UnmuteMsgCmd,
ForceUnmuteMsgCmd,
KickMsgCmd,
BanMsgCmd,
UnbanMsgCmd,
ForceBanMsgCmd,
MassBanMsgCmd,
MassMuteMsgCmd,
MassUnbanMsgCmd,
AddCaseMsgCmd,
CaseMsgCmd,
CasesUserMsgCmd,
CasesModMsgCmd,
HideCaseMsgCmd,
UnhideCaseMsgCmd,
DeleteCaseMsgCmd,
],
public: {
warnMember(pluginData) {
return (member: GuildMember, reason: string, reasonWithAttachments: string, warnOptions?: WarnOptions) => {
return warnMember(pluginData, member, reason, reasonWithAttachments, warnOptions);
};
},
kickMember(pluginData) {
return (member: GuildMember, reason: string, reasonWithAttachments: string, kickOptions?: KickOptions) => {
kickMember(pluginData, member, reason, reasonWithAttachments, kickOptions);
};
},
banUserId(pluginData) {
return (
userId: string,
reason?: string,
reasonWithAttachments?: string,
banOptions?: BanOptions,
banTime?: number,
) => {
return banUserId(pluginData, userId, reason, reasonWithAttachments, banOptions, banTime);
};
},
updateCase(pluginData) {
return (msg: Message, caseNumber: number | null, note: string) => {
updateCase(pluginData, msg, msg.author, caseNumber ?? undefined, note, [...msg.attachments.values()]);
};
},
hasNotePermission(pluginData) {
return (member: GuildMember, channelId: Snowflake) => {
return hasNotePermission(pluginData, member, channelId);
};
},
hasWarnPermission(pluginData) {
return (member: GuildMember, channelId: Snowflake) => {
return hasWarnPermission(pluginData, member, channelId);
};
},
hasMutePermission(pluginData) {
return (member: GuildMember, channelId: Snowflake) => {
return hasMutePermission(pluginData, member, channelId);
};
},
hasBanPermission(pluginData) {
return (member: GuildMember, channelId: Snowflake) => {
return hasBanPermission(pluginData, member, channelId);
};
},
on: mapToPublicFn(onModActionsEvent),
off: mapToPublicFn(offModActionsEvent),
getEventEmitter(pluginData) {
return () => pluginData.state.events;
},
},
beforeLoad(pluginData) {
const { state, guild } = pluginData;
state.mutes = GuildMutes.getGuildInstance(guild.id);
state.cases = GuildCases.getGuildInstance(guild.id);
state.tempbans = GuildTempbans.getGuildInstance(guild.id);
state.serverLogs = new GuildLogs(guild.id);
state.unloaded = false;
state.ignoredEvents = [];
// Massbans can take a while depending on rate limits,
// so we're giving each massban 15 minutes to complete before launching the next massban
state.massbanQueue = new Queue(15 * MINUTES);
state.events = new EventEmitter();
},
afterLoad(pluginData) {
const { state, guild } = pluginData;
state.unregisterGuildEventListener = onGuildEvent(guild.id, "expiredTempban", (tempban) =>
clearTempban(pluginData, tempban),
);
},
beforeUnload(pluginData) {
const { state } = pluginData;
state.unloaded = true;
state.unregisterGuildEventListener?.();
state.events.removeAllListeners();
},
});