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())
);
} else if (categories.count === 1) {
create(categories.rows[0]);
create(categories.rows[0]); // skip the category selection
} else {
let letters_array = Object.values(letters);
let category_list = categories.rows.map((category, i) => `${letters_array[i]} » ${category.name}`);
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}`); // list category names with an A-Z emoji
let collector_message = await message.channel.send(
new MessageEmbed()
.setColor(settings.colour)
@ -122,11 +122,11 @@ module.exports = class NewCommand extends Command {
);
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) => {
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);
};
@ -135,10 +135,10 @@ module.exports = class NewCommand extends Command {
});
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 });
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) => {
@ -152,7 +152,10 @@ module.exports = class NewCommand extends Command {
.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())
);
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
}
});
category.name = c.name;
category.roles = c.roles;
category.max_per_member = c.max_per_member;
category.name = c.name;
category.name_format = c.name_format;
category.opening_message = c.opening_message;
category.require_topic = c.require_topic;
category.roles = c.roles;
category.save();
let cat_channel = await this.client.channels.fetch(c.id);
@ -99,6 +101,8 @@ module.exports = class SettingsCommand extends Command {
name: c.name,
name_format: c.name_format,
guild: message.guild.id,
opening_message: c.opening_message,
require_topic: c.require_topic,
roles: c.roles,
});
@ -133,6 +137,8 @@ module.exports = class SettingsCommand extends Command {
max_per_member: c.max_per_member,
name: c.name,
name_format: c.name_format,
opening_message: c.opening_message,
require_topic: c.require_topic,
roles: c.roles
};
});

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,11 +10,11 @@ module.exports = {
}
}
let settings = await newm.guild?.settings;
if (!newm.guild) return;
if (settings?.log_messages) {
if (newm.system) return;
client.tickets.archives.updateMessage(newm);
}
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
}
};

View File

@ -1,7 +1,5 @@
// eslint-disable-next-line no-unused-vars
const { Collection, Client, Message, MessageEmbed } = require('discord.js');
// eslint-disable-next-line no-unused-vars
const Command = require('./command');
const fs = require('fs');
const { path } = require('../../utils/fs');
@ -41,8 +39,7 @@ module.exports = class CommandManager {
/** Register a command */
register(cmd) {
const exists = this.commands.has(cmd.name);
const is_internal = (exists && cmd.internal)
|| (exists && this.commands.get(cmd.name).internal);
const is_internal = (exists && cmd.internal) || (exists && this.commands.get(cmd.name).internal);
if (is_internal) {
let plugin = this.client.plugins.plugins.find(p => p.commands.includes(cmd.name));
@ -67,16 +64,18 @@ module.exports = class CommandManager {
*/
async handle(message) {
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);
let cmd_name = message.content.match(new RegExp(`^${prefix.replace(/(?=\W)/g, '\\')}(\\S+)`, 'mi'));
if (!cmd_name) return;
const prefix = settings.command_prefix;
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
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));
if (!cmd) return;
@ -85,16 +84,16 @@ module.exports = class CommandManager {
if (cmd.process_args) {
args = {};
let data = [...raw_args.matchAll(/(?<key>\w+)\??\s?:\s?(?<value>([^;]|;{2})*);/gmi)];
data.forEach(arg => args[arg.groups.key] = arg.groups.value.replace(/;{2}/gm, ';'));
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, ';')); // put the data into a useful format
for (let arg of cmd.args) {
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 {
const args_num = raw_args.split(' ').filter(arg => arg.length !== 0).length;
const required_args = cmd.args.reduce((acc, arg) => arg.required ? acc + 1 : acc, 0);
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); // count how many of the args are required
if (args_num < required_args) {
return await cmd.sendUsage(message.channel, cmd_name);
}
@ -120,8 +119,8 @@ module.exports = class CommandManager {
});
guild_categories.forEach(cat => {
cat.roles.forEach(r => staff_roles.add(r));
});
staff_roles = staff_roles.filter(r => message.member.roles.cache.has(r));
}); // add all of the staff role IDs to the Set
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;
if (not_staff) {
return await message.channel.send(
@ -144,7 +143,7 @@ module.exports = class CommandManager {
.setColor('ORANGE')
.setTitle(i18n('command_execution_error.title'))
.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,
log_messages: true, // transcripts/archives will be empty if false
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
logs: {