Update to Knub 19.1.1 and update plugins accordingly

This commit is contained in:
Dragory 2019-04-13 01:44:18 +03:00
parent 18e321f5bb
commit 50f5792bc5
24 changed files with 349 additions and 410 deletions

117
package-lock.json generated
View file

@ -2880,9 +2880,9 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
}, },
"fsevents": { "fsevents": {
"version": "1.2.4", "version": "1.2.7",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz",
"integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==",
"dev": true, "dev": true,
"optional": true, "optional": true,
"requires": { "requires": {
@ -2899,7 +2899,8 @@
"ansi-regex": { "ansi-regex": {
"version": "2.1.1", "version": "2.1.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"aproba": { "aproba": {
"version": "1.2.0", "version": "1.2.0",
@ -2908,7 +2909,7 @@
"optional": true "optional": true
}, },
"are-we-there-yet": { "are-we-there-yet": {
"version": "1.1.4", "version": "1.1.5",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true, "optional": true,
@ -2920,19 +2921,21 @@
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
} }
}, },
"chownr": { "chownr": {
"version": "1.0.1", "version": "1.1.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true "optional": true
@ -2940,17 +2943,20 @@
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"console-control-strings": { "console-control-strings": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
@ -2968,7 +2974,7 @@
} }
}, },
"deep-extend": { "deep-extend": {
"version": "0.5.1", "version": "0.6.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true "optional": true
@ -3017,7 +3023,7 @@
} }
}, },
"glob": { "glob": {
"version": "7.1.2", "version": "7.1.3",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true, "optional": true,
@ -3037,12 +3043,12 @@
"optional": true "optional": true
}, },
"iconv-lite": { "iconv-lite": {
"version": "0.4.21", "version": "0.4.24",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true, "optional": true,
"requires": { "requires": {
"safer-buffer": "^2.1.0" "safer-buffer": ">= 2.1.2 < 3"
} }
}, },
"ignore-walk": { "ignore-walk": {
@ -3067,7 +3073,8 @@
"inherits": { "inherits": {
"version": "2.0.3", "version": "2.0.3",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"ini": { "ini": {
"version": "1.3.5", "version": "1.3.5",
@ -3079,6 +3086,7 @@
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"number-is-nan": "^1.0.0" "number-is-nan": "^1.0.0"
} }
@ -3093,6 +3101,7 @@
"version": "3.0.4", "version": "3.0.4",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
} }
@ -3100,19 +3109,21 @@
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"minipass": { "minipass": {
"version": "2.2.4", "version": "2.3.5",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"safe-buffer": "^5.1.1", "safe-buffer": "^5.1.2",
"yallist": "^3.0.0" "yallist": "^3.0.0"
} }
}, },
"minizlib": { "minizlib": {
"version": "1.1.0", "version": "1.2.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true, "optional": true,
@ -3124,6 +3135,7 @@
"version": "0.5.1", "version": "0.5.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"minimist": "0.0.8" "minimist": "0.0.8"
} }
@ -3135,7 +3147,7 @@
"optional": true "optional": true
}, },
"needle": { "needle": {
"version": "2.2.0", "version": "2.2.4",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true, "optional": true,
@ -3146,18 +3158,18 @@
} }
}, },
"node-pre-gyp": { "node-pre-gyp": {
"version": "0.10.0", "version": "0.10.3",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true, "optional": true,
"requires": { "requires": {
"detect-libc": "^1.0.2", "detect-libc": "^1.0.2",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"needle": "^2.2.0", "needle": "^2.2.1",
"nopt": "^4.0.1", "nopt": "^4.0.1",
"npm-packlist": "^1.1.6", "npm-packlist": "^1.1.6",
"npmlog": "^4.0.2", "npmlog": "^4.0.2",
"rc": "^1.1.7", "rc": "^1.2.7",
"rimraf": "^2.6.1", "rimraf": "^2.6.1",
"semver": "^5.3.0", "semver": "^5.3.0",
"tar": "^4" "tar": "^4"
@ -3174,13 +3186,13 @@
} }
}, },
"npm-bundled": { "npm-bundled": {
"version": "1.0.3", "version": "1.0.5",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true "optional": true
}, },
"npm-packlist": { "npm-packlist": {
"version": "1.1.10", "version": "1.2.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true, "optional": true,
@ -3204,7 +3216,8 @@
"number-is-nan": { "number-is-nan": {
"version": "1.0.1", "version": "1.0.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
@ -3216,6 +3229,7 @@
"version": "1.4.0", "version": "1.4.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"wrappy": "1" "wrappy": "1"
} }
@ -3255,12 +3269,12 @@
"optional": true "optional": true
}, },
"rc": { "rc": {
"version": "1.2.7", "version": "1.2.8",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true, "optional": true,
"requires": { "requires": {
"deep-extend": "^0.5.1", "deep-extend": "^0.6.0",
"ini": "~1.3.0", "ini": "~1.3.0",
"minimist": "^1.2.0", "minimist": "^1.2.0",
"strip-json-comments": "~2.0.1" "strip-json-comments": "~2.0.1"
@ -3290,18 +3304,19 @@
} }
}, },
"rimraf": { "rimraf": {
"version": "2.6.2", "version": "2.6.3",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true, "optional": true,
"requires": { "requires": {
"glob": "^7.0.5" "glob": "^7.1.3"
} }
}, },
"safe-buffer": { "safe-buffer": {
"version": "5.1.1", "version": "5.1.2",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
@ -3316,7 +3331,7 @@
"optional": true "optional": true
}, },
"semver": { "semver": {
"version": "5.5.0", "version": "5.6.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true "optional": true
@ -3337,6 +3352,7 @@
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"code-point-at": "^1.0.0", "code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0", "is-fullwidth-code-point": "^1.0.0",
@ -3356,6 +3372,7 @@
"version": "3.0.1", "version": "3.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"ansi-regex": "^2.0.0" "ansi-regex": "^2.0.0"
} }
@ -3367,17 +3384,17 @@
"optional": true "optional": true
}, },
"tar": { "tar": {
"version": "4.4.1", "version": "4.4.8",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true, "optional": true,
"requires": { "requires": {
"chownr": "^1.0.1", "chownr": "^1.1.1",
"fs-minipass": "^1.2.5", "fs-minipass": "^1.2.5",
"minipass": "^2.2.4", "minipass": "^2.3.4",
"minizlib": "^1.1.0", "minizlib": "^1.1.1",
"mkdirp": "^0.5.0", "mkdirp": "^0.5.0",
"safe-buffer": "^5.1.1", "safe-buffer": "^5.1.2",
"yallist": "^3.0.2" "yallist": "^3.0.2"
} }
}, },
@ -3388,23 +3405,25 @@
"optional": true "optional": true
}, },
"wide-align": { "wide-align": {
"version": "1.1.2", "version": "1.1.3",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true, "optional": true,
"requires": { "requires": {
"string-width": "^1.0.2" "string-width": "^1.0.2 || 2"
} }
}, },
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"yallist": { "yallist": {
"version": "3.0.2", "version": "3.0.3",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
} }
} }
}, },
@ -5160,9 +5179,9 @@
"dev": true "dev": true
}, },
"knub": { "knub": {
"version": "18.2.0", "version": "19.1.1",
"resolved": "https://registry.npmjs.org/knub/-/knub-18.2.0.tgz", "resolved": "https://registry.npmjs.org/knub/-/knub-19.1.1.tgz",
"integrity": "sha512-FRRNmdA/lKjHdw+89uL+CgBLa4A4b4bpQKSHpvoxEDIMjejd482A7YpZ+4iwqpd6+Ua8C5NPBYtoAZlixT4cyw==", "integrity": "sha512-TOup9M+vV7Pij3KQE9yuC76mpz0GuJyVi+jvqfeRtDMEGAQc64Z1vtudK1He5xIRS3UdSS1s7emE9pSPnNxbeQ==",
"requires": { "requires": {
"escape-string-regexp": "^1.0.5", "escape-string-regexp": "^1.0.5",
"lodash.at": "^4.6.0", "lodash.at": "^4.6.0",
@ -5772,9 +5791,9 @@
} }
}, },
"nan": { "nan": {
"version": "2.10.0", "version": "2.13.2",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz",
"integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==",
"dev": true, "dev": true,
"optional": true "optional": true
}, },

View file

@ -34,7 +34,7 @@
"escape-string-regexp": "^1.0.5", "escape-string-regexp": "^1.0.5",
"humanize-duration": "^3.15.0", "humanize-duration": "^3.15.0",
"js-yaml": "^3.13.1", "js-yaml": "^3.13.1",
"knub": "^18.2.0", "knub": "^19.1.1",
"lodash.at": "^4.6.0", "lodash.at": "^4.6.0",
"lodash.chunk": "^4.2.0", "lodash.chunk": "^4.2.0",
"lodash.difference": "^4.5.0", "lodash.difference": "^4.5.0",

View file

@ -6,11 +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";
interface IAutoReactionsPluginPermissions { interface IAutoReactionsPluginConfig {
use: boolean; can_manage: boolean;
} }
export class AutoReactionsPlugin extends ZeppelinPlugin<IBasePluginConfig, IAutoReactionsPluginPermissions> { export class AutoReactionsPlugin extends ZeppelinPlugin<IAutoReactionsPluginConfig> {
public static pluginName = "auto_reactions"; public static pluginName = "auto_reactions";
protected savedMessages: GuildSavedMessages; protected savedMessages: GuildSavedMessages;
@ -18,19 +18,17 @@ export class AutoReactionsPlugin extends ZeppelinPlugin<IBasePluginConfig, IAuto
private onMessageCreateFn; private onMessageCreateFn;
getDefaultOptions(): IPluginOptions<IBasePluginConfig, IAutoReactionsPluginPermissions> { getDefaultOptions(): IPluginOptions<IAutoReactionsPluginConfig> {
return { return {
config: {}, config: {
can_manage: false,
permissions: {
use: false,
}, },
overrides: [ overrides: [
{ {
level: ">=100", level: ">=100",
permissions: { config: {
use: true, can_manage: true,
}, },
}, },
], ],
@ -55,7 +53,6 @@ export class AutoReactionsPlugin extends ZeppelinPlugin<IBasePluginConfig, IAuto
for (const reaction of args.reactions) { for (const reaction of args.reactions) {
if (!isEmoji(reaction)) { if (!isEmoji(reaction)) {
console.log("invalid:", reaction);
msg.channel.createMessage(errorMessage("One or more of the specified reactions were invalid!")); msg.channel.createMessage(errorMessage("One or more of the specified reactions were invalid!"));
return; return;
} }

View file

@ -23,8 +23,6 @@ export class BotControlPlugin extends GlobalPlugin<IBotControlPluginConfig> {
owners: [], owners: [],
update_cmd: null, update_cmd: null,
}, },
permissions: {},
}; };
} }

View file

@ -27,8 +27,6 @@ export class CasesPlugin extends ZeppelinPlugin<ICasesPluginConfig> {
log_automatic_actions: true, log_automatic_actions: true,
case_log_channel: null, case_log_channel: null,
}, },
permissions: {},
}; };
} }

View file

@ -1,5 +1,5 @@
import { decorators as d, IPluginOptions, Plugin } from "knub"; import { IPluginOptions } from "knub";
import { Invite, Message } from "eris"; import { Invite } from "eris";
import escapeStringRegexp from "escape-string-regexp"; import escapeStringRegexp from "escape-string-regexp";
import { GuildLogs } from "../data/GuildLogs"; import { GuildLogs } from "../data/GuildLogs";
import { LogType } from "../data/LogType"; import { LogType } from "../data/LogType";
@ -62,8 +62,6 @@ export class CensorPlugin extends ZeppelinPlugin<ICensorPluginConfig> {
blocked_regex: null, blocked_regex: null,
}, },
permissions: {},
overrides: [ overrides: [
{ {
level: ">=50", level: ">=50",

View file

@ -1,5 +1,5 @@
import http, { ServerResponse } from "http"; import http, { ServerResponse } from "http";
import { GlobalPlugin, IPluginOptions } from "knub"; import { GlobalPlugin, IPluginOptions, logger } 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";
@ -27,8 +27,6 @@ export class LogServerPlugin extends GlobalPlugin<ILogServerPluginConfig> {
config: { config: {
port: DEFAULT_PORT, port: DEFAULT_PORT,
}, },
permissions: {},
}; };
} }
@ -74,7 +72,7 @@ export class LogServerPlugin extends GlobalPlugin<ILogServerPluginConfig> {
this.server.on("error", async (err: any) => { this.server.on("error", async (err: any) => {
if (err.code === "EADDRINUSE" && !retried) { if (err.code === "EADDRINUSE" && !retried) {
console.log("Got EADDRINUSE, retrying in 2 sec..."); logger.info("Got EADDRINUSE, retrying in 2 sec...");
retried = true; retried = true;
await sleep(2000); await sleep(2000);
this.server.listen(port); this.server.listen(port);

View file

@ -1,7 +1,7 @@
import { decorators as d, IPluginOptions, logger, Plugin } from "knub"; import { decorators as d, IPluginOptions, logger } 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, TextChannel, User } from "eris";
import { import {
createChunkedMessage, createChunkedMessage,
deactivateMentions, deactivateMentions,
@ -56,13 +56,11 @@ interface ILogsPluginConfig {
[key: string]: string; [key: string]: string;
timestamp: string; timestamp: string;
}; };
ping_user: boolean;
} }
interface ILogsPluginPermissions { export class LogsPlugin extends ZeppelinPlugin<ILogsPluginConfig> {
pinged: boolean;
}
export class LogsPlugin extends ZeppelinPlugin<ILogsPluginConfig, ILogsPluginPermissions> {
public static pluginName = "logs"; public static pluginName = "logs";
protected guildLogs: GuildLogs; protected guildLogs: GuildLogs;
@ -78,7 +76,7 @@ export class LogsPlugin extends ZeppelinPlugin<ILogsPluginConfig, ILogsPluginPer
private onMessageDeleteBulkFn; private onMessageDeleteBulkFn;
private onMessageUpdateFn; private onMessageUpdateFn;
getDefaultOptions(): IPluginOptions<ILogsPluginConfig, ILogsPluginPermissions> { getDefaultOptions(): IPluginOptions<ILogsPluginConfig> {
return { return {
config: { config: {
channels: {}, channels: {},
@ -86,17 +84,14 @@ export class LogsPlugin extends ZeppelinPlugin<ILogsPluginConfig, ILogsPluginPer
timestamp: "YYYY-MM-DD HH:mm:ss", timestamp: "YYYY-MM-DD HH:mm:ss",
...DefaultLogMessages, ...DefaultLogMessages,
}, },
}, ping_user: true,
permissions: {
pinged: true,
}, },
overrides: [ overrides: [
{ {
level: ">=50", level: ">=50",
permissions: { config: {
pinged: false, ping_user: false,
}, },
}, },
], ],
@ -178,7 +173,9 @@ export class LogsPlugin extends ZeppelinPlugin<ILogsPluginConfig, ILogsPluginPer
if (user.user) user = user.user; if (user.user) user = user.user;
const member = this.guild.members.get(user.id); const member = this.guild.members.get(user.id);
if (this.hasPermission("pinged", { member, userId: user.id })) { const memberConfig = this.getMatchingConfig({ member, userId: user.id });
if (memberConfig.ping_user) {
// Ping/mention the user // Ping/mention the user
return `<@!${user.id}> (**${user.username}#${user.discriminator}**, \`${user.id}\`)`; return `<@!${user.id}> (**${user.username}#${user.discriminator}**, \`${user.id}\`)`;
} else { } else {

View file

@ -1,30 +1,28 @@
import { Plugin, decorators as d, IBasePluginConfig, IPluginOptions } from "knub"; import { Plugin, decorators as d, 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";
interface IMessageSaverPluginPermissions { interface IMessageSaverPluginConfig {
manage: boolean; can_manage: boolean;
} }
export class MessageSaverPlugin extends Plugin<IBasePluginConfig, IMessageSaverPluginPermissions> { export class MessageSaverPlugin extends Plugin<IMessageSaverPluginConfig> {
public static pluginName = "message_saver"; public static pluginName = "message_saver";
protected savedMessages: GuildSavedMessages; protected savedMessages: GuildSavedMessages;
getDefaultOptions(): IPluginOptions<IBasePluginConfig, IMessageSaverPluginPermissions> { getDefaultOptions(): IPluginOptions<IMessageSaverPluginConfig> {
return { return {
config: {}, config: {
can_manage: false,
permissions: {
manage: false,
}, },
overrides: [ overrides: [
{ {
level: ">=100", level: ">=100",
permissions: { config: {
manage: true, can_manage: true,
}, },
}, },
], ],

View file

@ -62,22 +62,20 @@ interface IModActionsPluginConfig {
ban_message: string; ban_message: string;
alert_on_rejoin: boolean; alert_on_rejoin: boolean;
alert_channel: string; alert_channel: string;
can_note: boolean;
can_warn: boolean;
can_mute: boolean;
can_kick: boolean;
can_ban: boolean;
can_view: boolean;
can_addcase: boolean;
can_massban: boolean;
can_hidecase: boolean;
can_act_as_other: boolean;
} }
interface IModActionsPluginPermissions { export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig> {
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;
@ -96,7 +94,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
this.ignoredEvents = []; this.ignoredEvents = [];
} }
getDefaultOptions(): IPluginOptions<IModActionsPluginConfig, IModActionsPluginPermissions> { getDefaultOptions(): IPluginOptions<IModActionsPluginConfig> {
return { return {
config: { config: {
dm_on_warn: true, dm_on_warn: true,
@ -115,38 +113,37 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
ban_message: "You have been banned from {guildName}. Reason given: {reason}", ban_message: "You have been banned from {guildName}. Reason given: {reason}",
alert_on_rejoin: false, alert_on_rejoin: false,
alert_channel: null, alert_channel: null,
},
permissions: { can_note: false,
note: false, can_warn: false,
warn: false, can_mute: false,
mute: false, can_kick: false,
kick: false, can_ban: false,
ban: false, can_view: false,
view: false, can_addcase: false,
addcase: false, can_massban: false,
massban: false, can_hidecase: false,
hidecase: false, can_act_as_other: false,
act_as_other: false,
}, },
overrides: [ overrides: [
{ {
level: ">=50", level: ">=50",
permissions: { config: {
note: true, can_note: true,
warn: true, can_warn: true,
mute: true, can_mute: true,
kick: true, can_kick: true,
ban: true, can_ban: true,
view: true, can_view: true,
addcase: true, can_addcase: true,
}, },
}, },
{ {
level: ">=100", level: ">=100",
permissions: { config: {
massban: true, can_massban: true,
hidecase: true, can_hidecase: true,
act_as_other: true, can_act_as_other: true,
}, },
}, },
], ],
@ -307,7 +304,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
* Update the specified case by adding more notes/details to it * Update the specified case by adding more notes/details to it
*/ */
@d.command(/update|updatecase/, "<caseNumber:number> <note:string$>") @d.command(/update|updatecase/, "<caseNumber:number> <note:string$>")
@d.permission("note") @d.permission("can_note")
async updateSpecificCmd(msg: Message, args: { caseNumber: number; note: string }) { async updateSpecificCmd(msg: Message, args: { caseNumber: number; note: string }) {
const theCase = await this.cases.findByCaseNumber(args.caseNumber); const theCase = await this.cases.findByCaseNumber(args.caseNumber);
if (!theCase) { if (!theCase) {
@ -328,7 +325,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
* Update the latest case * Update the latest case
*/ */
@d.command(/update|updatecase/, "<note:string$>") @d.command(/update|updatecase/, "<note:string$>")
@d.permission("note") @d.permission("can_note")
async updateLatestCmd(msg: Message, args: { note: string }) { async updateLatestCmd(msg: Message, args: { note: string }) {
const theCase = await this.cases.findLatestByModId(msg.author.id); const theCase = await this.cases.findLatestByModId(msg.author.id);
if (!theCase) { if (!theCase) {
@ -346,7 +343,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
} }
@d.command("note", "<userId:userId> <note:string$>") @d.command("note", "<userId:userId> <note:string$>")
@d.permission("note") @d.permission("can_note")
async noteCmd(msg: Message, args: any) { async noteCmd(msg: Message, args: any) {
const user = await this.bot.users.get(args.userId); const user = await this.bot.users.get(args.userId);
const userName = user ? `${user.username}#${user.discriminator}` : "member"; const userName = user ? `${user.username}#${user.discriminator}` : "member";
@ -365,7 +362,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
@d.command("warn", "<member:Member> <reason:string$>", { @d.command("warn", "<member:Member> <reason:string$>", {
options: [{ name: "mod", type: "member" }], options: [{ name: "mod", type: "member" }],
}) })
@d.permission("warn") @d.permission("can_warn")
async warnCmd(msg: Message, args: any) { async warnCmd(msg: Message, args: any) {
// Make sure we're allowed to warn this member // Make sure we're allowed to warn this member
if (!this.canActOn(msg.member, args.member)) { if (!this.canActOn(msg.member, args.member)) {
@ -433,7 +430,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
overloads: ["<member:Member> <time:delay>", "<member:Member> [reason:string$]"], overloads: ["<member:Member> <time:delay>", "<member:Member> [reason:string$]"],
options: [{ name: "mod", type: "member" }], options: [{ name: "mod", type: "member" }],
}) })
@d.permission("mute") @d.permission("can_mute")
async muteCmd(msg: Message, args: { member: Member; time?: number; reason?: string; mod: Member }) { async muteCmd(msg: Message, args: { member: Member; time?: number; reason?: string; mod: Member }) {
// Make sure we're allowed to mute this member // Make sure we're allowed to mute this member
if (!this.canActOn(msg.member, args.member)) { if (!this.canActOn(msg.member, args.member)) {
@ -566,7 +563,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
overloads: ["<member:Member> <time:delay>", "<member:Member> [reason:string$]"], overloads: ["<member:Member> <time:delay>", "<member:Member> [reason:string$]"],
options: [{ name: "mod", type: "member" }], options: [{ name: "mod", type: "member" }],
}) })
@d.permission("mute") @d.permission("can_mute")
async unmuteCmd(msg: Message, args: { member: Member; time?: number; reason?: string; mod?: Member }) { async unmuteCmd(msg: Message, args: { member: Member; time?: number; reason?: string; mod?: Member }) {
// Make sure we're allowed to mute this member // Make sure we're allowed to mute this member
if (!this.canActOn(msg.member, args.member)) { if (!this.canActOn(msg.member, args.member)) {
@ -651,7 +648,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
@d.command("kick", "<member:Member> [reason:string$]", { @d.command("kick", "<member:Member> [reason:string$]", {
options: [{ name: "mod", type: "member" }], options: [{ name: "mod", type: "member" }],
}) })
@d.permission("kick") @d.permission("can_kick")
async kickCmd(msg, args: { member: Member; reason: string; mod: Member }) { async kickCmd(msg, args: { member: Member; reason: string; mod: Member }) {
// Make sure we're allowed to kick this member // Make sure we're allowed to kick this member
if (!this.canActOn(msg.member, args.member)) { if (!this.canActOn(msg.member, args.member)) {
@ -721,7 +718,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
@d.command("ban", "<member:Member> [reason:string$]", { @d.command("ban", "<member:Member> [reason:string$]", {
options: [{ name: "mod", type: "member" }], options: [{ name: "mod", type: "member" }],
}) })
@d.permission("ban") @d.permission("can_ban")
async banCmd(msg, args: { member: Member; reason?: string; mod?: Member }) { async banCmd(msg, args: { member: Member; reason?: string; mod?: Member }) {
// Make sure we're allowed to ban this member // Make sure we're allowed to ban this member
if (!this.canActOn(msg.member, args.member)) { if (!this.canActOn(msg.member, args.member)) {
@ -791,7 +788,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
@d.command("softban", "<member:Member> [reason:string$]", { @d.command("softban", "<member:Member> [reason:string$]", {
options: [{ name: "mod", type: "member" }], options: [{ name: "mod", type: "member" }],
}) })
@d.permission("ban") @d.permission("can_ban")
async softbanCmd(msg, args) { async softbanCmd(msg, args) {
// Make sure we're allowed to ban this member // Make sure we're allowed to ban this member
if (!this.canActOn(msg.member, args.member)) { if (!this.canActOn(msg.member, args.member)) {
@ -849,7 +846,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
@d.command("unban", "<userId:userId> [reason:string$]", { @d.command("unban", "<userId:userId> [reason:string$]", {
options: [{ name: "mod", type: "member" }], options: [{ name: "mod", type: "member" }],
}) })
@d.permission("ban") @d.permission("can_ban")
async unbanCmd(msg: Message, args: { userId: string; reason: string; mod: Member }) { async unbanCmd(msg: Message, args: { userId: string; reason: string; mod: Member }) {
// The moderator who did the action is the message author or, if used, the specified --mod // The moderator who did the action is the message author or, if used, the specified --mod
let mod = msg.member; let mod = msg.member;
@ -896,7 +893,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
@d.command("forceban", "<userId:userId> [reason:string$]", { @d.command("forceban", "<userId:userId> [reason:string$]", {
options: [{ name: "mod", type: "member" }], options: [{ name: "mod", type: "member" }],
}) })
@d.permission("ban") @d.permission("can_ban")
async forcebanCmd(msg: Message, args: any) { async forcebanCmd(msg: Message, args: any) {
// If the user exists as a guild member, make sure we can act on them first // If the user exists as a guild member, make sure we can act on them first
const member = this.guild.members.get(args.userId); const member = this.guild.members.get(args.userId);
@ -948,7 +945,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
} }
@d.command("massban", "<userIds:string...>") @d.command("massban", "<userIds:string...>")
@d.permission("massban") @d.permission("can_massban")
async massbanCmd(msg: Message, args: { userIds: string[] }) { async massbanCmd(msg: Message, args: { userIds: string[] }) {
// Limit to 100 users at once (arbitrary?) // Limit to 100 users at once (arbitrary?)
if (args.userIds.length > 100) { if (args.userIds.length > 100) {
@ -1031,7 +1028,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
@d.command("addcase", "<type:string> <target:userId> [reason:string$]", { @d.command("addcase", "<type:string> <target:userId> [reason:string$]", {
options: [{ name: "mod", type: "member" }], options: [{ name: "mod", type: "member" }],
}) })
@d.permission("addcase") @d.permission("can_addcase")
async addcaseCmd(msg: Message, args: { type: string; target: string; reason?: string; mod?: Member }) { async addcaseCmd(msg: Message, args: { type: string; target: string; reason?: string; mod?: Member }) {
// Verify the user id is a valid snowflake-ish // Verify the user id is a valid snowflake-ish
if (!args.target.match(/^[0-9]{17,20}$/)) { if (!args.target.match(/^[0-9]{17,20}$/)) {
@ -1099,7 +1096,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
* If the argument passed is a user id, show all cases on that user * If the argument passed is a user id, show all cases on that user
*/ */
@d.command("case", "<caseNumber:number>") @d.command("case", "<caseNumber:number>")
@d.permission("view") @d.permission("can_view")
async showCaseCmd(msg: Message, args: { caseNumber: number }) { async showCaseCmd(msg: Message, args: { caseNumber: number }) {
// Assume case id // Assume case id
const theCase = await this.cases.findByCaseNumber(args.caseNumber); const theCase = await this.cases.findByCaseNumber(args.caseNumber);
@ -1116,7 +1113,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
} }
@d.command("cases", "<userId:userId> [opts:string$]") @d.command("cases", "<userId:userId> [opts:string$]")
@d.permission("view") @d.permission("can_view")
async userCasesCmd(msg: Message, args: { userId: string; opts?: string }) { async userCasesCmd(msg: Message, args: { userId: string; opts?: string }) {
const cases = await this.cases.with("notes").getByUserId(args.userId); const cases = await this.cases.with("notes").getByUserId(args.userId);
const normalCases = cases.filter(c => !c.is_hidden); const normalCases = cases.filter(c => !c.is_hidden);
@ -1177,7 +1174,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
@d.command("cases", null, { @d.command("cases", null, {
options: [{ name: "mod", type: "Member" }], options: [{ name: "mod", type: "Member" }],
}) })
@d.permission("view") @d.permission("can_view")
async recentCasesCmd(msg: Message, args: { mod?: Member }) { async recentCasesCmd(msg: Message, args: { mod?: Member }) {
const modId = args.mod ? args.mod.id : msg.author.id; const modId = args.mod ? args.mod.id : msg.author.id;
const recentCases = await this.cases.with("notes").getRecentByModId(modId, 5); const recentCases = await this.cases.with("notes").getRecentByModId(modId, 5);
@ -1202,7 +1199,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
} }
@d.command("hidecase", "<caseNum:number>") @d.command("hidecase", "<caseNum:number>")
@d.permission("hidecase") @d.permission("can_hidecase")
async hideCaseCmd(msg: Message, args: { caseNum: number }) { async hideCaseCmd(msg: Message, args: { caseNum: number }) {
const theCase = await this.cases.findByCaseNumber(args.caseNum); const theCase = await this.cases.findByCaseNumber(args.caseNum);
if (!theCase) { if (!theCase) {
@ -1217,7 +1214,7 @@ export class ModActionsPlugin extends ZeppelinPlugin<IModActionsPluginConfig, IM
} }
@d.command("unhidecase", "<caseNum:number>") @d.command("unhidecase", "<caseNum:number>")
@d.permission("hidecase") @d.permission("can_hidecase")
async unhideCaseCmd(msg: Message, args: { caseNum: number }) { async unhideCaseCmd(msg: Message, args: { caseNum: number }) {
const theCase = await this.cases.findByCaseNumber(args.caseNum); const theCase = await this.cases.findByCaseNumber(args.caseNum);
if (!theCase) { if (!theCase) {

View file

@ -13,14 +13,12 @@ import { decorators as d, IPluginOptions, logger } from "knub";
interface IMutesPluginConfig { interface IMutesPluginConfig {
mute_role: string; mute_role: string;
move_to_voice_channel: string; move_to_voice_channel: string;
can_view_list: boolean;
can_cleanup: boolean;
} }
interface IMutesPluginPermissions { export class MutesPlugin extends ZeppelinPlugin<IMutesPluginConfig> {
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;
@ -29,27 +27,26 @@ export class MutesPlugin extends ZeppelinPlugin<IMutesPluginConfig, IMutesPlugin
protected serverLogs: GuildLogs; protected serverLogs: GuildLogs;
private muteClearIntervalId: NodeJS.Timer; private muteClearIntervalId: NodeJS.Timer;
getDefaultOptions(): IPluginOptions<IMutesPluginConfig, IMutesPluginPermissions> { getDefaultOptions(): IPluginOptions<IMutesPluginConfig> {
return { return {
config: { config: {
mute_role: null, mute_role: null,
move_to_voice_channel: null, move_to_voice_channel: null,
},
permissions: { can_view_list: false,
view_list: false, can_cleanup: false,
cleanup: false,
}, },
overrides: [ overrides: [
{ {
level: ">=50", level: ">=50",
permissions: { config: {
view_list: true, can_view_list: true,
}, },
}, },
{ {
level: ">=100", level: ">=100",
permissions: { config: {
cleanup: true, can_cleanup: true,
}, },
}, },
], ],
@ -118,7 +115,7 @@ export class MutesPlugin extends ZeppelinPlugin<IMutesPluginConfig, IMutesPlugin
} }
@d.command("mutes") @d.command("mutes")
@d.permission("view_list") @d.permission("can_view_list")
public async postMuteList(msg: Message) { public async postMuteList(msg: Message) {
const lines = []; const lines = [];
@ -202,7 +199,7 @@ export class MutesPlugin extends ZeppelinPlugin<IMutesPluginConfig, IMutesPlugin
* COMMAND: Clear dangling mutes for members who have been banned * COMMAND: Clear dangling mutes for members who have been banned
*/ */
@d.command("clear_banned_mutes") @d.command("clear_banned_mutes")
@d.permission("cleanup") @d.permission("can_cleanup")
async clearBannedMutesCmd(msg: Message) { async clearBannedMutesCmd(msg: Message) {
await msg.channel.createMessage("Clearing mutes from banned users..."); await msg.channel.createMessage("Clearing mutes from banned users...");
@ -247,7 +244,7 @@ export class MutesPlugin extends ZeppelinPlugin<IMutesPluginConfig, IMutesPlugin
* COMMAND: Clear dangling mutes for members whose mute role was removed by other means * COMMAND: Clear dangling mutes for members whose mute role was removed by other means
*/ */
@d.command("clear_mutes_without_role") @d.command("clear_mutes_without_role")
@d.permission("cleanup") @d.permission("can_cleanup")
async clearMutesWithoutRoleCmd(msg: Message) { async clearMutesWithoutRoleCmd(msg: Message) {
const activeMutes = await this.mutes.getActiveMutes(); const activeMutes = await this.mutes.getActiveMutes();
const muteRole = this.getConfig().mute_role; const muteRole = this.getConfig().mute_role;
@ -270,7 +267,7 @@ export class MutesPlugin extends ZeppelinPlugin<IMutesPluginConfig, IMutesPlugin
} }
@d.command("clear_mute", "<userId:string>") @d.command("clear_mute", "<userId:string>")
@d.permission("cleanup") @d.permission("can_cleanup")
async clearMuteCmd(msg: Message, args: { userId: string }) { async clearMuteCmd(msg: Message, args: { userId: string }) {
const mute = await this.mutes.findExistingMuteForUserId(args.userId); const mute = await this.mutes.findExistingMuteForUserId(args.userId);
if (!mute) { if (!mute) {

View file

@ -1,32 +1,30 @@
import { decorators as d, IBasePluginConfig, IPluginOptions } from "knub"; import { decorators as d, IPluginOptions } from "knub";
import { GuildNameHistory } from "../data/GuildNameHistory"; import { GuildNameHistory } from "../data/GuildNameHistory";
import { Member, Message, 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"; import { ZeppelinPlugin } from "./ZeppelinPlugin";
interface INameHistoryPluginPermissions { interface INameHistoryPluginConfig {
view: boolean; can_view: boolean;
} }
export class NameHistoryPlugin extends ZeppelinPlugin<IBasePluginConfig, INameHistoryPluginPermissions> { export class NameHistoryPlugin extends ZeppelinPlugin<INameHistoryPluginConfig> {
public static pluginName = "name_history"; public static pluginName = "name_history";
protected nameHistory: GuildNameHistory; protected nameHistory: GuildNameHistory;
getDefaultOptions(): IPluginOptions<IBasePluginConfig, INameHistoryPluginPermissions> { getDefaultOptions(): IPluginOptions<INameHistoryPluginConfig> {
return { return {
config: {}, config: {
can_view: false,
permissions: {
view: false,
}, },
overrides: [ overrides: [
{ {
level: ">=50", level: ">=50",
permissions: { config: {
view: true, can_view: true,
}, },
}, },
], ],
@ -38,7 +36,7 @@ export class NameHistoryPlugin extends ZeppelinPlugin<IBasePluginConfig, INameHi
} }
@d.command("names", "<userId:userId>") @d.command("names", "<userId:userId>")
@d.permission("view") @d.permission("can_view")
async namesCmd(msg: Message, args: { userId: string }) { async namesCmd(msg: Message, args: { userId: string }) {
const names = await this.nameHistory.getByUserId(args.userId); const names = await this.nameHistory.getByUserId(args.userId);
if (!names) { if (!names) {

View file

@ -26,8 +26,6 @@ export class PersistPlugin extends ZeppelinPlugin<IPersistPluginConfig> {
persist_nicknames: false, persist_nicknames: false,
persist_voice_mutes: false, persist_voice_mutes: false,
}, },
permissions: {},
}; };
} }

View file

@ -1,5 +1,5 @@
import { decorators as d, IBasePluginConfig, IPluginOptions } from "knub"; import { decorators as d, IPluginOptions } from "knub";
import { Message, Role, TextableChannel, User } from "eris"; import { Message, Role, TextableChannel } 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";
@ -7,30 +7,28 @@ import { ZeppelinPlugin } from "./ZeppelinPlugin";
const TIMEOUT = 10 * 1000; const TIMEOUT = 10 * 1000;
interface IPingableRolesPluginPermissions { interface IPingableRolesPluginConfig {
use: boolean; can_manage: boolean;
} }
export class PingableRolesPlugin extends ZeppelinPlugin<IBasePluginConfig, IPingableRolesPluginPermissions> { export class PingableRolesPlugin extends ZeppelinPlugin<IPingableRolesPluginConfig> {
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(): IPluginOptions<IBasePluginConfig, IPingableRolesPluginPermissions> { getDefaultOptions(): IPluginOptions<IPingableRolesPluginConfig> {
return { return {
config: {}, config: {
can_manage: false,
permissions: {
use: false,
}, },
overrides: [ overrides: [
{ {
level: ">=100", level: ">=100",
permissions: { config: {
use: true, can_manage: true,
}, },
}, },
], ],
@ -53,7 +51,7 @@ export class PingableRolesPlugin extends ZeppelinPlugin<IBasePluginConfig, IPing
} }
@d.command("pingable_role disable", "<channelId:channelId> <role:role>") @d.command("pingable_role disable", "<channelId:channelId> <role:role>")
@d.permission("use") @d.permission("can_manage")
async disablePingableRoleCmd(msg: Message, args: { channelId: string; role: Role }) { async disablePingableRoleCmd(msg: Message, args: { channelId: string; role: Role }) {
const pingableRole = await this.pingableRoles.getByChannelAndRoleId(args.channelId, args.role.id); const pingableRole = await this.pingableRoles.getByChannelAndRoleId(args.channelId, args.role.id);
if (!pingableRole) { if (!pingableRole) {
@ -70,7 +68,7 @@ export class PingableRolesPlugin extends ZeppelinPlugin<IBasePluginConfig, IPing
} }
@d.command("pingable_role", "<channelId:channelId> <role:role>") @d.command("pingable_role", "<channelId:channelId> <role:role>")
@d.permission("use") @d.permission("can_manage")
async setPingableRoleCmd(msg: Message, args: { channelId: string; role: Role }) { async setPingableRoleCmd(msg: Message, args: { channelId: string; role: Role }) {
const existingPingableRole = await this.pingableRoles.getByChannelAndRoleId(args.channelId, args.role.id); const existingPingableRole = await this.pingableRoles.getByChannelAndRoleId(args.channelId, args.role.id);
if (existingPingableRole) { if (existingPingableRole) {
@ -87,7 +85,7 @@ export class PingableRolesPlugin extends ZeppelinPlugin<IBasePluginConfig, IPing
} }
@d.event("typingStart") @d.event("typingStart")
async onTypingStart(channel: TextableChannel, user: User) { async onTypingStart(channel: TextableChannel) {
const pingableRoles = await this.getPingableRolesForChannel(channel.id); const pingableRoles = await this.getPingableRolesForChannel(channel.id);
if (pingableRoles.length === 0) return; if (pingableRoles.length === 0) return;

View file

@ -1,4 +1,4 @@
import { Plugin, decorators as d, IBasePluginConfig, IPluginOptions } from "knub"; import { decorators as d, IPluginOptions } from "knub";
import { Channel, EmbedBase, Message, Role, TextChannel } from "eris"; import { Channel, EmbedBase, Message, Role, TextChannel } from "eris";
import { errorMessage, downloadFile, getRoleMentions } from "../utils"; import { errorMessage, downloadFile, getRoleMentions } from "../utils";
import { GuildSavedMessages } from "../data/GuildSavedMessages"; import { GuildSavedMessages } from "../data/GuildSavedMessages";
@ -9,12 +9,11 @@ const fsp = fs.promises;
const COLOR_MATCH_REGEX = /^#?([0-9a-f]{6})$/; const COLOR_MATCH_REGEX = /^#?([0-9a-f]{6})$/;
interface IPostPluginPermissions { interface IPostPluginConfig {
post: boolean; can_post: boolean;
edit: boolean;
} }
export class PostPlugin extends ZeppelinPlugin<IBasePluginConfig, IPostPluginPermissions> { export class PostPlugin extends ZeppelinPlugin<IPostPluginConfig> {
public static pluginName = "post"; public static pluginName = "post";
protected savedMessages: GuildSavedMessages; protected savedMessages: GuildSavedMessages;
@ -23,21 +22,17 @@ export class PostPlugin extends ZeppelinPlugin<IBasePluginConfig, IPostPluginPer
this.savedMessages = GuildSavedMessages.getInstance(this.guildId); this.savedMessages = GuildSavedMessages.getInstance(this.guildId);
} }
getDefaultOptions(): IPluginOptions<IBasePluginConfig, IPostPluginPermissions> { getDefaultOptions(): IPluginOptions<IPostPluginConfig> {
return { return {
config: {}, config: {
can_post: false,
permissions: {
post: false,
edit: false,
}, },
overrides: [ overrides: [
{ {
level: ">=100", level: ">=100",
permissions: { config: {
post: true, can_post: true,
edit: true,
}, },
}, },
], ],
@ -59,7 +54,7 @@ export class PostPlugin extends ZeppelinPlugin<IBasePluginConfig, IPostPluginPer
}, },
], ],
}) })
@d.permission("post") @d.permission("can_post")
async postCmd(msg: Message, args: { channel: Channel; content?: string; "enable-mentions": boolean }) { async postCmd(msg: Message, args: { channel: Channel; content?: string; "enable-mentions": boolean }) {
if (!(args.channel instanceof TextChannel)) { if (!(args.channel instanceof TextChannel)) {
msg.channel.createMessage(errorMessage("Channel is not a text channel")); msg.channel.createMessage(errorMessage("Channel is not a text channel"));
@ -123,7 +118,7 @@ export class PostPlugin extends ZeppelinPlugin<IBasePluginConfig, IPostPluginPer
{ name: "color", type: "string" }, { name: "color", type: "string" },
], ],
}) })
@d.permission("post") @d.permission("can_post")
async postEmbedCmd(msg: Message, args: { channel: Channel; title?: string; content?: string; color?: string }) { async postEmbedCmd(msg: Message, args: { channel: Channel; title?: string; content?: string; color?: string }) {
if (!(args.channel instanceof TextChannel)) { if (!(args.channel instanceof TextChannel)) {
msg.channel.createMessage(errorMessage("Channel is not a text channel")); msg.channel.createMessage(errorMessage("Channel is not a text channel"));
@ -159,7 +154,7 @@ export class PostPlugin extends ZeppelinPlugin<IBasePluginConfig, IPostPluginPer
* COMMAND: Edit the specified message posted by the bot * COMMAND: Edit the specified message posted by the bot
*/ */
@d.command("edit", "<messageId:string> <content:string$>") @d.command("edit", "<messageId:string> <content:string$>")
@d.permission("edit") @d.permission("can_post")
async editCmd(msg, args: { messageId: string; content: string }) { async editCmd(msg, args: { messageId: string; content: string }) {
const savedMessage = await this.savedMessages.find(args.messageId); const savedMessage = await this.savedMessages.find(args.messageId);
if (!savedMessage) { if (!savedMessage) {
@ -185,7 +180,7 @@ export class PostPlugin extends ZeppelinPlugin<IBasePluginConfig, IPostPluginPer
{ name: "color", type: "string" }, { name: "color", type: "string" },
], ],
}) })
@d.permission("edit") @d.permission("can_post")
async editEmbedCmd(msg: Message, args: { messageId: string; title?: string; content?: string; color?: string }) { async editEmbedCmd(msg: Message, args: { messageId: string; title?: string; content?: string; color?: string }) {
const savedMessage = await this.savedMessages.find(args.messageId); const savedMessage = await this.savedMessages.find(args.messageId);
if (!savedMessage) { if (!savedMessage) {

View file

@ -27,14 +27,11 @@ type PendingMemberRoleChanges = {
interface IReactionRolesPluginConfig { interface IReactionRolesPluginConfig {
auto_refresh_interval: number; auto_refresh_interval: number;
can_manage: boolean;
} }
interface IReactionRolesPluginPermissions { export class ReactionRolesPlugin extends ZeppelinPlugin<IReactionRolesPluginConfig> {
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;
@ -46,22 +43,19 @@ export class ReactionRolesPlugin extends ZeppelinPlugin<IReactionRolesPluginConf
private autoRefreshTimeout; private autoRefreshTimeout;
getDefaultOptions(): IPluginOptions<IReactionRolesPluginConfig, IReactionRolesPluginPermissions> { getDefaultOptions(): IPluginOptions<IReactionRolesPluginConfig> {
return { return {
config: { config: {
auto_refresh_interval: null, auto_refresh_interval: null,
},
permissions: { can_manage: false,
manage: false,
fallback_command: false,
}, },
overrides: [ overrides: [
{ {
level: ">=100", level: ">=100",
permissions: { config: {
manage: true, can_manage: true,
}, },
}, },
], ],
@ -195,7 +189,7 @@ export class ReactionRolesPlugin extends ZeppelinPlugin<IReactionRolesPluginConf
* COMMAND: Clear reaction roles from the specified message * COMMAND: Clear reaction roles from the specified message
*/ */
@d.command("reaction_roles clear", "<messageId:string>") @d.command("reaction_roles clear", "<messageId:string>")
@d.permission("manage") @d.permission("can_manage")
async clearReactionRolesCmd(msg: Message, args: { messageId: string }) { async clearReactionRolesCmd(msg: Message, args: { messageId: string }) {
const savedMessage = await this.savedMessages.find(args.messageId); const savedMessage = await this.savedMessages.find(args.messageId);
if (!savedMessage) { if (!savedMessage) {
@ -222,7 +216,7 @@ export class ReactionRolesPlugin extends ZeppelinPlugin<IReactionRolesPluginConf
* COMMAND: Refresh reaction roles in the specified message by removing all reactions and re-adding them * COMMAND: Refresh reaction roles in the specified message by removing all reactions and re-adding them
*/ */
@d.command("reaction_roles refresh", "<messageId:string>") @d.command("reaction_roles refresh", "<messageId:string>")
@d.permission("manage") @d.permission("can_manage")
async refreshReactionRolesCmd(msg: Message, args: { messageId: string }) { async refreshReactionRolesCmd(msg: Message, args: { messageId: string }) {
const savedMessage = await this.savedMessages.find(args.messageId); const savedMessage = await this.savedMessages.find(args.messageId);
if (!savedMessage) { if (!savedMessage) {
@ -247,7 +241,7 @@ export class ReactionRolesPlugin extends ZeppelinPlugin<IReactionRolesPluginConf
* :zep_ps4: = 543184300250759188 * :zep_ps4: = 543184300250759188
*/ */
@d.command("reaction_roles", "<messageId:string> <reactionRolePairs:string$>") @d.command("reaction_roles", "<messageId:string> <reactionRolePairs:string$>")
@d.permission("manage") @d.permission("can_manage")
async reactionRolesCmd(msg: Message, args: { messageId: string; reactionRolePairs: string }) { async reactionRolesCmd(msg: Message, args: { messageId: string; reactionRolePairs: string }) {
const savedMessage = await this.savedMessages.find(args.messageId); const savedMessage = await this.savedMessages.find(args.messageId);
if (!savedMessage) { if (!savedMessage) {

View file

@ -1,4 +1,4 @@
import { decorators as d, IBasePluginConfig, IPluginOptions } from "knub"; import { decorators as d, 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,11 +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;
interface IRemindersPluginPermissions { interface IRemindersPluginConfig {
use: boolean; can_use: boolean;
} }
export class RemindersPlugin extends ZeppelinPlugin<IBasePluginConfig, IRemindersPluginPermissions> { export class RemindersPlugin extends ZeppelinPlugin<IRemindersPluginConfig> {
public static pluginName = "reminders"; public static pluginName = "reminders";
protected reminders: GuildReminders; protected reminders: GuildReminders;
@ -21,19 +21,17 @@ export class RemindersPlugin extends ZeppelinPlugin<IBasePluginConfig, IReminder
private postRemindersTimeout; private postRemindersTimeout;
getDefaultOptions(): IPluginOptions<IBasePluginConfig, IRemindersPluginPermissions> { getDefaultOptions(): IPluginOptions<IRemindersPluginConfig> {
return { return {
config: {}, config: {
can_use: false,
permissions: {
use: false,
}, },
overrides: [ overrides: [
{ {
level: ">=50", level: ">=50",
permissions: { config: {
use: true, can_use: true,
}, },
}, },
], ],
@ -72,7 +70,7 @@ export class RemindersPlugin extends ZeppelinPlugin<IBasePluginConfig, IReminder
@d.command("remind", "<time:string> <reminder:string$>") @d.command("remind", "<time:string> <reminder:string$>")
@d.command("remindme", "<time:string> <reminder:string$>") @d.command("remindme", "<time:string> <reminder:string$>")
@d.permission("use") @d.permission("can_use")
async addReminderCmd(msg: Message, args: { time: string; reminder: string }) { async addReminderCmd(msg: Message, args: { time: string; reminder: string }) {
const now = moment(); const now = moment();
@ -115,7 +113,7 @@ export class RemindersPlugin extends ZeppelinPlugin<IBasePluginConfig, IReminder
} }
@d.command("reminders") @d.command("reminders")
@d.permission("use") @d.permission("can_use")
async reminderListCmd(msg: Message) { async reminderListCmd(msg: Message) {
const reminders = await this.reminders.getRemindersByUserId(msg.author.id); const reminders = await this.reminders.getRemindersByUserId(msg.author.id);
if (reminders.length === 0) { if (reminders.length === 0) {
@ -136,7 +134,7 @@ export class RemindersPlugin extends ZeppelinPlugin<IBasePluginConfig, IReminder
@d.command("reminders delete", "<num:number>") @d.command("reminders delete", "<num:number>")
@d.command("reminders d", "<num:number>") @d.command("reminders d", "<num:number>")
@d.permission("use") @d.permission("can_use")
async deleteReminderCmd(msg: Message, args: { num: number }) { async deleteReminderCmd(msg: Message, args: { num: number }) {
const reminders = await this.reminders.getRemindersByUserId(msg.author.id); const reminders = await this.reminders.getRemindersByUserId(msg.author.id);
reminders.sort(sorter("remind_at")); reminders.sort(sorter("remind_at"));

View file

@ -1,41 +1,39 @@
import { Plugin, decorators as d, IBasePluginConfig, IPluginOptions } from "knub"; import { decorators as d, 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 { asSingleLine, chunkArray, errorMessage, sorter, successMessage, trimLines } from "../utils"; import { asSingleLine, chunkArray, errorMessage, sorter, successMessage, trimLines } from "../utils";
import { ZeppelinPlugin } from "./ZeppelinPlugin"; import { ZeppelinPlugin } from "./ZeppelinPlugin";
interface ISelfGrantableRolesPluginPermissions { interface ISelfGrantableRolesPluginConfig {
manage: boolean; can_manage: boolean;
use: boolean; can_use: boolean;
ignore_cooldown: boolean; can_ignore_cooldown: boolean;
} }
export class SelfGrantableRolesPlugin extends ZeppelinPlugin<IBasePluginConfig, ISelfGrantableRolesPluginPermissions> { export class SelfGrantableRolesPlugin extends ZeppelinPlugin<ISelfGrantableRolesPluginConfig> {
public static pluginName = "self_grantable_roles"; public static pluginName = "self_grantable_roles";
protected selfGrantableRoles: GuildSelfGrantableRoles; protected selfGrantableRoles: GuildSelfGrantableRoles;
getDefaultOptions(): IPluginOptions<IBasePluginConfig, ISelfGrantableRolesPluginPermissions> { getDefaultOptions(): IPluginOptions<ISelfGrantableRolesPluginConfig> {
return { return {
config: {}, config: {
can_manage: false,
permissions: { can_use: false,
manage: false, can_ignore_cooldown: false,
use: false,
ignore_cooldown: false,
}, },
overrides: [ overrides: [
{ {
level: ">=50", level: ">=50",
permissions: { config: {
ignore_cooldown: true, can_ignore_cooldown: true,
}, },
}, },
{ {
level: ">=100", level: ">=100",
permissions: { config: {
manage: true, can_manage: true,
}, },
}, },
], ],
@ -47,8 +45,8 @@ export class SelfGrantableRolesPlugin extends ZeppelinPlugin<IBasePluginConfig,
} }
@d.command("role remove", "<roleNames:string...>") @d.command("role remove", "<roleNames:string...>")
@d.permission("use") @d.permission("can_use")
@d.cooldown(2500, "ignore_cooldown") @d.cooldown(2500, "can_ignore_cooldown")
async roleRemoveCmd(msg: Message, args: { roleNames: string[] }) { async roleRemoveCmd(msg: Message, args: { roleNames: string[] }) {
const lock = await this.locks.acquire(`grantableRoles:${msg.author.id}`); const lock = await this.locks.acquire(`grantableRoles:${msg.author.id}`);
@ -131,8 +129,8 @@ export class SelfGrantableRolesPlugin extends ZeppelinPlugin<IBasePluginConfig,
} }
@d.command("role", "<roleNames:string...>") @d.command("role", "<roleNames:string...>")
@d.permission("use") @d.permission("can_use")
@d.cooldown(1500, "ignore_cooldown") @d.cooldown(1500, "can_ignore_cooldown")
async roleCmd(msg: Message, args: { roleNames: string[] }) { async roleCmd(msg: Message, args: { roleNames: string[] }) {
const lock = await this.locks.acquire(`grantableRoles:${msg.author.id}`); const lock = await this.locks.acquire(`grantableRoles:${msg.author.id}`);
@ -218,7 +216,7 @@ export class SelfGrantableRolesPlugin extends ZeppelinPlugin<IBasePluginConfig,
@d.command("role help") @d.command("role help")
@d.command("role") @d.command("role")
@d.cooldown(5000, "ignore_cooldown") @d.cooldown(5000, "can_ignore_cooldown")
async roleHelpCmd(msg: Message) { async roleHelpCmd(msg: Message) {
const channelGrantableRoles = await this.selfGrantableRoles.getForChannel(msg.channel.id); const channelGrantableRoles = await this.selfGrantableRoles.getForChannel(msg.channel.id);
if (channelGrantableRoles.length === 0) return; if (channelGrantableRoles.length === 0) return;
@ -256,7 +254,7 @@ export class SelfGrantableRolesPlugin extends ZeppelinPlugin<IBasePluginConfig,
} }
@d.command("self_grantable_roles add", "<channel:channel> <roleId:string> [aliases:string...]") @d.command("self_grantable_roles add", "<channel:channel> <roleId:string> [aliases:string...]")
@d.permission("manage") @d.permission("can_manage")
async addSelfGrantableRoleCmd(msg: Message, args: { channel: GuildChannel; roleId: string; aliases?: string[] }) { async addSelfGrantableRoleCmd(msg: Message, args: { channel: GuildChannel; roleId: string; aliases?: string[] }) {
if (!(args.channel instanceof TextChannel)) { if (!(args.channel instanceof TextChannel)) {
msg.channel.createMessage(errorMessage("Invalid channel (must be a text channel)")); msg.channel.createMessage(errorMessage("Invalid channel (must be a text channel)"));
@ -285,7 +283,7 @@ export class SelfGrantableRolesPlugin extends ZeppelinPlugin<IBasePluginConfig,
} }
@d.command("self_grantable_roles delete", "<channel:channel> <roleId:string>") @d.command("self_grantable_roles delete", "<channel:channel> <roleId:string>")
@d.permission("manage") @d.permission("can_manage")
async deleteSelfGrantableRoleCmd(msg: Message, args: { channel: GuildChannel; roleId: string }) { async deleteSelfGrantableRoleCmd(msg: Message, args: { channel: GuildChannel; roleId: string }) {
await this.selfGrantableRoles.delete(args.channel.id, args.roleId); await this.selfGrantableRoles.delete(args.channel.id, args.roleId);
@ -297,7 +295,7 @@ export class SelfGrantableRolesPlugin extends ZeppelinPlugin<IBasePluginConfig,
} }
@d.command("self_grantable_roles", "<channel:channel>") @d.command("self_grantable_roles", "<channel:channel>")
@d.permission("manage") @d.permission("can_manage")
async selfGrantableRolesCmd(msg: Message, args: { channel: GuildChannel }) { async selfGrantableRolesCmd(msg: Message, args: { channel: GuildChannel }) {
if (!(args.channel instanceof TextChannel)) { if (!(args.channel instanceof TextChannel)) {
msg.channel.createMessage(errorMessage("Invalid channel (must be a text channel)")); msg.channel.createMessage(errorMessage("Invalid channel (must be a text channel)"));

View file

@ -9,14 +9,12 @@ import { GuildSavedMessages } from "../data/GuildSavedMessages";
interface ISlowmodePluginConfig { interface ISlowmodePluginConfig {
use_native_slowmode: boolean; use_native_slowmode: boolean;
can_manage: boolean;
is_affected: boolean;
} }
interface ISlowmodePluginPermissions { export class SlowmodePlugin extends ZeppelinPlugin<ISlowmodePluginConfig> {
manage: boolean;
affected: boolean;
}
export class SlowmodePlugin extends ZeppelinPlugin<ISlowmodePluginConfig, ISlowmodePluginPermissions> {
public static pluginName = "slowmode"; public static pluginName = "slowmode";
protected slowmodes: GuildSlowmodes; protected slowmodes: GuildSlowmodes;
@ -25,23 +23,21 @@ export class SlowmodePlugin extends ZeppelinPlugin<ISlowmodePluginConfig, ISlowm
private onMessageCreateFn; private onMessageCreateFn;
getDefaultOptions(): IPluginOptions<ISlowmodePluginConfig, ISlowmodePluginPermissions> { getDefaultOptions(): IPluginOptions<ISlowmodePluginConfig> {
return { return {
config: { config: {
use_native_slowmode: true, use_native_slowmode: true,
},
permissions: { can_manage: false,
manage: false, is_affected: true,
affected: true,
}, },
overrides: [ overrides: [
{ {
level: ">=50", level: ">=50",
permissions: { config: {
manage: true, can_manage: true,
affected: false, is_affected: false,
}, },
}, },
], ],
@ -128,7 +124,7 @@ export class SlowmodePlugin extends ZeppelinPlugin<ISlowmodePluginConfig, ISlowm
* COMMAND: Disable slowmode on the specified channel * COMMAND: Disable slowmode on the specified channel
*/ */
@d.command("slowmode disable", "<channel:channel>") @d.command("slowmode disable", "<channel:channel>")
@d.permission("manage") @d.permission("can_manage")
async disableSlowmodeCmd(msg: Message, args: { channel: GuildChannel & TextChannel }) { async disableSlowmodeCmd(msg: Message, args: { channel: GuildChannel & TextChannel }) {
const botSlowmode = await this.slowmodes.getChannelSlowmode(args.channel.id); const botSlowmode = await this.slowmodes.getChannelSlowmode(args.channel.id);
const hasNativeSlowmode = args.channel.rateLimitPerUser; const hasNativeSlowmode = args.channel.rateLimitPerUser;
@ -168,7 +164,7 @@ export class SlowmodePlugin extends ZeppelinPlugin<ISlowmodePluginConfig, ISlowm
* COMMAND: Clear slowmode from a specific user on a specific channel * COMMAND: Clear slowmode from a specific user on a specific channel
*/ */
@d.command("slowmode clear", "<channel:channel> <user:user>") @d.command("slowmode clear", "<channel:channel> <user:user>")
@d.permission("manage") @d.permission("can_manage")
async clearSlowmodeCmd(msg: Message, args: { channel: GuildChannel & TextChannel; user: User }) { async clearSlowmodeCmd(msg: Message, args: { channel: GuildChannel & TextChannel; user: User }) {
const channelSlowmode = await this.slowmodes.getChannelSlowmode(args.channel.id); const channelSlowmode = await this.slowmodes.getChannelSlowmode(args.channel.id);
if (!channelSlowmode) { if (!channelSlowmode) {
@ -185,7 +181,7 @@ export class SlowmodePlugin extends ZeppelinPlugin<ISlowmodePluginConfig, ISlowm
} }
@d.command("slowmode list") @d.command("slowmode list")
@d.permission("manage") @d.permission("can_manage")
async slowmodeListCmd(msg: Message) { async slowmodeListCmd(msg: Message) {
const channels = this.guild.channels; const channels = this.guild.channels;
const slowmodes: Array<{ channel: GuildChannel; seconds: number; native: boolean }> = []; const slowmodes: Array<{ channel: GuildChannel; seconds: number; native: boolean }> = [];
@ -227,7 +223,7 @@ export class SlowmodePlugin extends ZeppelinPlugin<ISlowmodePluginConfig, ISlowm
*/ */
@d.command("slowmode", "<channel:channel> <time:string>") @d.command("slowmode", "<channel:channel> <time:string>")
@d.command("slowmode", "<time:string>") @d.command("slowmode", "<time:string>")
@d.permission("manage") @d.permission("can_manage")
async slowmodeCmd(msg: Message, args: { channel?: GuildChannel & TextChannel; time: string }) { async slowmodeCmd(msg: Message, args: { channel?: GuildChannel & TextChannel; time: string }) {
const channel = args.channel || msg.channel; const channel = args.channel || msg.channel;

View file

@ -106,8 +106,6 @@ export class SpamPlugin extends ZeppelinPlugin<ISpamPluginConfig> {
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: [
{ {

View file

@ -17,11 +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";
interface IStarboardPluginPermissions { interface IStarboardPluginConfig {
manage: boolean; can_manage: boolean;
} }
export class StarboardPlugin extends ZeppelinPlugin<IBasePluginConfig, IStarboardPluginPermissions> { export class StarboardPlugin extends ZeppelinPlugin<IStarboardPluginConfig> {
public static pluginName = "starboard"; public static pluginName = "starboard";
protected starboards: GuildStarboards; protected starboards: GuildStarboards;
@ -29,19 +29,17 @@ export class StarboardPlugin extends ZeppelinPlugin<IBasePluginConfig, IStarboar
private onMessageDeleteFn; private onMessageDeleteFn;
getDefaultOptions(): IPluginOptions<IBasePluginConfig, IStarboardPluginPermissions> { getDefaultOptions(): IPluginOptions<IStarboardPluginConfig> {
return { return {
config: {}, config: {
can_manage: false,
permissions: {
manage: false,
}, },
overrides: [ overrides: [
{ {
level: ">=100", level: ">=100",
permissions: { config: {
manage: true, can_manage: true,
}, },
}, },
], ],
@ -64,7 +62,7 @@ export class StarboardPlugin extends ZeppelinPlugin<IBasePluginConfig, IStarboar
* An interactive setup for creating a starboard * An interactive setup for creating a starboard
*/ */
@d.command("starboard create") @d.command("starboard create")
@d.permission("manage") @d.permission("can_manage")
async setupCmd(msg: Message) { async setupCmd(msg: Message) {
const cancelMsg = () => msg.channel.createMessage("Cancelled"); const cancelMsg = () => msg.channel.createMessage("Cancelled");
@ -177,7 +175,7 @@ export class StarboardPlugin extends ZeppelinPlugin<IBasePluginConfig, IStarboar
* Deletes the starboard from the specified channel. The already-posted starboard messages are retained. * Deletes the starboard from the specified channel. The already-posted starboard messages are retained.
*/ */
@d.command("starboard delete", "<channelId:channelId>") @d.command("starboard delete", "<channelId:channelId>")
@d.permission("manage") @d.permission("can_manage")
async deleteCmd(msg: Message, args: { channelId: string }) { async deleteCmd(msg: Message, args: { channelId: string }) {
const starboard = await this.starboards.getStarboardByChannelId(args.channelId); const starboard = await this.starboards.getStarboardByChannelId(args.channelId);
if (!starboard) { if (!starboard) {

View file

@ -13,15 +13,13 @@ import { GuildArchives } from "../data/GuildArchives";
interface ITagsPluginConfig { interface ITagsPluginConfig {
prefix: string; prefix: string;
delete_with_command: boolean; delete_with_command: boolean;
can_create: boolean;
can_use: boolean;
can_list: boolean;
} }
interface ITagsPluginPermissions { export class TagsPlugin extends ZeppelinPlugin<ITagsPluginConfig> {
create: boolean;
use: boolean;
list: boolean;
}
export class TagsPlugin extends ZeppelinPlugin<ITagsPluginConfig, ITagsPluginPermissions> {
public static pluginName = "tags"; public static pluginName = "tags";
protected archives: GuildArchives; protected archives: GuildArchives;
@ -33,25 +31,23 @@ export class TagsPlugin extends ZeppelinPlugin<ITagsPluginConfig, ITagsPluginPer
protected tagFunctions; protected tagFunctions;
getDefaultOptions(): IPluginOptions<ITagsPluginConfig, ITagsPluginPermissions> { getDefaultOptions(): IPluginOptions<ITagsPluginConfig> {
return { return {
config: { config: {
prefix: "!!", prefix: "!!",
delete_with_command: true, delete_with_command: true,
},
permissions: { can_create: false,
create: false, can_use: true,
use: true, can_list: false,
list: false,
}, },
overrides: [ overrides: [
{ {
level: ">=50", level: ">=50",
permissions: { config: {
create: true, can_create: true,
list: true, can_list: true,
}, },
}, },
], ],
@ -109,7 +105,7 @@ export class TagsPlugin extends ZeppelinPlugin<ITagsPluginConfig, ITagsPluginPer
@d.command("tag list") @d.command("tag list")
@d.command("tags") @d.command("tags")
@d.command("taglist") @d.command("taglist")
@d.permission("list") @d.permission("can_list")
async tagListCmd(msg: Message) { async tagListCmd(msg: Message) {
const tags = await this.tags.all(); const tags = await this.tags.all();
if (tags.length === 0) { if (tags.length === 0) {
@ -125,7 +121,7 @@ export class TagsPlugin extends ZeppelinPlugin<ITagsPluginConfig, ITagsPluginPer
} }
@d.command("tag delete", "<tag:string>") @d.command("tag delete", "<tag:string>")
@d.permission("create") @d.permission("can_create")
async deleteTagCmd(msg: Message, args: { tag: string }) { async deleteTagCmd(msg: Message, args: { tag: string }) {
const tag = await this.tags.find(args.tag); const tag = await this.tags.find(args.tag);
if (!tag) { if (!tag) {
@ -138,14 +134,14 @@ export class TagsPlugin extends ZeppelinPlugin<ITagsPluginConfig, ITagsPluginPer
} }
@d.command("tag eval", "<body:string$>") @d.command("tag eval", "<body:string$>")
@d.permission("create") @d.permission("can_create")
async evalTagCmd(msg: Message, args: { body: string }) { async evalTagCmd(msg: Message, args: { body: string }) {
const rendered = await this.renderTag(args.body); const rendered = await this.renderTag(args.body);
msg.channel.createMessage(rendered); msg.channel.createMessage(rendered);
} }
@d.command("tag", "<tag:string> <body:string$>") @d.command("tag", "<tag:string> <body:string$>")
@d.permission("create") @d.permission("can_create")
async tagCmd(msg: Message, args: { tag: string; body: string }) { async tagCmd(msg: Message, args: { tag: string; body: string }) {
try { try {
parseTemplate(args.body); parseTemplate(args.body);

View file

@ -1,4 +1,4 @@
import { decorators as d, IBasePluginConfig, IPluginOptions } from "knub"; import { decorators as d, 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,21 +33,21 @@ const CLEAN_COMMAND_DELETE_DELAY = 5000;
const activeReloads: Map<string, TextChannel> = new Map(); const activeReloads: Map<string, TextChannel> = new Map();
interface IUtilityPluginPermissions { interface IUtilityPluginConfig {
roles: boolean; can_roles: boolean;
level: boolean; can_level: boolean;
search: boolean; can_search: boolean;
clean: boolean; can_clean: boolean;
info: boolean; can_info: boolean;
server: boolean; can_server: boolean;
reload_guild: boolean; can_reload_guild: boolean;
nickname: boolean; can_nickname: boolean;
ping: boolean; can_ping: boolean;
source: boolean; can_source: boolean;
vcmove: boolean; can_vcmove: boolean;
} }
export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPluginPermissions> { export class UtilityPlugin extends ZeppelinPlugin<IUtilityPluginConfig> {
public static pluginName = "utility"; public static pluginName = "utility";
protected logs: GuildLogs; protected logs: GuildLogs;
@ -55,43 +55,41 @@ export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPlu
protected savedMessages: GuildSavedMessages; protected savedMessages: GuildSavedMessages;
protected archives: GuildArchives; protected archives: GuildArchives;
getDefaultOptions(): IPluginOptions<IBasePluginConfig, IUtilityPluginPermissions> { getDefaultOptions(): IPluginOptions<IUtilityPluginConfig> {
return { return {
config: {}, config: {
can_roles: false,
permissions: { can_level: false,
roles: false, can_search: false,
level: false, can_clean: false,
search: false, can_info: false,
clean: false, can_server: false,
info: false, can_reload_guild: false,
server: false, can_nickname: false,
reload_guild: false, can_ping: false,
nickname: false, can_source: false,
ping: false, can_vcmove: false,
source: false,
vcmove: false,
}, },
overrides: [ overrides: [
{ {
level: ">=50", level: ">=50",
permissions: { config: {
roles: true, can_roles: true,
level: true, can_level: true,
search: true, can_search: true,
clean: true, can_clean: true,
info: true, can_info: true,
server: true, can_server: true,
nickname: true, can_nickname: true,
vcmove: true, can_vcmove: true,
}, },
}, },
{ {
level: ">=100", level: ">=100",
permissions: { config: {
reload_guild: true, can_reload_guild: true,
ping: true, can_ping: true,
source: true, can_source: true,
}, },
}, },
], ],
@ -118,7 +116,7 @@ export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPlu
}, },
], ],
}) })
@d.permission("roles") @d.permission("can_roles")
async rolesCmd(msg: Message, args: { search?: string; counts?: boolean }) { async rolesCmd(msg: Message, args: { search?: string; counts?: boolean }) {
let roles: Array<{ _memberCount?: number } & Role> = Array.from((msg.channel as TextChannel).guild.roles.values()); let roles: Array<{ _memberCount?: number } & Role> = Array.from((msg.channel as TextChannel).guild.roles.values());
if (args.search) { if (args.search) {
@ -185,7 +183,7 @@ export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPlu
} }
@d.command("level", "[userId:string]") @d.command("level", "[userId:string]")
@d.permission("level") @d.permission("can_level")
async levelCmd(msg: Message, args) { async levelCmd(msg: Message, args) {
const member = args.userId ? this.guild.members.get(args.userId) : msg.member; const member = args.userId ? this.guild.members.get(args.userId) : msg.member;
@ -218,7 +216,7 @@ export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPlu
}, },
], ],
}) })
@d.permission("search") @d.permission("can_search")
async searchCmd( async searchCmd(
msg: Message, msg: Message,
args: { query?: string; role?: string; page?: number; voice?: boolean; sort?: string }, args: { query?: string; role?: string; page?: number; voice?: boolean; sort?: string },
@ -327,7 +325,7 @@ export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPlu
@d.command("clean", "<count:number>") @d.command("clean", "<count:number>")
@d.command("clean all", "<count:number>") @d.command("clean all", "<count:number>")
@d.permission("clean") @d.permission("can_clean")
async cleanAllCmd(msg: Message, args: { count: number }) { async cleanAllCmd(msg: Message, args: { count: number }) {
if (args.count > MAX_CLEAN_COUNT || args.count <= 0) { if (args.count > MAX_CLEAN_COUNT || args.count <= 0) {
msg.channel.createMessage(errorMessage(`Clean count must be between 1 and ${MAX_CLEAN_COUNT}`)); msg.channel.createMessage(errorMessage(`Clean count must be between 1 and ${MAX_CLEAN_COUNT}`));
@ -350,7 +348,7 @@ export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPlu
} }
@d.command("clean user", "<userId:userid> <count:number>") @d.command("clean user", "<userId:userid> <count:number>")
@d.permission("clean") @d.permission("can_clean")
async cleanUserCmd(msg: Message, args: { userId: string; count: number }) { async cleanUserCmd(msg: Message, args: { userId: string; count: number }) {
if (args.count > MAX_CLEAN_COUNT || args.count <= 0) { if (args.count > MAX_CLEAN_COUNT || args.count <= 0) {
msg.channel.createMessage(errorMessage(`Clean count must be between 1 and ${MAX_CLEAN_COUNT}`)); msg.channel.createMessage(errorMessage(`Clean count must be between 1 and ${MAX_CLEAN_COUNT}`));
@ -373,7 +371,7 @@ export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPlu
} }
@d.command("clean bot", "<count:number>") @d.command("clean bot", "<count:number>")
@d.permission("clean") @d.permission("can_clean")
async cleanBotCmd(msg: Message, args: { count: number }) { async cleanBotCmd(msg: Message, args: { count: number }) {
if (args.count > MAX_CLEAN_COUNT || args.count <= 0) { if (args.count > MAX_CLEAN_COUNT || args.count <= 0) {
msg.channel.createMessage(errorMessage(`Clean count must be between 1 and ${MAX_CLEAN_COUNT}`)); msg.channel.createMessage(errorMessage(`Clean count must be between 1 and ${MAX_CLEAN_COUNT}`));
@ -396,7 +394,7 @@ export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPlu
} }
@d.command("info", "<userId:userId>") @d.command("info", "<userId:userId>")
@d.permission("info") @d.permission("can_info")
async infoCmd(msg: Message, args: { userId: string }) { async infoCmd(msg: Message, args: { userId: string }) {
const embed: EmbedOptions = { const embed: EmbedOptions = {
fields: [], fields: [],
@ -484,7 +482,7 @@ export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPlu
} }
@d.command(/(?:nickname|nick) reset/, "<target:member>") @d.command(/(?:nickname|nick) reset/, "<target:member>")
@d.permission("nickname") @d.permission("can_nickname")
async nicknameResetCmd(msg: Message, args: { target: Member; nickname: string }) { async nicknameResetCmd(msg: Message, args: { target: Member; nickname: string }) {
if (msg.member.id !== args.target.id && !this.canActOn(msg.member, args.target)) { if (msg.member.id !== args.target.id && !this.canActOn(msg.member, args.target)) {
msg.channel.createMessage(errorMessage("Cannot reset nickname: insufficient permissions")); msg.channel.createMessage(errorMessage("Cannot reset nickname: insufficient permissions"));
@ -504,7 +502,7 @@ export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPlu
} }
@d.command(/nickname|nick/, "<target:member> <nickname:string$>") @d.command(/nickname|nick/, "<target:member> <nickname:string$>")
@d.permission("nickname") @d.permission("can_nickname")
async nicknameCmd(msg: Message, args: { target: Member; nickname: string }) { async nicknameCmd(msg: Message, args: { target: Member; nickname: string }) {
if (msg.member.id !== args.target.id && !this.canActOn(msg.member, args.target)) { if (msg.member.id !== args.target.id && !this.canActOn(msg.member, args.target)) {
msg.channel.createMessage(errorMessage("Cannot change nickname: insufficient permissions")); msg.channel.createMessage(errorMessage("Cannot change nickname: insufficient permissions"));
@ -530,7 +528,7 @@ export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPlu
} }
@d.command("server") @d.command("server")
@d.permission("server") @d.permission("can_server")
async serverCmd(msg: Message) { async serverCmd(msg: Message) {
await this.guild.fetchAllMembers(); await this.guild.fetchAllMembers();
@ -601,7 +599,7 @@ export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPlu
} }
@d.command("ping") @d.command("ping")
@d.permission("ping") @d.permission("can_ping")
async pingCmd(msg: Message) { async pingCmd(msg: Message) {
const times = []; const times = [];
const messages: Message[] = []; const messages: Message[] = [];
@ -637,7 +635,7 @@ export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPlu
} }
@d.command("source", "<messageId:string>") @d.command("source", "<messageId:string>")
@d.permission("source") @d.permission("can_source")
async sourceCmd(msg: Message, args: { messageId: string }) { async sourceCmd(msg: Message, args: { messageId: string }) {
const savedMessage = await this.savedMessages.find(args.messageId); const savedMessage = await this.savedMessages.find(args.messageId);
if (!savedMessage) { if (!savedMessage) {
@ -656,7 +654,7 @@ export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPlu
} }
@d.command("vcmove", "<member:Member> <channel:string$>") @d.command("vcmove", "<member:Member> <channel:string$>")
@d.permission("vcmove") @d.permission("can_vcmove")
async vcmoveCmd(msg: Message, args: { member: Member; channel: string }) { async vcmoveCmd(msg: Message, args: { member: Member; channel: string }) {
let channel: VoiceChannel; let channel: VoiceChannel;
@ -727,7 +725,7 @@ export class UtilityPlugin extends ZeppelinPlugin<IBasePluginConfig, IUtilityPlu
} }
@d.command("reload_guild") @d.command("reload_guild")
@d.permission("reload_guild") @d.permission("can_reload_guild")
reloadGuildCmd(msg: Message) { reloadGuildCmd(msg: Message) {
if (activeReloads.has(this.guildId)) return; if (activeReloads.has(this.guildId)) return;
activeReloads.set(this.guildId, msg.channel as TextChannel); activeReloads.set(this.guildId, msg.channel as TextChannel);

View file

@ -1,12 +1,9 @@
import { IBasePluginConfig, IBasePluginPermissions, IPluginOptions, Plugin } from "knub"; import { IBasePluginConfig, 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< export class ZeppelinPlugin<TConfig extends {} = IBasePluginConfig> extends Plugin<TConfig> {
TConfig extends {} = IBasePluginConfig,
TPermissions extends {} = IBasePluginPermissions
> extends Plugin<TConfig, TPermissions> {
protected configSchema: any; protected configSchema: any;
protected permissionsSchema: any; protected permissionsSchema: any;
@ -45,26 +42,6 @@ export class ZeppelinPlugin<
} }
} }
// Validate permission values
if (this.permissionsSchema) {
const ajv = new Ajv();
const validate = ajv.compile(this.permissionsSchema);
if (options.permissions) {
const isValid = validate(options.permissions);
if (!isValid) return validate.errors;
}
if (options.overrides) {
for (const override of options.overrides) {
if (override.permissions) {
const isValid = validate(override.permissions);
if (!isValid) return validate.errors;
}
}
}
}
// No errors, return null // No errors, return null
return null; return null;
} }