diff --git a/src/models/interfaces.ts b/src/models/interfaces.ts index 79a88fb..f71d224 100644 --- a/src/models/interfaces.ts +++ b/src/models/interfaces.ts @@ -24,5 +24,11 @@ export interface IResponses { export interface IModule { readonly roles?: string[], - command: (message: Message, args: string) => void | Promise + command: (message: Message, args?: string) => void | Promise +} + +export interface ITrigger { + readonly roles?: string[], + trigger: (message: Message, args?: string) => boolean + execute: (message: Message, args?: string) => void | Promise } diff --git a/src/server.ts b/src/server.ts index e68df54..e38b2da 100644 --- a/src/server.ts +++ b/src/server.ts @@ -9,14 +9,16 @@ import fs = require('fs'); import logger from './logging'; import state from './state'; import * as data from './data'; +import { IModule, ITrigger } from './models/interfaces'; state.responses = require('./responses.json'); interface IModuleMap { - [name: string]: any; + [name: string]: IModule; } let cachedModules: IModuleMap = {}; +let cachedTriggers: ITrigger[] = []; const client = new discord.Client(); const rulesTrigger = process.env.DISCORD_RULES_TRIGGER; const rluesRole = process.env.DISCORD_RULES_ROLE; @@ -198,6 +200,18 @@ client.on('message', message => { } } catch (err) { logger.error(err); } + } else if (message.author.bot === false) { + // This is a normal channel message. + cachedTriggers.forEach(function (trigger) { + if (!trigger.roles || authorRoles && findArray(authorRoles, trigger.roles)) { + if (trigger.trigger(message) === true) { + logger.debug(`${message.author.username} ${message.author} [Channel: ${message.channel}] triggered: ${message.content}`); + try { + trigger.execute(message); + } catch (err) { logger.error(err); } + } + } + }); } }); @@ -216,6 +230,25 @@ fs.readdirSync('./commands/').forEach(function (file) { } }); +// Cache all triggers. +cachedTriggers = []; +fs.readdirSync('./triggers/').forEach(function (file) { + // Load the module if it's a script. + if (path.extname(file) === '.js') { + if (file.includes('.disabled')) { + logger.info(`Did not load disabled trigger: ${file}`); + } else { + const moduleName = path.basename(file, '.js').toLowerCase(); + logger.info(`Loaded trigger: ${moduleName} from ${file}`); + try { + cachedTriggers.push(require(`./triggers/${file}`)); + } catch (e) { + logger.error(`Could not load trigger ${moduleName}: ${e}`); + } + } + } +}); + data.readWarnings(); data.readBans(); diff --git a/src/triggers/pingBomb.ts b/src/triggers/pingBomb.ts new file mode 100644 index 0000000..cf4b7dc --- /dev/null +++ b/src/triggers/pingBomb.ts @@ -0,0 +1,15 @@ +import { ban } from '../common'; +import state from '../state'; +import logger from '../logging'; +import discord = require('discord.js'); + +export function trigger(message: discord.Message) { + return message.mentions.users.array().length > 10; +} + +export function execute(message: discord.Message) { + const count = message.mentions.users.array().length; + logger.info(`${message.author.toString()} tagged ${count} users in ${message.channel.toString()}`); + state.logChannel.send(`Ping bomb detected in ${message.channel.toString()} by ${message.author.toString()}`); + ban(message.author, message.author, message.guild); +};