mirror of
https://github.com/MinazukiAmane/Tinasha-Bot.git
synced 2025-03-15 11:35:58 +08:00
commit
- improved lyric command - improved eval - add reloadcmd command - update commands to use collection instead of array
This commit is contained in:
parent
12cc645120
commit
70a872de45
@ -12,5 +12,6 @@
|
|||||||
"@structures/*": ["./src/structures/*"]
|
"@structures/*": ["./src/structures/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"include": ["src"],
|
||||||
"exclude": ["node_modules", "**/node_modules/*"]
|
"exclude": ["node_modules", "**/node_modules/*"]
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
const { EmbedBuilder, ApplicationCommandOptionType } = require("discord.js");
|
const { EmbedBuilder, ApplicationCommandOptionType } = require("discord.js");
|
||||||
const { MESSAGES, EMBED_COLORS } = require("@root/config");
|
const { EMBED_COLORS } = require("@root/config");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {import("@structures/Command")}
|
* @type {import("@structures/Command")}
|
||||||
@ -39,86 +39,93 @@ module.exports = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
async function getLyric({ client, guild, member }, query) {
|
async function getLyric({ client, guild, member }, query) {
|
||||||
const player = client.musicManager.getPlayer(guild.id);
|
/** @type {import('../../handlers/manager')} */
|
||||||
|
const manager = client.musicManager
|
||||||
if (!player) {
|
const player = manager.getPlayer(guild.id)
|
||||||
return "🚫 There's no active music player in this server.";
|
let node = player?.node
|
||||||
}
|
if (!node) [node] = manager.nodeManager.nodes.values()
|
||||||
|
|
||||||
let track;
|
let track;
|
||||||
let lyrics;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!query) {
|
if (!query) {
|
||||||
if (!player.queue.current) {
|
// query not specified - use currently playing music
|
||||||
|
track = player?.queue.current;
|
||||||
|
if (!track) {
|
||||||
return "🚫 No music is currently playing!";
|
return "🚫 No music is currently playing!";
|
||||||
}
|
}
|
||||||
track = player.queue.current;
|
|
||||||
} else {
|
} else {
|
||||||
const result = await player.search({ query }, member.user);
|
// query specified -- search
|
||||||
|
const result = await node.search({ query }, member.user);
|
||||||
if (!result || result.loadType === "error" || result.loadType === "empty") {
|
if (!result || result.loadType === "error" || result.loadType === "empty") {
|
||||||
return "Failed to find any tracks for the query.";
|
return "Failed to find any tracks for the query.";
|
||||||
}
|
}
|
||||||
track = result.tracks[0];
|
track = result.tracks[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
const node = player.node;
|
// lavalyrics
|
||||||
const baseUrl = (node.options.port !== 80 && node.options.secure)
|
|
||||||
? `https://${node.options.host}:${node.options.port}`
|
|
||||||
: `http://${node.options.host}:${node.options.port}`;
|
|
||||||
|
|
||||||
// Try default lyrics endpoint first
|
|
||||||
try {
|
try {
|
||||||
const defaultLyricsUrl = `${baseUrl}/v4/sessions/${node.sessionId}/players/${guild.id}/track/lyrics?skipTrackSource=true`;
|
const lyrics = await node.request(`/lyrics?track=${encodeURIComponent(track.encoded)}&skipTrackSource=${true}`)
|
||||||
const defaultRes = await fetch(defaultLyricsUrl, {
|
if (lyrics && 'text' in lyrics) return createLyricsEmbed(lyrics, member, track)
|
||||||
headers: { Authorization: node.options.authorization }
|
else console.log(`Failed search LavaLyrics track ${track.info.title}`, lyrics)
|
||||||
});
|
} catch (e) {
|
||||||
|
console.error(`Error search LavaLyrics track ${track.info.title}`, e)
|
||||||
if (defaultRes.ok) {
|
|
||||||
lyrics = await defaultRes.json();
|
|
||||||
if (lyrics) {
|
|
||||||
return createLyricsEmbed(lyrics, member, track);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
client.logger.debug("Default lyrics endpoint failed:", err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to genius search if default endpoint fails
|
// javatimed
|
||||||
const geniusUrl = `${baseUrl}/v4/lyrics/search?query=${encodeURIComponent(track.info.title + " " + track.info.author)}&source=genius`;
|
if (node.info.plugins.includes('java-timed-lyrics')) {
|
||||||
const geniusRes = await fetch(geniusUrl, {
|
// java-timed (current)
|
||||||
headers: { Authorization: node.options.authorization }
|
if (!query) {
|
||||||
});
|
try {
|
||||||
|
const lyrics = await getCurrentLyricJavaTimed(node, guild.id)
|
||||||
if (!geniusRes.ok) {
|
if (lyrics && 'text' in lyrics) return createLyricsEmbed(lyrics, member, track)
|
||||||
if (geniusRes.status === 404) return "No lyrics found for this song.";
|
else console.log(`Failed search JavaTimed (current) track ${track.info.title}`, lyrics)
|
||||||
throw new Error(`Failed to fetch lyrics: ${geniusRes.status} ${geniusRes.statusText}`);
|
} catch (e) {
|
||||||
|
console.error(`Error search JavaTimed (current) track ${track.info.title}`, e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lyrics = await geniusRes.json();
|
// java-timed (search)
|
||||||
return createLyricsEmbed(lyrics, member, track);
|
try {
|
||||||
|
const lyrics = await searchLyricJavaTimed(node, guild.id)
|
||||||
} catch (error) {
|
if (lyrics.lines) {
|
||||||
client.logger.error("Lyric Command Error:", error);
|
for (const line of lyrics.lines) {
|
||||||
return "An error occurred while fetching the lyrics. Please try again later.";
|
line.timestamp = line.range.start
|
||||||
|
line.duration = line.range.end - line.range.start
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (lyrics && 'text' in lyrics) return createLyricsEmbed(lyrics, member, track)
|
||||||
|
else console.log(`Failed search JavaTimed (search) track ${track.info.title}`, lyrics)
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`Error search JavaTimed (search) track ${track.info.title}`, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "No lyrics found"
|
||||||
}
|
}
|
||||||
|
|
||||||
function createLyricsEmbed(lyrics, member, track) {
|
function createLyricsEmbed(lyrics, member, track) {
|
||||||
if (!lyrics) {
|
|
||||||
return "No lyrics found for this song.";
|
|
||||||
}
|
|
||||||
|
|
||||||
const embed = new EmbedBuilder()
|
const embed = new EmbedBuilder()
|
||||||
.setColor(EMBED_COLORS.BOT_EMBED)
|
.setColor(EMBED_COLORS.BOT_EMBED)
|
||||||
.setTitle(`${track.info.author} - ${track.info.title}`)
|
.setTitle(`${track.info.author} - ${track.info.title}`)
|
||||||
.setThumbnail(track.info.artworkUrl)
|
.setThumbnail(track.info.artworkUrl)
|
||||||
.setFooter({ text: `Requested by: ${member.user.displayName} | Source: ${lyrics.source || 'Unknown'}` });
|
.setFooter({ text: `Requested by: ${member.user.displayName} | Source: ${lyrics.provider || lyrics.source || lyrics.sourceName || '-'}` });
|
||||||
|
|
||||||
|
const lines = !lyrics.lines ? lyrics.text ?? 'No lyrics found' : lyrics.lines
|
||||||
|
.filter(Boolean)
|
||||||
|
.map(line => line.line)
|
||||||
|
.join("\n");
|
||||||
|
|
||||||
const lines = lyrics.lines.map(line => line.line).filter(Boolean).join("\n");
|
|
||||||
const truncatedLyrics = lines.length > 4096 ? `${lines.slice(0, 4093)}...` : lines;
|
const truncatedLyrics = lines.length > 4096 ? `${lines.slice(0, 4093)}...` : lines;
|
||||||
|
|
||||||
embed.setDescription(truncatedLyrics);
|
embed.setDescription(truncatedLyrics);
|
||||||
|
|
||||||
return { embeds: [embed] };
|
return { embeds: [embed] };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCurrentLyricJavaTimed(node, guildId) {
|
||||||
|
return node.request(`/sessions/${node.sessionId}/players/${guildId}/lyrics`)
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchLyricJavaTimed(node, track, source = "genius") {
|
||||||
|
return node.request(`/lyrics/search?query=${encodeURIComponent(track.info.title + " " + track.info.author)}&source=${source}`)
|
||||||
|
}
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
const { EmbedBuilder, ApplicationCommandOptionType } = require("discord.js");
|
const { EmbedBuilder, ApplicationCommandOptionType, AttachmentBuilder } = require("discord.js");
|
||||||
const { EMBED_COLORS } = require("@root/config");
|
const { EMBED_COLORS } = require("@root/config");
|
||||||
|
|
||||||
// This dummy token will be replaced by the actual token
|
// This dummy token will be replaced by the actual token
|
||||||
const DUMMY_TOKEN = "MY_TOKEN_IS_SECRET";
|
const DUMMY_TOKEN = "MY_TOKEN_IS_SECRET";
|
||||||
|
|
||||||
|
const AsyncFunctionConstructor = (async() => {}).constructor
|
||||||
|
let prev = null
|
||||||
|
let store = Object.create(null)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {import("@structures/Command")}
|
* @type {import("@structures/Command")}
|
||||||
*/
|
*/
|
||||||
@ -13,71 +17,113 @@ module.exports = {
|
|||||||
category: "OWNER",
|
category: "OWNER",
|
||||||
botPermissions: ["EmbedLinks"],
|
botPermissions: ["EmbedLinks"],
|
||||||
command: {
|
command: {
|
||||||
enabled: true,
|
enabled: process.env.DEV === 'true',
|
||||||
usage: "<script>",
|
usage: "<script>",
|
||||||
minArgsCount: 1,
|
minArgsCount: 1,
|
||||||
},
|
},
|
||||||
slashCommand: {
|
slashCommand: {
|
||||||
enabled: false,
|
enabled: process.env.DEV === 'true',
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
name: "expression",
|
name: "expression",
|
||||||
description: "content to evaluate",
|
description: "Code to evaluate",
|
||||||
type: ApplicationCommandOptionType.String,
|
type: ApplicationCommandOptionType.String,
|
||||||
required: true,
|
required: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "attachment",
|
||||||
|
description: "Code to evaluate",
|
||||||
|
type: ApplicationCommandOptionType.Attachment,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "async",
|
||||||
|
description: "Use async - requires return to retreive value",
|
||||||
|
type: ApplicationCommandOptionType.Boolean,
|
||||||
|
required: false
|
||||||
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
async messageRun(message, args) {
|
async messageRun(message, args, data) {
|
||||||
const input = args.join(" ");
|
let content = message.content.slice(data.prefix.length + data.invoke.length).trim()
|
||||||
|
|
||||||
if (!input) return message.safeReply("Please provide code to eval");
|
if (content.startsWith('```')) {
|
||||||
|
content = content.replace(/^```(js)?/, '')
|
||||||
let response;
|
if (content.endsWith('```')) content = content.slice(0, -3)
|
||||||
try {
|
|
||||||
const output = eval(input);
|
|
||||||
response = buildSuccessResponse(output, message.client);
|
|
||||||
} catch (ex) {
|
|
||||||
response = buildErrorResponse(ex);
|
|
||||||
}
|
}
|
||||||
await message.safeReply(response);
|
else if (content.startsWith('``')) {
|
||||||
|
content = content.slice(2, -2)
|
||||||
|
}
|
||||||
|
|
||||||
|
const attachment = message.attachments.at(0)
|
||||||
|
|
||||||
|
await message.reply(await execute(false, attachment, content, { message, args, data }, message.client));
|
||||||
},
|
},
|
||||||
|
|
||||||
async interactionRun(interaction) {
|
async interactionRun(interaction, data) {
|
||||||
const input = interaction.options.getString("expression");
|
const attachment = interaction.options.getAttachment("attachment")
|
||||||
|
const code = interaction.options.getString("expression")
|
||||||
|
const useAsync = interaction.options.getBoolean("async") ?? false
|
||||||
|
|
||||||
let response;
|
await interaction.followUp(await execute(useAsync, attachment, code, { interaction, data }, interaction.client));
|
||||||
try {
|
|
||||||
const output = eval(input);
|
|
||||||
response = buildSuccessResponse(output, interaction.client);
|
|
||||||
} catch (ex) {
|
|
||||||
response = buildErrorResponse(ex);
|
|
||||||
}
|
|
||||||
await interaction.followUp(response);
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildSuccessResponse = (output, client) => {
|
async function execute(useAsync, attachment, code, context, client) {
|
||||||
|
if (!code) {
|
||||||
|
if (!attachment) return "Specify code or attachment to run"
|
||||||
|
if (attachment.contentType !== 'text/javascript') return "Attachment type must be JavaScript"
|
||||||
|
|
||||||
|
const res = await fetch(attachment.url)
|
||||||
|
if (!res.ok && !code) return "Failed to retreive attachment"
|
||||||
|
code = await res.text()
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(context, {
|
||||||
|
client,
|
||||||
|
store: store,
|
||||||
|
_: prev
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exec = useAsync
|
||||||
|
? new AsyncFunctionConstructor('ctx', `with (ctx) {${code}}; return "return not set"`)
|
||||||
|
: new Function('ctx', `with (ctx) return eval(${JSON.stringify(code)})`)
|
||||||
|
const output = await exec.call(client, context)
|
||||||
|
|
||||||
|
prev = output
|
||||||
|
return buildResponse(output, client);
|
||||||
|
} catch (ex) {
|
||||||
|
return buildResponse(ex, client, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildResponse = (output, client, isError) => {
|
||||||
// Token protection
|
// Token protection
|
||||||
output = require("util").inspect(output, { depth: 0 }).replaceAll(client.token, DUMMY_TOKEN);
|
output = require("util").inspect(output, {
|
||||||
|
maxArrayLength: 5,
|
||||||
|
maxStringLength: 500,
|
||||||
|
depth: 3
|
||||||
|
}).replaceAll(client.token, DUMMY_TOKEN);
|
||||||
|
|
||||||
|
// use file
|
||||||
|
if (output.length > 200 || (output.match(/\n/g)?.length ?? 0) > 10) {
|
||||||
|
const file = new AttachmentBuilder(Buffer.from(output), { name: 'output.js' })
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: isError ? 'Error!' : 'Output:',
|
||||||
|
files: [file]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// use embed
|
||||||
|
else {
|
||||||
const embed = new EmbedBuilder()
|
const embed = new EmbedBuilder()
|
||||||
.setAuthor({ name: "📤 Output" })
|
.setAuthor({ name: isError ? "📤 Error" : "📤 Output" })
|
||||||
.setDescription("```js\n" + (output.length > 4096 ? `${output.substr(0, 4000)}...` : output) + "\n```")
|
.setDescription("```js\n" + output + "\n```")
|
||||||
.setColor("Random")
|
.setColor(isError ? EMBED_COLORS.ERROR : EMBED_COLORS.SUCCESS)
|
||||||
.setTimestamp(Date.now());
|
.setTimestamp(Date.now());
|
||||||
|
|
||||||
return { embeds: [embed] };
|
return { embeds: [embed] }
|
||||||
};
|
}
|
||||||
|
|
||||||
const buildErrorResponse = (err) => {
|
|
||||||
const embed = new EmbedBuilder();
|
|
||||||
embed
|
|
||||||
.setAuthor({ name: "📤 Error" })
|
|
||||||
.setDescription("```js\n" + (err.length > 4096 ? `${err.substr(0, 4000)}...` : err) + "\n```")
|
|
||||||
.setColor(EMBED_COLORS.ERROR)
|
|
||||||
.setTimestamp(Date.now());
|
|
||||||
|
|
||||||
return { embeds: [embed] };
|
|
||||||
};
|
};
|
||||||
|
120
src/commands/owner/reloadcmd.js
Normal file
120
src/commands/owner/reloadcmd.js
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
const path = require('path')
|
||||||
|
const { ApplicationCommandOptionType, ApplicationCommandType } = require('discord.js')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {import("@structures/Command")}
|
||||||
|
*/
|
||||||
|
module.exports = {
|
||||||
|
name: "reloadcmd",
|
||||||
|
description: "Reloads commands",
|
||||||
|
category: "OWNER",
|
||||||
|
command: {
|
||||||
|
enabled: process.env.DEV === 'true',
|
||||||
|
usage: "<filename> [guild]",
|
||||||
|
minArgsCount: 1,
|
||||||
|
},
|
||||||
|
slashCommand: {
|
||||||
|
enabled: process.env.DEV === 'true',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: "filename",
|
||||||
|
description: "File name to load. Reloads all if not specified",
|
||||||
|
type: ApplicationCommandOptionType.String,
|
||||||
|
required: true,
|
||||||
|
}, {
|
||||||
|
name: "guild",
|
||||||
|
description: "guild",
|
||||||
|
type: ApplicationCommandOptionType.String,
|
||||||
|
required: false,
|
||||||
|
}, {
|
||||||
|
name: "reregister",
|
||||||
|
description: "Reregisters command to manager",
|
||||||
|
type: ApplicationCommandOptionType.Boolean,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
async messageRun(message, args) {
|
||||||
|
await message.safeReply(await runReload(message.client, args[0], args[1]))
|
||||||
|
},
|
||||||
|
|
||||||
|
async interactionRun(interaction) {
|
||||||
|
await interaction.followUp(await runReload(
|
||||||
|
interaction.client,
|
||||||
|
interaction.options.getString("filename"),
|
||||||
|
interaction.options.getString("guild"),
|
||||||
|
interaction.options.getBoolean("reregister"),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function runReload(client, filename, guildid, rereg = false) {
|
||||||
|
// guild id
|
||||||
|
let guild
|
||||||
|
if (guildid) {
|
||||||
|
guild = client.guilds.cache.get(guildid);
|
||||||
|
if (!guild) return "No matching guild"
|
||||||
|
}
|
||||||
|
|
||||||
|
// load
|
||||||
|
if (filename[0] === '/') {
|
||||||
|
const cmdname = filename.slice(1)
|
||||||
|
const cmd = client.commands.get(cmdname)
|
||||||
|
if (!cmd) return "Cannot find command with name " + cmd
|
||||||
|
if (!cmd.category) return `Command category ${cmd} is undefined`
|
||||||
|
|
||||||
|
filename = cmd.category.toLowerCase() + '/' + cmdname
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path.extname(filename)) filename += '.js'
|
||||||
|
const target = path.resolve('src', 'commands', path.normalize(filename))
|
||||||
|
const oldCmd = require.cache[target]?.exports
|
||||||
|
const oldSlashEnable = oldCmd?.slashCommand?.enabled
|
||||||
|
delete require.cache[target]
|
||||||
|
const newCmd = require(target)
|
||||||
|
const newSlashEnable = newCmd?.slashCommand?.enabled
|
||||||
|
|
||||||
|
if (rereg) {
|
||||||
|
// register / edit
|
||||||
|
const cmdManager = guild ? guild.commands : client.application.commands
|
||||||
|
const slashCmd = {
|
||||||
|
name: newCmd.name,
|
||||||
|
description: newCmd.description,
|
||||||
|
type: ApplicationCommandType.ChatInput,
|
||||||
|
options: newCmd.slashCommand?.options
|
||||||
|
}
|
||||||
|
|
||||||
|
// slash commands
|
||||||
|
if (oldSlashEnable) {
|
||||||
|
const oldSlash = client.application.commands.cache.find(v => v.name === oldCmd.name)
|
||||||
|
if (oldSlash) {
|
||||||
|
if (newSlashEnable) await cmdManager.edit(oldSlash, slashCmd)
|
||||||
|
else await cmdManager.delete(oldSlash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (newSlashEnable) {
|
||||||
|
await cmdManager.create(slashCmd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove old
|
||||||
|
if (oldCmd?.command?.enabled) {
|
||||||
|
client.commands.delete(oldCmd.name.toLowerCase())
|
||||||
|
for (const alias of oldCmd.command.aliases ?? []) client.commandAlias.delete(alias)
|
||||||
|
}
|
||||||
|
if (oldSlashEnable) {
|
||||||
|
client.slashCommands.delete(oldCmd.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add new
|
||||||
|
if (newCmd?.command?.enabled) {
|
||||||
|
client.commands.set(newCmd.name.toLowerCase(), newCmd)
|
||||||
|
for (const alias of newCmd.command.aliases ?? []) client.commandAlias.set(alias, newCmd)
|
||||||
|
}
|
||||||
|
if (newSlashEnable) {
|
||||||
|
client.slashCommands.set(newCmd.name, newCmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `Reloaded ${filename}`
|
||||||
|
}
|
@ -310,7 +310,7 @@ function getMsgCategoryEmbeds(client, category, prefix) {
|
|||||||
// For REMAINING Categories
|
// For REMAINING Categories
|
||||||
const commands = client.commands.filter((cmd) => cmd.category === category);
|
const commands = client.commands.filter((cmd) => cmd.category === category);
|
||||||
|
|
||||||
if (commands.length === 0) {
|
if (commands.size === 0) {
|
||||||
const embed = new EmbedBuilder()
|
const embed = new EmbedBuilder()
|
||||||
.setColor(EMBED_COLORS.BOT_EMBED)
|
.setColor(EMBED_COLORS.BOT_EMBED)
|
||||||
.setThumbnail(CommandCategory[category]?.image)
|
.setThumbnail(CommandCategory[category]?.image)
|
||||||
@ -323,8 +323,9 @@ function getMsgCategoryEmbeds(client, category, prefix) {
|
|||||||
const arrSplitted = [];
|
const arrSplitted = [];
|
||||||
const arrEmbeds = [];
|
const arrEmbeds = [];
|
||||||
|
|
||||||
while (commands.length) {
|
const cmdArr = Array.from(commands.values())
|
||||||
let toAdd = commands.splice(0, commands.length > CMDS_PER_PAGE ? CMDS_PER_PAGE : commands.length);
|
while (cmdArr.length) {
|
||||||
|
let toAdd = cmdArr.splice(0, cmdArr.size > CMDS_PER_PAGE ? CMDS_PER_PAGE : cmdArr.size);
|
||||||
toAdd = toAdd.map((cmd) => `\`${prefix}${cmd.name}\`\n ❯ ${cmd.description}\n`);
|
toAdd = toAdd.map((cmd) => `\`${prefix}${cmd.name}\`\n ❯ ${cmd.description}\n`);
|
||||||
arrSplitted.push(toAdd);
|
arrSplitted.push(toAdd);
|
||||||
}
|
}
|
||||||
|
@ -43,10 +43,10 @@ module.exports = class BotClient extends Client {
|
|||||||
this.config = require("@root/config"); // load the config file
|
this.config = require("@root/config"); // load the config file
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {import('@structures/Command')[]}
|
* @type {Collection<string, import('@structures/Command')>}
|
||||||
*/
|
*/
|
||||||
this.commands = []; // store actual command
|
this.commands = new Collection(); // store actual command
|
||||||
this.commandIndex = new Collection(); // store (alias, arrayIndex) pair
|
this.commandAlias = new Map(); // store (alias, command) pair
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Collection<string, import('@structures/Command')>}
|
* @type {Collection<string, import('@structures/Command')>}
|
||||||
@ -135,8 +135,8 @@ module.exports = class BotClient extends Client {
|
|||||||
* @returns {import('@structures/Command')|undefined}
|
* @returns {import('@structures/Command')|undefined}
|
||||||
*/
|
*/
|
||||||
getCommand(invoke) {
|
getCommand(invoke) {
|
||||||
const index = this.commandIndex.get(invoke.toLowerCase());
|
const invokeLower = invoke.toLowerCase()
|
||||||
return index !== undefined ? this.commands[index] : undefined;
|
return this.commands.get(invokeLower) ?? this.commandAlias.get(invokeLower);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -151,18 +151,17 @@ module.exports = class BotClient extends Client {
|
|||||||
}
|
}
|
||||||
// Prefix Command
|
// Prefix Command
|
||||||
if (cmd.command?.enabled) {
|
if (cmd.command?.enabled) {
|
||||||
const index = this.commands.length;
|
const name = cmd.name.toLowerCase()
|
||||||
if (this.commandIndex.has(cmd.name)) {
|
if (this.commands.has(name)) {
|
||||||
throw new Error(`Command ${cmd.name} already registered`);
|
throw new Error(`Command ${cmd.name} already registered`);
|
||||||
}
|
}
|
||||||
if (Array.isArray(cmd.command.aliases)) {
|
if (Array.isArray(cmd.command.aliases)) {
|
||||||
cmd.command.aliases.forEach((alias) => {
|
cmd.command.aliases.forEach((alias) => {
|
||||||
if (this.commandIndex.has(alias)) throw new Error(`Alias ${alias} already registered`);
|
if (this.commandAlias.has(alias)) throw new Error(`Alias ${alias} already registered`);
|
||||||
this.commandIndex.set(alias.toLowerCase(), index);
|
this.commandAlias.set(alias.toLowerCase(), cmd);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.commandIndex.set(cmd.name.toLowerCase(), index);
|
this.commands.set(name, cmd);
|
||||||
this.commands.push(cmd);
|
|
||||||
} else {
|
} else {
|
||||||
this.logger.debug(`Skipping command ${cmd.name}. Disabled!`);
|
this.logger.debug(`Skipping command ${cmd.name}. Disabled!`);
|
||||||
}
|
}
|
||||||
@ -195,7 +194,7 @@ module.exports = class BotClient extends Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.success(`Loaded ${this.commands.length} commands`);
|
this.logger.success(`Loaded ${this.commands.size} commands`);
|
||||||
this.logger.success(`Loaded ${this.slashCommands.size} slash commands`);
|
this.logger.success(`Loaded ${this.slashCommands.size} slash commands`);
|
||||||
if (this.slashCommands.size > 100) throw new Error("A maximum of 100 slash commands can be enabled");
|
if (this.slashCommands.size > 100) throw new Error("A maximum of 100 slash commands can be enabled");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user