Add types for all plugin configs and permissions. Update code to work with Knub 18.
This commit is contained in:
parent
c96e98fcef
commit
b7b42705f9
22 changed files with 415 additions and 225 deletions
|
@ -1,4 +1,4 @@
|
|||
import { decorators as d } from "knub";
|
||||
import { decorators as d, IBasePluginConfig, IPluginOptions } from "knub";
|
||||
import { GuildSavedMessages } from "../data/GuildSavedMessages";
|
||||
import { SavedMessage } from "../data/entities/SavedMessage";
|
||||
import { GuildAutoReactions } from "../data/GuildAutoReactions";
|
||||
|
@ -6,7 +6,11 @@ import { Message } from "eris";
|
|||
import { customEmojiRegex, errorMessage, isEmoji, successMessage } from "../utils";
|
||||
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
||||
|
||||
export class AutoReactionsPlugin extends ZeppelinPlugin {
|
||||
interface IAutoReactionsPluginPermissions {
|
||||
use: boolean;
|
||||
}
|
||||
|
||||
export class AutoReactionsPlugin extends ZeppelinPlugin<IBasePluginConfig, IAutoReactionsPluginPermissions> {
|
||||
public static pluginName = "auto_reactions";
|
||||
|
||||
protected savedMessages: GuildSavedMessages;
|
||||
|
@ -14,8 +18,10 @@ export class AutoReactionsPlugin extends ZeppelinPlugin {
|
|||
|
||||
private onMessageCreateFn;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<IBasePluginConfig, IAutoReactionsPluginPermissions> {
|
||||
return {
|
||||
config: {},
|
||||
|
||||
permissions: {
|
||||
use: false,
|
||||
},
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { decorators as d, GlobalPlugin } from "knub";
|
||||
import { decorators as d, GlobalPlugin, IPluginOptions } from "knub";
|
||||
import child_process from "child_process";
|
||||
import { GuildChannel, Message, TextChannel } from "eris";
|
||||
import { createChunkedMessage, errorMessage, noop, sleep, sorter, successMessage } from "../utils";
|
||||
|
@ -6,17 +6,25 @@ import { ReactionRolesPlugin } from "./ReactionRoles";
|
|||
|
||||
let activeReload: [string, string] = null;
|
||||
|
||||
interface IBotControlPluginConfig {
|
||||
owners: string[];
|
||||
update_cmd: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A global plugin that allows bot owners to control the bot
|
||||
*/
|
||||
export class BotControlPlugin extends GlobalPlugin {
|
||||
export class BotControlPlugin extends GlobalPlugin<IBotControlPluginConfig> {
|
||||
public static pluginName = "bot_control";
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<IBotControlPluginConfig> {
|
||||
return {
|
||||
config: {
|
||||
owners: [],
|
||||
update_cmd: null,
|
||||
},
|
||||
|
||||
permissions: {},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -36,14 +44,14 @@ export class BotControlPlugin extends GlobalPlugin {
|
|||
}
|
||||
|
||||
isOwner(userId) {
|
||||
return this.configValue("owners").includes(userId);
|
||||
return this.getConfig().owners.includes(userId);
|
||||
}
|
||||
|
||||
@d.command("bot_full_update")
|
||||
async fullUpdateCmd(msg: Message) {
|
||||
if (!this.isOwner(msg.author.id)) return;
|
||||
|
||||
const updateCmd = this.configValue("update_cmd");
|
||||
const updateCmd = this.getConfig().update_cmd;
|
||||
if (!updateCmd) {
|
||||
msg.channel.createMessage(errorMessage("Update command not specified!"));
|
||||
return;
|
||||
|
|
|
@ -7,20 +7,28 @@ import { CaseTypeColors } from "../data/CaseTypeColors";
|
|||
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
||||
import { GuildActions } from "../data/GuildActions";
|
||||
import { GuildArchives } from "../data/GuildArchives";
|
||||
import { IPluginOptions } from "knub";
|
||||
|
||||
export class CasesPlugin extends ZeppelinPlugin {
|
||||
interface ICasesPluginConfig {
|
||||
log_automatic_actions: boolean;
|
||||
case_log_channel: string;
|
||||
}
|
||||
|
||||
export class CasesPlugin extends ZeppelinPlugin<ICasesPluginConfig> {
|
||||
public static pluginName = "cases";
|
||||
|
||||
protected actions: GuildActions;
|
||||
protected cases: GuildCases;
|
||||
protected archives: GuildArchives;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<ICasesPluginConfig> {
|
||||
return {
|
||||
config: {
|
||||
log_automatic_actions: true,
|
||||
case_log_channel: null,
|
||||
},
|
||||
|
||||
permissions: {},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -103,11 +111,9 @@ export class CasesPlugin extends ZeppelinPlugin {
|
|||
await this.createCaseNote(createdCase, modId, reason, automatic, false);
|
||||
}
|
||||
|
||||
if (
|
||||
this.configValue("case_log_channel") &&
|
||||
(!automatic || this.configValue("log_automatic_actions")) &&
|
||||
postInCaseLogOverride !== false
|
||||
) {
|
||||
const config = this.getConfig();
|
||||
|
||||
if (config.case_log_channel && (!automatic || config.log_automatic_actions) && postInCaseLogOverride !== false) {
|
||||
try {
|
||||
await this.postCaseToCaseLogChannel(createdCase);
|
||||
} catch (e) {} // tslint:disable-line
|
||||
|
@ -154,7 +160,7 @@ export class CasesPlugin extends ZeppelinPlugin {
|
|||
this.archives.makePermanent(archiveId);
|
||||
}
|
||||
|
||||
if ((!automatic || this.configValue("log_automatic_actions")) && postInCaseLogOverride !== false) {
|
||||
if ((!automatic || this.getConfig().log_automatic_actions) && postInCaseLogOverride !== false) {
|
||||
try {
|
||||
await this.postCaseToCaseLogChannel(theCase.id);
|
||||
} catch (e) {} // tslint:disable-line
|
||||
|
@ -225,7 +231,7 @@ export class CasesPlugin extends ZeppelinPlugin {
|
|||
* Returns silently if the case log channel isn't specified or is invalid.
|
||||
*/
|
||||
public postToCaseLogChannel(content: MessageContent, file: MessageFile = null): Promise<Message> {
|
||||
const caseLogChannelId = this.configValue("case_log_channel");
|
||||
const caseLogChannelId = this.getConfig().case_log_channel;
|
||||
if (!caseLogChannelId) return;
|
||||
|
||||
const caseLogChannel = this.guild.channels.get(caseLogChannelId);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { decorators as d, Plugin } from "knub";
|
||||
import { decorators as d, IPluginOptions, Plugin } from "knub";
|
||||
import { Invite, Message } from "eris";
|
||||
import escapeStringRegexp from "escape-string-regexp";
|
||||
import { GuildLogs } from "../data/GuildLogs";
|
||||
|
@ -13,8 +13,27 @@ import {
|
|||
import { ZalgoRegex } from "../data/Zalgo";
|
||||
import { GuildSavedMessages } from "../data/GuildSavedMessages";
|
||||
import { SavedMessage } from "../data/entities/SavedMessage";
|
||||
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
||||
|
||||
export class CensorPlugin extends Plugin {
|
||||
interface ICensorPluginConfig {
|
||||
filter_zalgo: boolean;
|
||||
filter_invites: boolean;
|
||||
invite_guild_whitelist: string[];
|
||||
invite_guild_blacklist: string[];
|
||||
invite_code_whitelist: string[];
|
||||
invite_code_blacklist: string[];
|
||||
allow_group_dm_invites: boolean;
|
||||
|
||||
filter_domains: boolean;
|
||||
domain_whitelist: string[];
|
||||
domain_blacklist: string[];
|
||||
|
||||
blocked_tokens: string[];
|
||||
blocked_words: string[];
|
||||
blocked_regex: string[];
|
||||
}
|
||||
|
||||
export class CensorPlugin extends ZeppelinPlugin<ICensorPluginConfig> {
|
||||
public static pluginName = "censor";
|
||||
|
||||
protected serverLogs: GuildLogs;
|
||||
|
@ -23,7 +42,7 @@ export class CensorPlugin extends Plugin {
|
|||
private onMessageCreateFn;
|
||||
private onMessageUpdateFn;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<ICensorPluginConfig> {
|
||||
return {
|
||||
config: {
|
||||
filter_zalgo: false,
|
||||
|
@ -43,6 +62,8 @@ export class CensorPlugin extends Plugin {
|
|||
blocked_regex: null,
|
||||
},
|
||||
|
||||
permissions: {},
|
||||
|
||||
overrides: [
|
||||
{
|
||||
level: ">=50",
|
||||
|
@ -97,12 +118,10 @@ export class CensorPlugin extends Plugin {
|
|||
async applyFiltersToMsg(savedMessage: SavedMessage) {
|
||||
if (!savedMessage.data.content) return;
|
||||
|
||||
const config = this.getConfigForMemberIdAndChannelId(savedMessage.user_id, savedMessage.channel_id);
|
||||
|
||||
// Filter zalgo
|
||||
const filterZalgo = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"filter_zalgo",
|
||||
);
|
||||
const filterZalgo = config.filter_zalgo;
|
||||
if (filterZalgo) {
|
||||
const result = ZalgoRegex.exec(savedMessage.data.content);
|
||||
if (result) {
|
||||
|
@ -112,37 +131,13 @@ export class CensorPlugin extends Plugin {
|
|||
}
|
||||
|
||||
// Filter invites
|
||||
const filterInvites = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"filter_invites",
|
||||
);
|
||||
const filterInvites = config.filter_invites;
|
||||
if (filterInvites) {
|
||||
const inviteGuildWhitelist: string[] = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"invite_guild_whitelist",
|
||||
);
|
||||
const inviteGuildBlacklist: string[] = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"invite_guild_blacklist",
|
||||
);
|
||||
const inviteCodeWhitelist: string[] = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"invite_code_whitelist",
|
||||
);
|
||||
const inviteCodeBlacklist: string[] = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"invite_code_blacklist",
|
||||
);
|
||||
const allowGroupDMInvites: boolean = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"allow_group_dm_invites",
|
||||
);
|
||||
const inviteGuildWhitelist = config.invite_guild_whitelist;
|
||||
const inviteGuildBlacklist = config.invite_guild_blacklist;
|
||||
const inviteCodeWhitelist = config.invite_code_whitelist;
|
||||
const inviteCodeBlacklist = config.invite_code_blacklist;
|
||||
const allowGroupDMInvites = config.allow_group_dm_invites;
|
||||
|
||||
const inviteCodes = getInviteCodesInString(savedMessage.data.content);
|
||||
|
||||
|
@ -185,22 +180,10 @@ export class CensorPlugin extends Plugin {
|
|||
}
|
||||
|
||||
// Filter domains
|
||||
const filterDomains = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"filter_domains",
|
||||
);
|
||||
const filterDomains = config.filter_domains;
|
||||
if (filterDomains) {
|
||||
const domainWhitelist: string[] = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"domain_whitelist",
|
||||
);
|
||||
const domainBlacklist: string[] = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"domain_blacklist",
|
||||
);
|
||||
const domainWhitelist = config.domain_whitelist;
|
||||
const domainBlacklist = config.domain_blacklist;
|
||||
|
||||
const urls = getUrlsInString(savedMessage.data.content);
|
||||
for (const thisUrl of urls) {
|
||||
|
@ -217,8 +200,7 @@ export class CensorPlugin extends Plugin {
|
|||
}
|
||||
|
||||
// Filter tokens
|
||||
const blockedTokens =
|
||||
this.configValueForMemberIdAndChannelId(savedMessage.user_id, savedMessage.channel_id, "blocked_tokens") || [];
|
||||
const blockedTokens = config.blocked_tokens || [];
|
||||
for (const token of blockedTokens) {
|
||||
if (savedMessage.data.content.toLowerCase().includes(token.toLowerCase())) {
|
||||
this.censorMessage(savedMessage, `blocked token (\`${token}\`) found`);
|
||||
|
@ -227,8 +209,7 @@ export class CensorPlugin extends Plugin {
|
|||
}
|
||||
|
||||
// Filter words
|
||||
const blockedWords =
|
||||
this.configValueForMemberIdAndChannelId(savedMessage.user_id, savedMessage.channel_id, "blocked_words") || [];
|
||||
const blockedWords = config.blocked_words || [];
|
||||
for (const word of blockedWords) {
|
||||
const regex = new RegExp(`\\b${escapeStringRegexp(word)}\\b`, "i");
|
||||
if (regex.test(savedMessage.data.content)) {
|
||||
|
@ -238,8 +219,7 @@ export class CensorPlugin extends Plugin {
|
|||
}
|
||||
|
||||
// Filter regex
|
||||
const blockedRegex =
|
||||
this.configValueForMemberIdAndChannelId(savedMessage.user_id, savedMessage.channel_id, "blocked_regex") || [];
|
||||
const blockedRegex = config.blocked_regex || [];
|
||||
for (const regexStr of blockedRegex) {
|
||||
const regex = new RegExp(regexStr, "i");
|
||||
if (regex.test(savedMessage.data.content)) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import http, { ServerResponse } from "http";
|
||||
import { GlobalPlugin } from "knub";
|
||||
import { GlobalPlugin, IPluginOptions } from "knub";
|
||||
import { GuildArchives } from "../data/GuildArchives";
|
||||
import { sleep } from "../utils";
|
||||
import moment from "moment-timezone";
|
||||
|
@ -12,12 +12,26 @@ function notFound(res: ServerResponse) {
|
|||
res.end("Not Found");
|
||||
}
|
||||
|
||||
export class LogServerPlugin extends GlobalPlugin {
|
||||
interface ILogServerPluginConfig {
|
||||
port: number;
|
||||
}
|
||||
|
||||
export class LogServerPlugin extends GlobalPlugin<ILogServerPluginConfig> {
|
||||
public static pluginName = "log_server";
|
||||
|
||||
protected archives: GuildArchives;
|
||||
protected server: http.Server;
|
||||
|
||||
protected getDefaultOptions(): IPluginOptions<ILogServerPluginConfig> {
|
||||
return {
|
||||
config: {
|
||||
port: DEFAULT_PORT,
|
||||
},
|
||||
|
||||
permissions: {},
|
||||
};
|
||||
}
|
||||
|
||||
async onLoad() {
|
||||
this.archives = new GuildArchives(null);
|
||||
|
||||
|
@ -55,6 +69,7 @@ export class LogServerPlugin extends GlobalPlugin {
|
|||
}
|
||||
});
|
||||
|
||||
const port = this.getConfig().port;
|
||||
let retried = false;
|
||||
|
||||
this.server.on("error", async (err: any) => {
|
||||
|
@ -62,13 +77,13 @@ export class LogServerPlugin extends GlobalPlugin {
|
|||
console.log("Got EADDRINUSE, retrying in 2 sec...");
|
||||
retried = true;
|
||||
await sleep(2000);
|
||||
this.server.listen(this.configValue("port", DEFAULT_PORT));
|
||||
this.server.listen(port);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
this.server.listen(this.configValue("port", DEFAULT_PORT));
|
||||
this.server.listen(port);
|
||||
}
|
||||
|
||||
async onUnload() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { decorators as d, Plugin } from "knub";
|
||||
import { decorators as d, IPluginOptions, Plugin } from "knub";
|
||||
import { GuildLogs } from "../data/GuildLogs";
|
||||
import { LogType } from "../data/LogType";
|
||||
import { Channel, Constants as ErisConstants, Member, Message, TextChannel, User } from "eris";
|
||||
|
@ -22,6 +22,7 @@ import { GuildSavedMessages } from "../data/GuildSavedMessages";
|
|||
import { SavedMessage } from "../data/entities/SavedMessage";
|
||||
import { GuildArchives } from "../data/GuildArchives";
|
||||
import { GuildCases } from "../data/GuildCases";
|
||||
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
||||
|
||||
interface ILogChannel {
|
||||
include?: string[];
|
||||
|
@ -40,7 +41,24 @@ const unknownUser = {
|
|||
discriminator: "0000",
|
||||
};
|
||||
|
||||
export class LogsPlugin extends Plugin {
|
||||
interface IChannelConfig {
|
||||
include?: string[];
|
||||
exclude?: string[];
|
||||
batched?: boolean;
|
||||
batch_time?: number;
|
||||
}
|
||||
|
||||
interface ILogsPluginConfig {
|
||||
channels: {
|
||||
[key: string]: IChannelConfig;
|
||||
};
|
||||
format: {
|
||||
[key: string]: string;
|
||||
timestamp: string;
|
||||
};
|
||||
}
|
||||
|
||||
export class LogsPlugin extends ZeppelinPlugin<ILogsPluginConfig> {
|
||||
public static pluginName = "logs";
|
||||
|
||||
protected guildLogs: GuildLogs;
|
||||
|
@ -56,7 +74,7 @@ export class LogsPlugin extends Plugin {
|
|||
private onMessageDeleteBulkFn;
|
||||
private onMessageUpdateFn;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<ILogsPluginConfig> {
|
||||
return {
|
||||
config: {
|
||||
channels: {},
|
||||
|
@ -65,6 +83,8 @@ export class LogsPlugin extends Plugin {
|
|||
...DefaultLogMessages,
|
||||
},
|
||||
},
|
||||
|
||||
permissions: {},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -98,7 +118,7 @@ export class LogsPlugin extends Plugin {
|
|||
}
|
||||
|
||||
async log(type, data) {
|
||||
const logChannels: ILogChannelMap = this.configValue("channels");
|
||||
const logChannels: ILogChannelMap = this.getConfig().channels;
|
||||
const typeStr = LogType[type];
|
||||
|
||||
for (const [channelId, opts] of Object.entries(logChannels)) {
|
||||
|
@ -130,12 +150,13 @@ export class LogsPlugin extends Plugin {
|
|||
}
|
||||
|
||||
getLogMessage(type, data): string {
|
||||
const format = this.configValue(`format.${LogType[type]}`, "");
|
||||
const config = this.getConfig();
|
||||
const format = config.format[LogType[type]] || "";
|
||||
if (format === "") return;
|
||||
|
||||
const formatted = formatTemplateString(format, data);
|
||||
|
||||
const timestampFormat = this.configValue("format.timestamp");
|
||||
const timestampFormat = config.format.timestamp;
|
||||
if (timestampFormat) {
|
||||
const timestamp = moment().format(timestampFormat);
|
||||
return `\`[${timestamp}]\` ${formatted}`;
|
||||
|
@ -387,7 +408,7 @@ export class LogsPlugin extends Plugin {
|
|||
member: stripObjectToScalars(member, ["user"]),
|
||||
channel: stripObjectToScalars(channel),
|
||||
messageText: disableCodeBlocks(deactivateMentions(savedMessage.data.content || "<no text content>")),
|
||||
messageDate: moment(savedMessage.data.timestamp, "x").format(this.configValue("format.timestamp")),
|
||||
messageDate: moment(savedMessage.data.timestamp, "x").format(this.getConfig().format.timestamp),
|
||||
attachments: disableLinkPreviews(useMediaUrls(attachments)),
|
||||
},
|
||||
savedMessage.id,
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
import { Plugin, decorators as d } from "knub";
|
||||
import { Plugin, decorators as d, IBasePluginConfig, IPluginOptions } from "knub";
|
||||
import { GuildChannel, Message, TextChannel } from "eris";
|
||||
import { GuildSavedMessages } from "../data/GuildSavedMessages";
|
||||
import { successMessage } from "../utils";
|
||||
|
||||
export class MessageSaverPlugin extends Plugin {
|
||||
interface IMessageSaverPluginPermissions {
|
||||
manage: boolean;
|
||||
}
|
||||
|
||||
export class MessageSaverPlugin extends Plugin<IBasePluginConfig, IMessageSaverPluginPermissions> {
|
||||
public static pluginName = "message_saver";
|
||||
|
||||
protected savedMessages: GuildSavedMessages;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<IBasePluginConfig, IMessageSaverPluginPermissions> {
|
||||
return {
|
||||
config: {},
|
||||
|
||||
permissions: {
|
||||
manage: false,
|
||||
},
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { decorators as d, waitForReaction, waitForReply } from "knub";
|
||||
import { decorators as d, IPluginOptions, waitForReaction, waitForReply } from "knub";
|
||||
import { Attachment, Constants as ErisConstants, Guild, Member, Message, TextChannel, User } from "eris";
|
||||
import humanizeDuration from "humanize-duration";
|
||||
import { GuildCases } from "../data/GuildCases";
|
||||
|
@ -48,7 +48,39 @@ const MessageResultText = {
|
|||
[MessageResult.ChannelMessaged]: "user messaged with a ping",
|
||||
};
|
||||
|
||||
export class ModActionsPlugin extends ZeppelinPlugin {
|
||||
interface IModActionsPluginConfig {
|
||||
dm_on_warn: boolean;
|
||||
dm_on_mute: boolean;
|
||||
dm_on_kick: boolean;
|
||||
dm_on_ban: boolean;
|
||||
message_on_warn: boolean;
|
||||
message_on_mute: boolean;
|
||||
message_on_kick: boolean;
|
||||
message_on_ban: boolean;
|
||||
message_channel: string;
|
||||
warn_message: string;
|
||||
mute_message: string;
|
||||
timed_mute_message: string;
|
||||
kick_message: string;
|
||||
ban_message: string;
|
||||
alert_on_rejoin: boolean;
|
||||
alert_channel: string;
|
||||
}
|
||||
|
||||
interface IModActionsPluginPermissions {
|
||||
note: boolean;
|
||||
warn: boolean;
|
||||
mute: boolean;
|
||||
kick: boolean;
|
||||
ban: boolean;
|
||||
view: boolean;
|
||||
addcase: boolean;
|
||||
massban: boolean;
|
||||
hidecase: boolean;
|
||||
act_as_other: boolean;
|
||||
}
|
||||
|
||||
export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IModActionsPluginPermissions> {
|
||||
public static pluginName = "mod_actions";
|
||||
|
||||
protected actions: GuildActions;
|
||||
|
@ -67,7 +99,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
|
|||
this.ignoredEvents = [];
|
||||
}
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<IModActionsPluginConfig, IModActionsPluginPermissions> {
|
||||
return {
|
||||
config: {
|
||||
dm_on_warn: true,
|
||||
|
@ -225,9 +257,11 @@ export class ModActionsPlugin extends ZeppelinPlugin {
|
|||
*/
|
||||
@d.event("guildMemberAdd")
|
||||
async onGuildMemberAdd(_, member: Member) {
|
||||
if (!this.configValue("alert_on_rejoin")) return;
|
||||
const config = this.getConfig();
|
||||
|
||||
const alertChannelId = this.configValue("alert_channel");
|
||||
if (!config.alert_on_rejoin) return;
|
||||
|
||||
const alertChannelId = config.alert_channel;
|
||||
if (!alertChannelId) return;
|
||||
|
||||
const actions = await this.cases.getByUserId(member.id);
|
||||
|
@ -353,17 +387,16 @@ export class ModActionsPlugin extends ZeppelinPlugin {
|
|||
mod = args.mod;
|
||||
}
|
||||
|
||||
const config = this.getConfig();
|
||||
const reason = this.formatReasonWithAttachments(args.reason, msg.attachments);
|
||||
|
||||
const warnMessage = this.configValue("warn_message")
|
||||
.replace("{guildName}", this.guild.name)
|
||||
.replace("{reason}", reason);
|
||||
const warnMessage = config.warn_message.replace("{guildName}", this.guild.name).replace("{reason}", reason);
|
||||
|
||||
const userMessageResult = await this.tryToMessageUser(
|
||||
args.member.user,
|
||||
warnMessage,
|
||||
this.configValue("dm_on_warn"),
|
||||
this.configValue("message_on_warn"),
|
||||
config.dm_on_warn,
|
||||
config.message_on_warn,
|
||||
);
|
||||
|
||||
if (userMessageResult === MessageResult.Failed) {
|
||||
|
@ -474,10 +507,12 @@ export class ModActionsPlugin extends ZeppelinPlugin {
|
|||
await this.mutes.setCaseId(args.member.id, theCase.id);
|
||||
}
|
||||
|
||||
const config = this.getConfig();
|
||||
|
||||
// Message the user informing them of the mute
|
||||
// Don't message them if we're updating an old mute
|
||||
if (reason && !hasOldCase) {
|
||||
const template = muteTime ? this.configValue("timed_mute_message") : this.configValue("mute_message");
|
||||
const template = muteTime ? config.timed_mute_message : config.mute_message;
|
||||
|
||||
const muteMessage = formatTemplateString(template, {
|
||||
guildName: this.guild.name,
|
||||
|
@ -488,8 +523,8 @@ export class ModActionsPlugin extends ZeppelinPlugin {
|
|||
userMessageResult = await this.tryToMessageUser(
|
||||
args.member.user,
|
||||
muteMessage,
|
||||
this.configValue("dm_on_mute"),
|
||||
this.configValue("message_on_mute"),
|
||||
config.dm_on_mute,
|
||||
config.message_on_mute,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -636,12 +671,13 @@ export class ModActionsPlugin extends ZeppelinPlugin {
|
|||
mod = args.mod;
|
||||
}
|
||||
|
||||
const config = this.getConfig();
|
||||
const reason = this.formatReasonWithAttachments(args.reason, msg.attachments);
|
||||
|
||||
// Attempt to message the user *before* kicking them, as doing it after may not be possible
|
||||
let userMessageResult: MessageResult = MessageResult.Ignored;
|
||||
if (args.reason) {
|
||||
const kickMessage = formatTemplateString(this.configValue("kick_message"), {
|
||||
const kickMessage = formatTemplateString(config.kick_message, {
|
||||
guildName: this.guild.name,
|
||||
reason,
|
||||
});
|
||||
|
@ -649,8 +685,8 @@ export class ModActionsPlugin extends ZeppelinPlugin {
|
|||
userMessageResult = await this.tryToMessageUser(
|
||||
args.member.user,
|
||||
kickMessage,
|
||||
this.configValue("dm_on_kick"),
|
||||
this.configValue("message_on_kick"),
|
||||
config.dm_on_kick,
|
||||
config.message_on_kick,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -705,12 +741,13 @@ export class ModActionsPlugin extends ZeppelinPlugin {
|
|||
mod = args.mod;
|
||||
}
|
||||
|
||||
const config = this.getConfig();
|
||||
const reason = this.formatReasonWithAttachments(args.reason, msg.attachments);
|
||||
|
||||
// Attempt to message the user *before* banning them, as doing it after may not be possible
|
||||
let userMessageResult: MessageResult = MessageResult.Ignored;
|
||||
if (reason) {
|
||||
const banMessage = formatTemplateString(this.configValue("ban_message"), {
|
||||
const banMessage = formatTemplateString(config.ban_message, {
|
||||
guildName: this.guild.name,
|
||||
reason,
|
||||
});
|
||||
|
@ -718,8 +755,8 @@ export class ModActionsPlugin extends ZeppelinPlugin {
|
|||
userMessageResult = await this.tryToMessageUser(
|
||||
args.member.user,
|
||||
banMessage,
|
||||
this.configValue("dm_on_ban"),
|
||||
this.configValue("message_on_ban"),
|
||||
config.dm_on_ban,
|
||||
config.message_on_ban,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1215,9 +1252,11 @@ export class ModActionsPlugin extends ZeppelinPlugin {
|
|||
} catch (e) {} // tslint:disable-line
|
||||
}
|
||||
|
||||
if (useChannel && this.configValue("message_channel")) {
|
||||
const messageChannel = this.getConfig().message_channel;
|
||||
|
||||
if (useChannel && messageChannel) {
|
||||
try {
|
||||
const channel = this.guild.channels.get(this.configValue("message_channel")) as TextChannel;
|
||||
const channel = this.guild.channels.get(messageChannel) as TextChannel;
|
||||
await channel.createMessage(`<@!${user.id}> ${str}`);
|
||||
return MessageResult.ChannelMessaged;
|
||||
} catch (e) {} // tslint:disable-line
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Member, Message, TextableChannel, User } from "eris";
|
||||
import { Member, Message, User } from "eris";
|
||||
import { GuildCases } from "../data/GuildCases";
|
||||
import moment from "moment-timezone";
|
||||
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
||||
|
@ -8,9 +8,18 @@ import { DBDateFormat, chunkMessageLines, stripObjectToScalars, successMessage,
|
|||
import humanizeDuration from "humanize-duration";
|
||||
import { LogType } from "../data/LogType";
|
||||
import { GuildLogs } from "../data/GuildLogs";
|
||||
import { decorators as d } from "knub";
|
||||
import { decorators as d, IPluginOptions } from "knub";
|
||||
|
||||
export class MutesPlugin extends ZeppelinPlugin {
|
||||
interface IMutesPluginConfig {
|
||||
mute_role: string;
|
||||
}
|
||||
|
||||
interface IMutesPluginPermissions {
|
||||
view_list: boolean;
|
||||
cleanup: boolean;
|
||||
}
|
||||
|
||||
export class MutesPlugin extends ZeppelinPlugin<IMutesPluginConfig, IMutesPluginPermissions> {
|
||||
public static pluginName = "mutes";
|
||||
|
||||
protected actions: GuildActions;
|
||||
|
@ -19,7 +28,7 @@ export class MutesPlugin extends ZeppelinPlugin {
|
|||
protected serverLogs: GuildLogs;
|
||||
private muteClearIntervalId: NodeJS.Timer;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<IMutesPluginConfig, IMutesPluginPermissions> {
|
||||
return {
|
||||
config: {
|
||||
mute_role: null,
|
||||
|
@ -71,7 +80,7 @@ export class MutesPlugin extends ZeppelinPlugin {
|
|||
}
|
||||
|
||||
public async muteMember(member: Member, muteTime: number = null) {
|
||||
const muteRole = this.configValue("mute_role");
|
||||
const muteRole = this.getConfig().mute_role;
|
||||
if (!muteRole) return;
|
||||
|
||||
await member.addRole(muteRole);
|
||||
|
@ -82,9 +91,9 @@ export class MutesPlugin extends ZeppelinPlugin {
|
|||
if (unmuteTime) {
|
||||
await this.mutes.addOrUpdateMute(member.id, unmuteTime);
|
||||
} else {
|
||||
const muteRole = this.configValue("mute_role");
|
||||
const muteRole = this.getConfig().mute_role;
|
||||
if (member.roles.includes(muteRole)) {
|
||||
await member.removeRole(this.configValue("mute_role"));
|
||||
await member.removeRole(muteRole);
|
||||
}
|
||||
|
||||
await this.mutes.clear(member.id);
|
||||
|
@ -139,7 +148,7 @@ export class MutesPlugin extends ZeppelinPlugin {
|
|||
// Manually added mute roles
|
||||
const muteUserIds = activeMutes.reduce((set, m) => set.add(m.user_id), new Set());
|
||||
const manuallyMutedMembers = [];
|
||||
const muteRole = this.configValue("mute_role");
|
||||
const muteRole = this.getConfig().mute_role;
|
||||
|
||||
if (muteRole) {
|
||||
this.guild.members.forEach(member => {
|
||||
|
@ -206,7 +215,7 @@ export class MutesPlugin extends ZeppelinPlugin {
|
|||
*/
|
||||
@d.event("guildMemberUpdate")
|
||||
async onGuildMemberUpdate(_, member: Member) {
|
||||
const muteRole = this.configValue("mute_role");
|
||||
const muteRole = this.getConfig().mute_role;
|
||||
if (!muteRole) return;
|
||||
|
||||
const mute = await this.mutes.findExistingMuteForUserId(member.id);
|
||||
|
@ -224,7 +233,7 @@ export class MutesPlugin extends ZeppelinPlugin {
|
|||
@d.permission("cleanup")
|
||||
async clearMutesWithoutRoleCmd(msg: Message) {
|
||||
const activeMutes = await this.mutes.getActiveMutes();
|
||||
const muteRole = this.configValue("mute_role");
|
||||
const muteRole = this.getConfig().mute_role;
|
||||
if (!muteRole) return;
|
||||
|
||||
await msg.channel.createMessage("Clearing mutes from members that don't have the mute role...");
|
||||
|
@ -264,7 +273,7 @@ export class MutesPlugin extends ZeppelinPlugin {
|
|||
|
||||
try {
|
||||
this.serverLogs.ignoreLog(LogType.MEMBER_ROLE_REMOVE, member.id);
|
||||
await member.removeRole(this.configValue("mute_role"));
|
||||
await member.removeRole(this.getConfig().mute_role);
|
||||
} catch (e) {} // tslint:disable-line
|
||||
|
||||
await this.mutes.clear(member.id);
|
||||
|
|
|
@ -1,16 +1,23 @@
|
|||
import { Plugin, decorators as d } from "knub";
|
||||
import { decorators as d, IBasePluginConfig, IPluginOptions } from "knub";
|
||||
import { GuildNameHistory } from "../data/GuildNameHistory";
|
||||
import { Member, Message, Relationship, User } from "eris";
|
||||
import { Member, Message, User } from "eris";
|
||||
import { NameHistoryEntryTypes } from "../data/NameHistoryEntryTypes";
|
||||
import { createChunkedMessage, errorMessage, trimLines } from "../utils";
|
||||
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
||||
|
||||
export class NameHistoryPlugin extends Plugin {
|
||||
interface INameHistoryPluginPermissions {
|
||||
view: boolean;
|
||||
}
|
||||
|
||||
export class NameHistoryPlugin extends ZeppelinPlugin<IBasePluginConfig, INameHistoryPluginPermissions> {
|
||||
public static pluginName = "name_history";
|
||||
|
||||
protected nameHistory: GuildNameHistory;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<IBasePluginConfig, INameHistoryPluginPermissions> {
|
||||
return {
|
||||
config: {},
|
||||
|
||||
permissions: {
|
||||
view: false,
|
||||
},
|
||||
|
|
|
@ -1,24 +1,33 @@
|
|||
import { Plugin, decorators as d } from "knub";
|
||||
import { decorators as d, IPluginOptions } from "knub";
|
||||
import { GuildPersistedData, IPartialPersistData } from "../data/GuildPersistedData";
|
||||
import intersection from "lodash.intersection";
|
||||
import { Member, MemberOptions } from "eris";
|
||||
import { GuildLogs } from "../data/GuildLogs";
|
||||
import { LogType } from "../data/LogType";
|
||||
import { stripObjectToScalars } from "../utils";
|
||||
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
||||
|
||||
export class PersistPlugin extends Plugin {
|
||||
interface IPersistPluginConfig {
|
||||
persisted_roles: string[];
|
||||
persist_nicknames: boolean;
|
||||
persist_voice_mutes: boolean;
|
||||
}
|
||||
|
||||
export class PersistPlugin extends ZeppelinPlugin<IPersistPluginConfig> {
|
||||
public static pluginName = "persist";
|
||||
|
||||
protected persistedData: GuildPersistedData;
|
||||
protected logs: GuildLogs;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<IPersistPluginConfig> {
|
||||
return {
|
||||
config: {
|
||||
persisted_roles: [],
|
||||
persist_nicknames: false,
|
||||
persist_voice_mutes: false,
|
||||
},
|
||||
|
||||
permissions: {},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -31,8 +40,9 @@ export class PersistPlugin extends Plugin {
|
|||
onGuildMemberRemove(_, member: Member) {
|
||||
let persist = false;
|
||||
const persistData: IPartialPersistData = {};
|
||||
const config = this.getConfig();
|
||||
|
||||
const persistedRoles = this.configValue("persisted_roles");
|
||||
const persistedRoles = config.persisted_roles;
|
||||
if (persistedRoles.length && member.roles) {
|
||||
const rolesToPersist = intersection(persistedRoles, member.roles);
|
||||
if (rolesToPersist.length) {
|
||||
|
@ -41,12 +51,12 @@ export class PersistPlugin extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
if (this.configValue("persist_nicknames") && member.nick) {
|
||||
if (config.persist_nicknames && member.nick) {
|
||||
persist = true;
|
||||
persistData.nickname = member.nick;
|
||||
}
|
||||
|
||||
if (this.configValue("persist_voice_mutes") && member.voiceState && member.voiceState.mute) {
|
||||
if (config.persist_voice_mutes && member.voiceState && member.voiceState.mute) {
|
||||
persist = true;
|
||||
persistData.is_voice_muted = true;
|
||||
}
|
||||
|
@ -63,8 +73,9 @@ export class PersistPlugin extends Plugin {
|
|||
|
||||
let restore = false;
|
||||
const toRestore: MemberOptions = {};
|
||||
const config = this.getConfig();
|
||||
|
||||
const persistedRoles = this.configValue("persisted_roles");
|
||||
const persistedRoles = config.persisted_roles;
|
||||
if (persistedRoles.length) {
|
||||
const rolesToRestore = intersection(persistedRoles, persistedData.roles);
|
||||
if (rolesToRestore.length) {
|
||||
|
@ -73,12 +84,12 @@ export class PersistPlugin extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
if (this.configValue("persist_nicknames") && persistedData.nickname) {
|
||||
if (config.persist_nicknames && persistedData.nickname) {
|
||||
restore = true;
|
||||
toRestore.nick = persistedData.nickname;
|
||||
}
|
||||
|
||||
if (this.configValue("persist_voice_mutes") && persistedData.is_voice_muted) {
|
||||
if (config.persist_voice_mutes && persistedData.is_voice_muted) {
|
||||
restore = true;
|
||||
toRestore.mute = true;
|
||||
}
|
||||
|
|
|
@ -1,20 +1,27 @@
|
|||
import { Plugin, decorators as d } from "knub";
|
||||
import { decorators as d, IBasePluginConfig, IPluginOptions } from "knub";
|
||||
import { Message, Role, TextableChannel, User } from "eris";
|
||||
import { GuildPingableRoles } from "../data/GuildPingableRoles";
|
||||
import { PingableRole } from "../data/entities/PingableRole";
|
||||
import { errorMessage, successMessage } from "../utils";
|
||||
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
||||
|
||||
const TIMEOUT = 10 * 1000;
|
||||
|
||||
export class PingableRolesPlugin extends Plugin {
|
||||
interface IPingableRolesPluginPermissions {
|
||||
use: boolean;
|
||||
}
|
||||
|
||||
export class PingableRolesPlugin extends ZeppelinPlugin<IBasePluginConfig, IPingableRolesPluginPermissions> {
|
||||
public static pluginName = "pingable_roles";
|
||||
|
||||
protected pingableRoles: GuildPingableRoles;
|
||||
protected cache: Map<string, PingableRole[]>;
|
||||
protected timeouts: Map<string, any>;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<IBasePluginConfig, IPingableRolesPluginPermissions> {
|
||||
return {
|
||||
config: {},
|
||||
|
||||
permissions: {
|
||||
use: false,
|
||||
},
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
import { Plugin, decorators as d } from "knub";
|
||||
import { Plugin, decorators as d, IBasePluginConfig, IPluginOptions } from "knub";
|
||||
import { Channel, EmbedBase, Message, Role, TextChannel } from "eris";
|
||||
import { errorMessage, downloadFile, roleMentionRegex, getRoleMentions } from "../utils";
|
||||
import { errorMessage, downloadFile, getRoleMentions } from "../utils";
|
||||
import { GuildSavedMessages } from "../data/GuildSavedMessages";
|
||||
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
||||
|
||||
import fs from "fs";
|
||||
const fsp = fs.promises;
|
||||
|
||||
const COLOR_MATCH_REGEX = /^#?([0-9a-f]{6})$/;
|
||||
|
||||
export class PostPlugin extends Plugin {
|
||||
interface IPostPluginPermissions {
|
||||
post: boolean;
|
||||
edit: boolean;
|
||||
}
|
||||
|
||||
export class PostPlugin extends ZeppelinPlugin<IBasePluginConfig, IPostPluginPermissions> {
|
||||
public static pluginName = "post";
|
||||
|
||||
protected savedMessages: GuildSavedMessages;
|
||||
|
@ -17,8 +23,10 @@ export class PostPlugin extends Plugin {
|
|||
this.savedMessages = GuildSavedMessages.getInstance(this.guildId);
|
||||
}
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<IBasePluginConfig, IPostPluginPermissions> {
|
||||
return {
|
||||
config: {},
|
||||
|
||||
permissions: {
|
||||
post: false,
|
||||
edit: false,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { decorators as d, logger } from "knub";
|
||||
import { decorators as d, IPluginOptions, logger } from "knub";
|
||||
import { CustomEmoji, errorMessage, isSnowflake, noop, sleep, successMessage } from "../utils";
|
||||
import { GuildReactionRoles } from "../data/GuildReactionRoles";
|
||||
import { Message, TextChannel } from "eris";
|
||||
|
@ -25,7 +25,16 @@ type PendingMemberRoleChanges = {
|
|||
}>;
|
||||
};
|
||||
|
||||
export class ReactionRolesPlugin extends ZeppelinPlugin {
|
||||
interface IReactionRolesPluginConfig {
|
||||
auto_refresh_interval: number;
|
||||
}
|
||||
|
||||
interface IReactionRolesPluginPermissions {
|
||||
manage: boolean;
|
||||
fallback_command: boolean;
|
||||
}
|
||||
|
||||
export class ReactionRolesPlugin extends ZeppelinPlugin<IReactionRolesPluginConfig, IReactionRolesPluginPermissions> {
|
||||
public static pluginName = "reaction_roles";
|
||||
|
||||
protected reactionRoles: GuildReactionRoles;
|
||||
|
@ -37,7 +46,7 @@ export class ReactionRolesPlugin extends ZeppelinPlugin {
|
|||
|
||||
private autoRefreshTimeout;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<IReactionRolesPluginConfig, IReactionRolesPluginPermissions> {
|
||||
return {
|
||||
config: {
|
||||
auto_refresh_interval: null,
|
||||
|
@ -66,7 +75,7 @@ export class ReactionRolesPlugin extends ZeppelinPlugin {
|
|||
this.pendingRoleChanges = new Map();
|
||||
this.pendingRefreshes = new Set();
|
||||
|
||||
let autoRefreshInterval = this.configValue("auto_refresh_interval");
|
||||
let autoRefreshInterval = this.getConfig().auto_refresh_interval;
|
||||
if (autoRefreshInterval != null) {
|
||||
autoRefreshInterval = Math.max(MIN_AUTO_REFRESH, autoRefreshInterval);
|
||||
this.autoRefreshLoop(autoRefreshInterval);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { decorators as d } from "knub";
|
||||
import { decorators as d, IBasePluginConfig, IPluginOptions } from "knub";
|
||||
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
||||
import { GuildReminders } from "../data/GuildReminders";
|
||||
import { Message, TextChannel } from "eris";
|
||||
|
@ -9,7 +9,11 @@ import { convertDelayStringToMS, createChunkedMessage, errorMessage, sorter, suc
|
|||
const REMINDER_LOOP_TIME = 10 * 1000;
|
||||
const MAX_TRIES = 3;
|
||||
|
||||
export class RemindersPlugin extends ZeppelinPlugin {
|
||||
interface IRemindersPluginPermissions {
|
||||
use: boolean;
|
||||
}
|
||||
|
||||
export class RemindersPlugin extends ZeppelinPlugin<IBasePluginConfig, IRemindersPluginPermissions> {
|
||||
public static pluginName = "reminders";
|
||||
|
||||
protected reminders: GuildReminders;
|
||||
|
@ -17,8 +21,10 @@ export class RemindersPlugin extends ZeppelinPlugin {
|
|||
|
||||
private postRemindersTimeout;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<IBasePluginConfig, IRemindersPluginPermissions> {
|
||||
return {
|
||||
config: {},
|
||||
|
||||
permissions: {
|
||||
use: false,
|
||||
},
|
||||
|
|
|
@ -1,15 +1,24 @@
|
|||
import { Plugin, decorators as d } from "knub";
|
||||
import { Plugin, decorators as d, IBasePluginConfig, IPluginOptions } from "knub";
|
||||
import { GuildSelfGrantableRoles } from "../data/GuildSelfGrantableRoles";
|
||||
import { GuildChannel, Message, Role, TextChannel } from "eris";
|
||||
import { chunkArray, errorMessage, sorter, successMessage } from "../utils";
|
||||
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
||||
|
||||
export class SelfGrantableRolesPlugin extends Plugin {
|
||||
interface ISelfGrantableRolesPluginPermissions {
|
||||
manage: boolean;
|
||||
use: boolean;
|
||||
ignore_cooldown: boolean;
|
||||
}
|
||||
|
||||
export class SelfGrantableRolesPlugin extends ZeppelinPlugin<IBasePluginConfig, ISelfGrantableRolesPluginPermissions> {
|
||||
public static pluginName = "self_grantable_roles";
|
||||
|
||||
protected selfGrantableRoles: GuildSelfGrantableRoles;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<IBasePluginConfig, ISelfGrantableRolesPluginPermissions> {
|
||||
return {
|
||||
config: {},
|
||||
|
||||
permissions: {
|
||||
manage: false,
|
||||
use: false,
|
||||
|
|
|
@ -1,17 +1,25 @@
|
|||
import { Plugin, decorators as d } from "knub";
|
||||
import { Plugin, decorators as d, IBasePluginConfig, IPluginOptions } from "knub";
|
||||
import { GuildChannel, Message, TextChannel, Constants as ErisConstants, User } from "eris";
|
||||
import { convertDelayStringToMS, errorMessage, noop, successMessage } from "../utils";
|
||||
import { GuildSlowmodes } from "../data/GuildSlowmodes";
|
||||
import humanizeDuration from "humanize-duration";
|
||||
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
||||
|
||||
export class SlowmodePlugin extends Plugin {
|
||||
interface ISlowmodePluginPermissions {
|
||||
manage: boolean;
|
||||
affected: boolean;
|
||||
}
|
||||
|
||||
export class SlowmodePlugin extends ZeppelinPlugin<IBasePluginConfig, ISlowmodePluginPermissions> {
|
||||
public static pluginName = "slowmode";
|
||||
|
||||
protected slowmodes: GuildSlowmodes;
|
||||
protected clearInterval;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<IBasePluginConfig, ISlowmodePluginPermissions> {
|
||||
return {
|
||||
config: {},
|
||||
|
||||
permissions: {
|
||||
manage: false,
|
||||
affected: true,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { decorators as d, Plugin } from "knub";
|
||||
import { decorators as d, IPluginOptions, Plugin } from "knub";
|
||||
import { Channel, Member, User } from "eris";
|
||||
import {
|
||||
getEmojiInString,
|
||||
|
@ -18,6 +18,7 @@ import { GuildSavedMessages } from "../data/GuildSavedMessages";
|
|||
import { GuildActions } from "../data/GuildActions";
|
||||
import { Case } from "../data/entities/Case";
|
||||
import { GuildMutes } from "../data/GuildMutes";
|
||||
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
||||
|
||||
enum RecentActionType {
|
||||
Message = 1,
|
||||
|
@ -44,7 +45,28 @@ const MAX_INTERVAL = 300;
|
|||
|
||||
const SPAM_ARCHIVE_EXPIRY_DAYS = 90;
|
||||
|
||||
export class SpamPlugin extends Plugin {
|
||||
interface IBaseSingleSpamConfig {
|
||||
interval: number;
|
||||
count: number;
|
||||
mute?: boolean;
|
||||
mute_time?: number;
|
||||
clean?: boolean;
|
||||
}
|
||||
|
||||
interface ISpamPluginConfig {
|
||||
max_censor: IBaseSingleSpamConfig;
|
||||
max_messages: IBaseSingleSpamConfig;
|
||||
max_mentions: IBaseSingleSpamConfig;
|
||||
max_links: IBaseSingleSpamConfig;
|
||||
max_attachments: IBaseSingleSpamConfig;
|
||||
max_emojis: IBaseSingleSpamConfig;
|
||||
max_newlines: IBaseSingleSpamConfig;
|
||||
max_duplicates: IBaseSingleSpamConfig;
|
||||
max_characters: IBaseSingleSpamConfig;
|
||||
max_voice_moves: IBaseSingleSpamConfig;
|
||||
}
|
||||
|
||||
export class SpamPlugin extends ZeppelinPlugin<ISpamPluginConfig> {
|
||||
public static pluginName = "spam";
|
||||
|
||||
protected actions: GuildActions;
|
||||
|
@ -68,9 +90,10 @@ export class SpamPlugin extends Plugin {
|
|||
|
||||
private expiryInterval;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<ISpamPluginConfig> {
|
||||
return {
|
||||
config: {
|
||||
max_censor: null,
|
||||
max_messages: null,
|
||||
max_mentions: null,
|
||||
max_links: null,
|
||||
|
@ -82,6 +105,8 @@ export class SpamPlugin extends Plugin {
|
|||
max_voice_moves: null,
|
||||
},
|
||||
|
||||
permissions: {},
|
||||
|
||||
// Default override to make mods immune to the spam filter
|
||||
overrides: [
|
||||
{
|
||||
|
@ -178,7 +203,7 @@ export class SpamPlugin extends Plugin {
|
|||
async logAndDetectMessageSpam(
|
||||
savedMessage: SavedMessage,
|
||||
type: RecentActionType,
|
||||
spamConfig: any,
|
||||
spamConfig: IBaseSingleSpamConfig,
|
||||
actionCount: number,
|
||||
description: string,
|
||||
) {
|
||||
|
@ -360,11 +385,9 @@ export class SpamPlugin extends Plugin {
|
|||
|
||||
// For interoperability with the Censor plugin
|
||||
async logCensor(savedMessage: SavedMessage) {
|
||||
const spamConfig = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"max_censor",
|
||||
);
|
||||
const config = this.getConfigForMemberIdAndChannelId(savedMessage.user_id, savedMessage.channel_id);
|
||||
const spamConfig = config.max_censor;
|
||||
|
||||
if (spamConfig) {
|
||||
this.logAndDetectMessageSpam(savedMessage, RecentActionType.Censor, spamConfig, 1, "too many censored messages");
|
||||
}
|
||||
|
@ -373,20 +396,14 @@ export class SpamPlugin extends Plugin {
|
|||
async onMessageCreate(savedMessage: SavedMessage) {
|
||||
if (savedMessage.is_bot) return;
|
||||
|
||||
const maxMessages = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"max_messages",
|
||||
);
|
||||
const config = this.getConfigForMemberIdAndChannelId(savedMessage.user_id, savedMessage.channel_id);
|
||||
|
||||
const maxMessages = config.max_messages;
|
||||
if (maxMessages) {
|
||||
this.logAndDetectMessageSpam(savedMessage, RecentActionType.Message, maxMessages, 1, "too many messages");
|
||||
}
|
||||
|
||||
const maxMentions = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"max_mentions",
|
||||
);
|
||||
const maxMentions = config.max_mentions;
|
||||
const mentions = savedMessage.data.content
|
||||
? [...getUserMentions(savedMessage.data.content), ...getRoleMentions(savedMessage.data.content)]
|
||||
: [];
|
||||
|
@ -400,21 +417,13 @@ export class SpamPlugin extends Plugin {
|
|||
);
|
||||
}
|
||||
|
||||
const maxLinks = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"max_links",
|
||||
);
|
||||
if (maxLinks && savedMessage.data.content) {
|
||||
const maxLinks = config.max_links;
|
||||
if (maxLinks && savedMessage.data.content && typeof savedMessage.data.content === "string") {
|
||||
const links = getUrlsInString(savedMessage.data.content);
|
||||
this.logAndDetectMessageSpam(savedMessage, RecentActionType.Link, maxLinks, links.length, "too many links");
|
||||
}
|
||||
|
||||
const maxAttachments = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"max_attachments",
|
||||
);
|
||||
const maxAttachments = config.max_attachments;
|
||||
if (maxAttachments && savedMessage.data.attachments) {
|
||||
this.logAndDetectMessageSpam(
|
||||
savedMessage,
|
||||
|
@ -425,21 +434,13 @@ export class SpamPlugin extends Plugin {
|
|||
);
|
||||
}
|
||||
|
||||
const maxEmoji = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"max_emojis",
|
||||
);
|
||||
const maxEmoji = config.max_emojis;
|
||||
if (maxEmoji && savedMessage.data.content) {
|
||||
const emojiCount = getEmojiInString(savedMessage.data.content).length;
|
||||
this.logAndDetectMessageSpam(savedMessage, RecentActionType.Emoji, maxEmoji, emojiCount, "too many emoji");
|
||||
}
|
||||
|
||||
const maxNewlines = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"max_newlines",
|
||||
);
|
||||
const maxNewlines = config.max_newlines;
|
||||
if (maxNewlines && savedMessage.data.content) {
|
||||
const newlineCount = (savedMessage.data.content.match(/\n/g) || []).length;
|
||||
this.logAndDetectMessageSpam(
|
||||
|
@ -451,11 +452,7 @@ export class SpamPlugin extends Plugin {
|
|||
);
|
||||
}
|
||||
|
||||
const maxCharacters = this.configValueForMemberIdAndChannelId(
|
||||
savedMessage.user_id,
|
||||
savedMessage.channel_id,
|
||||
"max_characters",
|
||||
);
|
||||
const maxCharacters = config.max_characters;
|
||||
if (maxCharacters && savedMessage.data.content) {
|
||||
const characterCount = [...savedMessage.data.content.trim()].length;
|
||||
this.logAndDetectMessageSpam(
|
||||
|
@ -473,11 +470,12 @@ export class SpamPlugin extends Plugin {
|
|||
@d.event("voiceChannelJoin")
|
||||
@d.event("voiceChannelSwitch")
|
||||
onVoiceChannelSwitch(member: Member, channel: Channel) {
|
||||
const spamConfig = this.configValueForMemberIdAndChannelId(member.id, channel.id, "max_voice_moves");
|
||||
if (spamConfig) {
|
||||
const config = this.getConfigForMemberIdAndChannelId(member.id, channel.id);
|
||||
const maxVoiceMoves = config.max_voice_moves;
|
||||
if (maxVoiceMoves) {
|
||||
this.logAndDetectOtherSpam(
|
||||
RecentActionType.VoiceChannelMove,
|
||||
spamConfig,
|
||||
maxVoiceMoves,
|
||||
member.id,
|
||||
1,
|
||||
"0",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { decorators as d, waitForReply, utils as knubUtils } from "knub";
|
||||
import { decorators as d, waitForReply, utils as knubUtils, IBasePluginConfig, IPluginOptions } from "knub";
|
||||
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
||||
import { GuildStarboards } from "../data/GuildStarboards";
|
||||
import { GuildChannel, Message, TextChannel } from "eris";
|
||||
|
@ -17,7 +17,11 @@ import moment from "moment-timezone";
|
|||
import { GuildSavedMessages } from "../data/GuildSavedMessages";
|
||||
import { SavedMessage } from "../data/entities/SavedMessage";
|
||||
|
||||
export class StarboardPlugin extends ZeppelinPlugin {
|
||||
interface IStarboardPluginPermissions {
|
||||
manage: boolean;
|
||||
}
|
||||
|
||||
export class StarboardPlugin extends ZeppelinPlugin<IBasePluginConfig, IStarboardPluginPermissions> {
|
||||
public static pluginName = "starboard";
|
||||
|
||||
protected starboards: GuildStarboards;
|
||||
|
@ -25,8 +29,10 @@ export class StarboardPlugin extends ZeppelinPlugin {
|
|||
|
||||
private onMessageDeleteFn;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<IBasePluginConfig, IStarboardPluginPermissions> {
|
||||
return {
|
||||
config: {},
|
||||
|
||||
permissions: {
|
||||
manage: false,
|
||||
},
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Plugin, decorators as d } from "knub";
|
||||
import { Plugin, decorators as d, IPluginOptions } from "knub";
|
||||
import { Message, TextChannel } from "eris";
|
||||
import { errorMessage, successMessage } from "../utils";
|
||||
import { GuildTags } from "../data/GuildTags";
|
||||
|
@ -6,6 +6,7 @@ import { GuildSavedMessages } from "../data/GuildSavedMessages";
|
|||
import { SavedMessage } from "../data/entities/SavedMessage";
|
||||
import moment from "moment-timezone";
|
||||
import humanizeDuration from "humanize-duration";
|
||||
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
||||
|
||||
const TAG_FUNCTIONS = {
|
||||
countdown(toDate) {
|
||||
|
@ -14,10 +15,21 @@ const TAG_FUNCTIONS = {
|
|||
const diff = target.diff(now);
|
||||
const result = humanizeDuration(diff, { largest: 2, round: true });
|
||||
return diff >= 0 ? result : `${result} ago`;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export class TagsPlugin extends Plugin {
|
||||
interface ITagsPluginConfig {
|
||||
prefix: string;
|
||||
delete_with_command: boolean;
|
||||
}
|
||||
|
||||
interface ITagsPluginPermissions {
|
||||
create: boolean;
|
||||
use: boolean;
|
||||
list: boolean;
|
||||
}
|
||||
|
||||
export class TagsPlugin extends ZeppelinPlugin<ITagsPluginConfig, ITagsPluginPermissions> {
|
||||
public static pluginName = "tags";
|
||||
|
||||
protected tags: GuildTags;
|
||||
|
@ -26,17 +38,17 @@ export class TagsPlugin extends Plugin {
|
|||
private onMessageCreateFn;
|
||||
private onMessageDeleteFn;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<ITagsPluginConfig, ITagsPluginPermissions> {
|
||||
return {
|
||||
config: {
|
||||
prefix: "!!",
|
||||
delete_with_command: true
|
||||
delete_with_command: true,
|
||||
},
|
||||
|
||||
permissions: {
|
||||
create: false,
|
||||
use: true,
|
||||
list: false
|
||||
list: false,
|
||||
},
|
||||
|
||||
overrides: [
|
||||
|
@ -44,10 +56,10 @@ export class TagsPlugin extends Plugin {
|
|||
level: ">=50",
|
||||
permissions: {
|
||||
create: true,
|
||||
list: true
|
||||
}
|
||||
}
|
||||
]
|
||||
list: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -78,7 +90,7 @@ export class TagsPlugin extends Plugin {
|
|||
return;
|
||||
}
|
||||
|
||||
const prefix = this.configValueForMsg(msg, "prefix");
|
||||
const prefix = this.getConfigForMsg(msg).prefix;
|
||||
const tagNames = tags.map(t => t.tag).sort();
|
||||
msg.channel.createMessage(`
|
||||
Available tags (use with ${prefix}tag): \`\`\`${tagNames.join(", ")}\`\`\`
|
||||
|
@ -103,7 +115,7 @@ export class TagsPlugin extends Plugin {
|
|||
async tagCmd(msg: Message, args: { tag: string; body: string }) {
|
||||
await this.tags.createOrUpdate(args.tag, args.body, msg.author.id);
|
||||
|
||||
const prefix = this.configValue("prefix");
|
||||
const prefix = this.getConfig().prefix;
|
||||
msg.channel.createMessage(successMessage(`Tag set! Use it with: \`${prefix}${args.tag}\``));
|
||||
}
|
||||
|
||||
|
@ -114,7 +126,7 @@ export class TagsPlugin extends Plugin {
|
|||
if (!msg.data.content) return;
|
||||
if (msg.is_bot) return;
|
||||
|
||||
const prefix = this.configValueForMemberIdAndChannelId(msg.user_id, msg.channel_id, "prefix");
|
||||
const prefix = this.getConfigForMemberIdAndChannelId(msg.user_id, msg.channel_id).prefix;
|
||||
if (!msg.data.content.startsWith(prefix)) return;
|
||||
|
||||
const tagNameMatch = msg.data.content.slice(prefix.length).match(/^\S+/);
|
||||
|
@ -148,7 +160,7 @@ export class TagsPlugin extends Plugin {
|
|||
const responseMsg = await channel.createMessage(body);
|
||||
|
||||
// Save the command-response message pair once the message is in our database
|
||||
if (this.configValueForMemberIdAndChannelId(msg.user_id, msg.channel_id, "delete_with_command")) {
|
||||
if (this.getConfigForMemberIdAndChannelId(msg.user_id, msg.channel_id).delete_with_command) {
|
||||
this.savedMessages.onceMessageAvailable(responseMsg.id, async () => {
|
||||
await this.tags.addResponse(msg.id, responseMsg.id);
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { decorators as d } from "knub";
|
||||
import { decorators as d, IBasePluginConfig, IPluginOptions } from "knub";
|
||||
import { CategoryChannel, Channel, EmbedOptions, Member, Message, Role, TextChannel, User, VoiceChannel } from "eris";
|
||||
import {
|
||||
channelMentionRegex,
|
||||
|
@ -33,7 +33,21 @@ const CLEAN_COMMAND_DELETE_DELAY = 5000;
|
|||
|
||||
const activeReloads: Map<string, TextChannel> = new Map();
|
||||
|
||||
export class UtilityPlugin extends ZeppelinPlugin {
|
||||
interface IUtilityPluginPermissions {
|
||||
roles: boolean;
|
||||
level: boolean;
|
||||
search: boolean;
|
||||
clean: boolean;
|
||||
info: boolean;
|
||||
server: boolean;
|
||||
reload_guild: boolean;
|
||||
nickname: boolean;
|
||||
ping: boolean;
|
||||
source: boolean;
|
||||
vcmove: boolean;
|
||||
}
|
||||
|
||||
export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPluginPermissions> {
|
||||
public static pluginName = "utility";
|
||||
|
||||
protected logs: GuildLogs;
|
||||
|
@ -41,8 +55,10 @@ export class UtilityPlugin extends ZeppelinPlugin {
|
|||
protected savedMessages: GuildSavedMessages;
|
||||
protected archives: GuildArchives;
|
||||
|
||||
getDefaultOptions() {
|
||||
getDefaultOptions(): IPluginOptions<IBasePluginConfig, IUtilityPluginPermissions> {
|
||||
return {
|
||||
config: {},
|
||||
|
||||
permissions: {
|
||||
roles: false,
|
||||
level: false,
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import { IPluginOptions, Plugin } from "knub";
|
||||
import { IBasePluginConfig, IBasePluginPermissions, IPluginOptions, Plugin } from "knub";
|
||||
import { PluginRuntimeError } from "../PluginRuntimeError";
|
||||
import Ajv, { ErrorObject } from "ajv";
|
||||
import { isSnowflake, isUnicodeEmoji } from "../utils";
|
||||
|
||||
export class ZeppelinPlugin extends Plugin {
|
||||
export class ZeppelinPlugin<
|
||||
TConfig extends {} = IBasePluginConfig,
|
||||
TPermissions extends {} = IBasePluginPermissions
|
||||
> extends Plugin<TConfig, TPermissions> {
|
||||
protected configSchema: any;
|
||||
protected permissionsSchema: any;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue