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