const { MessageAttachment } = require('discord.js'); const { Command } = require('../../../../interfaces'); const { PermissionNames } = require('../../../../../util/Constants.js'); const { stripIndents } = require('common-tags'); class SettingsCommand extends Command { constructor(client) { super(client, { name: 'settings', module: 'administration', aliases: [ 'setting', 'set' ], usage: "['list'|'reset'|setting] [value..]", arguments: [ { name: 'export', type: 'BOOLEAN', types: ['FLAG'], default: true }, { name: 'user', type: 'BOOLEAN', types: ['VERBAL', 'FLAG'], default: true }, { name: 'all', type: 'BOOLEAN', types: ['VERBAL', 'FLAG'], default: true, archivable: false } ], showUsage: true, examples: [ 'prefix !', 'modlogs #channel' ], throttling: { usages: 2, duration: 5 } }); this.client = client; } async execute(message, { params, args }) { const type = !message.guild || args.user ? 'USER' : 'GUILD'; if(type === 'GUILD') { const permissions = this.client.permissions.execute(message, message.command, ['ADMINISTRATOR', 'MANAGE_GUILD']); if(permissions.error) return message.respond(message.format('C_SETTINGS_MISSINGPERMISSIONS'), { emoji: 'failure' }); } if(args.export) return this._exportSettings(message, type); if(params.length === 0) return message.embed(this.usageEmbed(message)); const target = params[0].toLowerCase(); //params[0] should never be null if(target === 'list') { return this._listSettings(message, type, Boolean(args.all)); } else if(target === 'reset') { const prompt = await message.prompt(message.format('C_SETTINGS_RESETPROMPT', { type: message.format('C_SETTINGS_FORMATTYPE', { type }, true) }), { emoji: 'warning' }); if(!prompt) return undefined; const boolean = this.client.resolver.resolveBoolean(prompt.content.toLowerCase()); if(boolean === null) { return message.respond(message.format('C_SETTINGS_RESETINVALID'), { emoji: 'failure' }); } else if(!boolean) { return message.respond(message.format('C_SETTINGS_RESETABORT'), { emoji: 'success' }); } return this._resetSettings(message, type); } const settings = this.client.resolver.components(target, 'setting', true).sort((c) => c.resolve === type); if(settings.length === 0) { return message.respond(message.format('C_SETTINGS_SETTINGNOTFOUND'), { emoji: 'failure' }); } const [ setting ] = settings; message._settingCaller = target; const parameters = params.splice(1); if(parameters.length === 0) { return this._showSetting(message, setting); } if(setting.resolve === 'GUILD') { if(setting.clientPermissions.length > 0) { const missing = message.guild.permissionsFor(message.guild.me).missing(setting.clientPermissions); if(missing.length > 0) { await message.respond(message.format('C_SETTINGS_MISSINGCLIENTPERMISSIONS', { permissions: missing.map((m) => `\`${PermissionNames[m]}\``).join(', ') })); } } } if(parameters.join(' ').toLowerCase() === 'reset') { return this._resetSetting(message, setting); } if(setting.premium > message.guild.premium && !message.author.developer) { return message.respond(message.format('C_SETTINGS_PREMIUM', { current: message.guild.premium, required: setting.premium }), { emoji: 'failure' }); } const response = await setting.handle(message, parameters); if(response.ignore) return undefined; message.respond(response.msg, { emoji: response.error ? 'failure' : 'success', embed: response.embed || null }); } async _listSettings(message, type, all = false) { const prefix = message?.guild?.prefix || this.client._options.bot.prefix; const fields = []; const sorted = this.client.registry.components .filter((c) => c.type === 'module') .sort((a, b) => { const filter = (c) => c.type === 'setting'; return b.components.filter(filter).size - a.components.filter(filter).size; }); for(const module of sorted.values()) { const field = { name: module.id, value: '', inline: true }; for(const setting of module.components.values()) { if(setting.type !== 'setting' || type !== setting.resolve || !setting.archivable && !all) continue; field.value += `\`${message.author._settings.camelCase ? setting.name : setting.name.toLowerCase()}\`\n`; } if(field.value) fields.push(field); } for(let i = 0; i < fields.length % 3; i++) { fields.push({ name: '\u200b', value: '\u200b', inline: true }); } const embed = { author: { name: `${type === 'GUILD' ? message.format('C_SETTINGS_GUILDSETTINGSTITLE') : message.format('C_SETTINGS_USERSETTINGSTITLE')}`, icon_url: type === 'GUILD' ? message.guild.iconURL() : message.author.displayAvatarURL() //eslint-disable-line camelcase }, description: stripIndents`${message.format('C_SETTINGS_LISTSETTINGS', { prefix })} ${type === 'USER' ? '' : message.format('C_SETTINGS_LISTSETTINGSALT', { prefix })}`, fields }; return message.embed(embed); } async _showSetting(message, setting) { const embed = setting.usageEmbed(message); let dataFields = setting.fields(message.guild); if(dataFields instanceof Promise) dataFields = await dataFields; embed.fields = embed.fields.concat(dataFields); embed.author.icon_url = setting.resolve === 'GUILD' ? message.guild.iconURL() : message.author.displayAvatarURL(); //eslint-disable-line camelcase return message.embed(embed); } async _exportSettings(message, type) { const settings = type === 'USER' ? await message.author.settings() : await message.guild.settings(); const string = JSON.stringify(settings); const attachment = new MessageAttachment(Buffer.from(string), 'settings.json'); return message.respond(message.format('C_SETTINGS_EXPORT'), { emoji: 'success', files: [ attachment ] }); } async _resetSettings(message, type) { //Reset ALL settings. if(type === 'USER') { await message.author._resetSettings(); } else { await message.guild._resetSettings(); } return message.respond(message.format('C_SETTINGS_RESETSUCCESS', { type: message.format('C_SETTINGS_FORMATTYPE', { type }, true) }), { emoji: 'success' }); } async _resetSetting(message, setting) { //Reset an INDIVIDUAL setting. const { error, response } = await setting._handleReset(message); if(error) { return message.respond(message.format('C_SETTINGS_RESETSETTINGFAIL'), { emoji: 'failure' }); } return message.respond(response, { emoji: 'success' }); } } module.exports = SettingsCommand;