const resolveFolder = (folderName) => path.resolve(__dirname, '.', folderName) const fs = require('fs') const path = require('path') class CommandManager { constructor(client) { this.client = client this.cache = new Map() this.aliases = new Map() } load(options = {}) { const commandFolderPath = options.path || '../Plugins' const commandFolder = resolveFolder(commandFolderPath) if (options.category === undefined) options.category = true if (options.plugins === undefined) options.plugins = true // PluginMode will iterate through all SubFolders fs.readdirSync(commandFolder).map(async (dir) => { if (dir.endsWith('.txt')) return if (!options.category && dir.endsWith('.js')) { const commandPath = path.join(commandFolder, dir) this.loadCommand(commandPath) } else { fs.readdirSync(path.join(commandFolder, dir)).map((cmd) => { if (cmd.endsWith('.js') && !options.plugins) { const commandPath = path.join(commandFolder, dir, cmd) this.loadCommand(commandPath) } else if (commandFolderPath === '../Plugins') { if (cmd !== 'commands') return fs.readdirSync(path.join(commandFolder, dir, cmd)).map((cmdfile) => { if (!cmdfile.endsWith('.js')) return const commandPath = path.join(commandFolder, dir, cmd, cmdfile) this.loadCommand(commandPath) }) } }) } }) } loadCommand(commandPath) { const pull = require(path.join(commandPath)) if (pull.name) { pull.path = commandPath this.cache.set(pull.name, pull) } if (pull.aliases) { pull.aliases.map((p) => this.aliases.set(p, pull)) } return pull } reloadCommand(commandName) { const command = this.cache.get(commandName) if (!command) return const commandPath = path.join(command.path) delete require.cache[require.resolve(commandPath)] return this.loadCommand(commandPath) } isCommand(message) { if (message.isFromBot) return false const prefix = '!' const escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') const prefixRegex = new RegExp(`^(<@!?${this.client.id}>|${escapeRegex(prefix)})\\s*`) if (!prefixRegex.test(message.content)) return false const [, matchedPrefix] = message.content.match(prefixRegex) const args = message.content.slice(matchedPrefix.length).trim().split(/ +/) this.onMessage(message, prefix, args) return true } isInteraction(interaction) { if (interaction.type !== 2) return this.onInteraction(interaction) } async onMessage(message, guild, args) { const commandName = args.shift().toLowerCase() const command = this.cache.get(commandName) // || this.cache.find(cmd => cmd.aliases && cmd.aliases.includes(commandName)); if (!command && message.content.includes(this.client.id)) { // Handle, when Command has not been found const options = { content: 'I did not found the Command!' } this.client.helpers.sendMessage(message.channelId, options) } if (!command) return const messagecommand = new command({ manager: this, message, client: this.client, args, settings: {}, commandName: command.name, }) messagecommand.execute()?.catch?.((error) => { console.log(error) // Call Function on CommandResponse.js, handle the error return messagecommand.onError(error ?? 'custom') }) } async onInteraction(interaction) { const command = this.cache.get(interaction.data.name) if (!command) return const args = [] // Map all Values and Args interaction.data.options?.map((o) => { if (o.name) args.push(o.name) if (o.options) { o.options.map((o2) => { if (o2.value) return args.push(o2.value) if (o2.name) args.push(o2.name) if (o2.options) o2.options.map((v) => args.push(v.value)) }) } }) const messagecommand = new command({ manager: this, interaction, client: this.client, args, settings: {}, commandName: command.name, }) messagecommand.execute()?.catch?.((error) => { console.log(error) // Call Function on CommandResponse.js, handle the error return messagecommand.onError(error ?? 'custom') }) } } module.exports = CommandManager