Refactor listeners

This commit is contained in:
Isaac 2021-05-12 21:14:02 +01:00
parent 1a8b86dee0
commit c9d55e6feb
No known key found for this signature in database
GPG Key ID: F6812DBC6719B4E3
17 changed files with 229 additions and 111 deletions

View File

@ -89,6 +89,7 @@ process.on('unhandledRejection', error => {
const { selectPresence } = require('./utils/discord'); const { selectPresence } = require('./utils/discord');
const Cryptr = require('cryptr'); const Cryptr = require('cryptr');
const I18n = require('@eartharoid/i18n'); const I18n = require('@eartharoid/i18n');
const ListenerLoader = require('./modules/listeners/loader');
const CommandManager = require('./modules/commands/manager'); const CommandManager = require('./modules/commands/manager');
const PluginManager = require('./modules/plugins/manager'); const PluginManager = require('./modules/plugins/manager');
const TicketManager = require('./modules/tickets/manager'); const TicketManager = require('./modules/tickets/manager');
@ -150,7 +151,9 @@ class Bot extends Client {
this.setMaxListeners(this.config.max_listeners); // set the max listeners for each event this.setMaxListeners(this.config.max_listeners); // set the max listeners for each event
require('./updater')(this); // check for updates require('./updater')(this); // check for updates
require('./modules/listeners')(this); // load internal listeners
const listeners = new ListenerLoader(this);
listeners.load(); // load internal listeners
/** The ticket manager */ /** The ticket manager */
this.tickets = new TicketManager(this); this.tickets = new TicketManager(this);

View File

@ -1,6 +1,15 @@
module.exports = { const EventListener = require('../modules/listeners/listener');
event: 'debug',
execute: (client, data) => { module.exports = class DebugEventListener extends EventListener {
if (client.config.debug) client.log.debug(data); constructor(client) {
super(client, {
event: 'debug'
});
}
async execute(data) {
if (this.client.config.debug) {
this.client.log.debug(data);
}
} }
}; };

View File

@ -1,7 +1,14 @@
module.exports = { const EventListener = require('../modules/listeners/listener');
event: 'error',
execute: (client, error) => { module.exports = class ErrorEventListener extends EventListener {
client.log.warn('The client encountered an error'); constructor(client) {
client.log.error(error); super(client, {
event: 'error'
});
}
async execute(error) {
this.client.log.warn('The client encountered an error');
this.client.log.error(error);
} }
}; };

View File

@ -1,7 +1,14 @@
module.exports = { const EventListener = require('../modules/listeners/listener');
event: 'guildCreate',
execute: async (client, guild) => { module.exports = class GuildCreateEventListener extends EventListener {
client.log.info(`Added to "${guild.name}"`); constructor(client) {
super(client, {
event: 'guildCreate'
});
}
async execute(guild) {
this.client.log.info(`Added to "${guild.name}"`);
await guild.createSettings(); await guild.createSettings();
} }
}; };

View File

@ -1,7 +1,14 @@
module.exports = { const EventListener = require('../modules/listeners/listener');
event: 'guildDelete',
execute: async (client, guild) => { module.exports = class GuildDeleteEventListener extends EventListener {
client.log.info(`Removed from "${guild.name}"`); constructor(client) {
await guild.deleteSettings(); super(client, {
event: 'guildDelete'
});
}
async execute(guild) {
this.client.log.info(`Removed from "${guild.name}"`);
// await guild.deleteSettings();
} }
}; };

View File

@ -1,7 +1,14 @@
module.exports = { const EventListener = require('../modules/listeners/listener');
event: 'guildMemberRemove',
execute: async (client, member) => { module.exports = class GuildMemberRemoveEventListener extends EventListener {
let tickets = await client.db.models.Ticket.findAndCountAll({ constructor(client) {
super(client, {
event: 'guildMemberRemove'
});
}
async execute(member) {
let tickets = await this.client.db.models.Ticket.findAndCountAll({
where: { where: {
creator: member.id, creator: member.id,
guild: member.guild.id guild: member.guild.id
@ -9,9 +16,9 @@ module.exports = {
}); });
for (let ticket of tickets.rows) { for (let ticket of tickets.rows) {
await client.tickets.close(ticket.id, null, member.guild.id, 'Member left the guild'); await this.client.tickets.close(ticket.id, null, member.guild.id, 'Member left the guild');
} }
client.log.info(`Closed ${tickets.count} ticket(s) belonging to ${member.user.tag} who left "${member.guild.name}"`); this.client.log.info(`Closed ${tickets.count} ticket(s) belonging to ${member.user.tag} who left "${member.guild.name}"`);
} }
}; };

View File

@ -1,16 +1,23 @@
const EventListener = require('../modules/listeners/listener');
const { MessageEmbed } = require('discord.js'); const { MessageEmbed } = require('discord.js');
const { footer } = require('../utils/discord'); const { footer } = require('../utils/discord');
module.exports = { module.exports = class MessageEventListener extends EventListener {
event: 'message', constructor(client) {
execute: async (client, message) => { super(client, {
event: 'message'
});
}
async execute(message) {
if (!message.guild) return; if (!message.guild) return;
let settings = await message.guild.settings; let settings = await message.guild.settings;
if (!settings) settings = await message.guild.createSettings(); if (!settings) settings = await message.guild.createSettings();
const i18n = client.i18n.getLocale(settings.locale); const i18n = this.client.i18n.getLocale(settings.locale);
let t_row = await client.db.models.Ticket.findOne({ let t_row = await this.client.db.models.Ticket.findOne({
where: { where: {
id: message.channel.id id: message.channel.id
} }
@ -18,10 +25,10 @@ module.exports = {
if (t_row) { if (t_row) {
if (settings.log_messages && !message.system) { if (settings.log_messages && !message.system) {
client.tickets.archives.addMessage(message); // add the message to the archives (if it is in a ticket channel) this.client.tickets.archives.addMessage(message); // add the message to the archives (if it is in a ticket channel)
} }
const ignore = [client.user.id, t_row.creator]; const ignore = [this.client.user.id, t_row.creator];
if (!t_row.first_response && !ignore.includes(message.author.id)) { if (!t_row.first_response && !ignore.includes(message.author.id)) {
t_row.update({ t_row.update({
first_response: new Date() first_response: new Date()
@ -30,7 +37,7 @@ module.exports = {
} else { } else {
if (message.author.bot) return; if (message.author.bot) return;
let p_row = await client.db.models.Panel.findOne({ let p_row = await this.client.db.models.Panel.findOne({
where: { where: {
channel: message.channel.id channel: message.channel.id
} }
@ -41,13 +48,13 @@ module.exports = {
await message.delete(); await message.delete();
let cat_row = await client.db.models.Category.findOne({ let cat_row = await this.client.db.models.Category.findOne({
where: { where: {
id: p_row.categories id: p_row.categories
} }
}); });
let tickets = await client.db.models.Ticket.findAndCountAll({ let tickets = await this.client.db.models.Ticket.findAndCountAll({
where: { where: {
category: cat_row.id, category: cat_row.id,
creator: message.author.id, creator: message.author.id,
@ -94,7 +101,7 @@ module.exports = {
} }
} else { } else {
try { try {
await client.tickets.create(message.guild.id, message.author.id, cat_row.id, message.cleanContent); await this.client.tickets.create(message.guild.id, message.author.id, cat_row.id, message.cleanContent);
} catch (error) { } catch (error) {
const embed = new MessageEmbed() const embed = new MessageEmbed()
.setColor(settings.error_colour) .setColor(settings.error_colour)
@ -118,6 +125,7 @@ module.exports = {
} }
} }
client.commands.handle(message); // pass the message to the command handler this.client.commands.handle(message); // pass the message to the command handler
} }
}; };

View File

@ -1,11 +1,18 @@
module.exports = { const EventListener = require('../modules/listeners/listener');
event: 'messageDelete',
execute: async (client, message) => { module.exports = class MessageDeleteEventListener extends EventListener {
constructor(client) {
super(client, {
event: 'messageDelete'
});
}
async execute(message) {
if (!message.guild) return; if (!message.guild) return;
let settings = await message.guild.settings; let settings = await message.guild.settings;
if (!settings) settings = await message.guild.createSettings(); if (!settings) settings = await message.guild.createSettings();
if (settings.log_messages && !message.system) client.tickets.archives.deleteMessage(message); // mark the message as deleted in the database (if it exists) if (settings.log_messages && !message.system) this.client.tickets.archives.deleteMessage(message); // mark the message as deleted in the database (if it exists)
} }
}; };

View File

@ -1,36 +1,43 @@
const EventListener = require('../modules/listeners/listener');
const { MessageEmbed } = require('discord.js'); const { MessageEmbed } = require('discord.js');
const { footer } = require('../utils/discord'); const { footer } = require('../utils/discord');
module.exports = { module.exports = class MessageReactionAddEventListener extends EventListener {
event: 'messageReactionAdd', constructor(client) {
execute: async (client, r, u) => { super(client, {
event: 'messageReactionAdd'
});
}
async execute(r, u) {
if (r.partial) r = await r.fetch(); if (r.partial) r = await r.fetch();
if (u.partial) u = await u.fetch(); if (u.partial) u = await u.fetch();
if (u.id === client.user.id) return; if (u.id === this.client.user.id) return;
const guild = r.message.guild; const guild = r.message.guild;
if (!guild) return; if (!guild) return;
let settings = await guild.settings; let settings = await guild.settings;
if (!settings) settings = await guild.createSettings(); if (!settings) settings = await guild.createSettings();
const i18n = client.i18n.getLocale(settings.locale); const i18n = this.client.i18n.getLocale(settings.locale);
const channel = r.message.channel; const channel = r.message.channel;
const member = await guild.members.fetch(u.id); const member = await guild.members.fetch(u.id);
if (settings.blacklist.includes(u.id)) { if (settings.blacklist.includes(u.id)) {
return client.log.info(`Ignoring blacklisted member ${u.tag}`); return this.client.log.info(`Ignoring blacklisted member ${u.tag}`);
} else { } else {
settings.blacklist.forEach(element => { settings.blacklist.forEach(element => {
if (guild.roles.cache.has(element) && member.roles.cache.has(element)) { if (guild.roles.cache.has(element) && member.roles.cache.has(element)) {
return client.log.info(`Ignoring member ${u.tag} with blacklisted role`); return this.client.log.info(`Ignoring member ${u.tag} with blacklisted role`);
} }
}); });
} }
let t_row = await client.db.models.Ticket.findOne({ let t_row = await this.client.db.models.Ticket.findOne({
where: { where: {
id: channel.id id: channel.id
} }
@ -48,7 +55,7 @@ module.exports = {
VIEW_CHANNEL: true, VIEW_CHANNEL: true,
}, `Ticket claimed by ${member.user.tag}`); }, `Ticket claimed by ${member.user.tag}`);
let cat_row = await client.db.models.Category.findOne({ let cat_row = await this.client.db.models.Category.findOne({
where: { where: {
id: t_row.category id: t_row.category
} }
@ -60,7 +67,7 @@ module.exports = {
}, `Ticket claimed by ${member.user.tag}`); }, `Ticket claimed by ${member.user.tag}`);
} }
client.log.info(`${member.user.tag} has claimed "${channel.name}" in "${guild.name}"`); this.client.log.info(`${member.user.tag} has claimed "${channel.name}" in "${guild.name}"`);
await channel.send( await channel.send(
new MessageEmbed() new MessageEmbed()
@ -74,7 +81,7 @@ module.exports = {
await r.users.remove(u.id); await r.users.remove(u.id);
} }
} else { } else {
let p_row = await client.db.models.Panel.findOne({ let p_row = await this.client.db.models.Panel.findOne({
where: { where: {
message: r.message.id message: r.message.id
} }
@ -87,13 +94,13 @@ module.exports = {
let category_id = p_row.categories[r.emoji.name]; let category_id = p_row.categories[r.emoji.name];
if (!category_id) return; if (!category_id) return;
let cat_row = await client.db.models.Category.findOne({ let cat_row = await this.client.db.models.Category.findOne({
where: { where: {
id: category_id id: category_id
} }
}); });
let tickets = await client.db.models.Ticket.findAndCountAll({ let tickets = await this.client.db.models.Ticket.findAndCountAll({
where: { where: {
category: cat_row.id, category: cat_row.id,
creator: u.id, creator: u.id,
@ -140,7 +147,7 @@ module.exports = {
} }
} else { } else {
try { try {
await client.tickets.create(guild.id, u.id, cat_row.id); await this.client.tickets.create(guild.id, u.id, cat_row.id);
} catch (error) { } catch (error) {
const embed = new MessageEmbed() const embed = new MessageEmbed()
.setColor(settings.error_colour) .setColor(settings.error_colour)

View File

@ -1,12 +1,18 @@
module.exports = { const EventListener = require('../modules/listeners/listener');
event: 'messageUpdate',
execute: async (client, oldm, newm) => {
module.exports = class MessageUpdateEventListener extends EventListener {
constructor(client) {
super(client, {
event: 'messageUpdate'
});
}
async execute(oldm, newm) {
if (newm.partial) { if (newm.partial) {
try { try {
await newm.fetch(); await newm.fetch();
} catch (err) { } catch (err) {
return client.log.error(err); return this.client.log.error(err);
} }
} }
@ -15,6 +21,6 @@ module.exports = {
let settings = await newm.guild.settings; let settings = await newm.guild.settings;
if (!settings) settings = await newm.guild.createSettings(); if (!settings) settings = await newm.guild.createSettings();
if (settings.log_messages && !newm.system) client.tickets.archives.updateMessage(newm); // update the message in the database if (settings.log_messages && !newm.system) this.client.tickets.archives.updateMessage(newm); // update the message in the database
} }
}; };

View File

@ -1,6 +1,13 @@
module.exports = { const EventListener = require('../modules/listeners/listener');
event: 'rateLimit',
execute: (client, limit) => { module.exports = class RateLimitEventListener extends EventListener {
client.log.warn('Rate-limited!', limit); constructor(client) {
super(client, {
event: 'rateLimit'
});
}
async execute(limit) {
this.client.log.warn('Rate-limited!', limit);
} }
}; };

View File

@ -1,29 +1,34 @@
module.exports = { const EventListener = require('../modules/listeners/listener');
module.exports = class ReadyEventListener extends EventListener {
constructor(client) {
super(client, {
event: 'ready', event: 'ready',
once: true, once: true
execute: async (client) => { });
}
client.log.success(`Connected to Discord as "${client.user.tag}"`); async execute() {
this.client.log.success(`Connected to Discord as "${this.client.user.tag}"`);
client.commands.load(); // load internal commands this.client.commands.load(); // load internal commands
client.plugins.plugins.forEach(p => p.load()); // call load function for each plugin this.client.plugins.plugins.forEach(p => p.load()); // call load function for each plugin
if (client.config.presence.presences.length > 1) { if (this.client.config.presence.presences.length > 1) {
const { selectPresence } = require('../utils/discord'); const { selectPresence } = require('../utils/discord');
setInterval(() => { setInterval(() => {
let presence = selectPresence(); let presence = selectPresence();
client.user.setPresence(presence); this.client.user.setPresence(presence);
client.log.debug(`Updated presence: ${presence.activity.type} ${presence.activity.name}`); this.client.log.debug(`Updated presence: ${presence.activity.type} ${presence.activity.name}`);
}, client.config.presence.duration * 1000); }, this.client.config.presence.duration * 1000);
} }
if(client.config.super_secret_setting) { if (this.client.config.super_secret_setting) {
setInterval(async () => { setInterval(async () => {
await client.postStats(); await this.client.postStats();
}, 3600000); }, 3600000);
await client.postStats(); await this.client.postStats();
} }
} }
}; };

View File

@ -1,6 +1,13 @@
module.exports = { const EventListener = require('../modules/listeners/listener');
event: 'warn',
execute: (client, warning) => { module.exports = class WarnEventListener extends EventListener {
client.log.warn(warning); constructor(client) {
super(client, {
event: 'warn'
});
}
async execute(warning) {
this.client.log.warn(warning);
} }
}; };

View File

@ -1,17 +0,0 @@
const fs = require('fs');
const { path } = require('../utils/fs');
module.exports = client => {
const files = fs.readdirSync(path('./src/listeners'))
.filter(file => file.endsWith('.js'));
for (const file of files) {
const listener = require(`../listeners/${file}`);
const exec = (...args) => listener.execute(client, ...args);
let on = listener.once ? 'once' : 'on';
if (listener.raw)
client.ws[on](listener.event, exec);
else
client[on](listener.event, exec);
}
};

View File

@ -0,0 +1,10 @@
module.exports = class EventListener {
constructor(client, data) {
this.client = client;
this.event = data.event;
this.raw = data.raw || false;
this.once = data.once || false;
}
};

View File

@ -0,0 +1,38 @@
const fs = require('fs');
const { path } = require('../../utils/fs');
/**
* Manages the loading of event listeners
*/
module.exports = class ListenerLoader {
/**
* Create a ListenerLoader instance
* @param {Client} client
*/
constructor(client) {
/** The Discord Client */
this.client = client;
}
load() {
const files = fs.readdirSync(path('./src/listeners'))
.filter(file => file.endsWith('.js'));
for (let file of files) {
try {
file = require(`../../listeners/${file}`);
const listener = new file(this.client);
let on = listener.once ? 'once' : 'on';
if (listener.raw)
this.client.ws[on](listener.event, (...data) => listener.execute(...data));
else
this.client[on](listener.event, (...data) => listener.execute(...data));
} catch (e) {
this.client.log.warn('An error occurred whilst loading a listener');
this.client.log.error(e);
}
}
}
};

View File

@ -16,12 +16,12 @@ module.exports = async client => {
if (!semver.valid(latest)) return; if (!semver.valid(latest)) return;
if (semver.lt(current, latest)) { if (semver.lt(current, latest)) {
client.log.notice(client.log.f(`There is an update available for Discord Tickets (${current} -> ${update.tag_name})`)); client.log.notice(`There is an update available for Discord Tickets (${current} -> ${update.tag_name})`);
let lines = [ let lines = [
`&6You are currently using &c${current}&6, the latest is &a${update.tag_name}&6.`, `&k&6You are currently using &c${current}&6, the latest is &a${update.tag_name}&6.&r`,
`&6Download "&f${update.name}&6" from`, `&k&6Download "&f${update.name}&6" from&r`,
link('&6the GitHub releases page', 'https://github.com/discord-tickets/bot/releases/') link('&k&6the GitHub releases page.&r&6', 'https://github.com/discord-tickets/bot/releases/')
]; ];
console.log( console.log(