mirror of
https://github.com/Hessenuk/DiscordTickets.git
synced 2025-09-01 16:31:25 +03:00
215 lines
6.3 KiB
JavaScript
215 lines
6.3 KiB
JavaScript
|
|
const {
|
|
Client, // eslint-disable-line no-unused-vars
|
|
Collection,
|
|
Interaction, // eslint-disable-line no-unused-vars
|
|
MessageEmbed
|
|
} = require('discord.js');
|
|
|
|
const fs = require('fs');
|
|
const { path } = require('../../utils/fs');
|
|
|
|
/**
|
|
* Manages the loading and execution of commands
|
|
*/
|
|
module.exports = class CommandManager {
|
|
/**
|
|
* Create a CommandManager instance
|
|
* @param {import('../..').Bot} client
|
|
*/
|
|
constructor(client) {
|
|
/** The Discord Client */
|
|
this.client = client;
|
|
|
|
/**
|
|
* A discord.js Collection (Map) of loaded commands
|
|
* @type {Collection<string, import('./command')>}
|
|
*/
|
|
this.commands = new Collection();
|
|
}
|
|
|
|
/** Automatically load all internal commands */
|
|
load() {
|
|
const files = fs.readdirSync(path('./src/commands'))
|
|
.filter(file => file.endsWith('.js'));
|
|
|
|
for (let file of files) {
|
|
try {
|
|
file = require(`../../commands/${file}`);
|
|
new file(this.client);
|
|
} catch (e) {
|
|
this.client.log.warn('An error occurred whilst loading an internal command');
|
|
this.client.log.error(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Register a command */
|
|
register(command) {
|
|
const exists = this.commands.has(command.name);
|
|
const is_internal = (exists && command.internal) || (exists && this.commands.get(command.name).internal);
|
|
|
|
if (is_internal) {
|
|
const plugin = this.client.plugins.plugins.find(p => p.commands.includes(command.name));
|
|
if (plugin) this.client.log.commands(`The "${plugin.name}" plugin has overridden the internal "${command.name}" command`);
|
|
else this.client.log.commands(`An unknown plugin has overridden the internal "${command.name}" command`);
|
|
if(command.internal) return;
|
|
} else if (exists) {
|
|
throw new Error(`A non-internal command with the name "${command.name}" already exists`);
|
|
}
|
|
|
|
this.commands.set(command.name, command);
|
|
this.client.log.commands(`Loaded "${command.name}" command`);
|
|
}
|
|
|
|
async publish(guild) {
|
|
if (!guild) {
|
|
return this.client.guilds.cache.forEach(guild => {
|
|
this.publish(guild);
|
|
});
|
|
}
|
|
|
|
try {
|
|
const commands = await Promise.all(this.client.commands.commands.map(async command => await command.build(guild)));
|
|
await this.client.application.commands.set(commands, guild.id);
|
|
await this.updatePermissions(guild);
|
|
this.client.log.success(`Published ${this.client.commands.commands.size} commands to "${guild.name}"`);
|
|
} catch (error) {
|
|
this.client.log.warn('An error occurred whilst publishing the commands');
|
|
this.client.log.error(error);
|
|
}
|
|
}
|
|
|
|
async updatePermissions(guild) {
|
|
guild.commands.fetch().then(async commands => {
|
|
const permissions = [];
|
|
const settings = await this.client.utils.getSettings(guild.id);
|
|
const blacklist = [];
|
|
settings.blacklist.users?.forEach(userId => {
|
|
blacklist.push({
|
|
id: userId,
|
|
permission: false,
|
|
type: 'USER'
|
|
});
|
|
});
|
|
settings.blacklist.roles?.forEach(roleId => {
|
|
blacklist.push({
|
|
id: roleId,
|
|
permission: false,
|
|
type: 'ROLE'
|
|
});
|
|
});
|
|
|
|
const categories = await this.client.db.models.Category.findAll({ where: { guild: guild.id } });
|
|
const staff_roles = new Set(categories.map(category => category.roles).flat());
|
|
|
|
commands.forEach(async g_cmd => {
|
|
const cmd_permissions = [...blacklist];
|
|
const command = this.client.commands.commands.get(g_cmd.name);
|
|
|
|
if (command.staff_only) {
|
|
cmd_permissions.push({
|
|
id: guild.roles.everyone.id,
|
|
permission: false,
|
|
type: 'ROLE'
|
|
});
|
|
staff_roles.forEach(roleId => {
|
|
cmd_permissions.push({
|
|
id: roleId,
|
|
permission: true,
|
|
type: 'ROLE'
|
|
});
|
|
});
|
|
}
|
|
|
|
permissions.push({
|
|
id: g_cmd.id,
|
|
permissions: cmd_permissions
|
|
});
|
|
});
|
|
|
|
this.client.log.debug(`Command permissions for "${guild.name}"`, require('util').inspect(permissions, {
|
|
colors: true,
|
|
depth: 10
|
|
}));
|
|
|
|
try {
|
|
await guild.commands.permissions.set({ fullPermissions: permissions });
|
|
} catch (error) {
|
|
this.client.log.warn('An error occurred whilst updating command permissions');
|
|
this.client.log.error(error);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Execute a command
|
|
* @param {Interaction} interaction - Command message
|
|
*/
|
|
async handle(interaction) {
|
|
if (!interaction.guild) return this.client.log.debug('Ignoring non-guild command interaction');
|
|
await interaction.deferReply();
|
|
const settings = await this.client.utils.getSettings(interaction.guild.id);
|
|
const i18n = this.client.i18n.getLocale(settings.locale);
|
|
|
|
const command = this.commands.get(interaction.commandName);
|
|
if (!command) return;
|
|
|
|
const bot_permissions = interaction.guild.me.permissionsIn(interaction.channel);
|
|
const required_bot_permissions = [
|
|
'ATTACH_FILES',
|
|
'EMBED_LINKS',
|
|
'MANAGE_CHANNELS',
|
|
'MANAGE_MESSAGES'
|
|
];
|
|
|
|
if (!bot_permissions.has(required_bot_permissions)) {
|
|
const perms = required_bot_permissions.map(p => `\`${p}\``).join(', ');
|
|
if (bot_permissions.has('EMBED_LINKS')) {
|
|
await interaction.editReply({
|
|
embeds: [
|
|
new MessageEmbed()
|
|
.setColor('ORANGE')
|
|
.setTitle(i18n('bot.missing_permissions.title'))
|
|
.setDescription(i18n('bot.missing_permissions.description', perms))
|
|
]
|
|
});
|
|
} else {
|
|
await interaction.editReply({ content: i18n('bot.missing_permissions.description', perms) });
|
|
}
|
|
return;
|
|
}
|
|
|
|
const missing_permissions = command.permissions instanceof Array && !interaction.member.permissions.has(command.permissions);
|
|
if (missing_permissions) {
|
|
const perms = command.permissions.map(p => `\`${p}\``).join(', ');
|
|
return await interaction.editReply({
|
|
embeds: [
|
|
new MessageEmbed()
|
|
.setColor(settings.error_colour)
|
|
.setTitle(i18n('missing_permissions.title'))
|
|
.setDescription(i18n('missing_permissions.description', perms))
|
|
],
|
|
ephemeral: true
|
|
});
|
|
}
|
|
|
|
try {
|
|
this.client.log.commands(`Executing "${command.name}" command (invoked by ${interaction.user.tag})`);
|
|
await command.execute(interaction); // execute the command
|
|
} catch (e) {
|
|
this.client.log.warn(`An error occurred whilst executing the ${command.name} command`);
|
|
this.client.log.error(e);
|
|
await interaction.editReply({
|
|
embeds: [
|
|
new MessageEmbed()
|
|
.setColor('ORANGE')
|
|
.setTitle(i18n('command_execution_error.title'))
|
|
.setDescription(i18n('command_execution_error.description'))
|
|
]
|
|
}); // hopefully no user will ever see this message
|
|
}
|
|
}
|
|
|
|
};
|