Clean up and comment some code

This commit is contained in:
Isaac 2021-04-06 16:18:58 +01:00
parent e4f0f2a954
commit f96cae3c1e
11 changed files with 164 additions and 115 deletions

View File

@ -108,10 +108,10 @@ module.exports = class NewCommand extends Command {
.setFooter(settings.footer, message.guild.iconURL()) .setFooter(settings.footer, message.guild.iconURL())
); );
} else if (categories.count === 1) { } else if (categories.count === 1) {
create(categories.rows[0]); create(categories.rows[0]); // skip the category selection
} else { } else {
let letters_array = Object.values(letters); let letters_array = Object.values(letters); // convert the A-Z emoji object to an array
let category_list = categories.rows.map((category, i) => `${letters_array[i]} » ${category.name}`); let category_list = categories.rows.map((category, i) => `${letters_array[i]} » ${category.name}`); // list category names with an A-Z emoji
let collector_message = await message.channel.send( let collector_message = await message.channel.send(
new MessageEmbed() new MessageEmbed()
.setColor(settings.colour) .setColor(settings.colour)
@ -122,11 +122,11 @@ module.exports = class NewCommand extends Command {
); );
for (let i in categories.rows) { for (let i in categories.rows) {
await collector_message.react(letters_array[i]); await collector_message.react(letters_array[i]); // add the correct number of letter reactions
} }
const collector_filter = (reaction, user) => { const collector_filter = (reaction, user) => {
let allowed = letters_array.slice(0, categories.count); let allowed = letters_array.slice(0, categories.count); // get the first x letters of the emoji array
return user.id === message.author.id && allowed.includes(reaction.emoji.name); return user.id === message.author.id && allowed.includes(reaction.emoji.name);
}; };
@ -135,10 +135,10 @@ module.exports = class NewCommand extends Command {
}); });
collector.on('collect', async (reaction) => { collector.on('collect', async (reaction) => {
let index = letters_array.findIndex(value => value === reaction.emoji.name); let index = letters_array.findIndex(value => value === reaction.emoji.name); // find where the letter is in the alphabet
if (index === -1) return await collector_message.delete({ timeout: 15000 }); if (index === -1) return await collector_message.delete({ timeout: 15000 });
await collector_message.reactions.removeAll(); await collector_message.reactions.removeAll();
create(categories.rows[index], collector_message); create(categories.rows[index], collector_message); // create the ticket, passing the existing response message to be edited instead of creating a new one
}); });
collector.on('end', async (collected) => { collector.on('end', async (collected) => {
@ -152,7 +152,10 @@ module.exports = class NewCommand extends Command {
.setDescription(i18n('commands.new.response.select_category_timeout.description', category_list.join('\n'))) .setDescription(i18n('commands.new.response.select_category_timeout.description', category_list.join('\n')))
.setFooter(footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()) .setFooter(footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL())
); );
collector_message.delete({ timeout: 15000 }); setTimeout(async () => {
await collector_message.delete();
await message.delete();
}, 15000);
} }
}); });
} }

View File

@ -46,10 +46,12 @@ module.exports = class SettingsCommand extends Command {
id: c.id id: c.id
} }
}); });
category.name = c.name;
category.roles = c.roles;
category.max_per_member = c.max_per_member; category.max_per_member = c.max_per_member;
category.name = c.name;
category.name_format = c.name_format; category.name_format = c.name_format;
category.opening_message = c.opening_message;
category.require_topic = c.require_topic;
category.roles = c.roles;
category.save(); category.save();
let cat_channel = await this.client.channels.fetch(c.id); let cat_channel = await this.client.channels.fetch(c.id);
@ -99,6 +101,8 @@ module.exports = class SettingsCommand extends Command {
name: c.name, name: c.name,
name_format: c.name_format, name_format: c.name_format,
guild: message.guild.id, guild: message.guild.id,
opening_message: c.opening_message,
require_topic: c.require_topic,
roles: c.roles, roles: c.roles,
}); });
@ -133,6 +137,8 @@ module.exports = class SettingsCommand extends Command {
max_per_member: c.max_per_member, max_per_member: c.max_per_member,
name: c.name, name: c.name,
name_format: c.name_format, name_format: c.name_format,
opening_message: c.opening_message,
require_topic: c.require_topic,
roles: c.roles roles: c.roles
}; };
}); });

View File

@ -68,33 +68,33 @@ module.exports = async (client) => {
primaryKey: true, primaryKey: true,
allowNull: false, allowNull: false,
}, },
locale: { colour: {
type: DataTypes.STRING, type: DataTypes.STRING,
defaultValue: config.locale defaultValue: config.defaults.colour
}, },
command_prefix: { command_prefix: {
type: DataTypes.STRING, type: DataTypes.STRING,
defaultValue: config.defaults.command_prefix defaultValue: config.defaults.command_prefix
}, },
colour: {
type: DataTypes.STRING,
defaultValue: config.defaults.colour
},
success_colour: {
type: DataTypes.STRING,
defaultValue: 'GREEN'
},
error_colour: { error_colour: {
type: DataTypes.STRING, type: DataTypes.STRING,
defaultValue: 'RED' defaultValue: 'RED'
}, },
footer: {
type: DataTypes.STRING,
defaultValue: 'Discord Tickets by eartharoid'
},
locale: {
type: DataTypes.STRING,
defaultValue: config.locale
},
log_messages: { log_messages: {
type: DataTypes.BOOLEAN, type: DataTypes.BOOLEAN,
defaultValue: config.defaults.log_messages defaultValue: config.defaults.log_messages
}, },
footer: { success_colour: {
type: DataTypes.STRING, type: DataTypes.STRING,
defaultValue: 'Discord Tickets by eartharoid' defaultValue: 'GREEN'
}, },
}, { }, {
tableName: DB_TABLE_PREFIX + 'guilds' tableName: DB_TABLE_PREFIX + 'guilds'
@ -106,11 +106,6 @@ module.exports = async (client) => {
primaryKey: true, primaryKey: true,
allowNull: false, allowNull: false,
}, },
name: {
type: DataTypes.STRING,
allowNull: false,
unique: 'name-guild'
},
guild: { guild: {
type: DataTypes.CHAR(18), type: DataTypes.CHAR(18),
allowNull: false, allowNull: false,
@ -120,18 +115,36 @@ module.exports = async (client) => {
}, },
unique: 'name-guild' unique: 'name-guild'
}, },
roles: {
type: DataTypes.JSON
},
max_per_member: { max_per_member: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
defaultValue: 1 defaultValue: 1
}, },
name: {
type: DataTypes.STRING,
allowNull: false,
unique: 'name-guild'
},
name_format: { name_format: {
type: DataTypes.STRING, type: DataTypes.STRING,
allowNull: false, allowNull: false,
defaultValue: config.defaults.name_format defaultValue: config.defaults.name_format
} },
opening_message: {
type: DataTypes.STRING,
defaultValue: config.defaults.opening_message,
},
require_topic: {
type: DataTypes.BOOLEAN,
defaultValue: true,
},
roles: {
type: DataTypes.JSON,
allowNull: false,
},
questions: {
type: DataTypes.JSON,
allowNull: true,
},
}, { }, {
tableName: DB_TABLE_PREFIX + 'categories' tableName: DB_TABLE_PREFIX + 'categories'
}); });
@ -142,10 +155,21 @@ module.exports = async (client) => {
primaryKey: true, primaryKey: true,
allowNull: false, allowNull: false,
}, },
number: { category: {
type: DataTypes.INTEGER, type: DataTypes.CHAR(18),
allowNull: false,
references: {
model: Category,
key: 'id'
},
},
closed_by: {
type: DataTypes.CHAR(18),
allowNull: true,
},
creator: {
type: DataTypes.CHAR(18),
allowNull: false, allowNull: false,
unique: 'number-guild'
}, },
guild: { guild: {
type: DataTypes.CHAR(18), type: DataTypes.CHAR(18),
@ -156,30 +180,19 @@ module.exports = async (client) => {
}, },
unique: 'number-guild' unique: 'number-guild'
}, },
category: { number: {
type: DataTypes.CHAR(18), type: DataTypes.INTEGER,
allowNull: false,
references: {
model: Category,
key: 'id'
},
},
topic: {
type: DataTypes.STRING,
allowNull: true,
},
creator: {
type: DataTypes.CHAR(18),
allowNull: false, allowNull: false,
unique: 'number-guild'
}, },
open: { open: {
type: DataTypes.BOOLEAN, type: DataTypes.BOOLEAN,
defaultValue: true defaultValue: true
}, },
closed_by: { topic: {
type: DataTypes.CHAR(18), type: DataTypes.STRING,
allowNull: true, allowNull: true,
} },
}, { }, {
tableName: DB_TABLE_PREFIX + 'tickets' tableName: DB_TABLE_PREFIX + 'tickets'
}); });
@ -191,6 +204,22 @@ module.exports = async (client) => {
primaryKey: true, primaryKey: true,
allowNull: false, allowNull: false,
}, },
author: {
type: DataTypes.CHAR(18),
allowNull: false,
},
data: {
type: DataTypes.JSON,
allowNull: false,
},
deleted: {
type: DataTypes.BOOLEAN,
defaultValue: false,
},
edited: {
type: DataTypes.BOOLEAN,
defaultValue: false,
},
ticket: { ticket: {
type: DataTypes.CHAR(18), type: DataTypes.CHAR(18),
allowNull: false, allowNull: false,
@ -199,31 +228,31 @@ module.exports = async (client) => {
key: 'id' key: 'id'
}, },
}, },
author: {
type: DataTypes.CHAR(18),
allowNull: false,
},
edited: {
type: DataTypes.BOOLEAN,
defaultValue: false,
},
deleted: {
type: DataTypes.BOOLEAN,
defaultValue: false,
},
data: {
type: DataTypes.JSON
},
}, { }, {
tableName: DB_TABLE_PREFIX + 'messages' tableName: DB_TABLE_PREFIX + 'messages'
}); });
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
const UserEntity = sequelize.define('UserEntity', { const UserEntity = sequelize.define('UserEntity', {
user: { avatar: {
type: DataTypes.CHAR(18), type: DataTypes.STRING,
allowNull: false,
},
bot: {
type: DataTypes.BOOLEAN,
defaultValue: false,
},
colour: {
type: DataTypes.CHAR(6),
allowNull: true,
},
discriminator: {
type: DataTypes.STRING,
allowNull: false,
},
display_name: {
type: DataTypes.STRING,
allowNull: false, allowNull: false,
unique: 'id-ticket'
}, },
ticket: { ticket: {
type: DataTypes.CHAR(18), type: DataTypes.CHAR(18),
@ -232,14 +261,17 @@ module.exports = async (client) => {
references: { references: {
model: Ticket, model: Ticket,
key: 'id' key: 'id'
}, },
},
user: {
type: DataTypes.CHAR(18),
allowNull: false,
unique: 'id-ticket'
},
username: {
type: DataTypes.STRING,
allowNull: false,
}, },
avatar: DataTypes.STRING,
username: DataTypes.STRING,
discriminator: DataTypes.STRING,
display_name: DataTypes.STRING,
colour: DataTypes.CHAR(6),
bot: DataTypes.BOOLEAN
}, { }, {
tableName: DB_TABLE_PREFIX + 'user_entities' tableName: DB_TABLE_PREFIX + 'user_entities'
}); });
@ -251,6 +283,10 @@ module.exports = async (client) => {
allowNull: false, allowNull: false,
unique: 'id-ticket' unique: 'id-ticket'
}, },
name: {
type: DataTypes.STRING,
allowNull: false,
},
ticket: { ticket: {
type: DataTypes.CHAR(18), type: DataTypes.CHAR(18),
allowNull: false, allowNull: false,
@ -260,13 +296,20 @@ module.exports = async (client) => {
key: 'id' key: 'id'
}, },
}, },
name: DataTypes.STRING,
}, { }, {
tableName: DB_TABLE_PREFIX + 'channel_entities' tableName: DB_TABLE_PREFIX + 'channel_entities'
}); });
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
const RoleEntity = sequelize.define('RoleEntity', { const RoleEntity = sequelize.define('RoleEntity', {
colour: {
type: DataTypes.CHAR(6),
defaultValue: '7289DA',
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
role: { role: {
type: DataTypes.CHAR(18), type: DataTypes.CHAR(18),
allowNull: false, allowNull: false,
@ -281,8 +324,6 @@ module.exports = async (client) => {
key: 'id' key: 'id'
}, },
}, },
name: DataTypes.STRING,
colour: DataTypes.CHAR(6),
}, { }, {
tableName: DB_TABLE_PREFIX + 'role_entities' tableName: DB_TABLE_PREFIX + 'role_entities'
}); });

View File

@ -1,7 +1,6 @@
module.exports = { module.exports = {
event: 'debug', event: 'debug',
execute: (client, data) => { execute: (client, data) => {
if (client.config.debug) if (client.config.debug) client.log.debug(data);
client.log.debug(data);
} }
}; };

View File

@ -1,7 +1,7 @@
module.exports = { module.exports = {
event: 'guildCreate', event: 'guildCreate',
execute: async (client, guild) => { execute: async (client, guild) => {
client.log.info(`Added to ${guild.name}`); client.log.info(`Added to "${guild.name}"`);
await guild.createSettings(); await guild.createSettings();
} }
}; };

View File

@ -1,7 +1,7 @@
module.exports = { module.exports = {
event: 'guildDelete', event: 'guildDelete',
execute: async (client, guild) => { execute: async (client, guild) => {
client.log.info(`Removed from ${guild.name}`); client.log.info(`Removed from "${guild.name}"`);
await guild.deleteSettings(); await guild.deleteSettings();
} }
}; };

View File

@ -1,12 +1,13 @@
module.exports = { module.exports = {
event: 'message', event: 'message',
execute: async (client, message) => { execute: async (client, message) => {
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?.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)
client.tickets.archives.addMessage(message);
client.commands.handle(message); client.commands.handle(message); // pass the message to the command handler
} }
}; };

View File

@ -1,12 +1,11 @@
module.exports = { module.exports = {
event: 'messageDelete', event: 'messageDelete',
execute: async (client, message) => { execute: async (client, message) => {
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?.log_messages) { if (settings.log_messages && !message.system) client.tickets.archives.deleteMessage(message); // mark the message as deleted in the database (if it exists)
if (message.system) return;
client.tickets.archives.deleteMessage(message);
}
} }
}; };

View File

@ -10,11 +10,11 @@ module.exports = {
} }
} }
let settings = await newm.guild?.settings; if (!newm.guild) return;
if (settings?.log_messages) { let settings = await newm.guild.settings;
if (newm.system) return; if (!settings) settings = await newm.guild.createSettings();
client.tickets.archives.updateMessage(newm);
} if (settings.log_messages && !newm.system) client.tickets.archives.updateMessage(newm); // update the message in the database
} }
}; };

View File

@ -1,7 +1,5 @@
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
const { Collection, Client, Message, MessageEmbed } = require('discord.js'); const { Collection, Client, Message, MessageEmbed } = require('discord.js');
// eslint-disable-next-line no-unused-vars
const Command = require('./command');
const fs = require('fs'); const fs = require('fs');
const { path } = require('../../utils/fs'); const { path } = require('../../utils/fs');
@ -41,8 +39,7 @@ module.exports = class CommandManager {
/** Register a command */ /** Register a command */
register(cmd) { register(cmd) {
const exists = this.commands.has(cmd.name); const exists = this.commands.has(cmd.name);
const is_internal = (exists && cmd.internal) const is_internal = (exists && cmd.internal) || (exists && this.commands.get(cmd.name).internal);
|| (exists && this.commands.get(cmd.name).internal);
if (is_internal) { if (is_internal) {
let plugin = this.client.plugins.plugins.find(p => p.commands.includes(cmd.name)); let plugin = this.client.plugins.plugins.find(p => p.commands.includes(cmd.name));
@ -67,16 +64,18 @@ module.exports = class CommandManager {
*/ */
async handle(message) { async handle(message) {
let settings = await message.guild.settings; let settings = await message.guild.settings;
if (!settings) settings = await message.guild.createSettings();
const prefix = settings.command_prefix;
const i18n = this.client.i18n.get(settings.locale); const i18n = this.client.i18n.get(settings.locale);
let cmd_name = message.content.match(new RegExp(`^${prefix.replace(/(?=\W)/g, '\\')}(\\S+)`, 'mi')); const prefix = settings.command_prefix;
if (!cmd_name) return; const escaped_prefix = prefix.toLowerCase().replace(/(?=\W)/g, '\\'); // (lazy) escape every character so it can be used in a RexExp
const client_mention = `<@!?${this.client.user.id}>`;
let cmd_name = message.content.match(new RegExp(`^(${escaped_prefix}|${client_mention}\\s?)(\\S+)`, 'mi')); // capture prefix and command
if (!cmd_name) return; // stop here if the message is not a command
let raw_args = message.content.replace(cmd_name[0], '').trim(); // remove the prefix and command let raw_args = message.content.replace(cmd_name[0], '').trim(); // remove the prefix and command
cmd_name = cmd_name[1]; // set cmd_name to the actual string cmd_name = cmd_name[2].toLowerCase(); // set cmd_name to the actual command alias, effectively removing the prefix
const cmd = this.commands.find(cmd => cmd.aliases.includes(cmd_name)); const cmd = this.commands.find(cmd => cmd.aliases.includes(cmd_name));
if (!cmd) return; if (!cmd) return;
@ -85,16 +84,16 @@ module.exports = class CommandManager {
if (cmd.process_args) { if (cmd.process_args) {
args = {}; args = {};
let data = [...raw_args.matchAll(/(?<key>\w+)\??\s?:\s?(?<value>([^;]|;{2})*);/gmi)]; let data = [...raw_args.matchAll(/(?<key>\w+)\??\s?:\s?(?<value>([^;]|;{2})*);/gmi)]; // an array of argument objects
data.forEach(arg => args[arg.groups.key] = arg.groups.value.replace(/;{2}/gm, ';')); data.forEach(arg => args[arg.groups.key] = arg.groups.value.replace(/;{2}/gm, ';')); // put the data into a useful format
for (let arg of cmd.args) { for (let arg of cmd.args) {
if (arg.required && !args[arg]) { if (arg.required && !args[arg]) {
return await cmd.sendUsage(message.channel, cmd_name); return await cmd.sendUsage(message.channel, cmd_name); // send usage if any required arg is missing
} }
} }
} else { } else {
const args_num = raw_args.split(' ').filter(arg => arg.length !== 0).length; const args_num = raw_args.split(' ').filter(arg => arg.length !== 0).length; // count the number of single-word args were given
const required_args = cmd.args.reduce((acc, arg) => arg.required ? acc + 1 : acc, 0); const required_args = cmd.args.reduce((acc, arg) => arg.required ? acc + 1 : acc, 0); // count how many of the args are required
if (args_num < required_args) { if (args_num < required_args) {
return await cmd.sendUsage(message.channel, cmd_name); return await cmd.sendUsage(message.channel, cmd_name);
} }
@ -120,8 +119,8 @@ module.exports = class CommandManager {
}); });
guild_categories.forEach(cat => { guild_categories.forEach(cat => {
cat.roles.forEach(r => staff_roles.add(r)); cat.roles.forEach(r => staff_roles.add(r));
}); }); // add all of the staff role IDs to the Set
staff_roles = staff_roles.filter(r => message.member.roles.cache.has(r)); staff_roles = staff_roles.filter(r => message.member.roles.cache.has(r)); // filter out any roles that the member does not have
const not_staff = staff_roles.length === 0; const not_staff = staff_roles.length === 0;
if (not_staff) { if (not_staff) {
return await message.channel.send( return await message.channel.send(
@ -144,7 +143,7 @@ module.exports = class CommandManager {
.setColor('ORANGE') .setColor('ORANGE')
.setTitle(i18n('command_execution_error.title')) .setTitle(i18n('command_execution_error.title'))
.setDescription(i18n('command_execution_error.description')) .setDescription(i18n('command_execution_error.description'))
); ); // hopefully no user will ever see this message
} }
} }

View File

@ -25,6 +25,7 @@ module.exports = {
command_prefix: prefix, command_prefix: prefix,
log_messages: true, // transcripts/archives will be empty if false log_messages: true, // transcripts/archives will be empty if false
name_format: 'ticket-{number}', name_format: 'ticket-{number}',
opening_message: 'Hello {name}, thank you for creating a ticket. A member of staff will soon be available to assist you.\n\n__All messages in this channel are stored for future reference.__',
}, },
locale: 'en-GB', // used for globals (such as commands) and the default guild locale locale: 'en-GB', // used for globals (such as commands) and the default guild locale
logs: { logs: {