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 Cryptr = require('cryptr');
const I18n = require('@eartharoid/i18n');
const ListenerLoader = require('./modules/listeners/loader');
const CommandManager = require('./modules/commands/manager');
const PluginManager = require('./modules/plugins/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
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 */
this.tickets = new TicketManager(this);

View File

@ -1,6 +1,15 @@
module.exports = {
event: 'debug',
execute: (client, data) => {
if (client.config.debug) client.log.debug(data);
const EventListener = require('../modules/listeners/listener');
module.exports = class DebugEventListener extends EventListener {
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 = {
event: 'error',
execute: (client, error) => {
client.log.warn('The client encountered an error');
client.log.error(error);
const EventListener = require('../modules/listeners/listener');
module.exports = class ErrorEventListener extends EventListener {
constructor(client) {
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 = {
event: 'guildCreate',
execute: async (client, guild) => {
client.log.info(`Added to "${guild.name}"`);
const EventListener = require('../modules/listeners/listener');
module.exports = class GuildCreateEventListener extends EventListener {
constructor(client) {
super(client, {
event: 'guildCreate'
});
}
async execute(guild) {
this.client.log.info(`Added to "${guild.name}"`);
await guild.createSettings();
}
};

View File

@ -1,7 +1,14 @@
module.exports = {
event: 'guildDelete',
execute: async (client, guild) => {
client.log.info(`Removed from "${guild.name}"`);
await guild.deleteSettings();
const EventListener = require('../modules/listeners/listener');
module.exports = class GuildDeleteEventListener extends EventListener {
constructor(client) {
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 = {
event: 'guildMemberRemove',
execute: async (client, member) => {
let tickets = await client.db.models.Ticket.findAndCountAll({
const EventListener = require('../modules/listeners/listener');
module.exports = class GuildMemberRemoveEventListener extends EventListener {
constructor(client) {
super(client, {
event: 'guildMemberRemove'
});
}
async execute(member) {
let tickets = await this.client.db.models.Ticket.findAndCountAll({
where: {
creator: member.id,
guild: member.guild.id
@ -9,9 +16,9 @@ module.exports = {
});
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 { footer } = require('../utils/discord');
module.exports = {
event: 'message',
execute: async (client, message) => {
module.exports = class MessageEventListener extends EventListener {
constructor(client) {
super(client, {
event: 'message'
});
}
async execute(message) {
if (!message.guild) return;
let settings = await message.guild.settings;
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: {
id: message.channel.id
}
@ -18,10 +25,10 @@ module.exports = {
if (t_row) {
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)) {
t_row.update({
first_response: new Date()
@ -30,7 +37,7 @@ module.exports = {
} else {
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: {
channel: message.channel.id
}
@ -41,13 +48,13 @@ module.exports = {
await message.delete();
let cat_row = await client.db.models.Category.findOne({
let cat_row = await this.client.db.models.Category.findOne({
where: {
id: p_row.categories
}
});
let tickets = await client.db.models.Ticket.findAndCountAll({
let tickets = await this.client.db.models.Ticket.findAndCountAll({
where: {
category: cat_row.id,
creator: message.author.id,
@ -94,7 +101,7 @@ module.exports = {
}
} else {
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) {
const embed = new MessageEmbed()
.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 = {
event: 'messageDelete',
execute: async (client, message) => {
const EventListener = require('../modules/listeners/listener');
module.exports = class MessageDeleteEventListener extends EventListener {
constructor(client) {
super(client, {
event: 'messageDelete'
});
}
async execute(message) {
if (!message.guild) return;
let settings = await message.guild.settings;
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 { footer } = require('../utils/discord');
module.exports = {
event: 'messageReactionAdd',
execute: async (client, r, u) => {
module.exports = class MessageReactionAddEventListener extends EventListener {
constructor(client) {
super(client, {
event: 'messageReactionAdd'
});
}
async execute(r, u) {
if (r.partial) r = await r.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;
if (!guild) return;
let settings = await guild.settings;
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 member = await guild.members.fetch(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 {
settings.blacklist.forEach(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: {
id: channel.id
}
@ -48,7 +55,7 @@ module.exports = {
VIEW_CHANNEL: true,
}, `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: {
id: t_row.category
}
@ -60,7 +67,7 @@ module.exports = {
}, `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(
new MessageEmbed()
@ -74,7 +81,7 @@ module.exports = {
await r.users.remove(u.id);
}
} else {
let p_row = await client.db.models.Panel.findOne({
let p_row = await this.client.db.models.Panel.findOne({
where: {
message: r.message.id
}
@ -87,13 +94,13 @@ module.exports = {
let category_id = p_row.categories[r.emoji.name];
if (!category_id) return;
let cat_row = await client.db.models.Category.findOne({
let cat_row = await this.client.db.models.Category.findOne({
where: {
id: category_id
}
});
let tickets = await client.db.models.Ticket.findAndCountAll({
let tickets = await this.client.db.models.Ticket.findAndCountAll({
where: {
category: cat_row.id,
creator: u.id,
@ -140,7 +147,7 @@ module.exports = {
}
} else {
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) {
const embed = new MessageEmbed()
.setColor(settings.error_colour)
@ -157,7 +164,7 @@ module.exports = {
}
if (response) {
setTimeout(async() => {
setTimeout(async () => {
await response.delete();
}, 15000);
}

View File

@ -1,12 +1,18 @@
module.exports = {
event: 'messageUpdate',
execute: async (client, oldm, newm) => {
const EventListener = require('../modules/listeners/listener');
module.exports = class MessageUpdateEventListener extends EventListener {
constructor(client) {
super(client, {
event: 'messageUpdate'
});
}
async execute(oldm, newm) {
if (newm.partial) {
try {
await newm.fetch();
} 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;
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 = {
event: 'rateLimit',
execute: (client, limit) => {
client.log.warn('Rate-limited!', limit);
const EventListener = require('../modules/listeners/listener');
module.exports = class RateLimitEventListener extends EventListener {
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',
once: true,
execute: async (client) => {
once: true
});
}
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');
setInterval(() => {
let presence = selectPresence();
client.user.setPresence(presence);
client.log.debug(`Updated presence: ${presence.activity.type} ${presence.activity.name}`);
}, client.config.presence.duration * 1000);
this.client.user.setPresence(presence);
this.client.log.debug(`Updated presence: ${presence.activity.type} ${presence.activity.name}`);
}, this.client.config.presence.duration * 1000);
}
if(client.config.super_secret_setting) {
if (this.client.config.super_secret_setting) {
setInterval(async () => {
await client.postStats();
await this.client.postStats();
}, 3600000);
await client.postStats();
await this.client.postStats();
}
}
};

View File

@ -1,6 +1,13 @@
module.exports = {
event: 'warn',
execute: (client, warning) => {
client.log.warn(warning);
const EventListener = require('../modules/listeners/listener');
module.exports = class WarnEventListener extends EventListener {
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.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 = [
`&6You are currently using &c${current}&6, the latest is &a${update.tag_name}&6.`,
`&6Download "&f${update.name}&6" from`,
link('&6the GitHub releases page', 'https://github.com/discord-tickets/bot/releases/')
`&k&6You are currently using &c${current}&6, the latest is &a${update.tag_name}&6.&r`,
`&k&6Download "&f${update.name}&6" from&r`,
link('&k&6the GitHub releases page.&r&6', 'https://github.com/discord-tickets/bot/releases/')
];
console.log(