diff --git a/biome.json b/biome.json index dd0294af1..86ea89a20 100644 --- a/biome.json +++ b/biome.json @@ -53,23 +53,12 @@ }, "formatter": { "enabled": true, - "indentWidth": 4, + "indentWidth": 2, "indentStyle": "space", "lineEnding": "crlf", "lineWidth": 140, "formatWithErrors": true }, - "json": { - "linter": { - "enabled": true - }, - "formatter": { - "enabled": true, - "indentWidth": 2, - "lineEnding": "crlf", - "lineWidth": 80 - } - }, "javascript": { "formatter": { "quoteStyle": "double", diff --git a/locales/Bulgarian.json b/locales/Bulgarian.json index 51b11138d..1725e9596 100644 --- a/locales/Bulgarian.json +++ b/locales/Bulgarian.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/Croatian.json b/locales/Croatian.json index 51b11138d..1725e9596 100644 --- a/locales/Croatian.json +++ b/locales/Croatian.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/Czech.json b/locales/Czech.json index 51b11138d..1725e9596 100644 --- a/locales/Czech.json +++ b/locales/Czech.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/Danish.json b/locales/Danish.json index 51b11138d..1725e9596 100644 --- a/locales/Danish.json +++ b/locales/Danish.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/Dutch.json b/locales/Dutch.json index 51b11138d..1725e9596 100644 --- a/locales/Dutch.json +++ b/locales/Dutch.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/EnglishGB.json b/locales/EnglishGB.json index 51b11138d..1725e9596 100644 --- a/locales/EnglishGB.json +++ b/locales/EnglishGB.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/EnglishUS.json b/locales/EnglishUS.json index 51b11138d..1725e9596 100644 --- a/locales/EnglishUS.json +++ b/locales/EnglishUS.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/Finnish.json b/locales/Finnish.json index 51b11138d..1725e9596 100644 --- a/locales/Finnish.json +++ b/locales/Finnish.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/Greek.json b/locales/Greek.json index 51b11138d..1725e9596 100644 --- a/locales/Greek.json +++ b/locales/Greek.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/Hungarian.json b/locales/Hungarian.json index 51b11138d..1725e9596 100644 --- a/locales/Hungarian.json +++ b/locales/Hungarian.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/Italian.json b/locales/Italian.json index 51b11138d..1725e9596 100644 --- a/locales/Italian.json +++ b/locales/Italian.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/Korean.json b/locales/Korean.json index 1d3b62908..be75bfc91 100644 --- a/locales/Korean.json +++ b/locales/Korean.json @@ -526,15 +526,15 @@ "author": "게시자", "not_connected_to_voice_channel": "이 버튼을 사용하려면 먼저 <#{channel}>에 있어야 해요.", "need_dj_role": "이 명령어를 사용하려면 DJ 권한이 있어야 해요.", - "previous_by": "{user}에 의해 이전 노래 재생 중", + "previous_by": "{user}님에 의해 이전 노래 재생 중", "no_previous_song": "이전 노래가 없어요.", - "paused_by": "{user}에 의해 일시정지됨", - "resumed_by": "{user}에 의해 재계됨", - "skipped_by": "{user}에 의해 스킵됨", + "paused_by": "{user}님에 의해 일시정지됨", + "resumed_by": "{user}님에 의해 재계됨", + "skipped_by": "{user}님에 의해 스킵됨", "no_more_songs_in_queue": "대기열에 더 이상 노래가 없어요.", - "looping_by": "{user}에 의해 한곡 반복 중", - "looping_queue_by": "{user}에 의해 대기열 반복 중", - "looping_off_by": "{user}에 의해 반복 꺼짐" + "looping_by": "{user}님에 의해 한곡 반복 중", + "looping_queue_by": "{user}님에 의해 대기열 반복 중", + "looping_off_by": "{user}님에 의해 반복 꺼짐" }, "setupStart": { "now_playing": "재생 중", @@ -604,25 +604,25 @@ "paused": "일시정지", "resumed": "재계", "pause_resume": "음악이 {name}되었어요.", - "pause_resume_footer": "{displayName}에 의해 {name}됨", + "pause_resume_footer": "{displayName}님에 의해 {name}됨", "no_music_to_skip": "스킵할 노래가 없어요.", "skipped": "노래를 스킵했어요.", - "skipped_footer": "{displayName}에 의해 스킵됨", + "skipped_footer": "{displayName}님에 의해 스킵됨", "stopped": "노래를 정지했어요.", - "stopped_footer": "{displayName}에 의해 정지됨", - "nothing_playing": "재생 중인 노래가 없어요.", + "stopped_footer": "{displayName}님에 의해 정지됨", + "nothing_playing": "재생 중인 노래 없음", "loop_set": "{loop} 반복으로 설정했어요.", - "loop_footer": "{displayName}에 의해 {loop} 반복으로 설정됨", + "loop_footer": "{displayName}님에 의해 {loop} 반복으로 설정됨", "shuffled": "노래를 섞었어요.", "no_previous_track": "이전 노래가 없어요.", "playing_previous": "이전 노래를 재생할게요.", - "previous_footer": "{displayName}에 의해 이전 노래 재생 중", + "previous_footer": "{displayName}님에 의해 이전 노래 재생 중", "rewind_limit": "현재 노래 길이보다 더 되감기할 수 없어요.", "rewinded": "노래를 되감기했어요.", - "rewind_footer": "{displayName}에 의해 노래 되감기됨", + "rewind_footer": "{displayName}님에 의해 노래 되감기됨", "forward_limit": "현재 노래 길이보다 더 빨리감기할 수 없어요.", "forwarded": "노래를 빨리감기했어요.", - "forward_footer": "{displayName}에 의해 빨리감기됨", + "forward_footer": "{displayName}님에 의해 빨리감기됨", "button_not_available": "이 버튼은 사용할 수 없어요.", "no_music_playing": "현재 재생 중인 노래가 없어요." } diff --git a/locales/Lithuanian.json b/locales/Lithuanian.json index 51b11138d..1725e9596 100644 --- a/locales/Lithuanian.json +++ b/locales/Lithuanian.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/PortugueseBR.json b/locales/PortugueseBR.json index 51b11138d..1725e9596 100644 --- a/locales/PortugueseBR.json +++ b/locales/PortugueseBR.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/Romanian.json b/locales/Romanian.json index 51b11138d..1725e9596 100644 --- a/locales/Romanian.json +++ b/locales/Romanian.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/Swedish.json b/locales/Swedish.json index 51b11138d..1725e9596 100644 --- a/locales/Swedish.json +++ b/locales/Swedish.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/Thai.json b/locales/Thai.json index 51b11138d..1725e9596 100644 --- a/locales/Thai.json +++ b/locales/Thai.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/Turkish.json b/locales/Turkish.json index 51b11138d..1725e9596 100644 --- a/locales/Turkish.json +++ b/locales/Turkish.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/locales/Ukrainian.json b/locales/Ukrainian.json index 51b11138d..1725e9596 100644 --- a/locales/Ukrainian.json +++ b/locales/Ukrainian.json @@ -610,7 +610,7 @@ "skipped_footer": "Skipped by {displayName}", "stopped": "Stopped the music.", "stopped_footer": "Stopped by {displayName}", - "nothing_playing": "Nothing is playing right now.", + "nothing_playing": "Nothing is playing right now", "loop_set": "Loop set to {loop}.", "loop_footer": "Loop set to {loop} by {displayName}", "shuffled": "Shuffled the queue.", diff --git a/package.json b/package.json index 784554098..9ba6624fa 100644 --- a/package.json +++ b/package.json @@ -17,16 +17,7 @@ "type": "git", "url": "git+https://github.com/appujet/lavamusic.git" }, - "keywords": [ - "discord", - "music", - "bot", - "lavalink", - "shoukaku", - "lavamusic", - "typescript", - "prisma" - ], + "keywords": ["discord", "music", "bot", "lavalink", "shoukaku", "lavamusic", "typescript", "prisma"], "author": "appujet", "license": "GPL-3.0", "bugs": { @@ -39,7 +30,7 @@ "@types/node": "^22.5.4", "@types/signale": "^1.4.7", "prisma": "^5.19.1", - "typescript": "^5.5.4" + "typescript": "^5.6.2" }, "dependencies": { "@prisma/client": "^5.19.1", @@ -48,7 +39,7 @@ "dotenv": "^16.4.5", "i18n": "^0.15.1", "node-system-stats": "^1.3.0", - "shoukaku": "github:shipgirlproject/Shoukaku#master", + "shoukaku": "^4.1.1", "signale": "^1.4.0", "topgg-autoposter": "^2.0.2", "tslib": "^2.7.0", diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 6ea936c86..ad4099269 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -5,67 +5,72 @@ // Try Prisma Accelerate: https://pris.ly/cli/accelerate-init generator client { - provider = "prisma-client-js" - binaryTargets = ["native", "debian-openssl-3.0.x"] + provider = "prisma-client-js" + binaryTargets = ["native", "debian-openssl-3.0.x"] } datasource db { - provider = "sqlite" - url = "file:./lavamusic.db" + provider = "sqlite" + url = "file:./lavamusic.db" +} + +model Bot { + botId String @unique + totalPlaySong Int } model Guild { - guildId String @id - prefix String - language String? - stay Stay? - dj Dj? - roles Role[] - setup Setup? + guildId String @id + prefix String + language String? @default("EnglishUS") + stay Stay? + dj Dj? + roles Role[] + setup Setup? } model Stay { - guildId String @id - textId String - voiceId String - Guild Guild @relation(fields: [guildId], references: [guildId]) + guildId String @id + textId String + voiceId String + Guild Guild @relation(fields: [guildId], references: [guildId]) } model Dj { - guildId String @id - mode Boolean - Guild Guild @relation(fields: [guildId], references: [guildId]) + guildId String @id + mode Boolean + Guild Guild @relation(fields: [guildId], references: [guildId]) } model Role { - guildId String - roleId String - Guild Guild @relation(fields: [guildId], references: [guildId]) + guildId String + roleId String + Guild Guild @relation(fields: [guildId], references: [guildId]) - @@unique([guildId, roleId]) + @@unique([guildId, roleId]) } model Playlist { - id String @id @default(uuid()) - userId String - name String - songs Song[] + id String @id @default(uuid()) + userId String + name String + songs Song[] - @@unique([userId, name]) + @@unique([userId, name]) } model Song { - id String @id @default(uuid()) - track String - playlistId String - playlist Playlist @relation(fields: [playlistId], references: [id]) + id String @id @default(uuid()) + track String + playlistId String + playlist Playlist @relation(fields: [playlistId], references: [id]) - @@unique([track, playlistId]) + @@unique([track, playlistId]) } model Setup { - guildId String @id - textId String - messageId String - Guild Guild @relation(fields: [guildId], references: [guildId]) -} + guildId String @id + textId String + messageId String + Guild Guild @relation(fields: [guildId], references: [guildId]) +} \ No newline at end of file diff --git a/scripts/clean.js b/scripts/clean.js index 4ce4104c4..76de41728 100644 --- a/scripts/clean.js +++ b/scripts/clean.js @@ -3,15 +3,15 @@ import { rm } from "node:fs/promises"; import { resolve } from "node:path"; async function clean() { - try { - const path = resolve("dist"); - if (existsSync(path)) { - await rm(path, { recursive: true, force: true }); - } - } catch (error) { - console.error("Error while cleaning dist folder:", error); - process.exit(1); + try { + const path = resolve("dist"); + if (existsSync(path)) { + await rm(path, { recursive: true, force: true }); } + } catch (error) { + console.error("Error while cleaning dist folder:", error); + process.exit(1); + } } clean(); diff --git a/scripts/restart.ts b/scripts/restart.ts index f2ba2a50f..540ed1763 100644 --- a/scripts/restart.ts +++ b/scripts/restart.ts @@ -1,15 +1,15 @@ import { exec } from "node:child_process"; async function startLavamusic(): Promise { - exec("npm start", (error, stderr) => { - if (error) { - console.error(`Error starting Lavamusic: ${error.message}`); - return; - } - if (stderr) { - console.error(`Error output: ${stderr}`); - } - }); + exec("npm start", (error, stderr) => { + if (error) { + console.error(`Error starting Lavamusic: ${error.message}`); + return; + } + if (stderr) { + console.error(`Error output: ${stderr}`); + } + }); } setTimeout(startLavamusic, 5000); diff --git a/src/LavaClient.ts b/src/LavaClient.ts index 2c1663f04..8972bbac0 100644 --- a/src/LavaClient.ts +++ b/src/LavaClient.ts @@ -5,8 +5,8 @@ import Lavamusic from "./structures/Lavamusic.js"; const { GuildMembers, MessageContent, GuildVoiceStates, GuildMessages, Guilds, GuildMessageTyping } = GatewayIntentBits; const clientOptions: ClientOptions = { - intents: [Guilds, GuildMessages, MessageContent, GuildVoiceStates, GuildMembers, GuildMessageTyping], - allowedMentions: { parse: ["users", "roles"], repliedUser: false }, + intents: [Guilds, GuildMessages, MessageContent, GuildVoiceStates, GuildMembers, GuildMessageTyping], + allowedMentions: { parse: ["users", "roles"], repliedUser: false }, }; const client = new Lavamusic(clientOptions); diff --git a/src/commands/config/247.ts b/src/commands/config/247.ts index 25e8d5f31..eab0e7c69 100644 --- a/src/commands/config/247.ts +++ b/src/commands/config/247.ts @@ -2,71 +2,71 @@ import type { GuildMember } from "discord.js"; import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class _247 extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "247", - description: { - content: "cmd.247.description", - examples: ["247"], - usage: "247", - }, - category: "config", - aliases: ["stay"], - cooldown: 3, - args: false, - vote: true, - player: { - voice: true, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: ["ManageGuild"], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "247", + description: { + content: "cmd.247.description", + examples: ["247"], + usage: "247", + }, + category: "config", + aliases: ["stay"], + cooldown: 3, + args: false, + vote: true, + player: { + voice: true, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: ["ManageGuild"], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const embed = this.client.embed(); - let player = client.shoukaku.players.get(ctx.guild!.id) as any; - try { - const data = await client.db.get_247(ctx.guild!.id); - const member = ctx.member as GuildMember; - if (!member.voice.channel) { - return await ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.247.errors.not_in_voice")).setColor(client.color.red)], - }); - } - if (data) { - await client.db.delete_247(ctx.guild!.id); - return await ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.247.messages.disabled")).setColor(client.color.red)], - }); - } - await client.db.set_247(ctx.guild!.id, ctx.channel.id, member.voice.channel.id); - if (!player) { - player = await client.queue.create( - ctx.guild, - member.voice.channel, - ctx.channel, - client.shoukaku.options.nodeResolver(client.shoukaku.nodes), - ); - } - return await ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.247.messages.enabled")).setColor(this.client.color.main)], - }); - } catch (error) { - console.error("Error in 247 command:", error); - return await ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.247.errors.generic")).setColor(client.color.red)], - }); - } + public async run(client: Lavamusic, ctx: Context): Promise { + const embed = this.client.embed(); + let player = client.shoukaku.players.get(ctx.guild!.id) as any; + try { + const data = await client.db.get_247(ctx.guild!.id); + const member = ctx.member as GuildMember; + if (!member.voice.channel) { + return await ctx.sendMessage({ + embeds: [embed.setDescription(ctx.locale("cmd.247.errors.not_in_voice")).setColor(client.color.red)], + }); + } + if (data) { + await client.db.delete_247(ctx.guild!.id); + return await ctx.sendMessage({ + embeds: [embed.setDescription(ctx.locale("cmd.247.messages.disabled")).setColor(client.color.red)], + }); + } + await client.db.set_247(ctx.guild!.id, ctx.channel.id, member.voice.channel.id); + if (!player) { + player = await client.queue.create( + ctx.guild, + member.voice.channel, + ctx.channel, + client.shoukaku.options.nodeResolver(client.shoukaku.nodes), + ); + } + return await ctx.sendMessage({ + embeds: [embed.setDescription(ctx.locale("cmd.247.messages.enabled")).setColor(this.client.color.main)], + }); + } catch (error) { + console.error("Error in 247 command:", error); + return await ctx.sendMessage({ + embeds: [embed.setDescription(ctx.locale("cmd.247.errors.generic")).setColor(client.color.red)], + }); } + } } /** diff --git a/src/commands/config/Dj.ts b/src/commands/config/Dj.ts index 2cafdaf6e..71d5943d8 100644 --- a/src/commands/config/Dj.ts +++ b/src/commands/config/Dj.ts @@ -1,185 +1,185 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Dj extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "dj", - description: { - content: "cmd.dj.description", - examples: ["dj add @role", "dj remove @role", "dj clear", "dj toggle"], - usage: "dj", + constructor(client: Lavamusic) { + super(client, { + name: "dj", + description: { + content: "cmd.dj.description", + examples: ["dj add @role", "dj remove @role", "dj clear", "dj toggle"], + usage: "dj", + }, + category: "general", + aliases: ["dj"], + cooldown: 3, + args: true, + vote: true, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: ["ManageGuild"], + }, + slashCommand: true, + options: [ + { + name: "add", + description: "cmd.dj.options.add", + type: 1, + options: [ + { + name: "role", + description: "cmd.dj.options.role", + type: 8, + required: true, }, - category: "general", - aliases: ["dj"], - cooldown: 3, - args: true, - vote: true, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, + ], + }, + { + name: "remove", + description: "cmd.dj.options.remove", + type: 1, + options: [ + { + name: "role", + description: "cmd.dj.options.role", + type: 8, + required: true, }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: ["ManageGuild"], - }, - slashCommand: true, - options: [ - { - name: "add", - description: "cmd.dj.options.add", - type: 1, - options: [ - { - name: "role", - description: "cmd.dj.options.role", - type: 8, - required: true, - }, - ], - }, - { - name: "remove", - description: "cmd.dj.options.remove", - type: 1, - options: [ - { - name: "role", - description: "cmd.dj.options.role", - type: 8, - required: true, - }, - ], - }, - { - name: "clear", - description: "cmd.dj.options.clear", - type: 1, - }, - { - name: "toggle", - description: "cmd.dj.options.toggle", - type: 1, - }, - ], - }); - } - - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const embed = this.client.embed().setColor(this.client.color.main); - const dj = await client.db.getDj(ctx.guild!.id); - let subCommand: string; - let role: any; + ], + }, + { + name: "clear", + description: "cmd.dj.options.clear", + type: 1, + }, + { + name: "toggle", + description: "cmd.dj.options.toggle", + type: 1, + }, + ], + }); + } - if (ctx.isInteraction) { - subCommand = ctx.interaction.options.data[0].name; - if (subCommand === "add" || subCommand === "remove") { - role = ctx.interaction.options.data[0].options[0].role; - } - } else { - subCommand = args[0]; - role = ctx.message.mentions.roles.first() || ctx.guild.roles.cache.get(args[1]); - } + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const embed = this.client.embed().setColor(this.client.color.main); + const dj = await client.db.getDj(ctx.guild!.id); + let subCommand: string; + let role: any; - switch (subCommand) { - case "add": - if (!role) { - return ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.dj.errors.provide_role"))], - }); - } - if (await client.db.getRoles(ctx.guild!.id).then((r) => r.some((re) => re.roleId === role.id))) { - return ctx.sendMessage({ - embeds: [ - embed.setDescription( - ctx.locale("cmd.dj.messages.role_exists", { - roleId: role.id, - }), - ), - ], - }); - } - await client.db.addRole(ctx.guild!.id, role.id); - await client.db.setDj(ctx.guild!.id, true); - return ctx.sendMessage({ - embeds: [ - embed.setDescription( - ctx.locale("cmd.dj.messages.role_added", { - roleId: role.id, - }), - ), - ], - }); + if (ctx.isInteraction) { + subCommand = ctx.interaction.options.data[0].name; + if (subCommand === "add" || subCommand === "remove") { + role = ctx.interaction.options.data[0].options[0].role; + } + } else { + subCommand = args[0]; + role = ctx.message.mentions.roles.first() || ctx.guild.roles.cache.get(args[1]); + } - case "remove": - if (!role) { - return ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.dj.errors.provide_role"))], - }); - } - if (!(await client.db.getRoles(ctx.guild!.id).then((r) => r.some((re) => re.roleId === role.id)))) { - return ctx.sendMessage({ - embeds: [ - embed.setDescription( - ctx.locale("cmd.dj.messages.role_not_found", { - roleId: role.id, - }), - ), - ], - }); - } - await client.db.removeRole(ctx.guild!.id, role.id); - return ctx.sendMessage({ - embeds: [ - embed.setDescription( - ctx.locale("cmd.dj.messages.role_removed", { - roleId: role.id, - }), - ), - ], - }); + switch (subCommand) { + case "add": + if (!role) { + return ctx.sendMessage({ + embeds: [embed.setDescription(ctx.locale("cmd.dj.errors.provide_role"))], + }); + } + if (await client.db.getRoles(ctx.guild!.id).then((r) => r.some((re) => re.roleId === role.id))) { + return ctx.sendMessage({ + embeds: [ + embed.setDescription( + ctx.locale("cmd.dj.messages.role_exists", { + roleId: role.id, + }), + ), + ], + }); + } + await client.db.addRole(ctx.guild!.id, role.id); + await client.db.setDj(ctx.guild!.id, true); + return ctx.sendMessage({ + embeds: [ + embed.setDescription( + ctx.locale("cmd.dj.messages.role_added", { + roleId: role.id, + }), + ), + ], + }); - case "clear": - if (!dj) { - return ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.dj.errors.no_roles"))], - }); - } - await client.db.clearRoles(ctx.guild!.id); - return ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.dj.messages.all_roles_cleared"))], - }); + case "remove": + if (!role) { + return ctx.sendMessage({ + embeds: [embed.setDescription(ctx.locale("cmd.dj.errors.provide_role"))], + }); + } + if (!(await client.db.getRoles(ctx.guild!.id).then((r) => r.some((re) => re.roleId === role.id)))) { + return ctx.sendMessage({ + embeds: [ + embed.setDescription( + ctx.locale("cmd.dj.messages.role_not_found", { + roleId: role.id, + }), + ), + ], + }); + } + await client.db.removeRole(ctx.guild!.id, role.id); + return ctx.sendMessage({ + embeds: [ + embed.setDescription( + ctx.locale("cmd.dj.messages.role_removed", { + roleId: role.id, + }), + ), + ], + }); - case "toggle": - if (!dj) { - return ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.dj.errors.no_roles"))], - }); - } - await client.db.setDj(ctx.guild!.id, !dj.mode); - return ctx.sendMessage({ - embeds: [ - embed.setDescription( - ctx.locale("cmd.dj.messages.toggle", { - status: dj.mode ? "disabled" : "enabled", - }), - ), - ], - }); + case "clear": + if (!dj) { + return ctx.sendMessage({ + embeds: [embed.setDescription(ctx.locale("cmd.dj.errors.no_roles"))], + }); + } + await client.db.clearRoles(ctx.guild!.id); + return ctx.sendMessage({ + embeds: [embed.setDescription(ctx.locale("cmd.dj.messages.all_roles_cleared"))], + }); - default: - return ctx.sendMessage({ - embeds: [ - embed.setDescription(ctx.locale("cmd.dj.errors.invalid_subcommand")).addFields({ - name: ctx.locale("cmd.dj.subcommands"), - value: "`add`, `remove`, `clear`, `toggle`", - }), - ], - }); + case "toggle": + if (!dj) { + return ctx.sendMessage({ + embeds: [embed.setDescription(ctx.locale("cmd.dj.errors.no_roles"))], + }); } + await client.db.setDj(ctx.guild!.id, !dj.mode); + return ctx.sendMessage({ + embeds: [ + embed.setDescription( + ctx.locale("cmd.dj.messages.toggle", { + status: dj.mode ? "disabled" : "enabled", + }), + ), + ], + }); + + default: + return ctx.sendMessage({ + embeds: [ + embed.setDescription(ctx.locale("cmd.dj.errors.invalid_subcommand")).addFields({ + name: ctx.locale("cmd.dj.subcommands"), + value: "`add`, `remove`, `clear`, `toggle`", + }), + ], + }); } + } } /** diff --git a/src/commands/config/Language.ts b/src/commands/config/Language.ts index 050160751..d7c468017 100644 --- a/src/commands/config/Language.ts +++ b/src/commands/config/Language.ts @@ -3,145 +3,145 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js import { Language, LocaleFlags } from "../../types.js"; export default class LanguageCommand extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "language", - description: { - content: "cmd.language.description", - examples: ["language set `EnglishUS`", "language reset"], - usage: "language", + constructor(client: Lavamusic) { + super(client, { + name: "language", + description: { + content: "cmd.language.description", + examples: ["language set `EnglishUS`", "language reset"], + usage: "language", + }, + category: "config", + aliases: ["lang"], + cooldown: 3, + args: true, + vote: false, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: ["ManageGuild"], + }, + slashCommand: true, + options: [ + { + name: "set", + description: "cmd.language.options.set", + type: 1, + options: [ + { + name: "language", + description: "cmd.language.options.language", + type: 3, + required: true, + autocomplete: true, }, - category: "config", - aliases: ["lang"], - cooldown: 3, - args: true, - vote: false, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: ["ManageGuild"], - }, - slashCommand: true, - options: [ - { - name: "set", - description: "cmd.language.options.set", - type: 1, - options: [ - { - name: "language", - description: "cmd.language.options.language", - type: 3, - required: true, - autocomplete: true, - }, - ], - }, - { - name: "reset", - description: "cmd.language.options.reset", - type: 1, - }, - ], - }); + ], + }, + { + name: "reset", + description: "cmd.language.options.reset", + type: 1, + }, + ], + }); + } + + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + let subCommand: string; + + if (ctx.isInteraction) { + subCommand = ctx.interaction.options.data[0].name; + } else { + subCommand = args.shift(); } + if (subCommand === "set") { + const embed = client.embed().setColor(this.client.color.main); - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - let subCommand: string; - - if (ctx.isInteraction) { - subCommand = ctx.interaction.options.data[0].name; - } else { - subCommand = args.shift(); - } - if (subCommand === "set") { - const embed = client.embed().setColor(this.client.color.main); + const locale = await client.db.getLanguage(ctx.guild!.id); - const locale = await client.db.getLanguage(ctx.guild!.id); - - let lang: string; - - if (ctx.isInteraction) { - lang = ctx.interaction.options.data[0].options[0].value as string; - } else { - lang = args[0]; - } + let lang: string; - if (!Object.values(Language).includes(lang as Language)) { - const availableLanguages = Object.entries(LocaleFlags) - .map(([key, value]) => `${value}:\`${key}\``) - .reduce((acc, curr, index) => { - if (index % 2 === 0) { - return acc + curr + (index === Object.entries(LocaleFlags).length - 1 ? "" : " "); - } - return `${acc + curr}\n`; - }, ""); - return ctx.sendMessage({ - embeds: [ - embed.setDescription( - ctx.locale("cmd.language.invalid_language", { - languages: availableLanguages, - }), - ), - ], - }); - } + if (ctx.isInteraction) { + lang = ctx.interaction.options.data[0].options[0].value as string; + } else { + lang = args[0]; + } - if (locale && locale === lang) { - return ctx.sendMessage({ - embeds: [ - embed.setDescription( - ctx.locale("cmd.language.already_set", { - language: lang, - }), - ), - ], - }); + if (!Object.values(Language).includes(lang as Language)) { + const availableLanguages = Object.entries(LocaleFlags) + .map(([key, value]) => `${value}:\`${key}\``) + .reduce((acc, curr, index) => { + if (index % 2 === 0) { + return acc + curr + (index === Object.entries(LocaleFlags).length - 1 ? "" : " "); } + return `${acc + curr}\n`; + }, ""); + return ctx.sendMessage({ + embeds: [ + embed.setDescription( + ctx.locale("cmd.language.invalid_language", { + languages: availableLanguages, + }), + ), + ], + }); + } + + if (locale && locale === lang) { + return ctx.sendMessage({ + embeds: [ + embed.setDescription( + ctx.locale("cmd.language.already_set", { + language: lang, + }), + ), + ], + }); + } - await client.db.updateLanguage(ctx.guild!.id, lang); - ctx.guildLocale = lang; + await client.db.updateLanguage(ctx.guild!.id, lang); + ctx.guildLocale = lang; - return ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.language.set", { language: lang }))], - }); - } - if (subCommand === "reset") { - const embed = client.embed().setColor(this.client.color.main); + return ctx.sendMessage({ + embeds: [embed.setDescription(ctx.locale("cmd.language.set", { language: lang }))], + }); + } + if (subCommand === "reset") { + const embed = client.embed().setColor(this.client.color.main); - const locale = await client.db.getLanguage(ctx.guild!.id); + const locale = await client.db.getLanguage(ctx.guild!.id); - if (!locale) { - return ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.language.not_set"))], - }); - } + if (!locale) { + return ctx.sendMessage({ + embeds: [embed.setDescription(ctx.locale("cmd.language.not_set"))], + }); + } - await client.db.updateLanguage(ctx.guild!.id, Language.EnglishUS); - ctx.guildLocale = Language.EnglishUS; + await client.db.updateLanguage(ctx.guild!.id, Language.EnglishUS); + ctx.guildLocale = Language.EnglishUS; - return ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.language.reset"))], - }); - } + return ctx.sendMessage({ + embeds: [embed.setDescription(ctx.locale("cmd.language.reset"))], + }); } + } - public async autocomplete(interaction: AutocompleteInteraction): Promise { - const focusedValue = interaction.options.getFocused(); + public async autocomplete(interaction: AutocompleteInteraction): Promise { + const focusedValue = interaction.options.getFocused(); - const languages = Object.values(Language).map((language) => ({ - name: language, - value: language, - })); + const languages = Object.values(Language).map((language) => ({ + name: language, + value: language, + })); - const filtered = languages.filter((language) => language.name.toLowerCase().includes(focusedValue.toLowerCase())); + const filtered = languages.filter((language) => language.name.toLowerCase().includes(focusedValue.toLowerCase())); - await interaction.respond(filtered.slice(0, 25)).catch(console.error); - } + await interaction.respond(filtered.slice(0, 25)).catch(console.error); + } } diff --git a/src/commands/config/Prefix.ts b/src/commands/config/Prefix.ts index b745b03bd..2e62d78a3 100644 --- a/src/commands/config/Prefix.ts +++ b/src/commands/config/Prefix.ts @@ -1,110 +1,110 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Prefix extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "prefix", - description: { - content: "cmd.prefix.description", - examples: ["prefix set !", "prefix reset"], - usage: "prefix", + constructor(client: Lavamusic) { + super(client, { + name: "prefix", + description: { + content: "cmd.prefix.description", + examples: ["prefix set !", "prefix reset"], + usage: "prefix", + }, + category: "general", + aliases: ["pf"], + cooldown: 3, + args: true, + vote: false, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: ["ManageGuild"], + }, + slashCommand: true, + options: [ + { + name: "set", + description: "cmd.prefix.options.set", + type: 1, + options: [ + { + name: "prefix", + description: "cmd.prefix.options.prefix", + type: 3, + required: true, }, - category: "general", - aliases: ["pf"], - cooldown: 3, - args: true, - vote: false, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: ["ManageGuild"], - }, - slashCommand: true, - options: [ - { - name: "set", - description: "cmd.prefix.options.set", - type: 1, - options: [ - { - name: "prefix", - description: "cmd.prefix.options.prefix", - type: 3, - required: true, - }, - ], - }, - { - name: "reset", - description: "cmd.prefix.options.reset", - type: 1, - }, - ], - }); - } + ], + }, + { + name: "reset", + description: "cmd.prefix.options.reset", + type: 1, + }, + ], + }); + } - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const embed = client.embed().setColor(this.client.color.main); - const guildId = ctx.guild!.id; - const guildData = await client.db.get(guildId); - const isInteraction = ctx.isInteraction; - let subCommand: string; - let prefix: string; + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const embed = client.embed().setColor(this.client.color.main); + const guildId = ctx.guild!.id; + const guildData = await client.db.get(guildId); + const isInteraction = ctx.isInteraction; + let subCommand: string; + let prefix: string; - if (isInteraction) { - subCommand = ctx.interaction.options.data[0].name; - prefix = ctx.interaction.options.data[0].options[0]?.value.toString(); - } else { - subCommand = args[0] || ""; - prefix = args[1] || ""; - } + if (isInteraction) { + subCommand = ctx.interaction.options.data[0].name; + prefix = ctx.interaction.options.data[0].options[0]?.value.toString(); + } else { + subCommand = args[0] || ""; + prefix = args[1] || ""; + } - switch (subCommand) { - case "set": { - if (!prefix) { - const currentPrefix = guildData ? guildData.prefix : client.config.prefix; - embed.setDescription( - ctx.locale("cmd.prefix.messages.current_prefix", { - prefix: currentPrefix, - }), - ); - return await ctx.sendMessage({ embeds: [embed] }); - } - if (prefix.length > 3) { - embed.setDescription(ctx.locale("cmd.prefix.errors.prefix_too_long")); - return await ctx.sendMessage({ embeds: [embed] }); - } - await client.db.setPrefix(guildId, prefix); - embed.setDescription(ctx.locale("cmd.prefix.messages.prefix_set", { prefix })); - return await ctx.sendMessage({ embeds: [embed] }); - } - case "reset": { - const defaultPrefix = client.config.prefix; - await client.db.setPrefix(guildId, defaultPrefix); - embed.setDescription( - ctx.locale("cmd.prefix.messages.prefix_reset", { - prefix: defaultPrefix, - }), - ); - return await ctx.sendMessage({ embeds: [embed] }); - } - default: { - const currentPrefix = guildData ? guildData.prefix : client.config.prefix; - embed.setDescription( - ctx.locale("cmd.prefix.messages.current_prefix", { - prefix: currentPrefix, - }), - ); - return await ctx.sendMessage({ embeds: [embed] }); - } + switch (subCommand) { + case "set": { + if (!prefix) { + const currentPrefix = guildData ? guildData.prefix : client.config.prefix; + embed.setDescription( + ctx.locale("cmd.prefix.messages.current_prefix", { + prefix: currentPrefix, + }), + ); + return await ctx.sendMessage({ embeds: [embed] }); + } + if (prefix.length > 3) { + embed.setDescription(ctx.locale("cmd.prefix.errors.prefix_too_long")); + return await ctx.sendMessage({ embeds: [embed] }); } + await client.db.setPrefix(guildId, prefix); + embed.setDescription(ctx.locale("cmd.prefix.messages.prefix_set", { prefix })); + return await ctx.sendMessage({ embeds: [embed] }); + } + case "reset": { + const defaultPrefix = client.config.prefix; + await client.db.setPrefix(guildId, defaultPrefix); + embed.setDescription( + ctx.locale("cmd.prefix.messages.prefix_reset", { + prefix: defaultPrefix, + }), + ); + return await ctx.sendMessage({ embeds: [embed] }); + } + default: { + const currentPrefix = guildData ? guildData.prefix : client.config.prefix; + embed.setDescription( + ctx.locale("cmd.prefix.messages.current_prefix", { + prefix: currentPrefix, + }), + ); + return await ctx.sendMessage({ embeds: [embed] }); + } } + } } /** diff --git a/src/commands/config/Setup.ts b/src/commands/config/Setup.ts index f261efd97..5a00baf2d 100644 --- a/src/commands/config/Setup.ts +++ b/src/commands/config/Setup.ts @@ -3,179 +3,175 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js import { getButtons } from "../../utils/Buttons.js"; export default class Setup extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "setup", - description: { - content: "cmd.setup.description", - examples: ["setup create", "setup delete", "setup info"], - usage: "setup", + constructor(client: Lavamusic) { + super(client, { + name: "setup", + description: { + content: "cmd.setup.description", + examples: ["setup create", "setup delete", "setup info"], + usage: "setup", + }, + category: "config", + aliases: ["set"], + cooldown: 3, + args: true, + vote: true, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks", "ManageChannels"], + user: ["ManageGuild"], + }, + slashCommand: true, + options: [ + { + name: "create", + description: "cmd.setup.options.create", + type: 1, + }, + { + name: "delete", + description: "cmd.setup.options.delete", + type: 1, + }, + { + name: "info", + description: "cmd.setup.options.info", + type: 1, + }, + ], + }); + } + + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const subCommand = ctx.isInteraction ? ctx.interaction.options.data[0].name : args[0]; + const embed = client.embed().setColor(this.client.color.main); + switch (subCommand) { + case "create": { + const data = await client.db.getSetup(ctx.guild!.id); + if (data?.textId && data.messageId) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.setup.errors.channel_exists"), + color: client.color.red, + }, + ], + }); + } + const textChannel = await ctx.guild.channels.create({ + name: `${this.client.user.username}-song-requests`, + type: ChannelType.GuildText, + topic: "Song requests for the music bot.", + permissionOverwrites: [ + { + type: OverwriteType.Member, + id: this.client.user.id, + allow: [ + PermissionFlagsBits.ViewChannel, + PermissionFlagsBits.SendMessages, + PermissionFlagsBits.EmbedLinks, + PermissionFlagsBits.ReadMessageHistory, + ], }, - category: "config", - aliases: ["set"], - cooldown: 3, - args: true, - vote: true, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, + { + type: OverwriteType.Role, + id: ctx.guild.roles.everyone.id, + allow: [PermissionFlagsBits.ViewChannel, PermissionFlagsBits.SendMessages, PermissionFlagsBits.ReadMessageHistory], }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks", "ManageChannels"], - user: ["ManageGuild"], + ], + }); + const player = this.client.queue.get(ctx.guild!.id); + const image = this.client.config.links.img; + const desc = + player?.queue && player.current + ? `[${player.current.info.title}](${player.current.info.uri})` + : ctx.locale("player.setupStart.nothing_playing"); + embed.setDescription(desc).setImage(image); + await textChannel + .send({ + embeds: [embed], + components: getButtons(player, client), + }) + .then((msg) => { + client.db.setSetup(ctx.guild!.id, textChannel.id, msg.id); + }); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.setup.messages.channel_created", { channelId: textChannel.id }), + color: this.client.color.main, }, - slashCommand: true, - options: [ - { - name: "create", - description: "cmd.setup.options.create", - type: 1, - }, - { - name: "delete", - description: "cmd.setup.options.delete", - type: 1, - }, - { - name: "info", - description: "cmd.setup.options.info", - type: 1, - }, + ], + }); + break; + } + case "delete": { + const data2 = await client.db.getSetup(ctx.guild!.id); + if (!data2) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.setup.errors.channel_not_exists"), + color: client.color.red, + }, ], + }); + } + client.db.deleteSetup(ctx.guild!.id); + const textChannel = ctx.guild.channels.cache.get(data2.textId); + if (textChannel) await textChannel.delete().catch(() => {}); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.setup.messages.channel_deleted"), + color: this.client.color.main, + }, + ], }); - } - - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const subCommand = ctx.isInteraction ? ctx.interaction.options.data[0].name : args[0]; - const embed = client.embed().setColor(this.client.color.main); - switch (subCommand) { - case "create": { - const data = await client.db.getSetup(ctx.guild!.id); - if (data?.textId && data.messageId) { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.setup.errors.channel_exists"), - color: client.color.red, - }, - ], - }); - } - const textChannel = await ctx.guild.channels.create({ - name: `${this.client.user.username}-song-requests`, - type: ChannelType.GuildText, - topic: "Song requests for the music bot.", - permissionOverwrites: [ - { - type: OverwriteType.Member, - id: this.client.user.id, - allow: [ - PermissionFlagsBits.ViewChannel, - PermissionFlagsBits.SendMessages, - PermissionFlagsBits.EmbedLinks, - PermissionFlagsBits.ReadMessageHistory, - ], - }, - { - type: OverwriteType.Role, - id: ctx.guild.roles.everyone.id, - allow: [ - PermissionFlagsBits.ViewChannel, - PermissionFlagsBits.SendMessages, - PermissionFlagsBits.ReadMessageHistory, - ], - }, - ], - }); - const player = this.client.queue.get(ctx.guild!.id); - const image = this.client.config.links.img; - const desc = - player?.queue && player.current - ? `[${player.current.info.title}](${player.current.info.uri})` - : ctx.locale("player.setupStart.nothing_playing"); - embed.setDescription(desc).setImage(image); - await textChannel - .send({ - embeds: [embed], - components: getButtons(player, client), - }) - .then((msg) => { - client.db.setSetup(ctx.guild!.id, textChannel.id, msg.id); - }); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.setup.messages.channel_created", { channelId: textChannel.id }), - color: this.client.color.main, - }, - ], - }); - break; - } - case "delete": { - const data2 = await client.db.getSetup(ctx.guild!.id); - if (!data2) { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.setup.errors.channel_not_exists"), - color: client.color.red, - }, - ], - }); - } - client.db.deleteSetup(ctx.guild!.id); - const textChannel = ctx.guild.channels.cache.get(data2.textId); - if (textChannel) await textChannel.delete().catch(() => {}); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.setup.messages.channel_deleted"), - color: this.client.color.main, - }, - ], - }); - break; - } - case "info": { - const data3 = await client.db.getSetup(ctx.guild!.id); - if (!data3) { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.setup.errors.channel_not_exists"), - color: client.color.red, - }, - ], - }); - } - const channel = ctx.guild.channels.cache.get(data3.textId); - if (channel) { - embed.setDescription( - ctx.locale("cmd.setup.messages.channel_info", { - channelId: channel.id, - }), - ); - await ctx.sendMessage({ embeds: [embed] }); - } else { - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.setup.errors.channel_not_exists"), - color: client.color.red, - }, - ], - }); - } - break; - } - default: - break; + break; + } + case "info": { + const data3 = await client.db.getSetup(ctx.guild!.id); + if (!data3) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.setup.errors.channel_not_exists"), + color: client.color.red, + }, + ], + }); + } + const channel = ctx.guild.channels.cache.get(data3.textId); + if (channel) { + embed.setDescription( + ctx.locale("cmd.setup.messages.channel_info", { + channelId: channel.id, + }), + ); + await ctx.sendMessage({ embeds: [embed] }); + } else { + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.setup.errors.channel_not_exists"), + color: client.color.red, + }, + ], + }); } + break; + } + default: + break; } + } } /** diff --git a/src/commands/dev/CreateInvite.ts b/src/commands/dev/CreateInvite.ts index fc0bcdfd1..3d3c7d99f 100644 --- a/src/commands/dev/CreateInvite.ts +++ b/src/commands/dev/CreateInvite.ts @@ -2,69 +2,67 @@ import { ChannelType, PermissionFlagsBits, type TextChannel } from "discord.js"; import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class CreateInvite extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "createinvite", - description: { - content: "Create an invite link for a guild", - examples: ["createinvite 0000000000000000000"], - usage: "createinvite ", - }, - category: "dev", - aliases: ["ci", "gi", "ginvite", "guildinvite"], - cooldown: 3, - args: true, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: true, - client: ["SendMessages", "CreateInstantInvite", "ReadMessageHistory", "EmbedLinks", "ViewChannel"], - user: [], - }, - slashCommand: false, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "createinvite", + description: { + content: "Create an invite link for a guild", + examples: ["createinvite 0000000000000000000"], + usage: "createinvite ", + }, + category: "dev", + aliases: ["ci", "gi", "ginvite", "guildinvite"], + cooldown: 3, + args: true, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: true, + client: ["SendMessages", "CreateInstantInvite", "ReadMessageHistory", "EmbedLinks", "ViewChannel"], + user: [], + }, + slashCommand: false, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const guild = client.guilds.cache.get(args[0]); + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const guild = client.guilds.cache.get(args[0]); - if (!guild) { - return await ctx.sendMessage({ - embeds: [this.client.embed().setColor(this.client.color.red).setDescription("Guild not found")], - }); - } + if (!guild) { + return await ctx.sendMessage({ + embeds: [this.client.embed().setColor(this.client.color.red).setDescription("Guild not found")], + }); + } - const textChannel = guild.channels.cache.find( - (c) => - c.type === ChannelType.GuildText && - c - .permissionsFor(guild.members.me!) - ?.has(PermissionFlagsBits.CreateInstantInvite | PermissionFlagsBits.SendMessages | PermissionFlagsBits.ViewChannel), - ) as TextChannel | undefined; + const textChannel = guild.channels.cache.find( + (c) => + c.type === ChannelType.GuildText && + c + .permissionsFor(guild.members.me!) + ?.has(PermissionFlagsBits.CreateInstantInvite | PermissionFlagsBits.SendMessages | PermissionFlagsBits.ViewChannel), + ) as TextChannel | undefined; - if (!textChannel) { - return await ctx.sendMessage({ - embeds: [this.client.embed().setColor(this.client.color.red).setDescription("No suitable channel found")], - }); - } + if (!textChannel) { + return await ctx.sendMessage({ + embeds: [this.client.embed().setColor(this.client.color.red).setDescription("No suitable channel found")], + }); + } - const invite = await textChannel.createInvite({ - maxAge: 3600, - maxUses: 0, - reason: `Requested by developer: ${ctx.author.username}`, - }); + const invite = await textChannel.createInvite({ + maxAge: 3600, + maxUses: 0, + reason: `Requested by developer: ${ctx.author.username}`, + }); - return await ctx.sendMessage({ - embeds: [ - this.client.embed().setColor(this.client.color.main).setDescription(`Invite link for ${guild.name}: [Link](${invite.url})`), - ], - }); - } + return await ctx.sendMessage({ + embeds: [this.client.embed().setColor(this.client.color.main).setDescription(`Invite link for ${guild.name}: [Link](${invite.url})`)], + }); + } } /** diff --git a/src/commands/dev/DeleteInvites.ts b/src/commands/dev/DeleteInvites.ts index c63e6f72d..eb5a07881 100644 --- a/src/commands/dev/DeleteInvites.ts +++ b/src/commands/dev/DeleteInvites.ts @@ -1,51 +1,51 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class DestroyInvites extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "destroyinvites", - description: { - content: "Destroy all invite links created by the bot in a guild", - examples: ["destroyinvites 0000000000000000000"], - usage: "destroyinvites ", - }, - category: "dev", - aliases: ["di"], - cooldown: 3, - args: true, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: true, - client: ["SendMessages", "ManageGuild", "ReadMessageHistory", "ViewChannel"], - user: [], - }, - slashCommand: false, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "destroyinvites", + description: { + content: "Destroy all invite links created by the bot in a guild", + examples: ["destroyinvites 0000000000000000000"], + usage: "destroyinvites ", + }, + category: "dev", + aliases: ["di"], + cooldown: 3, + args: true, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: true, + client: ["SendMessages", "ManageGuild", "ReadMessageHistory", "ViewChannel"], + user: [], + }, + slashCommand: false, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const guild = client.guilds.cache.get(args[0]); + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const guild = client.guilds.cache.get(args[0]); - if (!guild) { - return await ctx.sendMessage("Guild not found."); - } + if (!guild) { + return await ctx.sendMessage("Guild not found."); + } - try { - const botInvites = (await guild.invites.fetch()).filter((invite) => invite.inviter?.id === client.user?.id); + try { + const botInvites = (await guild.invites.fetch()).filter((invite) => invite.inviter?.id === client.user?.id); - await Promise.all(botInvites.map((invite) => invite.delete())); + await Promise.all(botInvites.map((invite) => invite.delete())); - return await ctx.sendMessage(`Destroyed ${botInvites.size} invite(s) created by the bot.`); - } catch { - return await ctx.sendMessage("Failed to destroy invites."); - } + return await ctx.sendMessage(`Destroyed ${botInvites.size} invite(s) created by the bot.`); + } catch { + return await ctx.sendMessage("Failed to destroy invites."); } + } } /** diff --git a/src/commands/dev/Deploy.ts b/src/commands/dev/Deploy.ts index 9203a3397..602331a59 100644 --- a/src/commands/dev/Deploy.ts +++ b/src/commands/dev/Deploy.ts @@ -2,100 +2,100 @@ import { ActionRowBuilder, ButtonBuilder, type ButtonInteraction, ButtonStyle, C import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Deploy extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "deploy", - description: { - content: "Deploy commands", - examples: ["deploy"], - usage: "deploy", - }, - category: "dev", - aliases: ["deploy-commands"], - cooldown: 3, - args: false, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: true, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: false, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "deploy", + description: { + content: "Deploy commands", + examples: ["deploy"], + usage: "deploy", + }, + category: "dev", + aliases: ["deploy-commands"], + cooldown: 3, + args: false, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: true, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: false, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context, _args: string[]): Promise { - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder().setCustomId("deploy-global").setLabel("Global").setStyle(ButtonStyle.Secondary), - new ButtonBuilder().setCustomId("deploy-guild").setLabel("Guild").setStyle(ButtonStyle.Secondary), - ); + public async run(client: Lavamusic, ctx: Context, _args: string[]): Promise { + const row = new ActionRowBuilder().addComponents( + new ButtonBuilder().setCustomId("deploy-global").setLabel("Global").setStyle(ButtonStyle.Secondary), + new ButtonBuilder().setCustomId("deploy-guild").setLabel("Guild").setStyle(ButtonStyle.Secondary), + ); - let msg: Message | undefined; - try { - msg = await ctx.sendMessage({ - content: "Where do you want to deploy the commands?", - components: [row], - }); - } catch (error) { - console.error("Failed to send the initial message:", error); - return; - } + let msg: Message | undefined; + try { + msg = await ctx.sendMessage({ + content: "Where do you want to deploy the commands?", + components: [row], + }); + } catch (error) { + console.error("Failed to send the initial message:", error); + return; + } - const filter = (interaction: ButtonInteraction<"cached">) => { - if (interaction.user.id !== ctx.author.id) { - interaction - .reply({ - content: "You can't interact with this message", - ephemeral: true, - }) - .catch(console.error); - return false; - } - return true; - }; + const filter = (interaction: ButtonInteraction<"cached">) => { + if (interaction.user.id !== ctx.author.id) { + interaction + .reply({ + content: "You can't interact with this message", + ephemeral: true, + }) + .catch(console.error); + return false; + } + return true; + }; - const collector = ctx.channel.createMessageComponentCollector({ - filter, - componentType: ComponentType.Button, - time: 30000, - }); + const collector = ctx.channel.createMessageComponentCollector({ + filter, + componentType: ComponentType.Button, + time: 30000, + }); - collector.on("collect", async (interaction) => { - try { - if (interaction.customId === "deploy-global") { - await client.deployCommands(); - await ctx.editMessage({ - content: "Commands deployed globally.", - components: [], - }); - } else if (interaction.customId === "deploy-guild") { - await client.deployCommands(interaction.guild!.id); - await ctx.editMessage({ - content: "Commands deployed in this guild.", - components: [], - }); - } - } catch (error) { - console.error("Failed to handle interaction:", error); - } - }); + collector.on("collect", async (interaction) => { + try { + if (interaction.customId === "deploy-global") { + await client.deployCommands(); + await ctx.editMessage({ + content: "Commands deployed globally.", + components: [], + }); + } else if (interaction.customId === "deploy-guild") { + await client.deployCommands(interaction.guild!.id); + await ctx.editMessage({ + content: "Commands deployed in this guild.", + components: [], + }); + } + } catch (error) { + console.error("Failed to handle interaction:", error); + } + }); - collector.on("end", async (_collected, reason) => { - if (reason === "time" && msg) { - try { - await msg.delete(); - } catch (error) { - console.error("Failed to delete the message:", error); - } - } - }); - } + collector.on("end", async (_collected, reason) => { + if (reason === "time" && msg) { + try { + await msg.delete(); + } catch (error) { + console.error("Failed to delete the message:", error); + } + } + }); + } } /** diff --git a/src/commands/dev/Eval.ts b/src/commands/dev/Eval.ts index 6f0e890fc..0d892149e 100644 --- a/src/commands/dev/Eval.ts +++ b/src/commands/dev/Eval.ts @@ -4,78 +4,78 @@ import { fetch } from "undici"; import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Eval extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "eval", - description: { - content: "Evaluate code", - examples: ["eval"], - usage: "eval", - }, - category: "dev", - aliases: ["ev"], - cooldown: 3, - args: true, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: true, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: false, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "eval", + description: { + content: "Evaluate code", + examples: ["eval"], + usage: "eval", + }, + category: "dev", + aliases: ["ev"], + cooldown: 3, + args: true, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: true, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: false, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const code = args.join(" "); - try { - let evaled = eval(code); - if (evaled === client.config) evaled = "Nice try"; + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const code = args.join(" "); + try { + let evaled = eval(code); + if (evaled === client.config) evaled = "Nice try"; - if (typeof evaled !== "string") evaled = util.inspect(evaled); - if (evaled.length > 2000) { - const response = await fetch("https://hasteb.in/post", { - method: "POST", - headers: { - "Content-Type": "text/plain", - }, - body: evaled, - }); - const json: any = await response.json(); - evaled = `https://hasteb.in/${json.key}`; - return await ctx.sendMessage({ - content: evaled, - }); - } + if (typeof evaled !== "string") evaled = util.inspect(evaled); + if (evaled.length > 2000) { + const response = await fetch("https://hasteb.in/post", { + method: "POST", + headers: { + "Content-Type": "text/plain", + }, + body: evaled, + }); + const json: any = await response.json(); + evaled = `https://hasteb.in/${json.key}`; + return await ctx.sendMessage({ + content: evaled, + }); + } - const button = new ButtonBuilder().setStyle(ButtonStyle.Danger).setLabel("Delete").setCustomId("eval-delete"); - const row = new ActionRowBuilder().addComponents(button); + const button = new ButtonBuilder().setStyle(ButtonStyle.Danger).setLabel("Delete").setCustomId("eval-delete"); + const row = new ActionRowBuilder().addComponents(button); - const msg = await ctx.sendMessage({ - content: `\`\`\`js\n${evaled}\n\`\`\``, - components: [row], - }); + const msg = await ctx.sendMessage({ + content: `\`\`\`js\n${evaled}\n\`\`\``, + components: [row], + }); - const filter = (i: any) => i.customId === "eval-delete" && i.user.id === ctx.author.id; - const collector = msg.createMessageComponentCollector({ - time: 60000, - filter: filter, - }); + const filter = (i: any) => i.customId === "eval-delete" && i.user.id === ctx.author.id; + const collector = msg.createMessageComponentCollector({ + time: 60000, + filter: filter, + }); - collector.on("collect", async (i) => { - await i.deferUpdate(); - await msg.delete(); - }); - } catch (e) { - ctx.sendMessage(`\`\`\`js\n${e}\n\`\`\``); - } + collector.on("collect", async (i) => { + await i.deferUpdate(); + await msg.delete(); + }); + } catch (e) { + ctx.sendMessage(`\`\`\`js\n${e}\n\`\`\``); } + } } /** diff --git a/src/commands/dev/GuildLeave.ts b/src/commands/dev/GuildLeave.ts index e08c6b65b..7080d017b 100644 --- a/src/commands/dev/GuildLeave.ts +++ b/src/commands/dev/GuildLeave.ts @@ -2,74 +2,74 @@ import { ChannelType, type TextChannel } from "discord.js"; import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class GuildLeave extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "guildleave", - description: { - content: "Leave a guild", - examples: ["guildleave "], - usage: "guildleave ", - }, - category: "dev", - aliases: ["gl"], - cooldown: 3, - args: true, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: true, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: false, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "guildleave", + description: { + content: "Leave a guild", + examples: ["guildleave "], + usage: "guildleave ", + }, + category: "dev", + aliases: ["gl"], + cooldown: 3, + args: true, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: true, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: false, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const guildId = args[0]; + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const guildId = args[0]; - const guild = await client.shard - .broadcastEval( - (c, { guildId }) => { - const guild = c.guilds.cache.get(guildId); - return guild ? { id: guild.id, name: guild.name } : null; - }, - { context: { guildId } }, - ) - .then((results) => results.find((g) => g !== null)); + const guild = await client.shard + .broadcastEval( + (c, { guildId }) => { + const guild = c.guilds.cache.get(guildId); + return guild ? { id: guild.id, name: guild.name } : null; + }, + { context: { guildId } }, + ) + .then((results) => results.find((g) => g !== null)); - if (!guild) { - return await ctx.sendMessage("Guild not found."); - } + if (!guild) { + return await ctx.sendMessage("Guild not found."); + } - try { - await client.shard.broadcastEval( - async (c, { guildId }) => { - const guild = c.guilds.cache.get(guildId); - if (guild) { - await guild.leave(); - } - }, - { context: { guildId } }, - ); - await ctx.sendMessage(`Left guild ${guild.name}`); - } catch { - await ctx.sendMessage(`Failed to leave guild ${guild.name}`); - } + try { + await client.shard.broadcastEval( + async (c, { guildId }) => { + const guild = c.guilds.cache.get(guildId); + if (guild) { + await guild.leave(); + } + }, + { context: { guildId } }, + ); + await ctx.sendMessage(`Left guild ${guild.name}`); + } catch { + await ctx.sendMessage(`Failed to leave guild ${guild.name}`); + } - const logChannelId = process.env.LOG_CHANNEL_ID; - if (logChannelId) { - const logChannel = client.channels.cache.get(logChannelId) as TextChannel; - if (logChannel && logChannel.type === ChannelType.GuildText) { - await logChannel.send(`Bot has left guild: ${guild.name} (ID: ${guild.id})`); - } - } + const logChannelId = process.env.LOG_CHANNEL_ID; + if (logChannelId) { + const logChannel = client.channels.cache.get(logChannelId) as TextChannel; + if (logChannel && logChannel.type === ChannelType.GuildText) { + await logChannel.send(`Bot has left guild: ${guild.name} (ID: ${guild.id})`); + } } + } } /** diff --git a/src/commands/dev/GuildList.ts b/src/commands/dev/GuildList.ts index 7d7373aa3..da01025a3 100644 --- a/src/commands/dev/GuildList.ts +++ b/src/commands/dev/GuildList.ts @@ -1,49 +1,49 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class GuildList extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "guildlist", - description: { - content: "List all guilds the bot is in", - examples: ["guildlist"], - usage: "guildlist", - }, - category: "dev", - aliases: ["glst"], - cooldown: 3, - args: false, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: true, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: false, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "guildlist", + description: { + content: "List all guilds the bot is in", + examples: ["guildlist"], + usage: "guildlist", + }, + category: "dev", + aliases: ["glst"], + cooldown: 3, + args: false, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: true, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: false, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const guilds = await client.shard.broadcastEval((c) => c.guilds.cache.map((guild) => ({ name: guild.name, id: guild.id }))); - const allGuilds = guilds.reduce((acc, val) => acc.concat(val), []); + public async run(client: Lavamusic, ctx: Context): Promise { + const guilds = await client.shard.broadcastEval((c) => c.guilds.cache.map((guild) => ({ name: guild.name, id: guild.id }))); + const allGuilds = guilds.reduce((acc, val) => acc.concat(val), []); - const guildList = allGuilds.map((guild) => `- **${guild.name}** - (${guild.id})`); - const chunks = client.utils.chunk(guildList, 10) || [[]]; - const pages = chunks.map((chunk, index) => { - return this.client - .embed() - .setColor(this.client.color.main) - .setDescription(chunk.join("\n")) - .setFooter({ text: `Page ${index + 1} of ${chunks.length}` }); - }); - await client.utils.paginate(client, ctx, pages); - } + const guildList = allGuilds.map((guild) => `- **${guild.name}** - (${guild.id})`); + const chunks = client.utils.chunk(guildList, 10) || [[]]; + const pages = chunks.map((chunk, index) => { + return this.client + .embed() + .setColor(this.client.color.main) + .setDescription(chunk.join("\n")) + .setFooter({ text: `Page ${index + 1} of ${chunks.length}` }); + }); + await client.utils.paginate(client, ctx, pages); + } } /** diff --git a/src/commands/dev/Restart.ts b/src/commands/dev/Restart.ts index b670d582d..7f375b186 100644 --- a/src/commands/dev/Restart.ts +++ b/src/commands/dev/Restart.ts @@ -3,77 +3,77 @@ import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js"; import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Restart extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "restart", - description: { - content: "Restart the bot", - examples: ["restart"], - usage: "restart", - }, - category: "dev", - aliases: ["reboot"], - cooldown: 3, - args: false, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: true, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: false, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "restart", + description: { + content: "Restart the bot", + examples: ["restart"], + usage: "restart", + }, + category: "dev", + aliases: ["reboot"], + cooldown: 3, + args: false, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: true, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: false, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const embed = this.client.embed(); - const button = new ButtonBuilder().setStyle(ButtonStyle.Danger).setLabel("Confirm Restart").setCustomId("confirm-restart"); - const row = new ActionRowBuilder().addComponents(button); - const restartEmbed = embed - .setColor(this.client.color.red) - .setDescription(`**Are you sure you want to restart **\`${client.user.username}\`?`) - .setTimestamp(); + public async run(client: Lavamusic, ctx: Context): Promise { + const embed = this.client.embed(); + const button = new ButtonBuilder().setStyle(ButtonStyle.Danger).setLabel("Confirm Restart").setCustomId("confirm-restart"); + const row = new ActionRowBuilder().addComponents(button); + const restartEmbed = embed + .setColor(this.client.color.red) + .setDescription(`**Are you sure you want to restart **\`${client.user.username}\`?`) + .setTimestamp(); - const msg = await ctx.sendMessage({ - embeds: [restartEmbed], - components: [row], - }); + const msg = await ctx.sendMessage({ + embeds: [restartEmbed], + components: [row], + }); - const filter = (i: any) => i.customId === "confirm-restart" && i.user.id === ctx.author.id; - const collector = msg.createMessageComponentCollector({ - time: 30000, - filter, - }); + const filter = (i: any) => i.customId === "confirm-restart" && i.user.id === ctx.author.id; + const collector = msg.createMessageComponentCollector({ + time: 30000, + filter, + }); - collector.on("collect", async (i) => { - await i.deferUpdate(); + collector.on("collect", async (i) => { + await i.deferUpdate(); - await msg.edit({ - content: "Restarting the bot...", - embeds: [], - components: [], - }); + await msg.edit({ + content: "Restarting the bot...", + embeds: [], + components: [], + }); - await client.destroy(); - exec("node scripts/restart.ts"); - process.exit(0); - }); + await client.destroy(); + exec("node scripts/restart.ts"); + process.exit(0); + }); - collector.on("end", async () => { - if (!collector.collected.size) { - await msg.edit({ - content: "Restart cancelled.", - components: [], - }); - } + collector.on("end", async () => { + if (!collector.collected.size) { + await msg.edit({ + content: "Restart cancelled.", + components: [], }); - } + } + }); + } } /** diff --git a/src/commands/filters/8d.ts b/src/commands/filters/8d.ts index cf10b89d1..4f148f827 100644 --- a/src/commands/filters/8d.ts +++ b/src/commands/filters/8d.ts @@ -1,64 +1,64 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class _8d extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "8d", - description: { - content: "cmd.8d.description", - examples: ["8d"], - usage: "8d", - }, - category: "filters", - aliases: ["3d"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "8d", + description: { + content: "cmd.8d.description", + examples: ["8d"], + usage: "8d", + }, + category: "filters", + aliases: ["3d"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const filterEnabled = player.filters.includes("8D"); - const rotationConfig = filterEnabled ? {} : { rotationHz: 0.2 }; + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const filterEnabled = player.filters.includes("8D"); + const rotationConfig = filterEnabled ? {} : { rotationHz: 0.2 }; - await player.player.setRotation(rotationConfig); + await player.player.setRotation(rotationConfig); - if (filterEnabled) { - player.filters = player.filters.filter((filter) => filter !== "8D"); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.8d.messages.filter_disabled"), - color: this.client.color.main, - }, - ], - }); - } else { - player.filters.push("8D"); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.8d.messages.filter_enabled"), - color: this.client.color.main, - }, - ], - }); - } + if (filterEnabled) { + player.filters = player.filters.filter((filter) => filter !== "8D"); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.8d.messages.filter_disabled"), + color: this.client.color.main, + }, + ], + }); + } else { + player.filters.push("8D"); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.8d.messages.filter_enabled"), + color: this.client.color.main, + }, + ], + }); } + } } /** diff --git a/src/commands/filters/BassBoost.ts b/src/commands/filters/BassBoost.ts index 75188421f..fec2d6289 100644 --- a/src/commands/filters/BassBoost.ts +++ b/src/commands/filters/BassBoost.ts @@ -1,68 +1,68 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class BassBoost extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "bassboost", - description: { - content: "cmd.bassboost.description", - examples: ["bassboost"], - usage: "bassboost", - }, - category: "filters", - aliases: ["bb"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "bassboost", + description: { + content: "cmd.bassboost.description", + examples: ["bassboost"], + usage: "bassboost", + }, + category: "filters", + aliases: ["bb"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const filterEnabled = player.filters.includes("bassboost"); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const filterEnabled = player.filters.includes("bassboost"); - if (filterEnabled) { - await player.player.setEqualizer([]); - player.filters = player.filters.filter((filter) => filter !== "bassboost"); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.bassboost.messages.filter_disabled"), - color: this.client.color.main, - }, - ], - }); - } else { - await player.player.setEqualizer([ - { band: 0, gain: 0.34 }, - { band: 1, gain: 0.34 }, - { band: 2, gain: 0.34 }, - { band: 3, gain: 0.34 }, - ]); - player.filters.push("bassboost"); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.bassboost.messages.filter_enabled"), - color: this.client.color.main, - }, - ], - }); - } + if (filterEnabled) { + await player.player.setEqualizer([]); + player.filters = player.filters.filter((filter) => filter !== "bassboost"); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.bassboost.messages.filter_disabled"), + color: this.client.color.main, + }, + ], + }); + } else { + await player.player.setEqualizer([ + { band: 0, gain: 0.34 }, + { band: 1, gain: 0.34 }, + { band: 2, gain: 0.34 }, + { band: 3, gain: 0.34 }, + ]); + player.filters.push("bassboost"); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.bassboost.messages.filter_enabled"), + color: this.client.color.main, + }, + ], + }); } + } } /** diff --git a/src/commands/filters/Distorsion.ts b/src/commands/filters/Distorsion.ts index 289588984..8fc84bcde 100644 --- a/src/commands/filters/Distorsion.ts +++ b/src/commands/filters/Distorsion.ts @@ -1,72 +1,72 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Distorsion extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "distorsion", - description: { - content: "cmd.distorsion.description", - examples: ["distorsion"], - usage: "distorsion", - }, - category: "filters", - aliases: ["dt"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "distorsion", + description: { + content: "cmd.distorsion.description", + examples: ["distorsion"], + usage: "distorsion", + }, + category: "filters", + aliases: ["dt"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const filterEnabled = player.filters.includes("distorsion"); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const filterEnabled = player.filters.includes("distorsion"); - if (filterEnabled) { - await player.player.setDistortion({}); - player.filters = player.filters.filter((filter) => filter !== "distorsion"); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.distorsion.messages.filter_disabled"), - color: this.client.color.main, - }, - ], - }); - } else { - await player.player.setDistortion({ - sinOffset: 0, - sinScale: 1, - cosOffset: 0, - cosScale: 1, - tanOffset: 0, - tanScale: 1, - offset: 0, - scale: 1, - }); - player.filters.push("distorsion"); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.distorsion.messages.filter_enabled"), - color: this.client.color.main, - }, - ], - }); - } + if (filterEnabled) { + await player.player.setDistortion({}); + player.filters = player.filters.filter((filter) => filter !== "distorsion"); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.distorsion.messages.filter_disabled"), + color: this.client.color.main, + }, + ], + }); + } else { + await player.player.setDistortion({ + sinOffset: 0, + sinScale: 1, + cosOffset: 0, + cosScale: 1, + tanOffset: 0, + tanScale: 1, + offset: 0, + scale: 1, + }); + player.filters.push("distorsion"); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.distorsion.messages.filter_enabled"), + color: this.client.color.main, + }, + ], + }); } + } } /** diff --git a/src/commands/filters/Karaoke.ts b/src/commands/filters/Karaoke.ts index c41e3d358..492bd3387 100644 --- a/src/commands/filters/Karaoke.ts +++ b/src/commands/filters/Karaoke.ts @@ -1,68 +1,68 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Karaoke extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "karaoke", - description: { - content: "cmd.karaoke.description", - examples: ["karaoke"], - usage: "karaoke", - }, - category: "filters", - aliases: ["kk"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "karaoke", + description: { + content: "cmd.karaoke.description", + examples: ["karaoke"], + usage: "karaoke", + }, + category: "filters", + aliases: ["kk"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const filterEnabled = player.filters.includes("karaoke"); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const filterEnabled = player.filters.includes("karaoke"); - if (filterEnabled) { - await player.player.setKaraoke(); - player.filters = player.filters.filter((filter) => filter !== "karaoke"); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.karaoke.messages.filter_disabled"), - color: this.client.color.main, - }, - ], - }); - } else { - await player.player.setKaraoke({ - level: 1, - monoLevel: 1, - filterBand: 220, - filterWidth: 100, - }); - player.filters.push("karaoke"); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.karaoke.messages.filter_enabled"), - color: this.client.color.main, - }, - ], - }); - } + if (filterEnabled) { + await player.player.setKaraoke(); + player.filters = player.filters.filter((filter) => filter !== "karaoke"); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.karaoke.messages.filter_disabled"), + color: this.client.color.main, + }, + ], + }); + } else { + await player.player.setKaraoke({ + level: 1, + monoLevel: 1, + filterBand: 220, + filterWidth: 100, + }); + player.filters.push("karaoke"); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.karaoke.messages.filter_enabled"), + color: this.client.color.main, + }, + ], + }); } + } } /** diff --git a/src/commands/filters/LowPass.ts b/src/commands/filters/LowPass.ts index da33a65e9..04a23ac73 100644 --- a/src/commands/filters/LowPass.ts +++ b/src/commands/filters/LowPass.ts @@ -1,63 +1,63 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class LowPass extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "lowpass", - description: { - content: "cmd.lowpass.description", - examples: ["lowpass"], - usage: "lowpass ", - }, - category: "filters", - aliases: ["lp"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "lowpass", + description: { + content: "cmd.lowpass.description", + examples: ["lowpass"], + usage: "lowpass ", + }, + category: "filters", + aliases: ["lp"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const filterEnabled = player.filters.includes("lowpass"); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const filterEnabled = player.filters.includes("lowpass"); - if (filterEnabled) { - await player.player.setLowPass({ smoothing: 0 }); - player.filters = player.filters.filter((filter) => filter !== "lowpass"); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.lowpass.messages.filter_disabled"), - color: this.client.color.main, - }, - ], - }); - } else { - await player.player.setLowPass({ smoothing: 20 }); - player.filters.push("lowpass"); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.lowpass.messages.filter_enabled"), - color: this.client.color.main, - }, - ], - }); - } + if (filterEnabled) { + await player.player.setLowPass({ smoothing: 0 }); + player.filters = player.filters.filter((filter) => filter !== "lowpass"); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.lowpass.messages.filter_disabled"), + color: this.client.color.main, + }, + ], + }); + } else { + await player.player.setLowPass({ smoothing: 20 }); + player.filters.push("lowpass"); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.lowpass.messages.filter_enabled"), + color: this.client.color.main, + }, + ], + }); } + } } /** diff --git a/src/commands/filters/NightCore.ts b/src/commands/filters/NightCore.ts index 57cbae9d9..febbea514 100644 --- a/src/commands/filters/NightCore.ts +++ b/src/commands/filters/NightCore.ts @@ -1,63 +1,63 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class NightCore extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "nightcore", - description: { - content: "cmd.nightcore.description", - examples: ["nightcore"], - usage: "nightcore", - }, - category: "filters", - aliases: ["nc"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "nightcore", + description: { + content: "cmd.nightcore.description", + examples: ["nightcore"], + usage: "nightcore", + }, + category: "filters", + aliases: ["nc"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const filterEnabled = player.filters.includes("nightcore"); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const filterEnabled = player.filters.includes("nightcore"); - if (filterEnabled) { - await player.player.setTimescale({}); - player.filters = player.filters.filter((filter) => filter !== "nightcore"); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.nightcore.messages.filter_disabled"), - color: this.client.color.main, - }, - ], - }); - } else { - await player.player.setTimescale({ rate: 1.2 }); - player.filters.push("nightcore"); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.nightcore.messages.filter_enabled"), - color: this.client.color.main, - }, - ], - }); - } + if (filterEnabled) { + await player.player.setTimescale({}); + player.filters = player.filters.filter((filter) => filter !== "nightcore"); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.nightcore.messages.filter_disabled"), + color: this.client.color.main, + }, + ], + }); + } else { + await player.player.setTimescale({ rate: 1.2 }); + player.filters.push("nightcore"); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.nightcore.messages.filter_enabled"), + color: this.client.color.main, + }, + ], + }); } + } } /** diff --git a/src/commands/filters/Pitch.ts b/src/commands/filters/Pitch.ts index 5cb2105d4..b6577113e 100644 --- a/src/commands/filters/Pitch.ts +++ b/src/commands/filters/Pitch.ts @@ -1,72 +1,72 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Pitch extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "pitch", - description: { - content: "cmd.pitch.description", - examples: ["pitch 1", "pitch 1.5", "pitch 1,5"], - usage: "pitch ", - }, - category: "filters", - aliases: ["ph"], - cooldown: 3, - args: true, - vote: false, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "pitch", - description: "cmd.pitch.options.pitch", - type: 3, - required: true, - }, - ], - }); - } - - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const player = client.queue.get(ctx.guild!.id); - const pitchString = args[0].replace(",", "."); - const isValidNumber = /^[0-9]*\.?[0-9]+$/.test(pitchString); - const pitch = parseFloat(pitchString); + constructor(client: Lavamusic) { + super(client, { + name: "pitch", + description: { + content: "cmd.pitch.description", + examples: ["pitch 1", "pitch 1.5", "pitch 1,5"], + usage: "pitch ", + }, + category: "filters", + aliases: ["ph"], + cooldown: 3, + args: true, + vote: false, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "pitch", + description: "cmd.pitch.options.pitch", + type: 3, + required: true, + }, + ], + }); + } - if (!isValidNumber || isNaN(pitch) || pitch < 0.5 || pitch > 5) { - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.pitch.errors.invalid_number"), - color: this.client.color.red, - }, - ], - }); - return; - } + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const player = client.queue.get(ctx.guild!.id); + const pitchString = args[0].replace(",", "."); + const isValidNumber = /^[0-9]*\.?[0-9]+$/.test(pitchString); + const pitch = parseFloat(pitchString); - await player.player.setTimescale({ pitch }); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.pitch.messages.pitch_set", { - pitch, - }), - color: this.client.color.main, - }, - ], - }); + if (!isValidNumber || isNaN(pitch) || pitch < 0.5 || pitch > 5) { + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.pitch.errors.invalid_number"), + color: this.client.color.red, + }, + ], + }); + return; } + + await player.player.setTimescale({ pitch }); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.pitch.messages.pitch_set", { + pitch, + }), + color: this.client.color.main, + }, + ], + }); + } } /** diff --git a/src/commands/filters/Rate.ts b/src/commands/filters/Rate.ts index f9e1733d3..f197e3826 100644 --- a/src/commands/filters/Rate.ts +++ b/src/commands/filters/Rate.ts @@ -1,72 +1,72 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Rate extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "rate", - description: { - content: "cmd.rate.description", - examples: ["rate 1", "rate 1.5", "rate 1,5"], - usage: "rate ", - }, - category: "filters", - aliases: ["rt"], - cooldown: 3, - args: true, - vote: false, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "rate", - description: "cmd.rate.options.rate", - type: 3, - required: true, - }, - ], - }); - } - - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const player = client.queue.get(ctx.guild!.id); - const rateString = args[0].replace(",", "."); - const isValidNumber = /^[0-9]*\.?[0-9]+$/.test(rateString); - const rate = parseFloat(rateString); + constructor(client: Lavamusic) { + super(client, { + name: "rate", + description: { + content: "cmd.rate.description", + examples: ["rate 1", "rate 1.5", "rate 1,5"], + usage: "rate ", + }, + category: "filters", + aliases: ["rt"], + cooldown: 3, + args: true, + vote: false, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "rate", + description: "cmd.rate.options.rate", + type: 3, + required: true, + }, + ], + }); + } - if (!isValidNumber || isNaN(rate) || rate < 0.5 || rate > 5) { - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.rate.errors.invalid_number"), - color: this.client.color.red, - }, - ], - }); - return; - } + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const player = client.queue.get(ctx.guild!.id); + const rateString = args[0].replace(",", "."); + const isValidNumber = /^[0-9]*\.?[0-9]+$/.test(rateString); + const rate = parseFloat(rateString); - await player.player.setTimescale({ rate }); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.rate.messages.rate_set", { - rate, - }), - color: this.client.color.main, - }, - ], - }); + if (!isValidNumber || isNaN(rate) || rate < 0.5 || rate > 5) { + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.rate.errors.invalid_number"), + color: this.client.color.red, + }, + ], + }); + return; } + + await player.player.setTimescale({ rate }); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.rate.messages.rate_set", { + rate, + }), + color: this.client.color.main, + }, + ], + }); + } } /** diff --git a/src/commands/filters/Reset.ts b/src/commands/filters/Reset.ts index cced01703..0ed54a649 100644 --- a/src/commands/filters/Reset.ts +++ b/src/commands/filters/Reset.ts @@ -1,48 +1,48 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Reset extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "reset", - description: { - content: "cmd.reset.description", - examples: ["reset"], - usage: "reset", - }, - category: "filters", - aliases: ["rs"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: true, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "reset", + description: { + content: "cmd.reset.description", + examples: ["reset"], + usage: "reset", + }, + category: "filters", + aliases: ["rs"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: true, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - player.player.clearFilters(); - player.filters = []; - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.reset.messages.filters_reset"), - color: this.client.color.main, - }, - ], - }); - } + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + player.player.clearFilters(); + player.filters = []; + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.reset.messages.filters_reset"), + color: this.client.color.main, + }, + ], + }); + } } /** diff --git a/src/commands/filters/Rotation.ts b/src/commands/filters/Rotation.ts index 6519a80d1..81f32bf41 100644 --- a/src/commands/filters/Rotation.ts +++ b/src/commands/filters/Rotation.ts @@ -1,61 +1,61 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Rotation extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "rotation", - description: { - content: "cmd.rotation.description", - examples: ["rotation"], - usage: "rotation", - }, - category: "filters", - aliases: ["rt"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "rotation", + description: { + content: "cmd.rotation.description", + examples: ["rotation"], + usage: "rotation", + }, + category: "filters", + aliases: ["rt"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - if (player.filters.includes("rotation")) { - player.player.setRotation(); - player.filters = player.filters.filter((filter) => filter !== "rotation"); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.rotation.messages.disabled"), - color: this.client.color.main, - }, - ], - }); - } else { - player.player.setRotation({ rotationHz: 0 }); - player.filters.push("rotation"); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.rotation.messages.enabled"), - color: this.client.color.main, - }, - ], - }); - } + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + if (player.filters.includes("rotation")) { + player.player.setRotation(); + player.filters = player.filters.filter((filter) => filter !== "rotation"); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.rotation.messages.disabled"), + color: this.client.color.main, + }, + ], + }); + } else { + player.player.setRotation({ rotationHz: 0 }); + player.filters.push("rotation"); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.rotation.messages.enabled"), + color: this.client.color.main, + }, + ], + }); } + } } /** diff --git a/src/commands/filters/Speed.ts b/src/commands/filters/Speed.ts index cc467c539..589ebf16b 100644 --- a/src/commands/filters/Speed.ts +++ b/src/commands/filters/Speed.ts @@ -1,72 +1,72 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Speed extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "speed", - description: { - content: "cmd.speed.description", - examples: ["speed 1.5", "speed 1,5"], - usage: "speed ", - }, - category: "filters", - aliases: ["spd"], - cooldown: 3, - args: true, - vote: false, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "speed", - description: "cmd.speed.options.speed", - type: 3, - required: true, - }, - ], - }); - } - - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const player = client.queue.get(ctx.guild!.id); - const speedString = args[0].replace(",", "."); - const isValidNumber = /^[0-9]*\.?[0-9]+$/.test(speedString); - const speed = parseFloat(speedString); + constructor(client: Lavamusic) { + super(client, { + name: "speed", + description: { + content: "cmd.speed.description", + examples: ["speed 1.5", "speed 1,5"], + usage: "speed ", + }, + category: "filters", + aliases: ["spd"], + cooldown: 3, + args: true, + vote: false, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "speed", + description: "cmd.speed.options.speed", + type: 3, + required: true, + }, + ], + }); + } - if (!isValidNumber || isNaN(speed) || speed < 0.5 || speed > 5) { - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.speed.messages.invalid_number"), - color: this.client.color.red, - }, - ], - }); - return; - } + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const player = client.queue.get(ctx.guild!.id); + const speedString = args[0].replace(",", "."); + const isValidNumber = /^[0-9]*\.?[0-9]+$/.test(speedString); + const speed = parseFloat(speedString); - player.player.setTimescale({ speed }); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.speed.messages.set_speed", { - speed, - }), - color: this.client.color.main, - }, - ], - }); + if (!isValidNumber || isNaN(speed) || speed < 0.5 || speed > 5) { + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.speed.messages.invalid_number"), + color: this.client.color.red, + }, + ], + }); + return; } + + player.player.setTimescale({ speed }); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.speed.messages.set_speed", { + speed, + }), + color: this.client.color.main, + }, + ], + }); + } } /** diff --git a/src/commands/filters/Tremolo.ts b/src/commands/filters/Tremolo.ts index 0d31189a8..56fd9e7db 100644 --- a/src/commands/filters/Tremolo.ts +++ b/src/commands/filters/Tremolo.ts @@ -1,63 +1,63 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Tremolo extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "tremolo", - description: { - content: "cmd.tremolo.description", - examples: ["tremolo"], - usage: "tremolo", - }, - category: "filters", - aliases: ["tr"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "tremolo", + description: { + content: "cmd.tremolo.description", + examples: ["tremolo"], + usage: "tremolo", + }, + category: "filters", + aliases: ["tr"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const tremoloEnabled = player.filters.includes("tremolo"); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const tremoloEnabled = player.filters.includes("tremolo"); - if (tremoloEnabled) { - player.player.setTremolo(); - player.filters.splice(player.filters.indexOf("tremolo"), 1); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.tremolo.messages.disabled"), - color: this.client.color.main, - }, - ], - }); - } else { - player.player.setTremolo({ depth: 0.75, frequency: 4 }); - player.filters.push("tremolo"); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.tremolo.messages.enabled"), - color: this.client.color.main, - }, - ], - }); - } + if (tremoloEnabled) { + player.player.setTremolo(); + player.filters.splice(player.filters.indexOf("tremolo"), 1); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.tremolo.messages.disabled"), + color: this.client.color.main, + }, + ], + }); + } else { + player.player.setTremolo({ depth: 0.75, frequency: 4 }); + player.filters.push("tremolo"); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.tremolo.messages.enabled"), + color: this.client.color.main, + }, + ], + }); } + } } /** diff --git a/src/commands/filters/Vibrato.ts b/src/commands/filters/Vibrato.ts index 4dad08598..e9a3fced6 100644 --- a/src/commands/filters/Vibrato.ts +++ b/src/commands/filters/Vibrato.ts @@ -1,63 +1,63 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Vibrato extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "vibrato", - description: { - content: "cmd.vibrato.description", - examples: ["vibrato"], - usage: "vibrato", - }, - category: "filters", - aliases: ["vb"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "vibrato", + description: { + content: "cmd.vibrato.description", + examples: ["vibrato"], + usage: "vibrato", + }, + category: "filters", + aliases: ["vb"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const vibratoEnabled = player.filters.includes("vibrato"); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const vibratoEnabled = player.filters.includes("vibrato"); - if (vibratoEnabled) { - player.player.setVibrato(); - player.filters.splice(player.filters.indexOf("vibrato"), 1); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.vibrato.messages.disabled"), - color: this.client.color.main, - }, - ], - }); - } else { - player.player.setVibrato({ depth: 0.75, frequency: 4 }); - player.filters.push("vibrato"); - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.vibrato.messages.enabled"), - color: this.client.color.main, - }, - ], - }); - } + if (vibratoEnabled) { + player.player.setVibrato(); + player.filters.splice(player.filters.indexOf("vibrato"), 1); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.vibrato.messages.disabled"), + color: this.client.color.main, + }, + ], + }); + } else { + player.player.setVibrato({ depth: 0.75, frequency: 4 }); + player.filters.push("vibrato"); + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.vibrato.messages.enabled"), + color: this.client.color.main, + }, + ], + }); } + } } /** diff --git a/src/commands/info/About.ts b/src/commands/info/About.ts index 7865d9c01..acca4ffd0 100644 --- a/src/commands/info/About.ts +++ b/src/commands/info/About.ts @@ -2,83 +2,83 @@ import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js"; import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class About extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "about", - description: { - content: "cmd.about.description", - examples: ["about"], - usage: "about", - }, - category: "info", - aliases: ["ab"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "about", + description: { + content: "cmd.about.description", + examples: ["about"], + usage: "about", + }, + category: "info", + aliases: ["ab"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const inviteButton = new ButtonBuilder() - .setLabel(ctx.locale("buttons.invite")) - .setStyle(ButtonStyle.Link) - .setURL( - `https://discord.com/api/oauth2/authorize?client_id=${client.config.clientId}&permissions=8&scope=bot%20applications.commands`, - ); - const supportButton = new ButtonBuilder() - .setLabel(ctx.locale("buttons.support")) - .setStyle(ButtonStyle.Link) - .setURL("https://discord.gg/ns8CTk9J3e"); - const row = new ActionRowBuilder().addComponents(inviteButton, supportButton); - const embed = this.client - .embed() - .setAuthor({ - name: "Lavamusic", - iconURL: "https://media.discordapp.net/attachments/876035356460462090/888434725235097610/20210820_124325.png", - }) - .setThumbnail("https://media.discordapp.net/attachments/876035356460462090/888434725235097610/20210820_124325.png") - .setColor(this.client.color.main) - .addFields( - { - name: ctx.locale("cmd.about.fields.creator"), - value: "[appujet](https://github.com/appujet)", - inline: true, - }, - { - name: ctx.locale("cmd.about.fields.repository"), - value: "[Here](https://github.com/appujet/lavamusic)", - inline: true, - }, - { - name: ctx.locale("cmd.about.fields.support"), - value: "[Here](https://discord.gg/ns8CTk9J3e)", - inline: true, - }, - { - name: "\u200b", - value: ctx.locale("cmd.about.fields.description"), - inline: true, - }, - ); - await ctx.sendMessage({ - content: "", - embeds: [embed], - components: [row], - }); - } + public async run(client: Lavamusic, ctx: Context): Promise { + const inviteButton = new ButtonBuilder() + .setLabel(ctx.locale("buttons.invite")) + .setStyle(ButtonStyle.Link) + .setURL( + `https://discord.com/api/oauth2/authorize?client_id=${client.config.clientId}&permissions=8&scope=bot%20applications.commands`, + ); + const supportButton = new ButtonBuilder() + .setLabel(ctx.locale("buttons.support")) + .setStyle(ButtonStyle.Link) + .setURL("https://discord.gg/ns8CTk9J3e"); + const row = new ActionRowBuilder().addComponents(inviteButton, supportButton); + const embed = this.client + .embed() + .setAuthor({ + name: "Lavamusic", + iconURL: "https://media.discordapp.net/attachments/876035356460462090/888434725235097610/20210820_124325.png", + }) + .setThumbnail("https://media.discordapp.net/attachments/876035356460462090/888434725235097610/20210820_124325.png") + .setColor(this.client.color.main) + .addFields( + { + name: ctx.locale("cmd.about.fields.creator"), + value: "[appujet](https://github.com/appujet)", + inline: true, + }, + { + name: ctx.locale("cmd.about.fields.repository"), + value: "[Here](https://github.com/appujet/lavamusic)", + inline: true, + }, + { + name: ctx.locale("cmd.about.fields.support"), + value: "[Here](https://discord.gg/ns8CTk9J3e)", + inline: true, + }, + { + name: "\u200b", + value: ctx.locale("cmd.about.fields.description"), + inline: true, + }, + ); + await ctx.sendMessage({ + content: "", + embeds: [embed], + components: [row], + }); + } } /** diff --git a/src/commands/info/Botinfo.ts b/src/commands/info/Botinfo.ts index c4038bfea..2310b2e79 100644 --- a/src/commands/info/Botinfo.ts +++ b/src/commands/info/Botinfo.ts @@ -4,80 +4,80 @@ import { showTotalMemory, usagePercent } from "node-system-stats"; import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Botinfo extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "botinfo", - description: { - content: "cmd.botinfo.description", - examples: ["botinfo"], - usage: "botinfo", - }, - category: "info", - aliases: ["bi", "info", "stats", "status"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "botinfo", + description: { + content: "cmd.botinfo.description", + examples: ["botinfo"], + usage: "botinfo", + }, + category: "info", + aliases: ["bi", "info", "stats", "status"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const osInfo = `${os.type()} ${os.release()}`; - const osUptime = client.utils.formatTime(os.uptime()); - const osHostname = os.hostname(); - const cpuInfo = `${os.arch()} (${os.cpus().length} cores)`; - const cpuUsed = (await usagePercent({ coreIndex: 0, sampleMs: 2000 })).percent; - const memTotal = showTotalMemory(true); - const memUsed = (process.memoryUsage().rss / 1024 ** 2).toFixed(2); - const nodeVersion = process.version; - const discordJsVersion = version; - const commands = client.commands.size; + public async run(client: Lavamusic, ctx: Context): Promise { + const osInfo = `${os.type()} ${os.release()}`; + const osUptime = client.utils.formatTime(os.uptime()); + const osHostname = os.hostname(); + const cpuInfo = `${os.arch()} (${os.cpus().length} cores)`; + const cpuUsed = (await usagePercent({ coreIndex: 0, sampleMs: 2000 })).percent; + const memTotal = showTotalMemory(true); + const memUsed = (process.memoryUsage().rss / 1024 ** 2).toFixed(2); + const nodeVersion = process.version; + const discordJsVersion = version; + const commands = client.commands.size; - const promises = [ - client.shard.broadcastEval((client) => client.guilds.cache.size), - client.shard.broadcastEval((client) => client.guilds.cache.reduce((acc, guild) => acc + guild.memberCount, 0)), - client.shard.broadcastEval((client) => client.channels.cache.size), - ]; - return Promise.all(promises).then(async (results) => { - const guilds = results[0].reduce((acc, guildCount) => acc + guildCount, 0); - const users = results[1].reduce((acc, memberCount) => acc + memberCount, 0); - const channels = results[2].reduce((acc, channelCount) => acc + channelCount, 0); + const promises = [ + client.shard.broadcastEval((client) => client.guilds.cache.size), + client.shard.broadcastEval((client) => client.guilds.cache.reduce((acc, guild) => acc + guild.memberCount, 0)), + client.shard.broadcastEval((client) => client.channels.cache.size), + ]; + return Promise.all(promises).then(async (results) => { + const guilds = results[0].reduce((acc, guildCount) => acc + guildCount, 0); + const users = results[1].reduce((acc, memberCount) => acc + memberCount, 0); + const channels = results[2].reduce((acc, channelCount) => acc + channelCount, 0); - const botInfo = ctx.locale("cmd.botinfo.content", { - osInfo, - osUptime, - osHostname, - cpuInfo, - cpuUsed, - memUsed, - memTotal, - nodeVersion, - discordJsVersion, - guilds, - channels, - users, - commands, - }); + const botInfo = ctx.locale("cmd.botinfo.content", { + osInfo, + osUptime, + osHostname, + cpuInfo, + cpuUsed, + memUsed, + memTotal, + nodeVersion, + discordJsVersion, + guilds, + channels, + users, + commands, + }); - const embed = this.client.embed().setColor(this.client.color.main).setDescription(botInfo); + const embed = this.client.embed().setColor(this.client.color.main).setDescription(botInfo); - return await ctx.sendMessage({ - embeds: [embed], - }); - }); - } + return await ctx.sendMessage({ + embeds: [embed], + }); + }); + } } /** diff --git a/src/commands/info/Help.ts b/src/commands/info/Help.ts index eddcc5617..d38d6f39b 100644 --- a/src/commands/info/Help.ts +++ b/src/commands/info/Help.ts @@ -1,112 +1,111 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Help extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "help", - description: { - content: "cmd.help.description", - examples: ["help"], - usage: "help", - }, - category: "info", - aliases: ["h"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "command", - description: "cmd.help.options.command", - type: 3, - required: false, - }, - ], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "help", + description: { + content: "cmd.help.description", + examples: ["help"], + usage: "help", + }, + category: "info", + aliases: ["h"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "command", + description: "cmd.help.options.command", + type: 3, + required: false, + }, + ], + }); + } - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const embed = this.client.embed(); - const guild = await client.db.get(ctx.guild.id); - const commands = this.client.commands.filter((cmd) => cmd.category !== "dev"); - const categories = [...new Set(commands.map((cmd) => cmd.category))]; + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const embed = this.client.embed(); + const guild = await client.db.get(ctx.guild.id); + const commands = this.client.commands.filter((cmd) => cmd.category !== "dev"); + const categories = [...new Set(commands.map((cmd) => cmd.category))]; - if (args[0]) { - const command = this.client.commands.get(args[0].toLowerCase()); - if (!command) { - return await ctx.sendMessage({ - embeds: [ - embed.setColor(this.client.color.red).setDescription( - ctx.locale("cmd.help.not_found", { - cmdName: args[0], - }), - ), - ], - }); - } - const helpEmbed = embed - .setColor(client.color.main) - .setTitle(`${ctx.locale("cmd.help.title")} - ${command.name}`) - .setDescription( - ctx.locale("cmd.help.help_cmd", { - description: ctx.locale(command.description.content), - usage: `${guild.prefix}${command.description.usage}`, - examples: command.description.examples.map((example) => `${guild.prefix}${example}`).join(", "), - aliases: command.aliases.map((alias) => `\`${alias}\``).join(", "), - category: command.category, - cooldown: command.cooldown, - premUser: - command.permissions.user.length > 0 ? command.permissions.user.map((perm) => `\`${perm}\``).join(", ") : "None", - premBot: command.permissions.client.map((perm) => `\`${perm}\``).join(", "), - dev: command.permissions.dev ? "Yes" : "No", - slash: command.slashCommand ? "Yes" : "No", - args: command.args ? "Yes" : "No", - player: command.player.active ? "Yes" : "No", - dj: command.player.dj ? "Yes" : "No", - djPerm: command.player.djPerm ? command.player.djPerm : "None", - voice: command.player.voice ? "Yes" : "No", - }), - ); - return await ctx.sendMessage({ embeds: [helpEmbed] }); - } + if (args[0]) { + const command = this.client.commands.get(args[0].toLowerCase()); + if (!command) { + return await ctx.sendMessage({ + embeds: [ + embed.setColor(this.client.color.red).setDescription( + ctx.locale("cmd.help.not_found", { + cmdName: args[0], + }), + ), + ], + }); + } + const helpEmbed = embed + .setColor(client.color.main) + .setTitle(`${ctx.locale("cmd.help.title")} - ${command.name}`) + .setDescription( + ctx.locale("cmd.help.help_cmd", { + description: ctx.locale(command.description.content), + usage: `${guild.prefix}${command.description.usage}`, + examples: command.description.examples.map((example) => `${guild.prefix}${example}`).join(", "), + aliases: command.aliases.map((alias) => `\`${alias}\``).join(", "), + category: command.category, + cooldown: command.cooldown, + premUser: command.permissions.user.length > 0 ? command.permissions.user.map((perm) => `\`${perm}\``).join(", ") : "None", + premBot: command.permissions.client.map((perm) => `\`${perm}\``).join(", "), + dev: command.permissions.dev ? "Yes" : "No", + slash: command.slashCommand ? "Yes" : "No", + args: command.args ? "Yes" : "No", + player: command.player.active ? "Yes" : "No", + dj: command.player.dj ? "Yes" : "No", + djPerm: command.player.djPerm ? command.player.djPerm : "None", + voice: command.player.voice ? "Yes" : "No", + }), + ); + return await ctx.sendMessage({ embeds: [helpEmbed] }); + } - const fields = categories.map((category) => ({ - name: category, - value: commands - .filter((cmd) => cmd.category === category) - .map((cmd) => `\`${cmd.name}\``) - .join(", "), - inline: false, - })); + const fields = categories.map((category) => ({ + name: category, + value: commands + .filter((cmd) => cmd.category === category) + .map((cmd) => `\`${cmd.name}\``) + .join(", "), + inline: false, + })); - const helpEmbed = embed - .setColor(client.color.main) - .setTitle(ctx.locale("cmd.help.title")) - .setDescription( - ctx.locale("cmd.help.content", { - bot: client.user.username, - prefix: guild.prefix, - }), - ) - .setFooter({ - text: ctx.locale("cmd.help.footer", { prefix: guild.prefix }), - }) - .addFields(...fields); + const helpEmbed = embed + .setColor(client.color.main) + .setTitle(ctx.locale("cmd.help.title")) + .setDescription( + ctx.locale("cmd.help.content", { + bot: client.user.username, + prefix: guild.prefix, + }), + ) + .setFooter({ + text: ctx.locale("cmd.help.footer", { prefix: guild.prefix }), + }) + .addFields(...fields); - return await ctx.sendMessage({ embeds: [helpEmbed] }); - } + return await ctx.sendMessage({ embeds: [helpEmbed] }); + } } /** diff --git a/src/commands/info/Invite.ts b/src/commands/info/Invite.ts index 3e222457f..95952550f 100644 --- a/src/commands/info/Invite.ts +++ b/src/commands/info/Invite.ts @@ -2,51 +2,51 @@ import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js"; import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Invite extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "invite", - description: { - content: "cmd.invite.description", - examples: ["invite"], - usage: "invite", - }, - category: "info", - aliases: ["iv"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "invite", + description: { + content: "cmd.invite.description", + examples: ["invite"], + usage: "invite", + }, + category: "info", + aliases: ["iv"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const embed = this.client.embed(); - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setLabel(ctx.locale("buttons.invite")) - .setStyle(ButtonStyle.Link) - .setURL( - `https://discord.com/api/oauth2/authorize?client_id=${client.config.clientId}&permissions=8&scope=bot%20applications.commands`, - ), - new ButtonBuilder().setLabel(ctx.locale("buttons.support")).setStyle(ButtonStyle.Link).setURL("https://discord.gg/STXurwnZD5"), - ); - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.main).setDescription(ctx.locale("cmd.invite.content"))], - components: [row], - }); - } + public async run(client: Lavamusic, ctx: Context): Promise { + const embed = this.client.embed(); + const row = new ActionRowBuilder().addComponents( + new ButtonBuilder() + .setLabel(ctx.locale("buttons.invite")) + .setStyle(ButtonStyle.Link) + .setURL( + `https://discord.com/api/oauth2/authorize?client_id=${client.config.clientId}&permissions=8&scope=bot%20applications.commands`, + ), + new ButtonBuilder().setLabel(ctx.locale("buttons.support")).setStyle(ButtonStyle.Link).setURL("https://discord.gg/STXurwnZD5"), + ); + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.main).setDescription(ctx.locale("cmd.invite.content"))], + components: [row], + }); + } } /** diff --git a/src/commands/info/LavaLink.ts b/src/commands/info/LavaLink.ts index feccfe55c..63b1712df 100644 --- a/src/commands/info/LavaLink.ts +++ b/src/commands/info/LavaLink.ts @@ -1,88 +1,88 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class LavaLink extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "lavalink", - description: { - content: "cmd.lavalink.description", - examples: ["lavalink"], - usage: "lavalink", - }, - category: "info", - aliases: ["ll"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "lavalink", + description: { + content: "cmd.lavalink.description", + examples: ["lavalink"], + usage: "lavalink", + }, + category: "info", + aliases: ["ll"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const nodes = client.shoukaku.nodes; - const nodesPerPage = 2; + public async run(client: Lavamusic, ctx: Context): Promise { + const nodes = client.shoukaku.nodes; + const nodesPerPage = 2; - const nodeArray = Array.from(nodes.values()); - const chunks = client.utils.chunk(nodeArray, nodesPerPage); + const nodeArray = Array.from(nodes.values()); + const chunks = client.utils.chunk(nodeArray, nodesPerPage); - if (chunks.length === 0) chunks.push(nodeArray); + if (chunks.length === 0) chunks.push(nodeArray); - const pages = chunks.map((chunk, index) => { - const embed = this.client - .embed() - .setTitle(ctx.locale("cmd.lavalink.title")) - .setColor(this.client.color.main) - .setThumbnail(this.client.user.avatarURL()) - .setTimestamp(); + const pages = chunks.map((chunk, index) => { + const embed = this.client + .embed() + .setTitle(ctx.locale("cmd.lavalink.title")) + .setColor(this.client.color.main) + .setThumbnail(this.client.user.avatarURL()) + .setTimestamp(); - chunk.forEach((node) => { - const statusEmoji = node.stats ? "🟢" : "🔴"; - const stats = node.stats || { - players: 0, - playingPlayers: 0, - uptime: 0, - cpu: { cores: 0, systemLoad: 0, lavalinkLoad: 0 }, - memory: { used: 0, reservable: 0 }, - }; + chunk.forEach((node) => { + const statusEmoji = node.stats ? "🟢" : "🔴"; + const stats = node.stats || { + players: 0, + playingPlayers: 0, + uptime: 0, + cpu: { cores: 0, systemLoad: 0, lavalinkLoad: 0 }, + memory: { used: 0, reservable: 0 }, + }; - embed.addFields({ - name: `${node.name} (${statusEmoji})`, - value: `\`\`\`yaml\n${ctx.locale("cmd.lavalink.content", { - players: stats.players, - playingPlayers: stats.playingPlayers, - uptime: client.utils.formatTime(stats.uptime), - cores: stats.cpu.cores, - used: client.utils.formatBytes(stats.memory.used), - reservable: client.utils.formatBytes(stats.memory.reservable), - systemLoad: (stats.cpu.systemLoad * 100).toFixed(2), - lavalinkLoad: (stats.cpu.lavalinkLoad * 100).toFixed(2), - })}\n\`\`\``, - }); - }); + embed.addFields({ + name: `${node.name} (${statusEmoji})`, + value: `\`\`\`yaml\n${ctx.locale("cmd.lavalink.content", { + players: stats.players, + playingPlayers: stats.playingPlayers, + uptime: client.utils.formatTime(stats.uptime), + cores: stats.cpu.cores, + used: client.utils.formatBytes(stats.memory.used), + reservable: client.utils.formatBytes(stats.memory.reservable), + systemLoad: (stats.cpu.systemLoad * 100).toFixed(2), + lavalinkLoad: (stats.cpu.lavalinkLoad * 100).toFixed(2), + })}\n\`\`\``, + }); + }); - embed.setFooter({ - text: ctx.locale("cmd.lavalink.page_info", { - index: index + 1, - total: chunks.length, - }), - }); + embed.setFooter({ + text: ctx.locale("cmd.lavalink.page_info", { + index: index + 1, + total: chunks.length, + }), + }); - return embed; - }); - return await client.utils.paginate(client, ctx, pages); - } + return embed; + }); + return await client.utils.paginate(client, ctx, pages); + } } /** diff --git a/src/commands/info/Ping.ts b/src/commands/info/Ping.ts index 298795cef..29567c512 100644 --- a/src/commands/info/Ping.ts +++ b/src/commands/info/Ping.ts @@ -1,73 +1,73 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Ping extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "ping", - description: { - content: "cmd.ping.description", - examples: ["ping"], - usage: "ping", - }, - category: "general", - aliases: ["pong"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "ping", + description: { + content: "cmd.ping.description", + examples: ["ping"], + usage: "ping", + }, + category: "general", + aliases: ["pong"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(_client: Lavamusic, ctx: Context): Promise { - const msg = await ctx.sendDeferMessage(ctx.locale("cmd.ping.content")); + public async run(_client: Lavamusic, ctx: Context): Promise { + const msg = await ctx.sendDeferMessage(ctx.locale("cmd.ping.content")); - const botLatency = msg.createdTimestamp - ctx.createdTimestamp; - const apiLatency = Math.round(ctx.client.ws.ping); + const botLatency = msg.createdTimestamp - ctx.createdTimestamp; + const apiLatency = Math.round(ctx.client.ws.ping); - const botLatencySign = botLatency < 600 ? "+" : "-"; - const apiLatencySign = apiLatency < 500 ? "+" : "-"; + const botLatencySign = botLatency < 600 ? "+" : "-"; + const apiLatencySign = apiLatency < 500 ? "+" : "-"; - const embed = this.client - .embed() - .setAuthor({ - name: "Pong", - iconURL: this.client.user.displayAvatarURL(), - }) - .setColor(this.client.color.main) - .addFields([ - { - name: ctx.locale("cmd.ping.bot_latency"), - value: `\`\`\`diff\n${botLatencySign} ${botLatency}ms\n\`\`\``, - inline: true, - }, - { - name: ctx.locale("cmd.ping.api_latency"), - value: `\`\`\`diff\n${apiLatencySign} ${apiLatency}ms\n\`\`\``, - inline: true, - }, - ]) - .setFooter({ - text: ctx.locale("cmd.ping.requested_by", { - author: ctx.author.tag, - }), - iconURL: ctx.author.avatarURL({}), - }) - .setTimestamp(); + const embed = this.client + .embed() + .setAuthor({ + name: "Pong", + iconURL: this.client.user.displayAvatarURL(), + }) + .setColor(this.client.color.main) + .addFields([ + { + name: ctx.locale("cmd.ping.bot_latency"), + value: `\`\`\`diff\n${botLatencySign} ${botLatency}ms\n\`\`\``, + inline: true, + }, + { + name: ctx.locale("cmd.ping.api_latency"), + value: `\`\`\`diff\n${apiLatencySign} ${apiLatency}ms\n\`\`\``, + inline: true, + }, + ]) + .setFooter({ + text: ctx.locale("cmd.ping.requested_by", { + author: ctx.author.tag, + }), + iconURL: ctx.author.avatarURL({}), + }) + .setTimestamp(); - return await ctx.editMessage({ content: "", embeds: [embed] }); - } + return await ctx.editMessage({ content: "", embeds: [embed] }); + } } /** diff --git a/src/commands/music/Autoplay.ts b/src/commands/music/Autoplay.ts index d3266b486..8ad972ec4 100644 --- a/src/commands/music/Autoplay.ts +++ b/src/commands/music/Autoplay.ts @@ -1,60 +1,60 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Autoplay extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "autoplay", - description: { - content: "cmd.autoplay.description", - examples: ["autoplay"], - usage: "autoplay", - }, - category: "music", - aliases: ["ap"], - cooldown: 3, - args: false, - vote: true, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } - - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - if (!player) { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("player.errors.no_player"), - color: this.client.color.red, - }, - ], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "autoplay", + description: { + content: "cmd.autoplay.description", + examples: ["autoplay"], + usage: "autoplay", + }, + category: "music", + aliases: ["ap"], + cooldown: 3, + args: false, + vote: true, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - const embed = this.client.embed(); - const autoplay = player.autoplay; - player.setAutoplay(!autoplay); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + if (!player) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("player.errors.no_player"), + color: this.client.color.red, + }, + ], + }); + } - if (autoplay) { - embed.setDescription(ctx.locale("cmd.autoplay.messages.disabled")).setColor(this.client.color.main); - } else { - embed.setDescription(ctx.locale("cmd.autoplay.messages.enabled")).setColor(this.client.color.main); - } + const embed = this.client.embed(); + const autoplay = player.autoplay; + player.setAutoplay(!autoplay); - await ctx.sendMessage({ embeds: [embed] }); + if (autoplay) { + embed.setDescription(ctx.locale("cmd.autoplay.messages.disabled")).setColor(this.client.color.main); + } else { + embed.setDescription(ctx.locale("cmd.autoplay.messages.enabled")).setColor(this.client.color.main); } + + await ctx.sendMessage({ embeds: [embed] }); + } } /** diff --git a/src/commands/music/ClearQueue.ts b/src/commands/music/ClearQueue.ts index 3087c0f82..c0419ce24 100644 --- a/src/commands/music/ClearQueue.ts +++ b/src/commands/music/ClearQueue.ts @@ -1,56 +1,56 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class ClearQueue extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "clearqueue", - description: { - content: "cmd.clearqueue.description", - examples: ["clearqueue"], - usage: "clearqueue", - }, - category: "music", - aliases: ["cq"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } - - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const embed = this.client.embed(); + constructor(client: Lavamusic) { + super(client, { + name: "clearqueue", + description: { + content: "cmd.clearqueue.description", + examples: ["clearqueue"], + usage: "clearqueue", + }, + category: "music", + aliases: ["cq"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - if (!player) { - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("player.errors.no_player"))], - }); - } + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const embed = this.client.embed(); - if (player.queue.length === 0) { - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("player.errors.no_song"))], - }); - } + if (!player) { + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("player.errors.no_player"))], + }); + } - player.queue = []; - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.main).setDescription(ctx.locale("cmd.clearqueue.messages.cleared"))], - }); + if (player.queue.length === 0) { + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("player.errors.no_song"))], + }); } + + player.queue = []; + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.main).setDescription(ctx.locale("cmd.clearqueue.messages.cleared"))], + }); + } } /** diff --git a/src/commands/music/Grab.ts b/src/commands/music/Grab.ts index ee91ab13a..28e1b87c2 100644 --- a/src/commands/music/Grab.ts +++ b/src/commands/music/Grab.ts @@ -1,78 +1,78 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Grab extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "grab", - description: { - content: "cmd.grab.description", - examples: ["grab"], - usage: "grab", - }, - category: "music", - aliases: ["gr"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: false, - dj: false, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "grab", + description: { + content: "cmd.grab.description", + examples: ["grab"], + usage: "grab", + }, + category: "music", + aliases: ["gr"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: false, + dj: false, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); - await ctx.sendDeferMessage(ctx.locale("cmd.grab.loading")); + await ctx.sendDeferMessage(ctx.locale("cmd.grab.loading")); - if (!player?.current) { - return await ctx.sendMessage({ - embeds: [this.client.embed().setColor(this.client.color.red).setDescription(ctx.locale("player.errors.no_song"))], - }); - } + if (!player?.current) { + return await ctx.sendMessage({ + embeds: [this.client.embed().setColor(this.client.color.red).setDescription(ctx.locale("player.errors.no_song"))], + }); + } - const song = player.current; + const song = player.current; - const songInfo = ctx.locale("cmd.grab.content", { - title: song.info.title, - uri: song.info.uri, - artworkUrl: song.info.artworkUrl, - length: song.info.isStream ? "LIVE" : client.utils.formatTime(song.info.length), - requester: song.info.requester, - }); + const songInfo = ctx.locale("cmd.grab.content", { + title: song.info.title, + uri: song.info.uri, + artworkUrl: song.info.artworkUrl, + length: song.info.isStream ? "LIVE" : client.utils.formatTime(song.info.length), + requester: song.info.requester, + }); - try { - await ctx.author?.send({ - embeds: [ - this.client - .embed() - .setTitle(`**${song.info.title}**`) - .setURL(song.info.uri!) - .setThumbnail(song.info.artworkUrl!) - .setDescription(songInfo) - .setColor(this.client.color.main), - ], - }); + try { + await ctx.author?.send({ + embeds: [ + this.client + .embed() + .setTitle(`**${song.info.title}**`) + .setURL(song.info.uri!) + .setThumbnail(song.info.artworkUrl!) + .setDescription(songInfo) + .setColor(this.client.color.main), + ], + }); - return await ctx.editMessage({ - embeds: [this.client.embed().setDescription(ctx.locale("cmd.grab.check_dm")).setColor(this.client.color.green)], - }); - } catch (_e) { - return await ctx.editMessage({ - embeds: [this.client.embed().setDescription(ctx.locale("cmd.grab.dm_failed")).setColor(this.client.color.red)], - }); - } + return await ctx.editMessage({ + embeds: [this.client.embed().setDescription(ctx.locale("cmd.grab.check_dm")).setColor(this.client.color.green)], + }); + } catch (_e) { + return await ctx.editMessage({ + embeds: [this.client.embed().setDescription(ctx.locale("cmd.grab.dm_failed")).setColor(this.client.color.red)], + }); } + } } /** diff --git a/src/commands/music/Join.ts b/src/commands/music/Join.ts index 7f2eab587..1e21789a9 100644 --- a/src/commands/music/Join.ts +++ b/src/commands/music/Join.ts @@ -1,77 +1,77 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Join extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "join", - description: { - content: "cmd.join.description", - examples: ["join"], - usage: "join", - }, - category: "music", - aliases: ["come", "j"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks", "Connect", "Speak"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "join", + description: { + content: "cmd.join.description", + examples: ["join"], + usage: "join", + }, + category: "music", + aliases: ["come", "j"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks", "Connect", "Speak"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const embed = this.client.embed(); - let player = client.queue.get(ctx.guild!.id); + public async run(client: Lavamusic, ctx: Context): Promise { + const embed = this.client.embed(); + let player = client.queue.get(ctx.guild!.id); - if (player) { - const channelId = player.node.manager.connections.get(ctx.guild!.id)!.channelId; - return await ctx.sendMessage({ - embeds: [ - embed.setColor(this.client.color.main).setDescription( - ctx.locale("cmd.join.already_connected", { - channelId, - }), - ), - ], - }); - } + if (player) { + const channelId = player.node.manager.connections.get(ctx.guild!.id)!.channelId; + return await ctx.sendMessage({ + embeds: [ + embed.setColor(this.client.color.main).setDescription( + ctx.locale("cmd.join.already_connected", { + channelId, + }), + ), + ], + }); + } - const memberVoiceChannel = (ctx.member as any).voice.channel; - if (!memberVoiceChannel) { - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.join.no_voice_channel"))], - }); - } + const memberVoiceChannel = (ctx.member as any).voice.channel; + if (!memberVoiceChannel) { + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.join.no_voice_channel"))], + }); + } - player = await client.queue.create( - ctx.guild!, - memberVoiceChannel, - ctx.channel, - client.shoukaku.options.nodeResolver(client.shoukaku.nodes), - ); + player = await client.queue.create( + ctx.guild!, + memberVoiceChannel, + ctx.channel, + client.shoukaku.options.nodeResolver(client.shoukaku.nodes), + ); - const joinedChannelId = player.node.manager.connections.get(ctx.guild!.id)!.channelId; - return await ctx.sendMessage({ - embeds: [ - embed.setColor(this.client.color.main).setDescription( - ctx.locale("cmd.join.joined", { - channelId: joinedChannelId, - }), - ), - ], - }); - } + const joinedChannelId = player.node.manager.connections.get(ctx.guild!.id)!.channelId; + return await ctx.sendMessage({ + embeds: [ + embed.setColor(this.client.color.main).setDescription( + ctx.locale("cmd.join.joined", { + channelId: joinedChannelId, + }), + ), + ], + }); + } } /** diff --git a/src/commands/music/Leave.ts b/src/commands/music/Leave.ts index 8673a86a8..2a761bb0b 100644 --- a/src/commands/music/Leave.ts +++ b/src/commands/music/Leave.ts @@ -1,50 +1,50 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Leave extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "leave", - description: { - content: "cmd.leave.description", - examples: ["leave"], - usage: "leave", - }, - category: "music", - aliases: ["l"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: true, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "leave", + description: { + content: "cmd.leave.description", + examples: ["leave"], + usage: "leave", + }, + category: "music", + aliases: ["l"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: true, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const embed = this.client.embed(); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const embed = this.client.embed(); - if (player) { - const channelId = player.node.manager.connections.get(ctx.guild!.id)!.channelId; - player.destroy(); - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.main).setDescription(ctx.locale("cmd.leave.left", { channelId }))], - }); - } - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.leave.not_in_channel"))], - }); + if (player) { + const channelId = player.node.manager.connections.get(ctx.guild!.id)!.channelId; + player.destroy(); + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.main).setDescription(ctx.locale("cmd.leave.left", { channelId }))], + }); } + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.leave.not_in_channel"))], + }); + } } /** diff --git a/src/commands/music/Loop.ts b/src/commands/music/Loop.ts index f4b090424..84cf35429 100644 --- a/src/commands/music/Loop.ts +++ b/src/commands/music/Loop.ts @@ -1,59 +1,59 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Loop extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "loop", - description: { - content: "cmd.loop.description", - examples: ["loop", "loop queue", "loop song"], - usage: "loop", - }, - category: "general", - aliases: ["loop"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: false, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } - - public async run(client: Lavamusic, ctx: Context): Promise { - const embed = this.client.embed().setColor(this.client.color.main); - const player = client.queue.get(ctx.guild!.id); - let loopMessage = ""; + constructor(client: Lavamusic) { + super(client, { + name: "loop", + description: { + content: "cmd.loop.description", + examples: ["loop", "loop queue", "loop song"], + usage: "loop", + }, + category: "general", + aliases: ["loop"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: false, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - switch (player?.loop) { - case "off": - player.loop = "repeat"; - loopMessage = ctx.locale("cmd.loop.looping_song"); - break; - case "repeat": - player.loop = "queue"; - loopMessage = ctx.locale("cmd.loop.looping_queue"); - break; - case "queue": - player.loop = "off"; - loopMessage = ctx.locale("cmd.loop.looping_off"); - break; - } + public async run(client: Lavamusic, ctx: Context): Promise { + const embed = this.client.embed().setColor(this.client.color.main); + const player = client.queue.get(ctx.guild!.id); + let loopMessage = ""; - return await ctx.sendMessage({ - embeds: [embed.setDescription(loopMessage)], - }); + switch (player?.loop) { + case "off": + player.loop = "repeat"; + loopMessage = ctx.locale("cmd.loop.looping_song"); + break; + case "repeat": + player.loop = "queue"; + loopMessage = ctx.locale("cmd.loop.looping_queue"); + break; + case "queue": + player.loop = "off"; + loopMessage = ctx.locale("cmd.loop.looping_off"); + break; } + + return await ctx.sendMessage({ + embeds: [embed.setDescription(loopMessage)], + }); + } } /** diff --git a/src/commands/music/Nowplaying.ts b/src/commands/music/Nowplaying.ts index 55766cceb..fcbf5f6cc 100644 --- a/src/commands/music/Nowplaying.ts +++ b/src/commands/music/Nowplaying.ts @@ -1,65 +1,65 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Nowplaying extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "nowplaying", - description: { - content: "cmd.nowplaying.description", - examples: ["nowplaying"], - usage: "nowplaying", - }, - category: "music", - aliases: ["np"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: false, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "nowplaying", + description: { + content: "cmd.nowplaying.description", + examples: ["nowplaying"], + usage: "nowplaying", + }, + category: "music", + aliases: ["np"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: false, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id)!; - const track = player.current!; - const position = player.player.position; - const duration = track.info.length; - const bar = client.utils.progressBar(position, duration, 20); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id)!; + const track = player.current!; + const position = player.player.position; + const duration = track.info.length; + const bar = client.utils.progressBar(position, duration, 20); - const embed = this.client - .embed() - .setColor(this.client.color.main) - .setAuthor({ - name: ctx.locale("cmd.nowplaying.now_playing"), - iconURL: ctx.guild?.iconURL({})!, - }) - .setThumbnail(track.info.artworkUrl!) - .setDescription( - ctx.locale("cmd.nowplaying.track_info", { - title: track.info.title, - uri: track.info.uri, - requester: track.info.requester, - bar: bar, - }), - ) - .addFields({ - name: "\u200b", - value: `\`${client.utils.formatTime(position)} / ${client.utils.formatTime(duration)}\``, - }); + const embed = this.client + .embed() + .setColor(this.client.color.main) + .setAuthor({ + name: ctx.locale("cmd.nowplaying.now_playing"), + iconURL: ctx.guild?.iconURL({})!, + }) + .setThumbnail(track.info.artworkUrl!) + .setDescription( + ctx.locale("cmd.nowplaying.track_info", { + title: track.info.title, + uri: track.info.uri, + requester: track.info.requester, + bar: bar, + }), + ) + .addFields({ + name: "\u200b", + value: `\`${client.utils.formatTime(position)} / ${client.utils.formatTime(duration)}\``, + }); - return await ctx.sendMessage({ embeds: [embed] }); - } + return await ctx.sendMessage({ embeds: [embed] }); + } } /** diff --git a/src/commands/music/Pause.ts b/src/commands/music/Pause.ts index 48923906b..5107ede0b 100644 --- a/src/commands/music/Pause.ts +++ b/src/commands/music/Pause.ts @@ -1,51 +1,51 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Pause extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "pause", - description: { - content: "cmd.pause.description", - examples: ["pause"], - usage: "pause", - }, - category: "music", - aliases: ["pu"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: false, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "pause", + description: { + content: "cmd.pause.description", + examples: ["pause"], + usage: "pause", + }, + category: "music", + aliases: ["pu"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: false, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const embed = this.client.embed(); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const embed = this.client.embed(); - if (player?.paused) { - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("player.errors.already_paused"))], - }); - } + if (player?.paused) { + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("player.errors.already_paused"))], + }); + } - player?.pause(); + player?.pause(); - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.main).setDescription(ctx.locale("cmd.pause.successfully_paused"))], - }); - } + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.main).setDescription(ctx.locale("cmd.pause.successfully_paused"))], + }); + } } /** diff --git a/src/commands/music/Play.ts b/src/commands/music/Play.ts index fbf56afc3..4e6a5f4de 100644 --- a/src/commands/music/Play.ts +++ b/src/commands/music/Play.ts @@ -3,187 +3,181 @@ import { LoadType } from "shoukaku"; import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Play extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "play", - description: { - content: "cmd.play.description", - examples: [ - "play example", - "play https://www.youtube.com/watch?v=example", - "play https://open.spotify.com/track/example", - "play http://www.example.com/example.mp3", - ], - usage: "play ", - }, - category: "music", - aliases: ["p"], - cooldown: 3, - args: true, - vote: false, - player: { - voice: true, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks", "Connect", "Speak"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "song", - description: "cmd.play.options.song", - type: 3, - required: true, - autocomplete: true, - }, - ], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "play", + description: { + content: "cmd.play.description", + examples: [ + "play example", + "play https://www.youtube.com/watch?v=example", + "play https://open.spotify.com/track/example", + "play http://www.example.com/example.mp3", + ], + usage: "play ", + }, + category: "music", + aliases: ["p"], + cooldown: 3, + args: true, + vote: false, + player: { + voice: true, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks", "Connect", "Speak"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "song", + description: "cmd.play.options.song", + type: 3, + required: true, + autocomplete: true, + }, + ], + }); + } - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const query = args.join(" "); - await ctx.sendDeferMessage(ctx.locale("cmd.play.loading")); - let player = client.queue.get(ctx.guild!.id); - const vc = ctx.member as any; - if (!player) player = await client.queue.create(ctx.guild, vc.voice.channel, ctx.channel); + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const query = args.join(" "); + await ctx.sendDeferMessage(ctx.locale("cmd.play.loading")); + let player = client.queue.get(ctx.guild!.id); + const vc = ctx.member as any; + if (!player) player = await client.queue.create(ctx.guild, vc.voice.channel, ctx.channel); - const res = await this.client.queue.search(query); - const embed = this.client.embed(); + const res = await this.client.queue.search(query); + const embed = this.client.embed(); - switch (res.loadType) { - case LoadType.ERROR: - await ctx.editMessage({ - content: "", - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.play.errors.search_error"))], - }); - break; - case LoadType.EMPTY: - await ctx.editMessage({ - content: "", - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.play.errors.no_results"))], - }); - break; - case LoadType.TRACK: { - const track = player.buildTrack(res.data, ctx.author); - if (player.queue.length > client.config.maxQueueSize) - return await ctx.editMessage({ - content: "", - embeds: [ - embed - .setColor(this.client.color.red) - .setDescription(ctx.locale("cmd.play.errors.queue_too_long", { maxQueueSize: client.config.maxQueueSize })), - ], - }); - player.queue.push(track); - await player.isPlaying(); - await ctx.editMessage({ - content: "", - embeds: [ - embed - .setColor(this.client.color.main) - .setDescription(ctx.locale("cmd.play.added_to_queue", { title: res.data.info.title, uri: res.data.info.uri })), - ], - }); - break; - } - case LoadType.PLAYLIST: { - if (res.data.tracks.length > client.config.maxPlaylistSize) - return await ctx.editMessage({ - content: "", - embeds: [ - embed - .setColor(this.client.color.red) - .setDescription( - ctx.locale("cmd.play.errors.playlist_too_long", { maxPlaylistSize: client.config.maxPlaylistSize }), - ), - ], - }); - for (const track of res.data.tracks) { - const pl = player.buildTrack(track, ctx.author); - if (player.queue.length > client.config.maxQueueSize) - return await ctx.editMessage({ - content: "", - embeds: [ - embed - .setColor(this.client.color.red) - .setDescription( - ctx.locale("cmd.play.errors.queue_too_long", { maxQueueSize: client.config.maxQueueSize }), - ), - ], - }); - player.queue.push(pl); - } - await player.isPlaying(); - await ctx.editMessage({ - content: "", - embeds: [ - embed - .setColor(this.client.color.main) - .setDescription(ctx.locale("cmd.play.added_playlist_to_queue", { length: res.data.tracks.length })), - ], - }); - break; - } - case LoadType.SEARCH: { - const track1 = player.buildTrack(res.data[0], ctx.author); - if (player.queue.length > client.config.maxQueueSize) - return await ctx.editMessage({ - content: "", - embeds: [ - embed - .setColor(this.client.color.red) - .setDescription(ctx.locale("cmd.play.errors.queue_too_long", { maxQueueSize: client.config.maxQueueSize })), - ], - }); - player.queue.push(track1); - await player.isPlaying(); - await ctx.editMessage({ - content: "", - embeds: [ - embed - .setColor(this.client.color.main) - .setDescription( - ctx.locale("cmd.play.added_to_queue", { title: res.data[0].info.title, uri: res.data[0].info.uri }), - ), - ], - }); - break; - } + switch (res.loadType) { + case LoadType.ERROR: + await ctx.editMessage({ + content: "", + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.play.errors.search_error"))], + }); + break; + case LoadType.EMPTY: + await ctx.editMessage({ + content: "", + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.play.errors.no_results"))], + }); + break; + case LoadType.TRACK: { + const track = player.buildTrack(res.data, ctx.author); + if (player.queue.length > client.config.maxQueueSize) + return await ctx.editMessage({ + content: "", + embeds: [ + embed + .setColor(this.client.color.red) + .setDescription(ctx.locale("cmd.play.errors.queue_too_long", { maxQueueSize: client.config.maxQueueSize })), + ], + }); + player.queue.push(track); + await player.isPlaying(); + await ctx.editMessage({ + content: "", + embeds: [ + embed + .setColor(this.client.color.main) + .setDescription(ctx.locale("cmd.play.added_to_queue", { title: res.data.info.title, uri: res.data.info.uri })), + ], + }); + break; + } + case LoadType.PLAYLIST: { + if (res.data.tracks.length > client.config.maxPlaylistSize) + return await ctx.editMessage({ + content: "", + embeds: [ + embed + .setColor(this.client.color.red) + .setDescription(ctx.locale("cmd.play.errors.playlist_too_long", { maxPlaylistSize: client.config.maxPlaylistSize })), + ], + }); + for (const track of res.data.tracks) { + const pl = player.buildTrack(track, ctx.author); + if (player.queue.length > client.config.maxQueueSize) + return await ctx.editMessage({ + content: "", + embeds: [ + embed + .setColor(this.client.color.red) + .setDescription(ctx.locale("cmd.play.errors.queue_too_long", { maxQueueSize: client.config.maxQueueSize })), + ], + }); + player.queue.push(pl); } + await player.isPlaying(); + await ctx.editMessage({ + content: "", + embeds: [ + embed + .setColor(this.client.color.main) + .setDescription(ctx.locale("cmd.play.added_playlist_to_queue", { length: res.data.tracks.length })), + ], + }); + break; + } + case LoadType.SEARCH: { + const track1 = player.buildTrack(res.data[0], ctx.author); + if (player.queue.length > client.config.maxQueueSize) + return await ctx.editMessage({ + content: "", + embeds: [ + embed + .setColor(this.client.color.red) + .setDescription(ctx.locale("cmd.play.errors.queue_too_long", { maxQueueSize: client.config.maxQueueSize })), + ], + }); + player.queue.push(track1); + await player.isPlaying(); + await ctx.editMessage({ + content: "", + embeds: [ + embed + .setColor(this.client.color.main) + .setDescription(ctx.locale("cmd.play.added_to_queue", { title: res.data[0].info.title, uri: res.data[0].info.uri })), + ], + }); + break; + } } - public async autocomplete(interaction: AutocompleteInteraction): Promise { - const focusedValue = interaction.options.getFocused(); - - const res = await this.client.queue.search(focusedValue); - const songs = []; + } + public async autocomplete(interaction: AutocompleteInteraction): Promise { + const focusedValue = interaction.options.getFocused(); - if (res?.loadType) { - if (res.loadType === LoadType.SEARCH && res.data.length) { - res.data.slice(0, 10).forEach((track) => { - const name = `${track.info.title} by ${track.info.author}`; - songs.push({ - name: name.length > 100 ? `${name.substring(0, 97)}...` : name, - value: track.info.uri, - }); - }); - } else if (res.loadType === LoadType.PLAYLIST && res.data.tracks.length) { - res.data.tracks.slice(0, 10).forEach((track) => { - const name = `${track.info.title} by ${track.info.author}`; - songs.push({ - name: name.length > 100 ? `${name.substring(0, 97)}...` : name, - value: track.info.uri, - }); - }); - } - } + const res = await this.client.queue.search(focusedValue); + const songs = []; - return await interaction.respond(songs).catch(console.error); + if (res?.loadType) { + if (res.loadType === LoadType.SEARCH && res.data.length) { + res.data.slice(0, 10).forEach((track) => { + const name = `${track.info.title} by ${track.info.author}`; + songs.push({ + name: name.length > 100 ? `${name.substring(0, 97)}...` : name, + value: track.info.uri, + }); + }); + } else if (res.loadType === LoadType.PLAYLIST && res.data.tracks.length) { + res.data.tracks.slice(0, 10).forEach((track) => { + const name = `${track.info.title} by ${track.info.author}`; + songs.push({ + name: name.length > 100 ? `${name.substring(0, 97)}...` : name, + value: track.info.uri, + }); + }); + } } + + return await interaction.respond(songs).catch(console.error); + } } /** diff --git a/src/commands/music/PlayNext.ts b/src/commands/music/PlayNext.ts index 6d0a9c83d..8c73455cb 100644 --- a/src/commands/music/PlayNext.ts +++ b/src/commands/music/PlayNext.ts @@ -3,185 +3,173 @@ import { LoadType } from "shoukaku"; import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class PlayNext extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "playnext", - description: { - content: "cmd.playnext.description", - examples: [ - "playnext example", - "playnext https://www.youtube.com/watch?v=example", - "playnext https://open.spotify.com/track/example", - "playnext http://www.example.com/example.mp3", - ], - usage: "playnext ", - }, - category: "music", - aliases: ["pn"], - cooldown: 3, - args: true, - vote: false, - player: { - voice: true, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks", "Connect", "Speak"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "song", - description: "cmd.playnext.options.song", - type: 3, - required: true, - autocomplete: true, - }, - ], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "playnext", + description: { + content: "cmd.playnext.description", + examples: [ + "playnext example", + "playnext https://www.youtube.com/watch?v=example", + "playnext https://open.spotify.com/track/example", + "playnext http://www.example.com/example.mp3", + ], + usage: "playnext ", + }, + category: "music", + aliases: ["pn"], + cooldown: 3, + args: true, + vote: false, + player: { + voice: true, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks", "Connect", "Speak"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "song", + description: "cmd.playnext.options.song", + type: 3, + required: true, + autocomplete: true, + }, + ], + }); + } - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const query = args.join(" "); - let player = client.queue.get(ctx.guild!.id); - const vc = ctx.member as any; - if (!player) player = await client.queue.create(ctx.guild, vc.voice.channel, ctx.channel); + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const query = args.join(" "); + let player = client.queue.get(ctx.guild!.id); + const vc = ctx.member as any; + if (!player) player = await client.queue.create(ctx.guild, vc.voice.channel, ctx.channel); - await ctx.sendDeferMessage(ctx.locale("cmd.playnext.loading")); - const res = await this.client.queue.search(query); - const embed = this.client.embed(); - switch (res.loadType) { - case LoadType.ERROR: - await ctx.editMessage({ - content: "", - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.playnext.errors.search_error"))], - }); - break; - case LoadType.EMPTY: - await ctx.editMessage({ - content: "", - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.playnext.errors.no_results"))], - }); - break; - case LoadType.TRACK: { - const track = player.buildTrack(res.data, ctx.author); - if (player.queue.length > client.config.maxQueueSize) - return await ctx.editMessage({ - content: "", - embeds: [ - embed - .setColor(this.client.color.red) - .setDescription( - ctx.locale("cmd.playnext.errors.queue_too_long", { maxQueueSize: client.config.maxQueueSize }), - ), - ], - }); - player.queue.splice(0, 0, track); - await player.isPlaying(); - await ctx.editMessage({ - content: "", - embeds: [ - embed - .setColor(this.client.color.main) - .setDescription( - ctx.locale("cmd.playnext.added_to_play_next", { title: res.data.info.title, uri: res.data.info.uri }), - ), - ], - }); - break; - } - case LoadType.PLAYLIST: { - if (res.data.tracks.length > client.config.maxPlaylistSize) - return await ctx.editMessage({ - content: "", - embeds: [ - embed - .setColor(this.client.color.red) - .setDescription( - ctx.locale("cmd.playnext.errors.playlist_too_long", { maxPlaylistSize: client.config.maxPlaylistSize }), - ), - ], - }); - for (const track of res.data.tracks) { - const pl = player.buildTrack(track, ctx.author); - if (player.queue.length > client.config.maxQueueSize) - return await ctx.editMessage({ - content: "", - embeds: [ - embed - .setColor(this.client.color.red) - .setDescription( - ctx.locale("cmd.playnext.errors.queue_too_long", { maxQueueSize: client.config.maxQueueSize }), - ), - ], - }); - player.queue.splice(0, 0, pl); - } - await player.isPlaying(); - await ctx.editMessage({ - content: "", - embeds: [ - embed - .setColor(this.client.color.main) - .setDescription(ctx.locale("cmd.playnext.added_playlist_to_play_next", { length: res.data.tracks.length })), - ], - }); - break; - } - case LoadType.SEARCH: { - const track1 = player.buildTrack(res.data[0], ctx.author); - if (player.queue.length > client.config.maxQueueSize) - return await ctx.editMessage({ - content: "", - embeds: [ - embed - .setColor(this.client.color.red) - .setDescription( - ctx.locale("cmd.playnext.errors.queue_too_long", { maxQueueSize: client.config.maxQueueSize }), - ), - ], - }); - player.queue.splice(0, 0, track1); - await player.isPlaying(); - await ctx.editMessage({ - content: "", - embeds: [ - embed - .setColor(this.client.color.main) - .setDescription( - ctx.locale("cmd.playnext.added_to_play_next", { title: res.data[0].info.title, uri: res.data[0].info.uri }), - ), - ], - }); - break; - } + await ctx.sendDeferMessage(ctx.locale("cmd.playnext.loading")); + const res = await this.client.queue.search(query); + const embed = this.client.embed(); + switch (res.loadType) { + case LoadType.ERROR: + await ctx.editMessage({ + content: "", + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.playnext.errors.search_error"))], + }); + break; + case LoadType.EMPTY: + await ctx.editMessage({ + content: "", + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.playnext.errors.no_results"))], + }); + break; + case LoadType.TRACK: { + const track = player.buildTrack(res.data, ctx.author); + if (player.queue.length > client.config.maxQueueSize) + return await ctx.editMessage({ + content: "", + embeds: [ + embed + .setColor(this.client.color.red) + .setDescription(ctx.locale("cmd.playnext.errors.queue_too_long", { maxQueueSize: client.config.maxQueueSize })), + ], + }); + player.queue.splice(0, 0, track); + await player.isPlaying(); + await ctx.editMessage({ + content: "", + embeds: [ + embed + .setColor(this.client.color.main) + .setDescription(ctx.locale("cmd.playnext.added_to_play_next", { title: res.data.info.title, uri: res.data.info.uri })), + ], + }); + break; + } + case LoadType.PLAYLIST: { + if (res.data.tracks.length > client.config.maxPlaylistSize) + return await ctx.editMessage({ + content: "", + embeds: [ + embed + .setColor(this.client.color.red) + .setDescription(ctx.locale("cmd.playnext.errors.playlist_too_long", { maxPlaylistSize: client.config.maxPlaylistSize })), + ], + }); + for (const track of res.data.tracks) { + const pl = player.buildTrack(track, ctx.author); + if (player.queue.length > client.config.maxQueueSize) + return await ctx.editMessage({ + content: "", + embeds: [ + embed + .setColor(this.client.color.red) + .setDescription(ctx.locale("cmd.playnext.errors.queue_too_long", { maxQueueSize: client.config.maxQueueSize })), + ], + }); + player.queue.splice(0, 0, pl); } + await player.isPlaying(); + await ctx.editMessage({ + content: "", + embeds: [ + embed + .setColor(this.client.color.main) + .setDescription(ctx.locale("cmd.playnext.added_playlist_to_play_next", { length: res.data.tracks.length })), + ], + }); + break; + } + case LoadType.SEARCH: { + const track1 = player.buildTrack(res.data[0], ctx.author); + if (player.queue.length > client.config.maxQueueSize) + return await ctx.editMessage({ + content: "", + embeds: [ + embed + .setColor(this.client.color.red) + .setDescription(ctx.locale("cmd.playnext.errors.queue_too_long", { maxQueueSize: client.config.maxQueueSize })), + ], + }); + player.queue.splice(0, 0, track1); + await player.isPlaying(); + await ctx.editMessage({ + content: "", + embeds: [ + embed + .setColor(this.client.color.main) + .setDescription(ctx.locale("cmd.playnext.added_to_play_next", { title: res.data[0].info.title, uri: res.data[0].info.uri })), + ], + }); + break; + } } - public async autocomplete(interaction: AutocompleteInteraction): Promise { - const focusedValue = interaction.options.getFocused(); + } + public async autocomplete(interaction: AutocompleteInteraction): Promise { + const focusedValue = interaction.options.getFocused(); - const res = await this.client.queue.search(focusedValue); - const songs = []; + const res = await this.client.queue.search(focusedValue); + const songs = []; - if (res.loadType === LoadType.SEARCH && res.data.length) { - res.data.slice(0, 10).forEach((x) => { - let name = `${x.info.title} by ${x.info.author}`; - if (name.length > 100) { - name = `${name.substring(0, 97)}...`; - } - songs.push({ - name: name, - value: x.info.uri, - }); - }); + if (res.loadType === LoadType.SEARCH && res.data.length) { + res.data.slice(0, 10).forEach((x) => { + let name = `${x.info.title} by ${x.info.author}`; + if (name.length > 100) { + name = `${name.substring(0, 97)}...`; } - - return await interaction.respond(songs).catch(console.error); + songs.push({ + name: name, + value: x.info.uri, + }); + }); } + + return await interaction.respond(songs).catch(console.error); + } } /** diff --git a/src/commands/music/Queue.ts b/src/commands/music/Queue.ts index a6707fcc7..3fe7c4a04 100644 --- a/src/commands/music/Queue.ts +++ b/src/commands/music/Queue.ts @@ -1,89 +1,87 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Queue extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "queue", - description: { - content: "cmd.queue.description", - examples: ["queue"], - usage: "queue", - }, - category: "music", - aliases: ["q"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: false, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "queue", + description: { + content: "cmd.queue.description", + examples: ["queue"], + usage: "queue", + }, + category: "music", + aliases: ["q"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: false, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const embed = this.client.embed(); - if (player.queue.length === 0) { - return await ctx.sendMessage({ - embeds: [ - embed.setColor(this.client.color.main).setDescription( - ctx.locale("cmd.queue.now_playing", { - title: player.current.info.title, - uri: player.current.info.uri, - requester: player.current?.info.requester, - duration: player.current.info.isStream - ? ctx.locale("cmd.queue.live") - : client.utils.formatTime(player.current.info.length), - }), - ), - ], - }); - } - const songStrings = []; - for (let i = 0; i < player.queue.length; i++) { - const track = player.queue[i]; - songStrings.push( - ctx.locale("cmd.queue.track_info", { - index: i + 1, - title: track.info.title, - uri: track.info.uri, - requester: track?.info.requester, - duration: track.info.isStream ? ctx.locale("cmd.queue.live") : client.utils.formatTime(track.info.length), - }), - ); - } - let chunks = client.utils.chunk(songStrings, 10); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const embed = this.client.embed(); + if (player.queue.length === 0) { + return await ctx.sendMessage({ + embeds: [ + embed.setColor(this.client.color.main).setDescription( + ctx.locale("cmd.queue.now_playing", { + title: player.current.info.title, + uri: player.current.info.uri, + requester: player.current?.info.requester, + duration: player.current.info.isStream ? ctx.locale("cmd.queue.live") : client.utils.formatTime(player.current.info.length), + }), + ), + ], + }); + } + const songStrings = []; + for (let i = 0; i < player.queue.length; i++) { + const track = player.queue[i]; + songStrings.push( + ctx.locale("cmd.queue.track_info", { + index: i + 1, + title: track.info.title, + uri: track.info.uri, + requester: track?.info.requester, + duration: track.info.isStream ? ctx.locale("cmd.queue.live") : client.utils.formatTime(track.info.length), + }), + ); + } + let chunks = client.utils.chunk(songStrings, 10); - if (chunks.length === 0) chunks = [songStrings]; + if (chunks.length === 0) chunks = [songStrings]; - const pages = chunks.map((chunk, index) => { - return this.client - .embed() - .setColor(this.client.color.main) - .setAuthor({ - name: ctx.locale("cmd.queue.title"), - iconURL: ctx.guild.iconURL({}), - }) - .setDescription(chunk.join("\n")) - .setFooter({ - text: ctx.locale("cmd.queue.page_info", { - index: index + 1, - total: chunks.length, - }), - }); + const pages = chunks.map((chunk, index) => { + return this.client + .embed() + .setColor(this.client.color.main) + .setAuthor({ + name: ctx.locale("cmd.queue.title"), + iconURL: ctx.guild.iconURL({}), + }) + .setDescription(chunk.join("\n")) + .setFooter({ + text: ctx.locale("cmd.queue.page_info", { + index: index + 1, + total: chunks.length, + }), }); - return await client.utils.paginate(client, ctx, pages); - } + }); + return await client.utils.paginate(client, ctx, pages); + } } /** diff --git a/src/commands/music/Remove.ts b/src/commands/music/Remove.ts index 5b1f60567..b18bbe0ec 100644 --- a/src/commands/music/Remove.ts +++ b/src/commands/music/Remove.ts @@ -1,68 +1,68 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Remove extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "remove", - description: { - content: "cmd.remove.description", - examples: ["remove 1"], - usage: "remove ", - }, - category: "music", - aliases: ["rm"], - cooldown: 3, - args: true, - vote: false, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "song", - description: "cmd.remove.options.song", - type: 4, - required: true, - }, - ], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "remove", + description: { + content: "cmd.remove.description", + examples: ["remove 1"], + usage: "remove ", + }, + category: "music", + aliases: ["rm"], + cooldown: 3, + args: true, + vote: false, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "song", + description: "cmd.remove.options.song", + type: 4, + required: true, + }, + ], + }); + } - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const player = client.queue.get(ctx.guild!.id); - const embed = this.client.embed(); + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const player = client.queue.get(ctx.guild!.id); + const embed = this.client.embed(); - if (!player.queue.length) - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.remove.errors.no_songs"))], - }); + if (!player.queue.length) + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.remove.errors.no_songs"))], + }); - const songNumber = Number(args[0]); - if (isNaN(songNumber) || songNumber <= 0 || songNumber > player.queue.length) - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.remove.errors.invalid_number"))], - }); + const songNumber = Number(args[0]); + if (isNaN(songNumber) || songNumber <= 0 || songNumber > player.queue.length) + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.remove.errors.invalid_number"))], + }); - player.remove(songNumber - 1); - return await ctx.sendMessage({ - embeds: [ - embed.setColor(this.client.color.main).setDescription( - ctx.locale("cmd.remove.messages.removed", { - songNumber, - }), - ), - ], - }); - } + player.remove(songNumber - 1); + return await ctx.sendMessage({ + embeds: [ + embed.setColor(this.client.color.main).setDescription( + ctx.locale("cmd.remove.messages.removed", { + songNumber, + }), + ), + ], + }); + } } /** diff --git a/src/commands/music/Replay.ts b/src/commands/music/Replay.ts index d1a32907d..1e72a4b10 100644 --- a/src/commands/music/Replay.ts +++ b/src/commands/music/Replay.ts @@ -1,50 +1,50 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Replay extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "replay", - description: { - content: "cmd.replay.description", - examples: ["replay"], - usage: "replay", - }, - category: "music", - aliases: ["rp"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: false, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } - - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const embed = this.client.embed(); + constructor(client: Lavamusic) { + super(client, { + name: "replay", + description: { + content: "cmd.replay.description", + examples: ["replay"], + usage: "replay", + }, + category: "music", + aliases: ["rp"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: false, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - if (!player.current?.info.isSeekable) { - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.replay.errors.not_seekable"))], - }); - } + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const embed = this.client.embed(); - player.seek(0); - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.main).setDescription(ctx.locale("cmd.replay.messages.replaying"))], - }); + if (!player.current?.info.isSeekable) { + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.replay.errors.not_seekable"))], + }); } + + player.seek(0); + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.main).setDescription(ctx.locale("cmd.replay.messages.replaying"))], + }); + } } /** diff --git a/src/commands/music/Resume.ts b/src/commands/music/Resume.ts index d55eddfa5..f8128d439 100644 --- a/src/commands/music/Resume.ts +++ b/src/commands/music/Resume.ts @@ -1,50 +1,50 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Resume extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "resume", - description: { - content: "cmd.resume.description", - examples: ["resume"], - usage: "resume", - }, - category: "music", - aliases: ["r"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: false, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } - - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const embed = this.client.embed(); + constructor(client: Lavamusic) { + super(client, { + name: "resume", + description: { + content: "cmd.resume.description", + examples: ["resume"], + usage: "resume", + }, + category: "music", + aliases: ["r"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: false, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - if (!player.paused) { - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.resume.errors.not_paused"))], - }); - } + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const embed = this.client.embed(); - player.pause(); - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.main).setDescription(ctx.locale("cmd.resume.messages.resumed"))], - }); + if (!player.paused) { + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.resume.errors.not_paused"))], + }); } + + player.pause(); + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.main).setDescription(ctx.locale("cmd.resume.messages.resumed"))], + }); + } } /** diff --git a/src/commands/music/Search.ts b/src/commands/music/Search.ts index a26412b72..eb1af762e 100644 --- a/src/commands/music/Search.ts +++ b/src/commands/music/Search.ts @@ -4,121 +4,121 @@ import type { Song } from "../../structures/Dispatcher.js"; import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Search extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "search", - description: { - content: "cmd.search.description", - examples: ["search example"], - usage: "search ", - }, - category: "music", - aliases: ["sc"], - cooldown: 3, - args: true, - vote: true, - player: { - voice: true, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "song", - description: "cmd.search.options.song", - type: 3, - required: true, - }, - ], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "search", + description: { + content: "cmd.search.description", + examples: ["search example"], + usage: "search ", + }, + category: "music", + aliases: ["sc"], + cooldown: 3, + args: true, + vote: true, + player: { + voice: true, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "song", + description: "cmd.search.options.song", + type: 3, + required: true, + }, + ], + }); + } - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const embed = this.client.embed().setColor(this.client.color.main); - let player = client.queue.get(ctx.guild!.id); - const query = args.join(" "); - if (!player) { - const vc = ctx.member as any; - player = await client.queue.create( - ctx.guild, - vc.voice.channel, - ctx.channel, - client.shoukaku.options.nodeResolver(client.shoukaku.nodes), - ); - } - const res = await this.client.queue.search(query); - if (!res) { - return await ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.search.errors.no_results")).setColor(this.client.color.red)], - }); - } - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder().setCustomId("1").setLabel("1").setStyle(ButtonStyle.Primary), - new ButtonBuilder().setCustomId("2").setLabel("2").setStyle(ButtonStyle.Primary), - new ButtonBuilder().setCustomId("3").setLabel("3").setStyle(ButtonStyle.Primary), - new ButtonBuilder().setCustomId("4").setLabel("4").setStyle(ButtonStyle.Primary), - new ButtonBuilder().setCustomId("5").setLabel("5").setStyle(ButtonStyle.Primary), - ); - switch (res.loadType) { - case LoadType.ERROR: - ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.search.errors.search_error"))], - }); - break; - case LoadType.EMPTY: - ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.search.errors.no_results"))], - }); - break; - case LoadType.SEARCH: { - const tracks = res.data.slice(0, 5); - const embeds = tracks.map( - (track: Song, index: number) => `${index + 1}. [${track.info.title}](${track.info.uri}) - \`${track.info.author}\``, - ); - await ctx.sendMessage({ - embeds: [embed.setDescription(embeds.join("\n"))], - components: [row], - }); - break; - } - } - const collector = ctx.channel.createMessageComponentCollector({ - filter: (f: any) => f.user.id === ctx.author.id, - max: 1, - time: 60000, - idle: 60000 / 2, + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const embed = this.client.embed().setColor(this.client.color.main); + let player = client.queue.get(ctx.guild!.id); + const query = args.join(" "); + if (!player) { + const vc = ctx.member as any; + player = await client.queue.create( + ctx.guild, + vc.voice.channel, + ctx.channel, + client.shoukaku.options.nodeResolver(client.shoukaku.nodes), + ); + } + const res = await this.client.queue.search(query); + if (!res) { + return await ctx.sendMessage({ + embeds: [embed.setDescription(ctx.locale("cmd.search.errors.no_results")).setColor(this.client.color.red)], + }); + } + const row = new ActionRowBuilder().addComponents( + new ButtonBuilder().setCustomId("1").setLabel("1").setStyle(ButtonStyle.Primary), + new ButtonBuilder().setCustomId("2").setLabel("2").setStyle(ButtonStyle.Primary), + new ButtonBuilder().setCustomId("3").setLabel("3").setStyle(ButtonStyle.Primary), + new ButtonBuilder().setCustomId("4").setLabel("4").setStyle(ButtonStyle.Primary), + new ButtonBuilder().setCustomId("5").setLabel("5").setStyle(ButtonStyle.Primary), + ); + switch (res.loadType) { + case LoadType.ERROR: + ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.search.errors.search_error"))], }); - collector.on("collect", async (int: any) => { - const track = res.data[parseInt(int.customId) - 1]; - await int.deferUpdate(); - if (!track) return; - const song = player.buildTrack(track, ctx.author); - player.queue.push(song); - player.isPlaying(); - await ctx.editMessage({ - embeds: [ - embed.setDescription( - ctx.locale("cmd.search.messages.added_to_queue", { - title: song.info.title, - uri: song.info.uri, - }), - ), - ], - components: [], - }); - return collector.stop(); + break; + case LoadType.EMPTY: + ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.search.errors.no_results"))], }); - collector.on("end", async () => { - await ctx.editMessage({ components: [] }); + break; + case LoadType.SEARCH: { + const tracks = res.data.slice(0, 5); + const embeds = tracks.map( + (track: Song, index: number) => `${index + 1}. [${track.info.title}](${track.info.uri}) - \`${track.info.author}\``, + ); + await ctx.sendMessage({ + embeds: [embed.setDescription(embeds.join("\n"))], + components: [row], }); + break; + } } + const collector = ctx.channel.createMessageComponentCollector({ + filter: (f: any) => f.user.id === ctx.author.id, + max: 1, + time: 60000, + idle: 60000 / 2, + }); + collector.on("collect", async (int: any) => { + const track = res.data[parseInt(int.customId) - 1]; + await int.deferUpdate(); + if (!track) return; + const song = player.buildTrack(track, ctx.author); + player.queue.push(song); + player.isPlaying(); + await ctx.editMessage({ + embeds: [ + embed.setDescription( + ctx.locale("cmd.search.messages.added_to_queue", { + title: song.info.title, + uri: song.info.uri, + }), + ), + ], + components: [], + }); + return collector.stop(); + }); + collector.on("end", async () => { + await ctx.editMessage({ components: [] }); + }); + } } /** diff --git a/src/commands/music/Seek.ts b/src/commands/music/Seek.ts index f17c21489..d771f9736 100644 --- a/src/commands/music/Seek.ts +++ b/src/commands/music/Seek.ts @@ -1,79 +1,79 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Seek extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "seek", - description: { - content: "cmd.seek.description", - examples: ["seek 1m, seek 1h 30m", "seek 1h 30m 30s"], - usage: "seek ", - }, - category: "music", - aliases: ["s"], - cooldown: 3, - args: true, - vote: false, - player: { - voice: true, - dj: false, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "duration", - description: "cmd.seek.options.duration", - type: 3, - required: true, - }, - ], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "seek", + description: { + content: "cmd.seek.description", + examples: ["seek 1m, seek 1h 30m", "seek 1h 30m 30s"], + usage: "seek ", + }, + category: "music", + aliases: ["s"], + cooldown: 3, + args: true, + vote: false, + player: { + voice: true, + dj: false, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "duration", + description: "cmd.seek.options.duration", + type: 3, + required: true, + }, + ], + }); + } - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const player = client.queue.get(ctx.guild!.id); - const current = player.current.info; - const embed = this.client.embed(); - const duration = client.utils.parseTime(args.join(" ")); - if (!duration) { - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.seek.errors.invalid_format"))], - }); - } - if (!current.isSeekable) { - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.seek.errors.not_seekable"))], - }); - } - if (duration > current.length) { - return await ctx.sendMessage({ - embeds: [ - embed.setColor(this.client.color.red).setDescription( - ctx.locale("cmd.seek.errors.beyond_duration", { - length: client.utils.formatTime(current.length), - }), - ), - ], - }); - } - player.seek(duration); - return await ctx.sendMessage({ - embeds: [ - embed.setColor(this.client.color.main).setDescription( - ctx.locale("cmd.seek.messages.seeked_to", { - duration: client.utils.formatTime(duration), - }), - ), - ], - }); + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const player = client.queue.get(ctx.guild!.id); + const current = player.current.info; + const embed = this.client.embed(); + const duration = client.utils.parseTime(args.join(" ")); + if (!duration) { + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.seek.errors.invalid_format"))], + }); + } + if (!current.isSeekable) { + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.seek.errors.not_seekable"))], + }); + } + if (duration > current.length) { + return await ctx.sendMessage({ + embeds: [ + embed.setColor(this.client.color.red).setDescription( + ctx.locale("cmd.seek.errors.beyond_duration", { + length: client.utils.formatTime(current.length), + }), + ), + ], + }); } + player.seek(duration); + return await ctx.sendMessage({ + embeds: [ + embed.setColor(this.client.color.main).setDescription( + ctx.locale("cmd.seek.messages.seeked_to", { + duration: client.utils.formatTime(duration), + }), + ), + ], + }); + } } /** diff --git a/src/commands/music/Shuffle.ts b/src/commands/music/Shuffle.ts index 4328cde13..ff8af78ca 100644 --- a/src/commands/music/Shuffle.ts +++ b/src/commands/music/Shuffle.ts @@ -1,48 +1,48 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Shuffle extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "shuffle", - description: { - content: "cmd.shuffle.description", - examples: ["shuffle"], - usage: "shuffle", - }, - category: "music", - aliases: ["sh"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "shuffle", + description: { + content: "cmd.shuffle.description", + examples: ["shuffle"], + usage: "shuffle", + }, + category: "music", + aliases: ["sh"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const embed = this.client.embed(); - if (!player.queue.length) { - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("player.errors.no_song"))], - }); - } - player.setShuffle(); - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.main).setDescription(ctx.locale("cmd.shuffle.messages.shuffled"))], - }); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const embed = this.client.embed(); + if (!player.queue.length) { + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("player.errors.no_song"))], + }); } + player.setShuffle(); + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.main).setDescription(ctx.locale("cmd.shuffle.messages.shuffled"))], + }); + } } /** diff --git a/src/commands/music/Skip.ts b/src/commands/music/Skip.ts index 057b415a5..99907f49f 100644 --- a/src/commands/music/Skip.ts +++ b/src/commands/music/Skip.ts @@ -1,59 +1,59 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Skip extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "skip", - description: { - content: "cmd.skip.description", - examples: ["skip"], - usage: "skip", - }, - category: "music", - aliases: ["sk"], - cooldown: 3, - args: false, - vote: true, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "skip", + description: { + content: "cmd.skip.description", + examples: ["skip"], + usage: "skip", + }, + category: "music", + aliases: ["sk"], + cooldown: 3, + args: false, + vote: true, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const embed = this.client.embed(); - if (player.queue.length === 0) { - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("player.errors.no_song"))], - }); - } - const currentTrack = player.current.info; - player.skip(); - if (ctx.isInteraction) { - return await ctx.sendMessage({ - embeds: [ - embed.setColor(this.client.color.main).setDescription( - ctx.locale("cmd.skip.messages.skipped", { - title: currentTrack.title, - uri: currentTrack.uri, - }), - ), - ], - }); - } - ctx.message?.react("👍"); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const embed = this.client.embed(); + if (player.queue.length === 0) { + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("player.errors.no_song"))], + }); + } + const currentTrack = player.current.info; + player.skip(); + if (ctx.isInteraction) { + return await ctx.sendMessage({ + embeds: [ + embed.setColor(this.client.color.main).setDescription( + ctx.locale("cmd.skip.messages.skipped", { + title: currentTrack.title, + uri: currentTrack.uri, + }), + ), + ], + }); } + ctx.message?.react("👍"); + } } /** diff --git a/src/commands/music/Skipto.ts b/src/commands/music/Skipto.ts index 1ebb24623..c64292f56 100644 --- a/src/commands/music/Skipto.ts +++ b/src/commands/music/Skipto.ts @@ -1,64 +1,64 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Skipto extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "skipto", - description: { - content: "cmd.skipto.description", - examples: ["skipto 3"], - usage: "skipto ", - }, - category: "music", - aliases: ["skt"], - cooldown: 3, - args: true, - vote: true, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "number", - description: "cmd.skipto.options.number", - type: 4, - required: true, - }, - ], - }); - } - - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const player = client.queue.get(ctx.guild!.id); - const embed = this.client.embed(); - const num = Number(args[0]); + constructor(client: Lavamusic) { + super(client, { + name: "skipto", + description: { + content: "cmd.skipto.description", + examples: ["skipto 3"], + usage: "skipto ", + }, + category: "music", + aliases: ["skt"], + cooldown: 3, + args: true, + vote: true, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "number", + description: "cmd.skipto.options.number", + type: 4, + required: true, + }, + ], + }); + } - if (!player.queue.length || isNaN(num) || num > player.queue.length || num < 1) { - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.skipto.errors.invalid_number"))], - }); - } + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const player = client.queue.get(ctx.guild!.id); + const embed = this.client.embed(); + const num = Number(args[0]); - player.skip(num); - return await ctx.sendMessage({ - embeds: [ - embed.setColor(this.client.color.main).setDescription( - ctx.locale("cmd.skipto.messages.skipped_to", { - number: num, - }), - ), - ], - }); + if (!player.queue.length || isNaN(num) || num > player.queue.length || num < 1) { + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.skipto.errors.invalid_number"))], + }); } + + player.skip(num); + return await ctx.sendMessage({ + embeds: [ + embed.setColor(this.client.color.main).setDescription( + ctx.locale("cmd.skipto.messages.skipped_to", { + number: num, + }), + ), + ], + }); + } } /** diff --git a/src/commands/music/Stop.ts b/src/commands/music/Stop.ts index e8f97a802..4569dddc7 100644 --- a/src/commands/music/Stop.ts +++ b/src/commands/music/Stop.ts @@ -1,46 +1,46 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Stop extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "stop", - description: { - content: "cmd.stop.description", - examples: ["stop"], - usage: "stop", - }, - category: "music", - aliases: ["sp"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "stop", + description: { + content: "cmd.stop.description", + examples: ["stop"], + usage: "stop", + }, + category: "music", + aliases: ["sp"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - const player = client.queue.get(ctx.guild!.id); - const embed = this.client.embed(); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const embed = this.client.embed(); - player.queue = []; - player.stop(); + player.queue = []; + player.stop(); - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.main).setDescription(ctx.locale("cmd.stop.messages.stopped"))], - }); - } + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.main).setDescription(ctx.locale("cmd.stop.messages.stopped"))], + }); + } } /** diff --git a/src/commands/music/Volume.ts b/src/commands/music/Volume.ts index 36ef52acb..c0f98ea39 100644 --- a/src/commands/music/Volume.ts +++ b/src/commands/music/Volume.ts @@ -1,71 +1,71 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class Volume extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "volume", - description: { - content: "cmd.volume.description", - examples: ["volume 100"], - usage: "volume ", - }, - category: "music", - aliases: ["v", "vol"], - cooldown: 3, - args: true, - vote: true, - player: { - voice: true, - dj: true, - active: true, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "number", - description: "cmd.volume.options.number", - type: 4, - required: true, - }, - ], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "volume", + description: { + content: "cmd.volume.description", + examples: ["volume 100"], + usage: "volume ", + }, + category: "music", + aliases: ["v", "vol"], + cooldown: 3, + args: true, + vote: true, + player: { + voice: true, + dj: true, + active: true, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "number", + description: "cmd.volume.options.number", + type: 4, + required: true, + }, + ], + }); + } - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const player = client.queue.get(ctx.guild!.id); - const embed = this.client.embed(); - const number = Number(args[0]); + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const player = client.queue.get(ctx.guild!.id); + const embed = this.client.embed(); + const number = Number(args[0]); - if (isNaN(number) || number < 0 || number > 200) { - let description = ""; - if (isNaN(number)) description = ctx.locale("cmd.volume.messages.invalid_number"); - else if (number < 0) description = ctx.locale("cmd.volume.messages.too_low"); - else if (number > 200) description = ctx.locale("cmd.volume.messages.too_high"); + if (isNaN(number) || number < 0 || number > 200) { + let description = ""; + if (isNaN(number)) description = ctx.locale("cmd.volume.messages.invalid_number"); + else if (number < 0) description = ctx.locale("cmd.volume.messages.too_low"); + else if (number > 200) description = ctx.locale("cmd.volume.messages.too_high"); - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(description)], - }); - } + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(description)], + }); + } - await player.player.setGlobalVolume(number); - const currentVolume = player.player.volume; + await player.player.setGlobalVolume(number); + const currentVolume = player.player.volume; - return await ctx.sendMessage({ - embeds: [ - embed.setColor(this.client.color.main).setDescription( - ctx.locale("cmd.volume.messages.set", { - volume: currentVolume, - }), - ), - ], - }); - } + return await ctx.sendMessage({ + embeds: [ + embed.setColor(this.client.color.main).setDescription( + ctx.locale("cmd.volume.messages.set", { + volume: currentVolume, + }), + ), + ], + }); + } } /** diff --git a/src/commands/playlist/AddSong.ts b/src/commands/playlist/AddSong.ts index c4ef21ff3..41e95af92 100644 --- a/src/commands/playlist/AddSong.ts +++ b/src/commands/playlist/AddSong.ts @@ -3,144 +3,144 @@ import { LoadType } from "shoukaku"; import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class AddSong extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "addsong", - description: { - content: "cmd.addsong.description", - examples: ["addsong test exemple", "addsong exemple https://www.youtube.com/watch?v=example"], - usage: "addsong ", - }, - category: "playlist", - aliases: ["as"], - cooldown: 3, - args: true, - vote: true, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "playlist", - description: "cmd.addsong.options.playlist", - type: 3, - required: true, - autocomplete: true, - }, - { - name: "song", - description: "cmd.addsong.options.song", - type: 3, - required: true, - }, - ], - }); + constructor(client: Lavamusic) { + super(client, { + name: "addsong", + description: { + content: "cmd.addsong.description", + examples: ["addsong test exemple", "addsong exemple https://www.youtube.com/watch?v=example"], + usage: "addsong ", + }, + category: "playlist", + aliases: ["as"], + cooldown: 3, + args: true, + vote: true, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "playlist", + description: "cmd.addsong.options.playlist", + type: 3, + required: true, + autocomplete: true, + }, + { + name: "song", + description: "cmd.addsong.options.song", + type: 3, + required: true, + }, + ], + }); + } + + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const playlist = args.shift(); + const song = args.join(" "); + + if (!playlist) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.addsong.messages.no_playlist"), + color: this.client.color.red, + }, + ], + }); } - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const playlist = args.shift(); - const song = args.join(" "); - - if (!playlist) { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.addsong.messages.no_playlist"), - color: this.client.color.red, - }, - ], - }); - } - - if (!song) { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.addsong.messages.no_song"), - color: this.client.color.red, - }, - ], - }); - } - const res = await client.queue.search(song); - - if (!res || res.loadType === LoadType.EMPTY) { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.addsong.messages.no_songs_found"), - color: this.client.color.red, - }, - ], - }); - } - - const playlistData = await client.db.getPlaylist(ctx.author.id, playlist); - - if (!playlistData) { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.addsong.messages.playlist_not_found"), - color: this.client.color.red, - }, - ], - }); - } - - let trackStrings: any; - let count: number; - - if (res.loadType === LoadType.PLAYLIST) { - trackStrings = res.data.tracks; - count = res.data.tracks.length; - } else if (res.loadType === LoadType.TRACK) { - trackStrings = [res.data]; - count = 1; - } else if (res.loadType === LoadType.SEARCH) { - trackStrings = [res.data[0]]; - count = 1; - } - - await client.db.addSong(ctx.author.id, playlist, trackStrings); - - await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.addsong.messages.added", { - count, - playlist: playlistData.name, - }), - color: this.client.color.main, - }, - ], - }); + if (!song) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.addsong.messages.no_song"), + color: this.client.color.red, + }, + ], + }); + } + const res = await client.queue.search(song); + + if (!res || res.loadType === LoadType.EMPTY) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.addsong.messages.no_songs_found"), + color: this.client.color.red, + }, + ], + }); } - public async autocomplete(interaction: AutocompleteInteraction): Promise { - const focusedValue = interaction.options.getFocused(); - const userId = interaction.user.id; - - const playlists = await this.client.db.getUserPlaylists(userId); - - const filtered = playlists.filter((playlist) => playlist.name.toLowerCase().startsWith(focusedValue.toLowerCase())); + const playlistData = await client.db.getPlaylist(ctx.author.id, playlist); + + if (!playlistData) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.addsong.messages.playlist_not_found"), + color: this.client.color.red, + }, + ], + }); + } - return await interaction.respond( - filtered.map((playlist) => ({ - name: playlist.name, - value: playlist.name, - })), - ); + let trackStrings: any; + let count: number; + + if (res.loadType === LoadType.PLAYLIST) { + trackStrings = res.data.tracks; + count = res.data.tracks.length; + } else if (res.loadType === LoadType.TRACK) { + trackStrings = [res.data]; + count = 1; + } else if (res.loadType === LoadType.SEARCH) { + trackStrings = [res.data[0]]; + count = 1; } + + await client.db.addSong(ctx.author.id, playlist, trackStrings); + + await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.addsong.messages.added", { + count, + playlist: playlistData.name, + }), + color: this.client.color.main, + }, + ], + }); + } + + public async autocomplete(interaction: AutocompleteInteraction): Promise { + const focusedValue = interaction.options.getFocused(); + const userId = interaction.user.id; + + const playlists = await this.client.db.getUserPlaylists(userId); + + const filtered = playlists.filter((playlist) => playlist.name.toLowerCase().startsWith(focusedValue.toLowerCase())); + + return await interaction.respond( + filtered.map((playlist) => ({ + name: playlist.name, + value: playlist.name, + })), + ); + } } /** diff --git a/src/commands/playlist/Create.ts b/src/commands/playlist/Create.ts index c6b80a7ea..57babb129 100644 --- a/src/commands/playlist/Create.ts +++ b/src/commands/playlist/Create.ts @@ -1,72 +1,72 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class CreatePlaylist extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "create", - description: { - content: "cmd.create.description", - examples: ["create "], - usage: "create ", - }, - category: "playlist", - aliases: ["cre"], - cooldown: 3, - args: true, - vote: true, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "name", - description: "cmd.create.options.name", - type: 3, - required: true, - }, - ], - }); - } - - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const name = args.join(" ").trim(); - const embed = this.client.embed(); + constructor(client: Lavamusic) { + super(client, { + name: "create", + description: { + content: "cmd.create.description", + examples: ["create "], + usage: "create ", + }, + category: "playlist", + aliases: ["cre"], + cooldown: 3, + args: true, + vote: true, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "name", + description: "cmd.create.options.name", + type: 3, + required: true, + }, + ], + }); + } - if (name.length > 50) { - return await ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.create.messages.name_too_long")).setColor(this.client.color.red)], - }); - } + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const name = args.join(" ").trim(); + const embed = this.client.embed(); - const playlistExists = await client.db.getPlaylist(ctx.author.id, name); - if (playlistExists) { - return await ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.create.messages.playlist_exists")).setColor(this.client.color.red)], - }); - } + if (name.length > 50) { + return await ctx.sendMessage({ + embeds: [embed.setDescription(ctx.locale("cmd.create.messages.name_too_long")).setColor(this.client.color.red)], + }); + } - await client.db.createPlaylist(ctx.author.id, name); - return await ctx.sendMessage({ - embeds: [ - embed - .setDescription( - ctx.locale("cmd.create.messages.playlist_created", { - name, - }), - ) - .setColor(this.client.color.green), - ], - }); + const playlistExists = await client.db.getPlaylist(ctx.author.id, name); + if (playlistExists) { + return await ctx.sendMessage({ + embeds: [embed.setDescription(ctx.locale("cmd.create.messages.playlist_exists")).setColor(this.client.color.red)], + }); } + + await client.db.createPlaylist(ctx.author.id, name); + return await ctx.sendMessage({ + embeds: [ + embed + .setDescription( + ctx.locale("cmd.create.messages.playlist_created", { + name, + }), + ) + .setColor(this.client.color.green), + ], + }); + } } /** diff --git a/src/commands/playlist/Delete.ts b/src/commands/playlist/Delete.ts index 663bd4518..c99e32de6 100644 --- a/src/commands/playlist/Delete.ts +++ b/src/commands/playlist/Delete.ts @@ -2,86 +2,86 @@ import type { AutocompleteInteraction } from "discord.js"; import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class DeletePlaylist extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "delete", - description: { - content: "cmd.delete.description", - examples: ["delete "], - usage: "delete ", - }, - category: "playlist", - aliases: ["del"], - cooldown: 3, - args: true, - vote: true, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "playlist", - description: "cmd.delete.options.playlist", - type: 3, - required: true, - autocomplete: true, - }, - ], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "delete", + description: { + content: "cmd.delete.description", + examples: ["delete "], + usage: "delete ", + }, + category: "playlist", + aliases: ["del"], + cooldown: 3, + args: true, + vote: true, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "playlist", + description: "cmd.delete.options.playlist", + type: 3, + required: true, + autocomplete: true, + }, + ], + }); + } - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const playlistName = args.join(" ").trim(); - const embed = this.client.embed(); + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const playlistName = args.join(" ").trim(); + const embed = this.client.embed(); - const playlistExists = await client.db.getPlaylist(ctx.author.id, playlistName); - if (!playlistExists) { - return await ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.delete.messages.playlist_not_found")).setColor(this.client.color.red)], - }); - } + const playlistExists = await client.db.getPlaylist(ctx.author.id, playlistName); + if (!playlistExists) { + return await ctx.sendMessage({ + embeds: [embed.setDescription(ctx.locale("cmd.delete.messages.playlist_not_found")).setColor(this.client.color.red)], + }); + } - // First, delete all songs from the playlist - await client.db.deleteSongsFromPlaylist(ctx.author.id, playlistName); + // First, delete all songs from the playlist + await client.db.deleteSongsFromPlaylist(ctx.author.id, playlistName); - await client.db.deletePlaylist(ctx.author.id, playlistName); - return await ctx.sendMessage({ - embeds: [ - embed - .setDescription( - ctx.locale("cmd.delete.messages.playlist_deleted", { - playlistName, - }), - ) - .setColor(this.client.color.green), - ], - }); - } + await client.db.deletePlaylist(ctx.author.id, playlistName); + return await ctx.sendMessage({ + embeds: [ + embed + .setDescription( + ctx.locale("cmd.delete.messages.playlist_deleted", { + playlistName, + }), + ) + .setColor(this.client.color.green), + ], + }); + } - public async autocomplete(interaction: AutocompleteInteraction): Promise { - const focusedValue = interaction.options.getFocused(); - const userId = interaction.user.id; + public async autocomplete(interaction: AutocompleteInteraction): Promise { + const focusedValue = interaction.options.getFocused(); + const userId = interaction.user.id; - const playlists = await this.client.db.getUserPlaylists(userId); + const playlists = await this.client.db.getUserPlaylists(userId); - const filtered = playlists.filter((playlist) => playlist.name.toLowerCase().startsWith(focusedValue.toLowerCase())); + const filtered = playlists.filter((playlist) => playlist.name.toLowerCase().startsWith(focusedValue.toLowerCase())); - await interaction.respond( - filtered.map((playlist) => ({ - name: playlist.name, - value: playlist.name, - })), - ); - } + await interaction.respond( + filtered.map((playlist) => ({ + name: playlist.name, + value: playlist.name, + })), + ); + } } /** diff --git a/src/commands/playlist/List.ts b/src/commands/playlist/List.ts index 73e136c91..28785f817 100644 --- a/src/commands/playlist/List.ts +++ b/src/commands/playlist/List.ts @@ -1,128 +1,128 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class GetPlaylists extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "list", - description: { - content: "cmd.list.description", - examples: ["list", "list @user"], - usage: "list [@user]", - }, - category: "playlist", - aliases: ["lst"], - cooldown: 3, - args: false, - vote: false, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "user", - description: "cmd.list.options.user", - type: 6, - required: false, - }, - ], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "list", + description: { + content: "cmd.list.description", + examples: ["list", "list @user"], + usage: "list [@user]", + }, + category: "playlist", + aliases: ["lst"], + cooldown: 3, + args: false, + vote: false, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "user", + description: "cmd.list.options.user", + type: 6, + required: false, + }, + ], + }); + } - public async run(client: Lavamusic, ctx: Context): Promise { - try { - let userId: string | null = null; - let targetUser = ctx.args[0]; + public async run(client: Lavamusic, ctx: Context): Promise { + try { + let userId: string | null = null; + let targetUser = ctx.args[0]; - if (targetUser?.startsWith("<@") && targetUser.endsWith(">")) { - targetUser = targetUser.slice(2, -1); + if (targetUser?.startsWith("<@") && targetUser.endsWith(">")) { + targetUser = targetUser.slice(2, -1); - if (targetUser.startsWith("!")) { - targetUser = targetUser.slice(1); - } + if (targetUser.startsWith("!")) { + targetUser = targetUser.slice(1); + } - targetUser = await client.users.fetch(targetUser); - userId = targetUser.id; - } else if (targetUser) { - try { - targetUser = await client.users.fetch(targetUser); - userId = targetUser.id; - } catch (_error) { - const users = client.users.cache.filter((user) => user.username.toLowerCase() === targetUser.toLowerCase()); + targetUser = await client.users.fetch(targetUser); + userId = targetUser.id; + } else if (targetUser) { + try { + targetUser = await client.users.fetch(targetUser); + userId = targetUser.id; + } catch (_error) { + const users = client.users.cache.filter((user) => user.username.toLowerCase() === targetUser.toLowerCase()); - if (users.size > 0) { - targetUser = users.first(); - userId = targetUser?.id ?? null; - } else { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.list.messages.invalid_username"), - color: this.client.color.red, - }, - ], - }); - } - } - } else { - userId = ctx.author.id; - targetUser = ctx.author; - } + if (users.size > 0) { + targetUser = users.first(); + userId = targetUser?.id ?? null; + } else { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.list.messages.invalid_username"), + color: this.client.color.red, + }, + ], + }); + } + } + } else { + userId = ctx.author.id; + targetUser = ctx.author; + } - if (!userId) { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.list.messages.invalid_userid"), - color: this.client.color.red, - }, - ], - }); - } + if (!userId) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.list.messages.invalid_userid"), + color: this.client.color.red, + }, + ], + }); + } - const playlists = await client.db.getUserPlaylists(userId); + const playlists = await client.db.getUserPlaylists(userId); - if (!playlists || playlists.length === 0) { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.list.messages.no_playlists"), - color: this.client.color.red, - }, - ], - }); - } + if (!playlists || playlists.length === 0) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.list.messages.no_playlists"), + color: this.client.color.red, + }, + ], + }); + } - const targetUsername = targetUser ? targetUser.username : ctx.locale("cmd.list.messages.your"); - return await ctx.sendMessage({ - embeds: [ - { - title: ctx.locale("cmd.list.messages.playlists_title", { username: targetUsername }), - description: playlists.map((playlist: any) => playlist.name).join("\n"), - color: this.client.color.main, - }, - ], - }); - } catch (error) { - console.error(error); - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.list.messages.error"), - color: this.client.color.red, - }, - ], - }); - } + const targetUsername = targetUser ? targetUser.username : ctx.locale("cmd.list.messages.your"); + return await ctx.sendMessage({ + embeds: [ + { + title: ctx.locale("cmd.list.messages.playlists_title", { username: targetUsername }), + description: playlists.map((playlist: any) => playlist.name).join("\n"), + color: this.client.color.main, + }, + ], + }); + } catch (error) { + console.error(error); + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.list.messages.error"), + color: this.client.color.red, + }, + ], + }); } + } } /** diff --git a/src/commands/playlist/Load.ts b/src/commands/playlist/Load.ts index f23cdd3cc..e495ce53c 100644 --- a/src/commands/playlist/Load.ts +++ b/src/commands/playlist/Load.ts @@ -2,114 +2,114 @@ import type { AutocompleteInteraction } from "discord.js"; import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class LoadPlaylist extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "load", - description: { - content: "cmd.load.description", - examples: ["load "], - usage: "load ", - }, - category: "playlist", - aliases: ["lo"], - cooldown: 3, - args: true, - vote: true, - player: { - voice: true, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "playlist", - description: "cmd.load.options.playlist", - type: 3, - required: true, - autocomplete: true, - }, - ], - }); - } - - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - let player = client.queue.get(ctx.guild!.id); - const playlistName = args.join(" ").trim(); - const playlistData = await client.db.getPlaylist(ctx.author.id, playlistName); - if (!playlistData) { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.load.messages.playlist_not_exist"), - color: this.client.color.red, - }, - ], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "load", + description: { + content: "cmd.load.description", + examples: ["load "], + usage: "load ", + }, + category: "playlist", + aliases: ["lo"], + cooldown: 3, + args: true, + vote: true, + player: { + voice: true, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "playlist", + description: "cmd.load.options.playlist", + type: 3, + required: true, + autocomplete: true, + }, + ], + }); + } - const songs = await client.db.getSongs(ctx.author.id, playlistName); - if (!songs.length) { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.load.messages.playlist_empty"), - color: client.color.red, - }, - ], - }); - } + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + let player = client.queue.get(ctx.guild!.id); + const playlistName = args.join(" ").trim(); + const playlistData = await client.db.getPlaylist(ctx.author.id, playlistName); + if (!playlistData) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.load.messages.playlist_not_exist"), + color: this.client.color.red, + }, + ], + }); + } - const vc = ctx.member as any; - if (!player) { - player = await client.queue.create( - ctx.guild, - vc.voice.channel, - ctx.channel, - client.shoukaku.options.nodeResolver(client.shoukaku.nodes), - ); - } + const songs = await client.db.getSongs(ctx.author.id, playlistName); + if (!songs.length) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.load.messages.playlist_empty"), + color: client.color.red, + }, + ], + }); + } - for (const song of songs) { - const trackData = JSON.parse(song.track); - for (const track of trackData) { - const builtTrack = player.buildTrack(track, ctx.author as any); - player.queue.push(builtTrack); - } - } + const vc = ctx.member as any; + if (!player) { + player = await client.queue.create( + ctx.guild, + vc.voice.channel, + ctx.channel, + client.shoukaku.options.nodeResolver(client.shoukaku.nodes), + ); + } - await player.isPlaying(); - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.load.messages.playlist_loaded", { name: playlistData.name, count: songs.length }), - color: this.client.color.main, - }, - ], - }); + for (const song of songs) { + const trackData = JSON.parse(song.track); + for (const track of trackData) { + const builtTrack = player.buildTrack(track, ctx.author as any); + player.queue.push(builtTrack); + } } - public async autocomplete(interaction: AutocompleteInteraction): Promise { - const focusedValue = interaction.options.getFocused(); - const userId = interaction.user.id; + await player.isPlaying(); + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.load.messages.playlist_loaded", { name: playlistData.name, count: songs.length }), + color: this.client.color.main, + }, + ], + }); + } - const playlists = await this.client.db.getUserPlaylists(userId); + public async autocomplete(interaction: AutocompleteInteraction): Promise { + const focusedValue = interaction.options.getFocused(); + const userId = interaction.user.id; - const filtered = playlists.filter((playlist) => playlist.name.toLowerCase().startsWith(focusedValue.toLowerCase())); + const playlists = await this.client.db.getUserPlaylists(userId); - await interaction.respond( - filtered.map((playlist) => ({ - name: playlist.name, - value: playlist.name, - })), - ); - } + const filtered = playlists.filter((playlist) => playlist.name.toLowerCase().startsWith(focusedValue.toLowerCase())); + + await interaction.respond( + filtered.map((playlist) => ({ + name: playlist.name, + value: playlist.name, + })), + ); + } } /** diff --git a/src/commands/playlist/RemoveSong.ts b/src/commands/playlist/RemoveSong.ts index 04c2e7201..8f11b5039 100644 --- a/src/commands/playlist/RemoveSong.ts +++ b/src/commands/playlist/RemoveSong.ts @@ -3,128 +3,128 @@ import { LoadType } from "shoukaku"; import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class RemoveSong extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "removesong", - description: { - content: "cmd.removesong.description", - examples: ["removesong "], - usage: "removesong ", - }, - category: "playlist", - aliases: ["rs"], - cooldown: 3, - args: true, - vote: true, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, - }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], - }, - slashCommand: true, - options: [ - { - name: "playlist", - description: "cmd.removesong.options.playlist", - type: 3, - required: true, - autocomplete: true, - }, - { - name: "song", - description: "cmd.removesong.options.song", - type: 3, - required: true, - }, - ], - }); - } + constructor(client: Lavamusic) { + super(client, { + name: "removesong", + description: { + content: "cmd.removesong.description", + examples: ["removesong "], + usage: "removesong ", + }, + category: "playlist", + aliases: ["rs"], + cooldown: 3, + args: true, + vote: true, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "playlist", + description: "cmd.removesong.options.playlist", + type: 3, + required: true, + autocomplete: true, + }, + { + name: "song", + description: "cmd.removesong.options.song", + type: 3, + required: true, + }, + ], + }); + } - public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { - const playlist = args.shift(); - const song = args.join(" "); + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const playlist = args.shift(); + const song = args.join(" "); - if (!playlist) { - const errorMessage = this.client - .embed() - .setDescription(ctx.locale("cmd.removesong.messages.provide_playlist")) - .setColor(this.client.color.red); - return await ctx.sendMessage({ embeds: [errorMessage] }); - } + if (!playlist) { + const errorMessage = this.client + .embed() + .setDescription(ctx.locale("cmd.removesong.messages.provide_playlist")) + .setColor(this.client.color.red); + return await ctx.sendMessage({ embeds: [errorMessage] }); + } - if (!song) { - const errorMessage = this.client - .embed() - .setDescription(ctx.locale("cmd.removesong.messages.provide_song")) - .setColor(this.client.color.red); - return await ctx.sendMessage({ embeds: [errorMessage] }); - } + if (!song) { + const errorMessage = this.client + .embed() + .setDescription(ctx.locale("cmd.removesong.messages.provide_song")) + .setColor(this.client.color.red); + return await ctx.sendMessage({ embeds: [errorMessage] }); + } - const playlistData = await client.db.getPlaylist(ctx.author.id, playlist); + const playlistData = await client.db.getPlaylist(ctx.author.id, playlist); - if (!playlistData) { - const playlistNotFoundError = this.client - .embed() - .setDescription(ctx.locale("cmd.removesong.messages.playlist_not_exist")) - .setColor(this.client.color.red); - return await ctx.sendMessage({ embeds: [playlistNotFoundError] }); - } + if (!playlistData) { + const playlistNotFoundError = this.client + .embed() + .setDescription(ctx.locale("cmd.removesong.messages.playlist_not_exist")) + .setColor(this.client.color.red); + return await ctx.sendMessage({ embeds: [playlistNotFoundError] }); + } - const res = await client.queue.search(song); + const res = await client.queue.search(song); - if (!res || res.loadType !== LoadType.TRACK) { - const noSongsFoundError = this.client - .embed() - .setDescription(ctx.locale("cmd.removesong.messages.song_not_found")) - .setColor(this.client.color.red); - return await ctx.sendMessage({ embeds: [noSongsFoundError] }); - } + if (!res || res.loadType !== LoadType.TRACK) { + const noSongsFoundError = this.client + .embed() + .setDescription(ctx.locale("cmd.removesong.messages.song_not_found")) + .setColor(this.client.color.red); + return await ctx.sendMessage({ embeds: [noSongsFoundError] }); + } - const trackToRemove = res.data; + const trackToRemove = res.data; - try { - await client.db.removeSong(ctx.author.id, playlist, trackToRemove.encoded); + try { + await client.db.removeSong(ctx.author.id, playlist, trackToRemove.encoded); - const successMessage = this.client - .embed() - .setDescription( - ctx.locale("cmd.removesong.messages.song_removed", { - song: trackToRemove.info.title, - playlist: playlistData.name, - }), - ) - .setColor(this.client.color.green); - await ctx.sendMessage({ embeds: [successMessage] }); - } catch (error) { - console.error(error); - const genericError = this.client - .embed() - .setDescription(ctx.locale("cmd.removesong.messages.error_occurred")) - .setColor(this.client.color.red); - return await ctx.sendMessage({ embeds: [genericError] }); - } + const successMessage = this.client + .embed() + .setDescription( + ctx.locale("cmd.removesong.messages.song_removed", { + song: trackToRemove.info.title, + playlist: playlistData.name, + }), + ) + .setColor(this.client.color.green); + await ctx.sendMessage({ embeds: [successMessage] }); + } catch (error) { + console.error(error); + const genericError = this.client + .embed() + .setDescription(ctx.locale("cmd.removesong.messages.error_occurred")) + .setColor(this.client.color.red); + return await ctx.sendMessage({ embeds: [genericError] }); } - public async autocomplete(interaction: AutocompleteInteraction): Promise { - const focusedValue = interaction.options.getFocused(); - const userId = interaction.user.id; + } + public async autocomplete(interaction: AutocompleteInteraction): Promise { + const focusedValue = interaction.options.getFocused(); + const userId = interaction.user.id; - const playlists = await this.client.db.getUserPlaylists(userId); + const playlists = await this.client.db.getUserPlaylists(userId); - const filtered = playlists.filter((playlist) => playlist.name.toLowerCase().startsWith(focusedValue.toLowerCase())); + const filtered = playlists.filter((playlist) => playlist.name.toLowerCase().startsWith(focusedValue.toLowerCase())); - await interaction.respond( - filtered.map((playlist) => ({ - name: playlist.name, - value: playlist.name, - })), - ); - } + await interaction.respond( + filtered.map((playlist) => ({ + name: playlist.name, + value: playlist.name, + })), + ); + } } /** diff --git a/src/commands/playlist/Steal.ts b/src/commands/playlist/Steal.ts index c780c7a21..d39f92fa9 100644 --- a/src/commands/playlist/Steal.ts +++ b/src/commands/playlist/Steal.ts @@ -1,197 +1,191 @@ import { Command, type Context, type Lavamusic } from "../../structures/index.js"; export default class StealPlaylist extends Command { - constructor(client: Lavamusic) { - super(client, { - name: "steal", - description: { - content: "cmd.steal.description", - examples: ["steal <@user> "], - usage: "steal <@user> ", - }, - category: "playlist", - aliases: ["st"], - cooldown: 3, - args: true, - vote: false, - player: { - voice: false, - dj: false, - active: false, - djPerm: null, + constructor(client: Lavamusic) { + super(client, { + name: "steal", + description: { + content: "cmd.steal.description", + examples: ["steal <@user> "], + usage: "steal <@user> ", + }, + category: "playlist", + aliases: ["st"], + cooldown: 3, + args: true, + vote: false, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, + }, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], + user: [], + }, + slashCommand: true, + options: [ + { + name: "user", + description: "cmd.steal.options.user", + type: 6, + required: true, + }, + { + name: "playlist", + description: "cmd.steal.options.playlist", + type: 3, + required: true, + autocomplete: true, + }, + ], + }); + } + + public async run(client: Lavamusic, ctx: Context): Promise { + let targetUser = ctx.args[0]; + const playlistName = ctx.args[1]; + let targetUserId: string | null = null; + + if (targetUser?.startsWith("<@") && targetUser.endsWith(">")) { + targetUser = targetUser.slice(2, -1); + if (targetUser.startsWith("!")) { + targetUser = targetUser.slice(1); + } + targetUser = await client.users.fetch(targetUser); + targetUserId = targetUser.id; + } else if (targetUser) { + try { + targetUser = await client.users.fetch(targetUser); + targetUserId = targetUser.id; + } catch (_error) { + const users = client.users.cache.filter((user) => user.username.toLowerCase() === targetUser.toLowerCase()); + + if (users.size > 0) { + targetUser = users.first(); + targetUserId = targetUser.id; + } else { + return await ctx.sendMessage({ + embeds: [ + { + description: "Invalid username or user not found.", + color: this.client.color.red, + }, + ], + }); + } + } + } + + if (!playlistName) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.steal.messages.provide_playlist"), + color: this.client.color.red, + }, + ], + }); + } + + if (!targetUserId) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.steal.messages.provide_user"), + color: this.client.color.red, + }, + ], + }); + } + + try { + const targetPlaylist = await client.db.getPlaylist(targetUserId, playlistName); + + if (!targetPlaylist) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.steal.messages.playlist_not_exist"), + color: this.client.color.red, }, - permissions: { - dev: false, - client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks"], - user: [], + ], + }); + } + + const targetSongs = await client.db.getSongs(targetUserId, playlistName); + + const existingPlaylist = await client.db.getPlaylist(ctx.author.id, playlistName); + if (existingPlaylist) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.steal.messages.playlist_exists", { playlist: playlistName }), + color: this.client.color.red, }, - slashCommand: true, - options: [ - { - name: "user", - description: "cmd.steal.options.user", - type: 6, - required: true, - }, - { - name: "playlist", - description: "cmd.steal.options.playlist", - type: 3, - required: true, - autocomplete: true, - }, - ], + ], }); + } + + await client.db.createPlaylistWithSongs(ctx.author.id, playlistName, targetSongs); + + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.steal.messages.playlist_stolen", { + playlist: playlistName, + user: targetUser.username, + }), + color: this.client.color.main, + }, + ], + }); + } catch (error) { + console.error(error); + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.steal.messages.error_occurred"), + color: this.client.color.red, + }, + ], + }); } + } - public async run(client: Lavamusic, ctx: Context): Promise { - let targetUser = ctx.args[0]; - const playlistName = ctx.args[1]; - let targetUserId: string | null = null; - - if (targetUser?.startsWith("<@") && targetUser.endsWith(">")) { - targetUser = targetUser.slice(2, -1); - if (targetUser.startsWith("!")) { - targetUser = targetUser.slice(1); - } - targetUser = await client.users.fetch(targetUser); - targetUserId = targetUser.id; - } else if (targetUser) { - try { - targetUser = await client.users.fetch(targetUser); - targetUserId = targetUser.id; - } catch (_error) { - const users = client.users.cache.filter((user) => user.username.toLowerCase() === targetUser.toLowerCase()); - - if (users.size > 0) { - targetUser = users.first(); - targetUserId = targetUser.id; - } else { - return await ctx.sendMessage({ - embeds: [ - { - description: "Invalid username or user not found.", - color: this.client.color.red, - }, - ], - }); - } - } - } + public async autocomplete(interaction) { + try { + const focusedValue = interaction.options.getFocused(); + const userOptionId = interaction.options.get("user")?.value; - if (!playlistName) { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.steal.messages.provide_playlist"), - color: this.client.color.red, - }, - ], - }); - } + if (!userOptionId) { + await interaction.respond([{ name: "Please specify a user to search their playlists.", value: "NoUser" }]).catch(console.error); + return; + } - if (!targetUserId) { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.steal.messages.provide_user"), - color: this.client.color.red, - }, - ], - }); - } + const user = await interaction.client.users.fetch(userOptionId); + if (!user) { + await interaction.respond([{ name: "User not found.", value: "NoUserFound" }]).catch(console.error); + return; + } - try { - const targetPlaylist = await client.db.getPlaylist(targetUserId, playlistName); - - if (!targetPlaylist) { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.steal.messages.playlist_not_exist"), - color: this.client.color.red, - }, - ], - }); - } - - const targetSongs = await client.db.getSongs(targetUserId, playlistName); - - const existingPlaylist = await client.db.getPlaylist(ctx.author.id, playlistName); - if (existingPlaylist) { - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.steal.messages.playlist_exists", { playlist: playlistName }), - color: this.client.color.red, - }, - ], - }); - } - - await client.db.createPlaylistWithSongs(ctx.author.id, playlistName, targetSongs); - - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.steal.messages.playlist_stolen", { - playlist: playlistName, - user: targetUser.username, - }), - color: this.client.color.main, - }, - ], - }); - } catch (error) { - console.error(error); - return await ctx.sendMessage({ - embeds: [ - { - description: ctx.locale("cmd.steal.messages.error_occurred"), - color: this.client.color.red, - }, - ], - }); - } - } + const playlists = await this.client.db.getUserPlaylists(user.id); - public async autocomplete(interaction) { - try { - const focusedValue = interaction.options.getFocused(); - const userOptionId = interaction.options.get("user")?.value; - - if (!userOptionId) { - await interaction - .respond([{ name: "Please specify a user to search their playlists.", value: "NoUser" }]) - .catch(console.error); - return; - } - - const user = await interaction.client.users.fetch(userOptionId); - if (!user) { - await interaction.respond([{ name: "User not found.", value: "NoUserFound" }]).catch(console.error); - return; - } - - const playlists = await this.client.db.getUserPlaylists(user.id); - - if (!playlists || playlists.length === 0) { - await interaction.respond([{ name: "No playlists found for this user.", value: "NoPlaylists" }]).catch(console.error); - return; - } - - const filtered = playlists.filter((playlist) => playlist.name.toLowerCase().startsWith(focusedValue.toLowerCase())); - - return await interaction - .respond(filtered.map((playlist) => ({ name: playlist.name, value: playlist.name }))) - .catch(console.error); - } catch (error) { - console.error("Error in autocomplete interaction:", error); - return await interaction - .respond([{ name: "An error occurred while fetching playlists.", value: "Error" }]) - .catch(console.error); - } + if (!playlists || playlists.length === 0) { + await interaction.respond([{ name: "No playlists found for this user.", value: "NoPlaylists" }]).catch(console.error); + return; + } + + const filtered = playlists.filter((playlist) => playlist.name.toLowerCase().startsWith(focusedValue.toLowerCase())); + + return await interaction.respond(filtered.map((playlist) => ({ name: playlist.name, value: playlist.name }))).catch(console.error); + } catch (error) { + console.error("Error in autocomplete interaction:", error); + return await interaction.respond([{ name: "An error occurred while fetching playlists.", value: "Error" }]).catch(console.error); } + } } /** diff --git a/src/config.ts b/src/config.ts index 34257ddd3..021447195 100644 --- a/src/config.ts +++ b/src/config.ts @@ -2,80 +2,80 @@ import "dotenv/config"; import { SearchEngine } from "./types.js"; const parseBoolean = (value) => { - if (typeof value !== "string") return false; - return value.trim().toLowerCase() === "true"; + if (typeof value !== "string") return false; + return value.trim().toLowerCase() === "true"; }; export default { - token: process.env.TOKEN, - prefix: process.env.PREFIX, - color: { - red: 0xff0000, - green: 0x00ff00, - blue: 0x0000ff, - yellow: 0xffff00, - main: 0x2f3136, + token: process.env.TOKEN, + prefix: process.env.PREFIX, + color: { + red: 0xff0000, + green: 0x00ff00, + blue: 0x0000ff, + yellow: 0xffff00, + main: 0x2f3136, + }, + emoji: { + // You can add custom emoji with ID format (e.g., <:emojiName:123456789012345678>) + pause: "⏸️", + resume: "▶️", + stop: "⏹️", + skip: "⏭️", + previous: "⏮️", + forward: "⏩", + rewind: "⏪", + voldown: "🔉", + volup: "🔊", + shuffle: "🔀", + loop: { + none: "🔁", + track: "🔂", }, - emoji: { - // You can add custom emoji with ID format (e.g., <:emojiName:123456789012345678>) - pause: "⏸️", - resume: "▶️", - stop: "⏹️", - skip: "⏩", - previous: "⏪", - forward: "⏭️", - replay: "🔄", - voldown: "🔉", - volup: "🔊", - shuffle: "🔀", - loop: { - none: "🔁", - track: "🔂", - }, - page: { - last: "⏩", - first: "⏪", - back: "⬅️", - next: "➡️", - cancel: "⏹️", - }, + page: { + last: "⏩", + first: "⏪", + back: "⬅️", + next: "➡️", + cancel: "⏹️", }, - defaultLanguage: process.env.DEFAULT_LANGUAGE, - topGG: process.env.TOPGG, - keepAlive: parseBoolean(process.env.KEEP_ALIVE), - autoNode: parseBoolean(process.env.AUTO_NODE), - searchEngine: SearchEngine[process.env.SEARCH_ENGINE] || SearchEngine.YouTubeMusic, - maxPlaylistSize: parseInt(process.env.MAX_PLAYLIST_SIZE || "100"), - botStatus: process.env.BOT_STATUS || "online", - botActivity: process.env.BOT_ACTIVITY || "Lavamusic", - botActivityType: parseInt(process.env.BOT_ACTIVITY_TYPE || "2"), - maxQueueSize: parseInt(process.env.MAX_QUEUE_SIZE || "100"), - owners: process.env.OWNER_IDS ? JSON.parse(process.env.OWNER_IDS) : [], - clientId: process.env.CLIENT_ID, - guildId: process.env.GUILD_ID, - logChannelId: process.env.LOG_CHANNEL_ID, - commandLogs: process.env.LOG_COMMANDS_ID, - links: { - img: process.env.IMG_LINK || "https://i.imgur.com/ud3EWNh.jpg", - }, - icons: { - youtube: "https://i.imgur.com/xzVHhFY.png", - spotify: "https://i.imgur.com/qvdqtsc.png", - soundcloud: "https://i.imgur.com/MVnJ7mj.png", - applemusic: "https://i.imgur.com/Wi0oyYm.png", - deezer: "https://i.imgur.com/xyZ43FG.png", - jiosaavn: "https://i.imgur.com/N9Nt80h.png", - }, - lavalink: process.env.LAVALINK_SERVERS - ? JSON.parse(process.env.LAVALINK_SERVERS).map((server) => { - return { - url: server.url, - auth: server.auth, - name: server.name, - secure: parseBoolean(server.secure), - }; - }) - : [], + }, + defaultLanguage: process.env.DEFAULT_LANGUAGE, + topGG: process.env.TOPGG, + keepAlive: parseBoolean(process.env.KEEP_ALIVE), + autoNode: parseBoolean(process.env.AUTO_NODE), + searchEngine: SearchEngine[process.env.SEARCH_ENGINE] || SearchEngine.YouTubeMusic, + maxPlaylistSize: parseInt(process.env.MAX_PLAYLIST_SIZE || "100"), + botStatus: process.env.BOT_STATUS || "online", + botActivity: process.env.BOT_ACTIVITY || "Lavamusic", + botActivityType: parseInt(process.env.BOT_ACTIVITY_TYPE || "2"), + maxQueueSize: parseInt(process.env.MAX_QUEUE_SIZE || "100"), + owners: process.env.OWNER_IDS ? JSON.parse(process.env.OWNER_IDS) : [], + clientId: process.env.CLIENT_ID, + guildId: process.env.GUILD_ID, + logChannelId: process.env.LOG_CHANNEL_ID, + commandLogs: process.env.LOG_COMMANDS_ID, + links: { + img: process.env.IMG_LINK || "https://i.imgur.com/ud3EWNh.jpg", + }, + icons: { + youtube: "https://i.imgur.com/xzVHhFY.png", + spotify: "https://i.imgur.com/qvdqtsc.png", + soundcloud: "https://i.imgur.com/MVnJ7mj.png", + applemusic: "https://i.imgur.com/Wi0oyYm.png", + deezer: "https://i.imgur.com/xyZ43FG.png", + jiosaavn: "https://i.imgur.com/N9Nt80h.png", + }, + lavalink: process.env.LAVALINK_SERVERS + ? JSON.parse(process.env.LAVALINK_SERVERS).map((server) => { + return { + url: server.url, + auth: server.auth, + name: server.name, + secure: parseBoolean(server.secure), + }; + }) + : [], }; /** diff --git a/src/database/server.ts b/src/database/server.ts index 2850aa980..6f6df052f 100644 --- a/src/database/server.ts +++ b/src/database/server.ts @@ -2,221 +2,211 @@ import { type Dj, type Guild, type Playlist, PrismaClient, type Role, type Setup import config from "../config.js"; export default class ServerData { - private prisma: PrismaClient; - - constructor() { - this.prisma = new PrismaClient(); - } - - public async get(guildId: string): Promise { - return ( - (await this.prisma.guild.findUnique({ - where: { guildId }, - })) ?? this.createGuild(guildId) - ); - } - - private async createGuild(guildId: string): Promise { - return await this.prisma.guild.create({ - data: { guildId, prefix: config.prefix }, - }); - } - - public async setPrefix(guildId: string, prefix: string): Promise { - await this.prisma.guild.upsert({ - where: { guildId }, - update: { prefix }, - create: { guildId, prefix }, - }); - } - - public async set_247(guildId: string, textId: string, voiceId: string): Promise { - await this.prisma.stay.upsert({ - where: { guildId }, - update: { textId, voiceId }, - create: { guildId, textId, voiceId }, - }); - } - - public async delete_247(guildId: string): Promise { - await this.prisma.stay.delete({ where: { guildId } }); - } - - public async setDj(guildId: string, mode: boolean): Promise { - await this.prisma.dj.upsert({ - where: { guildId }, - update: { mode }, - create: { guildId, mode }, - }); - } - - public async get_247(guildId?: string): Promise { - if (guildId) { - return await this.prisma.stay.findUnique({ where: { guildId } }); - } - return this.prisma.stay.findMany(); - } - - public async getDj(guildId: string): Promise { - return await this.prisma.dj.findUnique({ where: { guildId } }); - } - - public async getRoles(guildId: string): Promise { - return await this.prisma.role.findMany({ where: { guildId } }); - } - - public async addRole(guildId: string, roleId: string): Promise { - await this.prisma.role.create({ data: { guildId, roleId } }); - } - - public async removeRole(guildId: string, roleId: string): Promise { - await this.prisma.role.deleteMany({ where: { guildId, roleId } }); - } - - public async clearRoles(guildId: string): Promise { - await this.prisma.role.deleteMany({ where: { guildId } }); - } - - public async getSetup(guildId: string): Promise { - return await this.prisma.setup.findUnique({ where: { guildId } }); - } - - public async setSetup(guildId: string, textId: string, messageId: string): Promise { - await this.prisma.setup.upsert({ - where: { guildId }, - update: { textId, messageId }, - create: { guildId, textId, messageId }, - }); - } - - public async deleteSetup(guildId: string): Promise { - await this.prisma.setup.delete({ where: { guildId } }); - } - - public async getPlaylist(userId: string, name: string): Promise { - return await this.prisma.playlist.findUnique({ - where: { userId_name: { userId, name } }, - }); - } - - public async getUserPlaylists(userId: string) { - return await this.prisma.playlist.findMany({ - where: { - userId: userId, - }, - }); - } - - public async createPlaylistWithSongs(userId: string, name: string, songs: any[]): Promise { - await this.prisma.playlist.create({ - data: { - userId, - name, - songs: { - create: songs.map((song) => ({ track: song.track })), - }, - }, - }); - } - - public async createPlaylist(userId: string, name: string): Promise { - await this.prisma.playlist.create({ data: { userId, name } }); - } - - public async deletePlaylist(userId: string, name: string): Promise { - await this.prisma.playlist.delete({ - where: { userId_name: { userId, name } }, - }); - } - - public async deleteSongsFromPlaylist(userId: string, playlistName: string): Promise { - const playlist = await this.getPlaylist(userId, playlistName); - if (playlist) { - await this.prisma.song.deleteMany({ - where: { - playlistId: playlist.id, - }, - }); - } - } - - public async addSong(userId: string, name: string, song: string): Promise { - const playlist = await this.getPlaylist(userId, name); - if (playlist) { - await this.prisma.song.create({ - data: { - track: JSON.stringify(song), - playlistId: playlist.id, - }, - }); - } else { - await this.createPlaylist(userId, name); - await this.addSong(userId, name, song); - } - } - - public async removeSong(userId: string, playlistName: string, encodedSong: string): Promise { - const playlist = await this.getPlaylist(userId, playlistName); - if (playlist) { - await this.prisma.song.deleteMany({ - where: { - playlistId: playlist.id, - track: { - contains: encodedSong, - }, - }, - }); - } - } - - public async getSongs(userId: string, name: string): Promise { - const playlist = await this.getPlaylist(userId, name); - if (playlist) { - return this.prisma.song.findMany({ - where: { playlistId: playlist.id }, - }); - } - return []; - } - - public async clearPlaylist(userId: string, name: string): Promise { - const playlist = await this.getPlaylist(userId, name); - if (playlist) { - await this.prisma.song.deleteMany({ - where: { playlistId: playlist.id }, - }); - } - } - - public async clearPlaylists(userId: string): Promise { - await this.prisma.playlist.deleteMany({ where: { userId } }); - } - - public async clearAllPlaylists(): Promise { - await this.prisma.playlist.deleteMany(); - } - - public async clearAllSongs(): Promise { - await this.prisma.song.deleteMany(); - } - - public async updateLanguage(guildId: string, language: string): Promise { - const guild = await this.get(guildId); - if (guild) { - await this.prisma.guild.update({ - where: { guildId }, - data: { language }, - }); - } else { - await this.createGuild(guildId); - await this.updateLanguage(guildId, language); - } - } - - public async getLanguage(guildId: string): Promise { - const guild = await this.get(guildId); - return guild?.language ?? config.defaultLanguage; - } + private prisma: PrismaClient; + + constructor() { + this.prisma = new PrismaClient(); + } + + public async get(guildId: string): Promise { + return (await this.prisma.guild.findUnique({ where: { guildId } })) ?? this.createGuild(guildId); + } + + private async createGuild(guildId: string): Promise { + return await this.prisma.guild.create({ + data: { + guildId, + prefix: config.prefix, + }, + }); + } + + public async setPrefix(guildId: string, prefix: string): Promise { + await this.prisma.guild.upsert({ + where: { guildId }, + update: { prefix }, + create: { guildId, prefix }, + }); + } + + public async getPrefix(guildId: string): Promise { + const guild = await this.get(guildId); + return guild?.prefix ?? config.prefix; + } + + public async updateLanguage(guildId: string, language: string): Promise { + await this.prisma.guild.update({ + where: { guildId }, + data: { language }, + }); + } + + public async getLanguage(guildId: string): Promise { + const guild = await this.get(guildId); + return guild?.language ?? config.defaultLanguage; + } + + public async getSetup(guildId: string): Promise { + return await this.prisma.setup.findUnique({ where: { guildId } }); + } + + public async setSetup(guildId: string, textId: string, messageId: string): Promise { + await this.prisma.setup.upsert({ + where: { guildId }, + update: { textId, messageId }, + create: { guildId, textId, messageId }, + }); + } + + public async deleteSetup(guildId: string): Promise { + await this.prisma.setup.delete({ where: { guildId } }); + } + + public async set_247(guildId: string, textId: string, voiceId: string): Promise { + await this.prisma.stay.upsert({ + where: { guildId }, + update: { textId, voiceId }, + create: { guildId, textId, voiceId }, + }); + } + + public async delete_247(guildId: string): Promise { + await this.prisma.stay.delete({ where: { guildId } }); + } + + public async get_247(guildId?: string): Promise { + if (guildId) { + return await this.prisma.stay.findUnique({ where: { guildId } }); + } + return this.prisma.stay.findMany(); + } + + public async setDj(guildId: string, mode: boolean): Promise { + await this.prisma.dj.upsert({ + where: { guildId }, + update: { mode }, + create: { guildId, mode }, + }); + } + + public async getDj(guildId: string): Promise { + return await this.prisma.dj.findUnique({ where: { guildId } }); + } + + public async getRoles(guildId: string): Promise { + return await this.prisma.role.findMany({ where: { guildId } }); + } + + public async addRole(guildId: string, roleId: string): Promise { + await this.prisma.role.create({ data: { guildId, roleId } }); + } + + public async removeRole(guildId: string, roleId: string): Promise { + await this.prisma.role.deleteMany({ where: { guildId, roleId } }); + } + + public async clearRoles(guildId: string): Promise { + await this.prisma.role.deleteMany({ where: { guildId } }); + } + + public async getPlaylist(userId: string, name: string): Promise { + return await this.prisma.playlist.findUnique({ + where: { userId_name: { userId, name } }, + }); + } + + public async getUserPlaylists(userId: string): Promise { + return await this.prisma.playlist.findMany({ + where: { userId }, + }); + } + + public async createPlaylist(userId: string, name: string): Promise { + await this.prisma.playlist.create({ data: { userId, name } }); + } + + public async createPlaylistWithSongs(userId: string, name: string, songs: any[]): Promise { + await this.prisma.playlist.create({ + data: { + userId, + name, + songs: { + create: songs.map((song) => ({ track: song.track })), + }, + }, + }); + } + + public async deletePlaylist(userId: string, name: string): Promise { + await this.prisma.playlist.delete({ + where: { userId_name: { userId, name } }, + }); + } + + public async deleteSongsFromPlaylist(userId: string, playlistName: string): Promise { + const playlist = await this.getPlaylist(userId, playlistName); + if (playlist) { + await this.prisma.song.deleteMany({ + where: { + playlistId: playlist.id, + }, + }); + } + } + + public async addSong(userId: string, name: string, song: string): Promise { + const playlist = await this.getPlaylist(userId, name); + if (playlist) { + await this.prisma.song.create({ + data: { + track: JSON.stringify(song), + playlistId: playlist.id, + }, + }); + } else { + await this.createPlaylist(userId, name); + await this.addSong(userId, name, song); + } + } + + public async removeSong(userId: string, playlistName: string, encodedSong: string): Promise { + const playlist = await this.getPlaylist(userId, playlistName); + if (playlist) { + await this.prisma.song.deleteMany({ + where: { + playlistId: playlist.id, + track: { contains: encodedSong }, + }, + }); + } + } + + public async getSongs(userId: string, name: string): Promise { + const playlist = await this.getPlaylist(userId, name); + if (playlist) { + return this.prisma.song.findMany({ where: { playlistId: playlist.id } }); + } + return []; + } + + public async clearPlaylist(userId: string, name: string): Promise { + const playlist = await this.getPlaylist(userId, name); + if (playlist) { + await this.prisma.song.deleteMany({ where: { playlistId: playlist.id } }); + } + } + + public async clearPlaylists(userId: string): Promise { + await this.prisma.playlist.deleteMany({ where: { userId } }); + } + + public async clearAllPlaylists(): Promise { + await this.prisma.playlist.deleteMany(); + } + + public async clearAllSongs(): Promise { + await this.prisma.song.deleteMany(); + } } /** diff --git a/src/events/client/ChannelDelete.ts b/src/events/client/ChannelDelete.ts index 1fc1ceeaf..e873a698f 100644 --- a/src/events/client/ChannelDelete.ts +++ b/src/events/client/ChannelDelete.ts @@ -1,42 +1,39 @@ import { Event, type Lavamusic } from "../../structures/index.js"; export default class ChannelDelete extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "channelDelete", - }); - } + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "channelDelete", + }); + } - public async run(channel: any): Promise { - const { guild } = channel; - const setup = await this.client.db.getSetup(guild.id); - const stay = await this.client.db.get_247(guild.id); + public async run(channel: any): Promise { + const { guild } = channel; + const setup = await this.client.db.getSetup(guild.id); + const stay = await this.client.db.get_247(guild.id); - if (Array.isArray(stay)) { - for (const s of stay) { - if (channel.type === 2 && s.voiceId === channel.id) { - await this.client.db.delete_247(guild.id); - break; - } - } - } else if (stay) { - if (channel.type === 2 && stay.voiceId === channel.id) { - await this.client.db.delete_247(guild.id); - } + if (Array.isArray(stay)) { + for (const s of stay) { + if (channel.type === 2 && s.voiceId === channel.id) { + await this.client.db.delete_247(guild.id); + break; } + } + } else if (stay) { + if (channel.type === 2 && stay.voiceId === channel.id) { + await this.client.db.delete_247(guild.id); + } + } - if (setup && channel.type === 0 && setup.textId === channel.id) { - await this.client.db.deleteSetup(guild.id); - } + if (setup && channel.type === 0 && setup.textId === channel.id) { + await this.client.db.deleteSetup(guild.id); + } - const queue = this.client.queue.get(guild.id); - if (queue) { - if ( - queue.channelId === channel.id || - (queue.player && queue.node.manager.connections.get(guild.id)!.channelId === channel.id) - ) { - queue.stop(); - } - } + const queue = this.client.queue.get(guild.id); + if (queue) { + if (queue.channelId === channel.id || (queue.player && queue.node.manager.connections.get(guild.id)!.channelId === channel.id)) { + queue.stop(); + } } + } } diff --git a/src/events/client/GuildCreate.ts b/src/events/client/GuildCreate.ts index e7b2a27e4..dff12b95e 100644 --- a/src/events/client/GuildCreate.ts +++ b/src/events/client/GuildCreate.ts @@ -2,73 +2,73 @@ import { EmbedBuilder, type Guild, type GuildMember, type TextChannel } from "di import { Event, type Lavamusic } from "../../structures/index.js"; export default class GuildCreate extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "guildCreate", - }); - } + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "guildCreate", + }); + } - public async run(guild: Guild): Promise { - let owner: GuildMember | undefined; - try { - owner = await guild.members.fetch(guild.ownerId); - } catch (e) { - this.client.logger.error(`Error fetching owner for guild ${guild.id}: ${e}`); - } + public async run(guild: Guild): Promise { + let owner: GuildMember | undefined; + try { + owner = await guild.members.fetch(guild.ownerId); + } catch (e) { + this.client.logger.error(`Error fetching owner for guild ${guild.id}: ${e}`); + } - const embed = new EmbedBuilder() - .setColor(this.client.config.color.green) - .setAuthor({ - name: guild.name, - iconURL: guild.iconURL({ extension: "jpeg" }), - }) - .setDescription(`**${guild.name}** has been added to my guilds!`) - .setThumbnail(guild.iconURL({ extension: "jpeg" })) - .addFields( - { - name: "Owner", - value: owner ? owner.user.tag : "Unknown#0000", - inline: true, - }, - { - name: "Members", - value: guild.memberCount.toString(), - inline: true, - }, - { - name: "Created At", - value: ``, - inline: true, - }, - { - name: "Joined At", - value: ``, - inline: true, - }, - { name: "ID", value: guild.id, inline: true }, - ) - .setTimestamp(); + const embed = new EmbedBuilder() + .setColor(this.client.config.color.green) + .setAuthor({ + name: guild.name, + iconURL: guild.iconURL({ extension: "jpeg" }), + }) + .setDescription(`**${guild.name}** has been added to my guilds!`) + .setThumbnail(guild.iconURL({ extension: "jpeg" })) + .addFields( + { + name: "Owner", + value: owner ? owner.user.tag : "Unknown#0000", + inline: true, + }, + { + name: "Members", + value: guild.memberCount.toString(), + inline: true, + }, + { + name: "Created At", + value: ``, + inline: true, + }, + { + name: "Joined At", + value: ``, + inline: true, + }, + { name: "ID", value: guild.id, inline: true }, + ) + .setTimestamp(); - const logChannelId = this.client.config.logChannelId; - if (!logChannelId) { - this.client.logger.error("Log channel ID not found in configuration."); - return; - } + const logChannelId = this.client.config.logChannelId; + if (!logChannelId) { + this.client.logger.error("Log channel ID not found in configuration."); + return; + } - try { - const channel = (await this.client.channels.fetch(logChannelId)) as TextChannel; - if (!channel) { - this.client.logger.error( - `Log channel not found with ID ${logChannelId}. Please change the settings in .env or, if you have a channel, invite me to that guild.`, - ); - return; - } + try { + const channel = (await this.client.channels.fetch(logChannelId)) as TextChannel; + if (!channel) { + this.client.logger.error( + `Log channel not found with ID ${logChannelId}. Please change the settings in .env or, if you have a channel, invite me to that guild.`, + ); + return; + } - await channel.send({ embeds: [embed] }); - } catch (error) { - this.client.logger.error(`Error sending message to log channel ${logChannelId}: ${error}`); - } + await channel.send({ embeds: [embed] }); + } catch (error) { + this.client.logger.error(`Error sending message to log channel ${logChannelId}: ${error}`); } + } } /** diff --git a/src/events/client/GuildDelete.ts b/src/events/client/GuildDelete.ts index 9df21f6f8..4b813c00c 100644 --- a/src/events/client/GuildDelete.ts +++ b/src/events/client/GuildDelete.ts @@ -2,72 +2,72 @@ import { EmbedBuilder, type Guild, type GuildMember, type TextChannel } from "di import { Event, type Lavamusic } from "../../structures/index.js"; export default class GuildDelete extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "guildDelete", - }); - } + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "guildDelete", + }); + } - public async run(guild: Guild): Promise { - let owner: GuildMember | undefined; - try { - owner = await guild.members.fetch(guild.ownerId); - } catch (error) { - this.client.logger.error(`Error fetching owner for guild ${guild.id}: ${error}`); - } + public async run(guild: Guild): Promise { + let owner: GuildMember | undefined; + try { + owner = await guild.members.fetch(guild.ownerId); + } catch (error) { + this.client.logger.error(`Error fetching owner for guild ${guild.id}: ${error}`); + } - const embed = new EmbedBuilder() - .setColor(this.client.config.color.red) - .setAuthor({ - name: guild.name || "Unknown Guild", - iconURL: guild.iconURL({ extension: "jpeg" }), - }) - .setDescription(`**${guild.name}** has been removed from my guilds!`) - .setThumbnail(guild.iconURL({ extension: "jpeg" })) - .addFields( - { - name: "Owner", - value: owner ? owner.user.tag : "Unknown#0000", - inline: true, - }, - { - name: "Members", - value: guild.memberCount?.toString() || "Unknown", - inline: true, - }, - { - name: "Created At", - value: ``, - inline: true, - }, - { - name: "Removed At", - value: ``, - inline: true, - }, - { name: "ID", value: guild.id, inline: true }, - ) - .setTimestamp(); + const embed = new EmbedBuilder() + .setColor(this.client.config.color.red) + .setAuthor({ + name: guild.name || "Unknown Guild", + iconURL: guild.iconURL({ extension: "jpeg" }), + }) + .setDescription(`**${guild.name}** has been removed from my guilds!`) + .setThumbnail(guild.iconURL({ extension: "jpeg" })) + .addFields( + { + name: "Owner", + value: owner ? owner.user.tag : "Unknown#0000", + inline: true, + }, + { + name: "Members", + value: guild.memberCount?.toString() || "Unknown", + inline: true, + }, + { + name: "Created At", + value: ``, + inline: true, + }, + { + name: "Removed At", + value: ``, + inline: true, + }, + { name: "ID", value: guild.id, inline: true }, + ) + .setTimestamp(); - const logChannelId = this.client.config.logChannelId; - if (!logChannelId) { - this.client.logger.error("Log channel ID not found in configuration."); - return; - } + const logChannelId = this.client.config.logChannelId; + if (!logChannelId) { + this.client.logger.error("Log channel ID not found in configuration."); + return; + } - try { - const channel = (await this.client.channels.fetch(logChannelId)) as TextChannel; - if (!channel) { - this.client.logger.error( - `Log channel not found with ID ${logChannelId}. Please change the settings in .env or, if you have a channel, invite me to that guild.`, - ); - return; - } - await channel.send({ embeds: [embed] }); - } catch (error) { - this.client.logger.error(`Error sending message to log channel ${logChannelId}: ${error}`); - } + try { + const channel = (await this.client.channels.fetch(logChannelId)) as TextChannel; + if (!channel) { + this.client.logger.error( + `Log channel not found with ID ${logChannelId}. Please change the settings in .env or, if you have a channel, invite me to that guild.`, + ); + return; + } + await channel.send({ embeds: [embed] }); + } catch (error) { + this.client.logger.error(`Error sending message to log channel ${logChannelId}: ${error}`); } + } } /** diff --git a/src/events/client/InteractionCreate.ts b/src/events/client/InteractionCreate.ts index 800f563ac..6f7c8ab7b 100644 --- a/src/events/client/InteractionCreate.ts +++ b/src/events/client/InteractionCreate.ts @@ -1,258 +1,249 @@ import { - ActionRowBuilder, - type AutocompleteInteraction, - ButtonBuilder, - ButtonStyle, - ChannelType, - Collection, - CommandInteraction, - EmbedBuilder, - type GuildMember, - InteractionType, - PermissionFlagsBits, - type TextChannel, + ActionRowBuilder, + type AutocompleteInteraction, + ButtonBuilder, + ButtonStyle, + ChannelType, + Collection, + CommandInteraction, + EmbedBuilder, + type GuildMember, + InteractionType, + PermissionFlagsBits, + type TextChannel, } from "discord.js"; import { T } from "../../structures/I18n.js"; import { Context, Event, type Lavamusic } from "../../structures/index.js"; export default class InteractionCreate extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "interactionCreate", - }); - } - - public async run(interaction: CommandInteraction | AutocompleteInteraction): Promise { - if (interaction instanceof CommandInteraction && interaction.isCommand()) { - const setup = await this.client.db.getSetup(interaction.guildId); - const allowedCategories = ["filters", "music", "playlist"]; - const commandInSetup = this.client.commands.get(interaction.commandName); - const locale = await this.client.db.getLanguage(interaction.guildId); + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "interactionCreate", + }); + } - if ( - setup && - interaction.channelId === setup.textId && - !(commandInSetup && allowedCategories.includes(commandInSetup.category)) - ) { - return await interaction.reply({ - content: T(locale, "event.interaction.setup_channel"), - ephemeral: true, - }); - } + public async run(interaction: CommandInteraction | AutocompleteInteraction): Promise { + if (interaction instanceof CommandInteraction && interaction.isCommand()) { + const setup = await this.client.db.getSetup(interaction.guildId); + const allowedCategories = ["filters", "music", "playlist"]; + const commandInSetup = this.client.commands.get(interaction.commandName); + const locale = await this.client.db.getLanguage(interaction.guildId); - const { commandName } = interaction; - await this.client.db.get(interaction.guildId); + if (setup && interaction.channelId === setup.textId && !(commandInSetup && allowedCategories.includes(commandInSetup.category))) { + return await interaction.reply({ + content: T(locale, "event.interaction.setup_channel"), + ephemeral: true, + }); + } - const command = this.client.commands.get(commandName); - if (!command) return; + const { commandName } = interaction; + await this.client.db.get(interaction.guildId); - const ctx = new Context(interaction as any, interaction.options.data as any); - ctx.setArgs(interaction.options.data as any); - ctx.guildLocale = locale; - const clientMember = interaction.guild.members.resolve(this.client.user); - if (!(interaction.inGuild() && interaction.channel.permissionsFor(clientMember)?.has(PermissionFlagsBits.ViewChannel))) return; + const command = this.client.commands.get(commandName); + if (!command) return; - if ( - !( - clientMember.permissions.has(PermissionFlagsBits.ViewChannel) && - clientMember.permissions.has(PermissionFlagsBits.SendMessages) && - clientMember.permissions.has(PermissionFlagsBits.EmbedLinks) && - clientMember.permissions.has(PermissionFlagsBits.ReadMessageHistory) - ) - ) { - return await (interaction.member as GuildMember) - .send({ - content: T(locale, "event.interaction.no_send_message"), - }) - .catch(() => {}); - } + const ctx = new Context(interaction as any, interaction.options.data as any); + ctx.setArgs(interaction.options.data as any); + ctx.guildLocale = locale; + const clientMember = interaction.guild.members.resolve(this.client.user); + if (!(interaction.inGuild() && interaction.channel.permissionsFor(clientMember)?.has(PermissionFlagsBits.ViewChannel))) return; - const logs = this.client.channels.cache.get(this.client.config.commandLogs); + if ( + !( + clientMember.permissions.has(PermissionFlagsBits.ViewChannel) && + clientMember.permissions.has(PermissionFlagsBits.SendMessages) && + clientMember.permissions.has(PermissionFlagsBits.EmbedLinks) && + clientMember.permissions.has(PermissionFlagsBits.ReadMessageHistory) + ) + ) { + return await (interaction.member as GuildMember) + .send({ + content: T(locale, "event.interaction.no_send_message"), + }) + .catch(() => {}); + } - if (command.permissions) { - if (command.permissions?.client) { - const missingClientPermissions = command.permissions.client.filter((perm) => !clientMember.permissions.has(perm)); + const logs = this.client.channels.cache.get(this.client.config.commandLogs); - if (missingClientPermissions.length > 0) { - return await interaction.reply({ - content: T(locale, "event.interaction.no_permission", { - permissions: missingClientPermissions.map((perm) => `\`${perm}\``).join(", "), - }), - ephemeral: true, - }); - } - } + if (command.permissions) { + if (command.permissions?.client) { + const missingClientPermissions = command.permissions.client.filter((perm) => !clientMember.permissions.has(perm)); - if (command.permissions?.user && !(interaction.member as GuildMember).permissions.has(command.permissions.user)) { - await interaction.reply({ - content: T(locale, "event.interaction.no_user_permission"), - ephemeral: true, - }); - return; - } + if (missingClientPermissions.length > 0) { + return await interaction.reply({ + content: T(locale, "event.interaction.no_permission", { + permissions: missingClientPermissions.map((perm) => `\`${perm}\``).join(", "), + }), + ephemeral: true, + }); + } + } - if (command.permissions?.dev && this.client.config.owners) { - const isDev = this.client.config.owners.includes(interaction.user.id); - if (!isDev) return; - } - } - if (command.vote && this.client.config.topGG) { - const voted = await this.client.topGG.hasVoted(interaction.user.id); - if (!voted) { - const voteBtn = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setLabel(T(locale, "event.interaction.vote_button")) - .setURL(`https://top.gg/bot/${this.client.config.clientId}/vote`) - .setStyle(ButtonStyle.Link), - ); + if (command.permissions?.user && !(interaction.member as GuildMember).permissions.has(command.permissions.user)) { + await interaction.reply({ + content: T(locale, "event.interaction.no_user_permission"), + ephemeral: true, + }); + return; + } - return await interaction.reply({ - content: T(locale, "event.interaction.vote_message"), - components: [voteBtn], - ephemeral: true, - }); - } - } - if (command.player) { - if (command.player.voice) { - if (!(interaction.member as GuildMember).voice.channel) { - return await interaction.reply({ - content: T(locale, "event.interaction.no_voice_channel", { command: command.name }), - }); - } + if (command.permissions?.dev && this.client.config.owners) { + const isDev = this.client.config.owners.includes(interaction.user.id); + if (!isDev) return; + } + } + if (command.vote && this.client.config.topGG) { + const voted = await this.client.topGG.hasVoted(interaction.user.id); + if (!voted) { + const voteBtn = new ActionRowBuilder().addComponents( + new ButtonBuilder() + .setLabel(T(locale, "event.interaction.vote_button")) + .setURL(`https://top.gg/bot/${this.client.config.clientId}/vote`) + .setStyle(ButtonStyle.Link), + ); - if (!clientMember.permissions.has(PermissionFlagsBits.Connect)) { - return await interaction.reply({ - content: T(locale, "event.interaction.no_connect_permission", { command: command.name }), - }); - } + return await interaction.reply({ + content: T(locale, "event.interaction.vote_message"), + components: [voteBtn], + ephemeral: true, + }); + } + } + if (command.player) { + if (command.player.voice) { + if (!(interaction.member as GuildMember).voice.channel) { + return await interaction.reply({ + content: T(locale, "event.interaction.no_voice_channel", { command: command.name }), + }); + } - if (!clientMember.permissions.has(PermissionFlagsBits.Speak)) { - return await interaction.reply({ - content: T(locale, "event.interaction.no_speak_permission", { command: command.name }), - }); - } + if (!clientMember.permissions.has(PermissionFlagsBits.Connect)) { + return await interaction.reply({ + content: T(locale, "event.interaction.no_connect_permission", { command: command.name }), + }); + } - if ( - (interaction.member as GuildMember).voice.channel.type === ChannelType.GuildStageVoice && - !clientMember.permissions.has(PermissionFlagsBits.RequestToSpeak) - ) { - return await interaction.reply({ - content: T(locale, "event.interaction.no_request_to_speak", { command: command.name }), - }); - } + if (!clientMember.permissions.has(PermissionFlagsBits.Speak)) { + return await interaction.reply({ + content: T(locale, "event.interaction.no_speak_permission", { command: command.name }), + }); + } - if ( - clientMember.voice.channel && - clientMember.voice.channelId !== (interaction.member as GuildMember).voice.channelId - ) { - return await interaction.reply({ - content: T(locale, "event.interaction.different_voice_channel", { - channel: `<#${clientMember.voice.channelId}>`, - command: command.name, - }), - }); - } - } + if ( + (interaction.member as GuildMember).voice.channel.type === ChannelType.GuildStageVoice && + !clientMember.permissions.has(PermissionFlagsBits.RequestToSpeak) + ) { + return await interaction.reply({ + content: T(locale, "event.interaction.no_request_to_speak", { command: command.name }), + }); + } - if (command.player.active) { - const queue = this.client.queue.get(interaction.guildId); - if (!(queue?.queue && queue.current)) { - return await interaction.reply({ - content: T(locale, "event.interaction.no_music_playing"), - }); - } - } + if (clientMember.voice.channel && clientMember.voice.channelId !== (interaction.member as GuildMember).voice.channelId) { + return await interaction.reply({ + content: T(locale, "event.interaction.different_voice_channel", { + channel: `<#${clientMember.voice.channelId}>`, + command: command.name, + }), + }); + } + } - if (command.player.dj) { - const dj = await this.client.db.getDj(interaction.guildId); - if (dj?.mode) { - const djRole = await this.client.db.getRoles(interaction.guildId); - if (!djRole) { - return await interaction.reply({ - content: T(locale, "event.interaction.no_dj_role"), - }); - } + if (command.player.active) { + const queue = this.client.queue.get(interaction.guildId); + if (!(queue?.queue && queue.current)) { + return await interaction.reply({ + content: T(locale, "event.interaction.no_music_playing"), + }); + } + } - const hasDJRole = (interaction.member as GuildMember).roles.cache.some((role) => - djRole.map((r) => r.roleId).includes(role.id), - ); - if (!(hasDJRole && !(interaction.member as GuildMember).permissions.has(PermissionFlagsBits.ManageGuild))) { - return await interaction.reply({ - content: T(locale, "event.interaction.no_dj_permission"), - ephemeral: true, - }); - } - } - } + if (command.player.dj) { + const dj = await this.client.db.getDj(interaction.guildId); + if (dj?.mode) { + const djRole = await this.client.db.getRoles(interaction.guildId); + if (!djRole) { + return await interaction.reply({ + content: T(locale, "event.interaction.no_dj_role"), + }); } - if (!this.client.cooldown.has(commandName)) { - this.client.cooldown.set(commandName, new Collection()); + const hasDJRole = (interaction.member as GuildMember).roles.cache.some((role) => djRole.map((r) => r.roleId).includes(role.id)); + if (!(hasDJRole && !(interaction.member as GuildMember).permissions.has(PermissionFlagsBits.ManageGuild))) { + return await interaction.reply({ + content: T(locale, "event.interaction.no_dj_permission"), + ephemeral: true, + }); } + } + } + } - const now = Date.now(); - const timestamps = this.client.cooldown.get(commandName)!; - const cooldownAmount = (command.cooldown || 5) * 1000; + if (!this.client.cooldown.has(commandName)) { + this.client.cooldown.set(commandName, new Collection()); + } - if (timestamps.has(interaction.user.id)) { - const expirationTime = timestamps.get(interaction.user.id)! + cooldownAmount; - const timeLeft = (expirationTime - now) / 1000; - if (now < expirationTime && timeLeft > 0.9) { - return await interaction.reply({ - content: T(locale, "event.interaction.cooldown", { - time: timeLeft.toFixed(1), - command: commandName, - }), - }); - } - timestamps.set(interaction.user.id, now); - setTimeout(() => timestamps.delete(interaction.user.id), cooldownAmount); - } else { - timestamps.set(interaction.user.id, now); - setTimeout(() => timestamps.delete(interaction.user.id), cooldownAmount); - } + const now = Date.now(); + const timestamps = this.client.cooldown.get(commandName)!; + const cooldownAmount = (command.cooldown || 5) * 1000; - try { - await command.run(this.client, ctx, ctx.args); - if (setup && interaction.channelId === setup.textId && allowedCategories.includes(command.category)) { - setTimeout(() => { - interaction.deleteReply().catch(() => {}); - }, 5000); - } - if (logs) { - const embed = new EmbedBuilder() - .setAuthor({ - name: "Slash - Command Logs", - iconURL: this.client.user?.avatarURL({ - size: 2048, - }), - }) - .setColor(this.client.config.color.blue) - .setDescription( - `**\`${command.name}\`** | Used By **${interaction.user.tag} \`${interaction.user.id}\`** From **${interaction.guild.name} \`${interaction.guild.id}\`**`, - ) - .setTimestamp(); + if (timestamps.has(interaction.user.id)) { + const expirationTime = timestamps.get(interaction.user.id)! + cooldownAmount; + const timeLeft = (expirationTime - now) / 1000; + if (now < expirationTime && timeLeft > 0.9) { + return await interaction.reply({ + content: T(locale, "event.interaction.cooldown", { + time: timeLeft.toFixed(1), + command: commandName, + }), + }); + } + timestamps.set(interaction.user.id, now); + setTimeout(() => timestamps.delete(interaction.user.id), cooldownAmount); + } else { + timestamps.set(interaction.user.id, now); + setTimeout(() => timestamps.delete(interaction.user.id), cooldownAmount); + } - await (logs as TextChannel).send({ embeds: [embed] }); - } - } catch (error) { - this.client.logger.error(error); - await interaction.reply({ - content: T(locale, "event.interaction.error", { error }), - }); - } - } else if (interaction.type === InteractionType.ApplicationCommandAutocomplete) { - const command = this.client.commands.get(interaction.commandName); - if (!command) return; + try { + await command.run(this.client, ctx, ctx.args); + if (setup && interaction.channelId === setup.textId && allowedCategories.includes(command.category)) { + setTimeout(() => { + interaction.deleteReply().catch(() => {}); + }, 5000); + } + if (logs) { + const embed = new EmbedBuilder() + .setAuthor({ + name: "Slash - Command Logs", + iconURL: this.client.user?.avatarURL({ + size: 2048, + }), + }) + .setColor(this.client.config.color.blue) + .setDescription( + `**\`${command.name}\`** | Used By **${interaction.user.tag} \`${interaction.user.id}\`** From **${interaction.guild.name} \`${interaction.guild.id}\`**`, + ) + .setTimestamp(); - try { - await command.autocomplete(interaction); - } catch (error) { - console.error(error); - } + await (logs as TextChannel).send({ embeds: [embed] }); } + } catch (error) { + this.client.logger.error(error); + await interaction.reply({ + content: T(locale, "event.interaction.error", { error }), + }); + } + } else if (interaction.type === InteractionType.ApplicationCommandAutocomplete) { + const command = this.client.commands.get(interaction.commandName); + if (!command) return; + + try { + await command.autocomplete(interaction); + } catch (error) { + console.error(error); + } } + } } /** diff --git a/src/events/client/MessageCreate.ts b/src/events/client/MessageCreate.ts index 51fd82ffc..d66231f40 100644 --- a/src/events/client/MessageCreate.ts +++ b/src/events/client/MessageCreate.ts @@ -1,260 +1,258 @@ import { - ActionRowBuilder, - ButtonBuilder, - ButtonStyle, - ChannelType, - Collection, - EmbedBuilder, - type GuildMember, - type Message, - PermissionFlagsBits, - type TextChannel, + ActionRowBuilder, + ButtonBuilder, + ButtonStyle, + ChannelType, + Collection, + EmbedBuilder, + type GuildMember, + type Message, + PermissionFlagsBits, + type TextChannel, } from "discord.js"; import { T } from "../../structures/I18n.js"; import { Context, Event, type Lavamusic } from "../../structures/index.js"; export default class MessageCreate extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "messageCreate", - }); - } + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "messageCreate", + }); + } - public async run(message: Message): Promise { - if (message.author.bot) return; + public async run(message: Message): Promise { + if (message.author.bot) return; - const setup = await this.client.db.getSetup(message.guildId); - if (setup && setup.textId === message.channelId) { - return this.client.emit("setupSystem", message); - } - const locale = await this.client.db.getLanguage(message.guildId); - - const guild = await this.client.db.get(message.guildId); - const mention = new RegExp(`^<@!?${this.client.user.id}>( |)$`); - if (mention.test(message.content)) { - await message.reply({ - content: T(locale, "event.message.prefix_mention", { - prefix: guild.prefix, - }), - }); - return; - } + const setup = await this.client.db.getSetup(message.guildId); + if (setup && setup.textId === message.channelId) { + return this.client.emit("setupSystem", message); + } + const locale = await this.client.db.getLanguage(message.guildId); - const escapeRegex = (str: string): string => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); - const prefixRegex = new RegExp(`^(<@!?${this.client.user.id}>|${escapeRegex(guild.prefix)})\\s*`); - if (!prefixRegex.test(message.content)) return; + const guild = await this.client.db.get(message.guildId); + const mention = new RegExp(`^<@!?${this.client.user.id}>( |)$`); + if (mention.test(message.content)) { + await message.reply({ + content: T(locale, "event.message.prefix_mention", { + prefix: guild.prefix, + }), + }); + return; + } - const [matchedPrefix] = message.content.match(prefixRegex); - const args = message.content.slice(matchedPrefix.length).trim().split(/ +/g); - const cmd = args.shift()?.toLowerCase(); - const command = this.client.commands.get(cmd) || this.client.commands.get(this.client.aliases.get(cmd) as string); - if (!command) return; + const escapeRegex = (str: string): string => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); + const prefixRegex = new RegExp(`^(<@!?${this.client.user.id}>|${escapeRegex(guild.prefix)})\\s*`); + if (!prefixRegex.test(message.content)) return; - const ctx = new Context(message, args); - ctx.setArgs(args); - ctx.guildLocale = locale; + const [matchedPrefix] = message.content.match(prefixRegex); + const args = message.content.slice(matchedPrefix.length).trim().split(/ +/g); + const cmd = args.shift()?.toLowerCase(); + const command = this.client.commands.get(cmd) || this.client.commands.get(this.client.aliases.get(cmd) as string); + if (!command) return; - const clientMember = message.guild.members.resolve(this.client.user); - if (!(message.inGuild() && message.channel.permissionsFor(clientMember)?.has(PermissionFlagsBits.ViewChannel))) return; + const ctx = new Context(message, args); + ctx.setArgs(args); + ctx.guildLocale = locale; - if ( - !( - clientMember.permissions.has(PermissionFlagsBits.ViewChannel) && - clientMember.permissions.has(PermissionFlagsBits.SendMessages) && - clientMember.permissions.has(PermissionFlagsBits.EmbedLinks) && - clientMember.permissions.has(PermissionFlagsBits.ReadMessageHistory) - ) - ) { - return await message.author - .send({ - content: T(locale, "event.message.no_send_message"), - }) - .catch(() => {}); - } + const clientMember = message.guild.members.resolve(this.client.user); + if (!(message.inGuild() && message.channel.permissionsFor(clientMember)?.has(PermissionFlagsBits.ViewChannel))) return; - if (command.permissions) { - if (command.permissions?.client) { - const missingClientPermissions = command.permissions.client.filter((perm) => !clientMember.permissions.has(perm)); + if ( + !( + clientMember.permissions.has(PermissionFlagsBits.ViewChannel) && + clientMember.permissions.has(PermissionFlagsBits.SendMessages) && + clientMember.permissions.has(PermissionFlagsBits.EmbedLinks) && + clientMember.permissions.has(PermissionFlagsBits.ReadMessageHistory) + ) + ) { + return await message.author + .send({ + content: T(locale, "event.message.no_send_message"), + }) + .catch(() => {}); + } - if (missingClientPermissions.length > 0) { - return await message.reply({ - content: T(locale, "event.message.no_permission", { - permissions: missingClientPermissions.map((perm) => `\`${perm}\``).join(", "), - }), - }); - } - } + if (command.permissions) { + if (command.permissions?.client) { + const missingClientPermissions = command.permissions.client.filter((perm) => !clientMember.permissions.has(perm)); - if (command.permissions?.user) { - if (!(message.member as GuildMember).permissions.has(command.permissions.user)) { - return await message.reply({ - content: T(locale, "event.message.no_user_permission"), - }); - } + if (missingClientPermissions.length > 0) { + return await message.reply({ + content: T(locale, "event.message.no_permission", { + permissions: missingClientPermissions.map((perm) => `\`${perm}\``).join(", "), + }), + }); + } + } - if (command.permissions?.dev && this.client.config.owners) { - const isDev = this.client.config.owners.includes(message.author.id); - if (!isDev) return; - } - } + if (command.permissions?.user) { + if (!(message.member as GuildMember).permissions.has(command.permissions.user)) { + return await message.reply({ + content: T(locale, "event.message.no_user_permission"), + }); + } - if (command.vote && this.client.config.topGG) { - const voted = await this.client.topGG.hasVoted(message.author.id); - if (!voted) { - const voteBtn = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setLabel(T(locale, "event.message.vote_button")) - .setURL(`https://top.gg/bot/${this.client.config.clientId}/vote`) - .setStyle(ButtonStyle.Link), - ); + if (command.permissions?.dev && this.client.config.owners) { + const isDev = this.client.config.owners.includes(message.author.id); + if (!isDev) return; + } + } - return await message.reply({ - content: T(locale, "event.message.vote_message"), - components: [voteBtn], - }); - } - } + if (command.vote && this.client.config.topGG) { + const voted = await this.client.topGG.hasVoted(message.author.id); + if (!voted) { + const voteBtn = new ActionRowBuilder().addComponents( + new ButtonBuilder() + .setLabel(T(locale, "event.message.vote_button")) + .setURL(`https://top.gg/bot/${this.client.config.clientId}/vote`) + .setStyle(ButtonStyle.Link), + ); - if (command.player) { - if (command.player.voice) { - if (!(message.member as GuildMember).voice.channel) { - return await message.reply({ - content: T(locale, "event.message.no_voice_channel", { command: command.name }), - }); - } + return await message.reply({ + content: T(locale, "event.message.vote_message"), + components: [voteBtn], + }); + } + } - if (!clientMember.permissions.has(PermissionFlagsBits.Connect)) { - return await message.reply({ - content: T(locale, "event.message.no_connect_permission", { command: command.name }), - }); - } + if (command.player) { + if (command.player.voice) { + if (!(message.member as GuildMember).voice.channel) { + return await message.reply({ + content: T(locale, "event.message.no_voice_channel", { command: command.name }), + }); + } - if (!clientMember.permissions.has(PermissionFlagsBits.Speak)) { - return await message.reply({ - content: T(locale, "event.message.no_speak_permission", { command: command.name }), - }); - } + if (!clientMember.permissions.has(PermissionFlagsBits.Connect)) { + return await message.reply({ + content: T(locale, "event.message.no_connect_permission", { command: command.name }), + }); + } - if ( - (message.member as GuildMember).voice.channel.type === ChannelType.GuildStageVoice && - !clientMember.permissions.has(PermissionFlagsBits.RequestToSpeak) - ) { - return await message.reply({ - content: T(locale, "event.message.no_request_to_speak", { command: command.name }), - }); - } + if (!clientMember.permissions.has(PermissionFlagsBits.Speak)) { + return await message.reply({ + content: T(locale, "event.message.no_speak_permission", { command: command.name }), + }); + } - if (clientMember.voice.channel && clientMember.voice.channelId !== (message.member as GuildMember).voice.channelId) { - return await message.reply({ - content: T(locale, "event.message.different_voice_channel", { - channel: `<#${clientMember.voice.channelId}>`, - command: command.name, - }), - }); - } - } + if ( + (message.member as GuildMember).voice.channel.type === ChannelType.GuildStageVoice && + !clientMember.permissions.has(PermissionFlagsBits.RequestToSpeak) + ) { + return await message.reply({ + content: T(locale, "event.message.no_request_to_speak", { command: command.name }), + }); + } - if (command.player.active) { - const queue = this.client.queue.get(message.guildId); - if (!(queue?.queue && queue.current)) { - return await message.reply({ - content: T(locale, "event.message.no_music_playing"), - }); - } - } + if (clientMember.voice.channel && clientMember.voice.channelId !== (message.member as GuildMember).voice.channelId) { + return await message.reply({ + content: T(locale, "event.message.different_voice_channel", { + channel: `<#${clientMember.voice.channelId}>`, + command: command.name, + }), + }); + } + } - if (command.player.dj) { - const dj = await this.client.db.getDj(message.guildId); - if (dj?.mode) { - const djRole = await this.client.db.getRoles(message.guildId); - if (!djRole) { - return await message.reply({ - content: T(locale, "event.message.no_dj_role"), - }); - } + if (command.player.active) { + const queue = this.client.queue.get(message.guildId); + if (!(queue?.queue && queue.current)) { + return await message.reply({ + content: T(locale, "event.message.no_music_playing"), + }); + } + } - const hasDJRole = (message.member as GuildMember).roles.cache.some((role) => - djRole.map((r) => r.roleId).includes(role.id), - ); - if (!(hasDJRole && !(message.member as GuildMember).permissions.has(PermissionFlagsBits.ManageGuild))) { - return await message.reply({ - content: T(locale, "event.message.no_dj_permission"), - }); - } - } - } + if (command.player.dj) { + const dj = await this.client.db.getDj(message.guildId); + if (dj?.mode) { + const djRole = await this.client.db.getRoles(message.guildId); + if (!djRole) { + return await message.reply({ + content: T(locale, "event.message.no_dj_role"), + }); } - if (command.args && !args.length) { - const embed = this.client - .embed() - .setColor(this.client.color.red) - .setTitle(T(locale, "event.message.missing_arguments")) - .setDescription( - T(locale, "event.message.missing_arguments_description", { - command: command.name, - examples: command.description.examples ? command.description.examples.join("\n") : "None", - }), - ) - .setFooter({ text: T(locale, "event.message.syntax_footer") }); - await message.reply({ embeds: [embed] }); - return; + const hasDJRole = (message.member as GuildMember).roles.cache.some((role) => djRole.map((r) => r.roleId).includes(role.id)); + if (!(hasDJRole && !(message.member as GuildMember).permissions.has(PermissionFlagsBits.ManageGuild))) { + return await message.reply({ + content: T(locale, "event.message.no_dj_permission"), + }); } + } + } + } - if (!this.client.cooldown.has(cmd)) { - this.client.cooldown.set(cmd, new Collection()); - } - const now = Date.now(); - const timestamps = this.client.cooldown.get(cmd)!; - const cooldownAmount = (command.cooldown || 5) * 1000; + if (command.args && !args.length) { + const embed = this.client + .embed() + .setColor(this.client.color.red) + .setTitle(T(locale, "event.message.missing_arguments")) + .setDescription( + T(locale, "event.message.missing_arguments_description", { + command: command.name, + examples: command.description.examples ? command.description.examples.join("\n") : "None", + }), + ) + .setFooter({ text: T(locale, "event.message.syntax_footer") }); + await message.reply({ embeds: [embed] }); + return; + } - if (timestamps.has(message.author.id)) { - const expirationTime = timestamps.get(message.author.id)! + cooldownAmount; - const timeLeft = (expirationTime - now) / 1000; - if (now < expirationTime && timeLeft > 0.9) { - return await message.reply({ - content: T(locale, "event.message.cooldown", { time: timeLeft.toFixed(1), command: cmd }), - }); - } - timestamps.set(message.author.id, now); - setTimeout(() => timestamps.delete(message.author.id), cooldownAmount); - } else { - timestamps.set(message.author.id, now); - setTimeout(() => timestamps.delete(message.author.id), cooldownAmount); - } + if (!this.client.cooldown.has(cmd)) { + this.client.cooldown.set(cmd, new Collection()); + } + const now = Date.now(); + const timestamps = this.client.cooldown.get(cmd)!; + const cooldownAmount = (command.cooldown || 5) * 1000; - if (args.includes("@everyone") || args.includes("@here")) { - return await message.reply({ - content: T(locale, "event.message.no_mention_everyone"), - }); - } + if (timestamps.has(message.author.id)) { + const expirationTime = timestamps.get(message.author.id)! + cooldownAmount; + const timeLeft = (expirationTime - now) / 1000; + if (now < expirationTime && timeLeft > 0.9) { + return await message.reply({ + content: T(locale, "event.message.cooldown", { time: timeLeft.toFixed(1), command: cmd }), + }); + } + timestamps.set(message.author.id, now); + setTimeout(() => timestamps.delete(message.author.id), cooldownAmount); + } else { + timestamps.set(message.author.id, now); + setTimeout(() => timestamps.delete(message.author.id), cooldownAmount); + } - try { - return command.run(this.client, ctx, ctx.args); - } catch (error) { - this.client.logger.error(error); - await message.reply({ - content: T(locale, "event.message.error", { error: error.message || "Unknown error" }), - }); - } finally { - const logs = this.client.channels.cache.get(this.client.config.commandLogs); - if (logs) { - const embed = new EmbedBuilder() - .setAuthor({ - name: "Prefix - Command Logs", - iconURL: this.client.user?.avatarURL({ size: 2048 }), - }) - .setColor(this.client.config.color.green) - .setDescription( - `**\`${command.name}\`** | Used By **${message.author.tag} \`${message.author.id}\`** From **${message.guild.name} \`${message.guild.id}\`**`, - ) - .setTimestamp(); + if (args.includes("@everyone") || args.includes("@here")) { + return await message.reply({ + content: T(locale, "event.message.no_mention_everyone"), + }); + } - await (logs as TextChannel).send({ embeds: [embed] }); - } - } + try { + return command.run(this.client, ctx, ctx.args); + } catch (error) { + this.client.logger.error(error); + await message.reply({ + content: T(locale, "event.message.error", { error: error.message || "Unknown error" }), + }); + } finally { + const logs = this.client.channels.cache.get(this.client.config.commandLogs); + if (logs) { + const embed = new EmbedBuilder() + .setAuthor({ + name: "Prefix - Command Logs", + iconURL: this.client.user?.avatarURL({ size: 2048 }), + }) + .setColor(this.client.config.color.green) + .setDescription( + `**\`${command.name}\`** | Used By **${message.author.tag} \`${message.author.id}\`** From **${message.guild.name} \`${message.guild.id}\`**`, + ) + .setTimestamp(); + + await (logs as TextChannel).send({ embeds: [embed] }); } + } } + } } /** diff --git a/src/events/client/Ready.ts b/src/events/client/Ready.ts index ac45ae9d1..696222e93 100644 --- a/src/events/client/Ready.ts +++ b/src/events/client/Ready.ts @@ -3,34 +3,34 @@ import config from "../../config.js"; import { Event, type Lavamusic } from "../../structures/index.js"; export default class Ready extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "ready", - }); - } + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "ready", + }); + } - public async run(): Promise { - this.client.logger.success(`${this.client.user?.tag} is ready!`); + public async run(): Promise { + this.client.logger.success(`${this.client.user?.tag} is ready!`); - this.client.user?.setPresence({ - activities: [ - { - name: config.botActivity, - type: config.botActivityType, - }, - ], - status: config.botStatus as any, - }); + this.client.user?.setPresence({ + activities: [ + { + name: config.botActivity, + type: config.botActivityType, + }, + ], + status: config.botStatus as any, + }); - if (config.topGG) { - const autoPoster = AutoPoster(config.topGG, this.client); - setInterval(() => { - autoPoster.on("posted", (_stats) => {}); - }, 86400000); // 24 hours in milliseconds - } else { - this.client.logger.warn("Top.gg token not found. Skipping auto poster."); - } + if (config.topGG) { + const autoPoster = AutoPoster(config.topGG, this.client); + setInterval(() => { + autoPoster.on("posted", (_stats) => {}); + }, 86400000); // 24 hours in milliseconds + } else { + this.client.logger.warn("Top.gg token not found. Skipping auto poster."); } + } } /** diff --git a/src/events/client/SetupButtons.ts b/src/events/client/SetupButtons.ts index b59ba5ea2..4144cb9db 100644 --- a/src/events/client/SetupButtons.ts +++ b/src/events/client/SetupButtons.ts @@ -6,232 +6,232 @@ import { buttonReply } from "../../utils/SetupSystem.js"; import { checkDj } from "../player/TrackStart.js"; export default class SetupButtons extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "setupButtons", - }); + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "setupButtons", + }); + } + + public async run(interaction: any): Promise { + const locale = await this.client.db.getLanguage(interaction.guildId); + + if (!interaction.replied) await interaction.deferReply().catch(() => {}); + if (!interaction.member.voice.channel) { + return await buttonReply(interaction, T(locale, "event.setupButton.no_voice_channel_button"), this.client.color.red); + } + const clientMember = interaction.guild.members.cache.get(this.client.user.id); + if (clientMember.voice.channel && clientMember.voice.channelId !== interaction.member.voice.channelId) { + return await buttonReply( + interaction, + T(locale, "event.setupButton.different_voice_channel_button", { + channel: clientMember.voice.channel, + }), + this.client.color.red, + ); + } + const player = this.client.queue.get(interaction.guildId); + if (!player) return await buttonReply(interaction, T(locale, "event.setupButton.no_music_playing"), this.client.color.red); + if (!player.queue) return await buttonReply(interaction, T(locale, "event.setupButton.no_music_playing"), this.client.color.red); + if (!player.current) return await buttonReply(interaction, T(locale, "event.setupButton.no_music_playing"), this.client.color.red); + const data = await this.client.db.getSetup(interaction.guildId); + const { title, uri, length, artworkUrl, sourceName, isStream, requester } = player.current.info; + let message: Message; + try { + message = await interaction.channel.messages.fetch(data.messageId, { + cache: true, + }); + } catch (_e) { + /* empty */ } - public async run(interaction: any): Promise { - const locale = await this.client.db.getLanguage(interaction.guildId); + const iconUrl = this.client.config.icons[sourceName] || this.client.user.displayAvatarURL({ extension: "png" }); + const embed = this.client + .embed() + .setAuthor({ + name: T(locale, "event.setupButton.now_playing"), + iconURL: iconUrl, + }) + .setColor(this.client.color.main) + .setDescription( + `[${title}](${uri}) - ${isStream ? T(locale, "event.setupButton.live") : this.client.utils.formatTime(length)} - ${T(locale, "event.setupButton.requested_by", { requester })}`, + ) + .setImage(artworkUrl || this.client.user.displayAvatarURL({ extension: "png" })); - if (!interaction.replied) await interaction.deferReply().catch(() => {}); - if (!interaction.member.voice.channel) { - return await buttonReply(interaction, T(locale, "event.setupButton.no_voice_channel_button"), this.client.color.red); - } - const clientMember = interaction.guild.members.cache.get(this.client.user.id); - if (clientMember.voice.channel && clientMember.voice.channelId !== interaction.member.voice.channelId) { - return await buttonReply( - interaction, - T(locale, "event.setupButton.different_voice_channel_button", { - channel: clientMember.voice.channel, + if (!interaction.isButton()) return; + if (!(await checkDj(this.client, interaction))) { + return await buttonReply(interaction, T(locale, "event.setupButton.no_dj_permission"), this.client.color.red); + } + if (message) { + const handleVolumeChange = async (change: number) => { + const vol = player.player.volume + change; + player.player.setGlobalVolume(vol); + await buttonReply(interaction, T(locale, "event.setupButton.volume_set", { vol }), this.client.color.main); + await message.edit({ + embeds: [ + embed.setFooter({ + text: T(locale, "event.setupButton.volume_footer", { + vol, + displayName: interaction.member.displayName, + }), + iconURL: interaction.member.displayAvatarURL({}), + }), + ], + }); + }; + switch (interaction.customId) { + case "LOW_VOL_BUT": + await handleVolumeChange(-10); + break; + case "HIGH_VOL_BUT": + await handleVolumeChange(10); + break; + case "PAUSE_BUT": { + const name = player.player.paused ? T(locale, "event.setupButton.resumed") : T(locale, "event.setupButton.paused"); + player.pause(); + await buttonReply(interaction, T(locale, "event.setupButton.pause_resume", { name }), this.client.color.main); + await message.edit({ + embeds: [ + embed.setFooter({ + text: T(locale, "event.setupButton.pause_resume_footer", { + name, + displayName: interaction.member.displayName, }), - this.client.color.red, - ); + iconURL: interaction.member.displayAvatarURL({}), + }), + ], + components: getButtons(player, this.client), + }); + break; } - const player = this.client.queue.get(interaction.guildId); - if (!player) return await buttonReply(interaction, T(locale, "event.setupButton.no_music_playing"), this.client.color.red); - if (!player.queue) return await buttonReply(interaction, T(locale, "event.setupButton.no_music_playing"), this.client.color.red); - if (!player.current) return await buttonReply(interaction, T(locale, "event.setupButton.no_music_playing"), this.client.color.red); - const data = await this.client.db.getSetup(interaction.guildId); - const { title, uri, length, artworkUrl, sourceName, isStream, requester } = player.current.info; - let message: Message; - try { - message = await interaction.channel.messages.fetch(data.messageId, { - cache: true, - }); - } catch (_e) { - /* empty */ + case "SKIP_BUT": + if (!player.queue.length) { + return await buttonReply(interaction, T(locale, "event.setupButton.no_music_to_skip"), this.client.color.main); + } + player.skip(); + await buttonReply(interaction, T(locale, "event.setupButton.skipped"), this.client.color.main); + await message.edit({ + embeds: [ + embed.setFooter({ + text: T(locale, "event.setupButton.skipped_footer", { + displayName: interaction.member.displayName, + }), + iconURL: interaction.member.displayAvatarURL({}), + }), + ], + }); + break; + case "STOP_BUT": + player.stop(); + await buttonReply(interaction, T(locale, "event.setupButton.stopped"), this.client.color.main); + await message.edit({ + embeds: [ + embed + .setFooter({ + text: T(locale, "event.setupButton.stopped_footer", { + displayName: interaction.member.displayName, + }), + iconURL: interaction.member.displayAvatarURL({}), + }) + .setDescription(T(locale, "event.setupButton.nothing_playing")) + .setImage(this.client.config.links.img) + .setAuthor({ + name: this.client.user.username, + iconURL: this.client.user.displayAvatarURL({ + extension: "png", + }), + }), + ], + }); + break; + case "LOOP_BUT": { + const loopOptions: Array<"off" | "queue" | "repeat"> = ["off", "queue", "repeat"]; + const newLoop = loopOptions[(loopOptions.indexOf(player.loop) + 1) % loopOptions.length]; + player.setLoop(newLoop); + await buttonReply( + interaction, + T(locale, "event.setupButton.loop_set", { + loop: newLoop, + }), + this.client.color.main, + ); + await message.edit({ + embeds: [ + embed.setFooter({ + text: T(locale, "event.setupButton.loop_footer", { + loop: newLoop, + displayName: interaction.member.displayName, + }), + iconURL: interaction.member.displayAvatarURL({}), + }), + ], + }); + break; } - - const iconUrl = this.client.config.icons[sourceName] || this.client.user.displayAvatarURL({ extension: "png" }); - const embed = this.client - .embed() - .setAuthor({ - name: T(locale, "event.setupButton.now_playing"), - iconURL: iconUrl, - }) - .setColor(this.client.color.main) - .setDescription( - `[${title}](${uri}) - ${isStream ? T(locale, "event.setupButton.live") : this.client.utils.formatTime(length)} - ${T(locale, "event.setupButton.requested_by", { requester })}`, - ) - .setImage(artworkUrl || this.client.user.displayAvatarURL({ extension: "png" })); - - if (!interaction.isButton()) return; - if (!(await checkDj(this.client, interaction))) { - return await buttonReply(interaction, T(locale, "event.setupButton.no_dj_permission"), this.client.color.red); + case "SHUFFLE_BUT": + player.setShuffle(); + await buttonReply(interaction, T(locale, "event.setupButton.shuffled"), this.client.color.main); + break; + case "PREV_BUT": + if (!player.previous) { + return await buttonReply(interaction, T(locale, "event.setupButton.no_previous_track"), this.client.color.main); + } + player.previousTrack(); + await buttonReply(interaction, T(locale, "event.setupButton.playing_previous"), this.client.color.main); + await message.edit({ + embeds: [ + embed.setFooter({ + text: T(locale, "event.setupButton.previous_footer", { + displayName: interaction.member.displayName, + }), + iconURL: interaction.member.displayAvatarURL({}), + }), + ], + }); + break; + case "REWIND_BUT": { + const time = player.player.position - 10000; + if (time < 0) { + return await buttonReply(interaction, T(locale, "event.setupButton.rewind_limit"), this.client.color.main); + } + player.seek(time); + await buttonReply(interaction, T(locale, "event.setupButton.rewinded"), this.client.color.main); + await message.edit({ + embeds: [ + embed.setFooter({ + text: T(locale, "event.setupButton.rewind_footer", { + displayName: interaction.member.displayName, + }), + iconURL: interaction.member.displayAvatarURL({}), + }), + ], + }); + break; } - if (message) { - const handleVolumeChange = async (change: number) => { - const vol = player.player.volume + change; - player.player.setGlobalVolume(vol); - await buttonReply(interaction, T(locale, "event.setupButton.volume_set", { vol }), this.client.color.main); - await message.edit({ - embeds: [ - embed.setFooter({ - text: T(locale, "event.setupButton.volume_footer", { - vol, - displayName: interaction.member.displayName, - }), - iconURL: interaction.member.displayAvatarURL({}), - }), - ], - }); - }; - switch (interaction.customId) { - case "LOW_VOL_BUT": - await handleVolumeChange(-10); - break; - case "HIGH_VOL_BUT": - await handleVolumeChange(10); - break; - case "PAUSE_BUT": { - const name = player.player.paused ? T(locale, "event.setupButton.resumed") : T(locale, "event.setupButton.paused"); - player.pause(); - await buttonReply(interaction, T(locale, "event.setupButton.pause_resume", { name }), this.client.color.main); - await message.edit({ - embeds: [ - embed.setFooter({ - text: T(locale, "event.setupButton.pause_resume_footer", { - name, - displayName: interaction.member.displayName, - }), - iconURL: interaction.member.displayAvatarURL({}), - }), - ], - components: getButtons(player, this.client), - }); - break; - } - case "SKIP_BUT": - if (!player.queue.length) { - return await buttonReply(interaction, T(locale, "event.setupButton.no_music_to_skip"), this.client.color.main); - } - player.skip(); - await buttonReply(interaction, T(locale, "event.setupButton.skipped"), this.client.color.main); - await message.edit({ - embeds: [ - embed.setFooter({ - text: T(locale, "event.setupButton.skipped_footer", { - displayName: interaction.member.displayName, - }), - iconURL: interaction.member.displayAvatarURL({}), - }), - ], - }); - break; - case "STOP_BUT": - player.stop(); - await buttonReply(interaction, T(locale, "event.setupButton.stopped"), this.client.color.main); - await message.edit({ - embeds: [ - embed - .setFooter({ - text: T(locale, "event.setupButton.stopped_footer", { - displayName: interaction.member.displayName, - }), - iconURL: interaction.member.displayAvatarURL({}), - }) - .setDescription(T(locale, "event.setupButton.nothing_playing")) - .setImage(this.client.config.links.img) - .setAuthor({ - name: this.client.user.username, - iconURL: this.client.user.displayAvatarURL({ - extension: "png", - }), - }), - ], - }); - break; - case "LOOP_BUT": { - const loopOptions: Array<"off" | "queue" | "repeat"> = ["off", "queue", "repeat"]; - const newLoop = loopOptions[(loopOptions.indexOf(player.loop) + 1) % loopOptions.length]; - player.setLoop(newLoop); - await buttonReply( - interaction, - T(locale, "event.setupButton.loop_set", { - loop: newLoop, - }), - this.client.color.main, - ); - await message.edit({ - embeds: [ - embed.setFooter({ - text: T(locale, "event.setupButton.loop_footer", { - loop: newLoop, - displayName: interaction.member.displayName, - }), - iconURL: interaction.member.displayAvatarURL({}), - }), - ], - }); - break; - } - case "SHUFFLE_BUT": - player.setShuffle(); - await buttonReply(interaction, T(locale, "event.setupButton.shuffled"), this.client.color.main); - break; - case "PREV_BUT": - if (!player.previous) { - return await buttonReply(interaction, T(locale, "event.setupButton.no_previous_track"), this.client.color.main); - } - player.previousTrack(); - await buttonReply(interaction, T(locale, "event.setupButton.playing_previous"), this.client.color.main); - await message.edit({ - embeds: [ - embed.setFooter({ - text: T(locale, "event.setupButton.previous_footer", { - displayName: interaction.member.displayName, - }), - iconURL: interaction.member.displayAvatarURL({}), - }), - ], - }); - break; - case "REWIND_BUT": { - const time = player.player.position - 10000; - if (time < 0) { - return await buttonReply(interaction, T(locale, "event.setupButton.rewind_limit"), this.client.color.main); - } - player.seek(time); - await buttonReply(interaction, T(locale, "event.setupButton.rewinded"), this.client.color.main); - await message.edit({ - embeds: [ - embed.setFooter({ - text: T(locale, "event.setupButton.rewind_footer", { - displayName: interaction.member.displayName, - }), - iconURL: interaction.member.displayAvatarURL({}), - }), - ], - }); - break; - } - case "FORWARD_BUT": { - const time = player.player.position + 10000; - if (time > player.current.info.length) { - return await buttonReply(interaction, T(locale, "event.setupButton.forward_limit"), this.client.color.main); - } - player.seek(time); - await buttonReply(interaction, T(locale, "event.setupButton.forwarded"), this.client.color.main); - await message.edit({ - embeds: [ - embed.setFooter({ - text: T(locale, "event.setupButton.forward_footer", { - displayName: interaction.member.displayName, - }), - iconURL: interaction.member.displayAvatarURL({}), - }), - ], - }); - break; - } - default: - await buttonReply(interaction, T(locale, "event.setupButton.button_not_available"), this.client.color.main); - break; - } + case "FORWARD_BUT": { + const time = player.player.position + 10000; + if (time > player.current.info.length) { + return await buttonReply(interaction, T(locale, "event.setupButton.forward_limit"), this.client.color.main); + } + player.seek(time); + await buttonReply(interaction, T(locale, "event.setupButton.forwarded"), this.client.color.main); + await message.edit({ + embeds: [ + embed.setFooter({ + text: T(locale, "event.setupButton.forward_footer", { + displayName: interaction.member.displayName, + }), + iconURL: interaction.member.displayAvatarURL({}), + }), + ], + }); + break; } + default: + await buttonReply(interaction, T(locale, "event.setupButton.button_not_available"), this.client.color.main); + break; + } } + } } /** diff --git a/src/events/client/SetupSystem.ts b/src/events/client/SetupSystem.ts index 72acb39fb..37d658975 100644 --- a/src/events/client/SetupSystem.ts +++ b/src/events/client/SetupSystem.ts @@ -4,61 +4,61 @@ import { Event, type Lavamusic } from "../../structures/index.js"; import { oops, setupStart } from "../../utils/SetupSystem.js"; export default class SetupSystem extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "setupSystem", - }); - } - - public async run(message: Message): Promise { - const locale = await this.client.db.getLanguage(message.guildId); - const channel = message.channel as TextChannel; - if (!(channel instanceof TextChannel)) return; - if (!message.member?.voice.channel) { - await oops(channel, T(locale, "event.message.no_voice_channel_queue")); - await message.delete().catch(() => {}); - return; - } + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "setupSystem", + }); + } - const voiceChannel = message.member.voice.channel; - const clientUser = this.client.user; - const clientMember = message.guild.members.cache.get(clientUser.id); + public async run(message: Message): Promise { + const locale = await this.client.db.getLanguage(message.guildId); + const channel = message.channel as TextChannel; + if (!(channel instanceof TextChannel)) return; + if (!message.member?.voice.channel) { + await oops(channel, T(locale, "event.message.no_voice_channel_queue")); + await message.delete().catch(() => {}); + return; + } - if (!voiceChannel.permissionsFor(clientUser).has(PermissionsBitField.Flags.Connect | PermissionsBitField.Flags.Speak)) { - await oops( - channel, - T(locale, "event.message.no_permission_connect_speak", { - channel: voiceChannel.id, - }), - ); - await message.delete().catch(() => {}); - return; - } + const voiceChannel = message.member.voice.channel; + const clientUser = this.client.user; + const clientMember = message.guild.members.cache.get(clientUser.id); - if (clientMember?.voice.channel && clientMember.voice.channelId !== voiceChannel.id) { - await oops( - channel, - T(locale, "event.message.different_voice_channel_queue", { - channel: clientMember.voice.channelId, - }), - ); - await message.delete().catch(() => {}); - return; - } + if (!voiceChannel.permissionsFor(clientUser).has(PermissionsBitField.Flags.Connect | PermissionsBitField.Flags.Speak)) { + await oops( + channel, + T(locale, "event.message.no_permission_connect_speak", { + channel: voiceChannel.id, + }), + ); + await message.delete().catch(() => {}); + return; + } - let player = this.client.queue.get(message.guildId); - if (!player) { - player = await this.client.queue.create( - message.guild, - voiceChannel, - message.channel, - this.client.shoukaku.options.nodeResolver(this.client.shoukaku.nodes), - ); - } + if (clientMember?.voice.channel && clientMember.voice.channelId !== voiceChannel.id) { + await oops( + channel, + T(locale, "event.message.different_voice_channel_queue", { + channel: clientMember.voice.channelId, + }), + ); + await message.delete().catch(() => {}); + return; + } - await setupStart(this.client, message.content, player, message); - await message.delete().catch(() => {}); + let player = this.client.queue.get(message.guildId); + if (!player) { + player = await this.client.queue.create( + message.guild, + voiceChannel, + message.channel, + this.client.shoukaku.options.nodeResolver(this.client.shoukaku.nodes), + ); } + + await setupStart(this.client, message.content, player, message); + await message.delete().catch(() => {}); + } } /** diff --git a/src/events/client/VoiceStateUpdate.ts b/src/events/client/VoiceStateUpdate.ts index 80c2029d2..1c95876b5 100644 --- a/src/events/client/VoiceStateUpdate.ts +++ b/src/events/client/VoiceStateUpdate.ts @@ -2,79 +2,79 @@ import { ChannelType, type GuildMember, type VoiceState } from "discord.js"; import { Event, type Lavamusic } from "../../structures/index.js"; export default class VoiceStateUpdate extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "voiceStateUpdate", - }); - } + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "voiceStateUpdate", + }); + } - public async run(_oldState: VoiceState, newState: VoiceState): Promise { - const guildId = newState.guild.id; - if (!guildId) return; + public async run(_oldState: VoiceState, newState: VoiceState): Promise { + const guildId = newState.guild.id; + if (!guildId) return; - const player = this.client.queue.get(guildId); - if (!player) return; + const player = this.client.queue.get(guildId); + if (!player) return; - const vcConnection = player.node.manager.connections.get(guildId); - if (!vcConnection?.channelId) return; + const vcConnection = player.node.manager.connections.get(guildId); + if (!vcConnection?.channelId) return; - const vc = newState.guild.channels.cache.get(vcConnection.channelId); - if (!(vc && vc.members instanceof Map)) return; + const vc = newState.guild.channels.cache.get(vcConnection.channelId); + if (!(vc && vc.members instanceof Map)) return; - const is247 = await this.client.db.get_247(guildId); + const is247 = await this.client.db.get_247(guildId); - if (!(newState.guild.members.cache.get(this.client.user.id)?.voice.channelId || !is247) && player) { - return player.destroy(); - } + if (!(newState.guild.members.cache.get(this.client.user.id)?.voice.channelId || !is247) && player) { + return player.destroy(); + } - if ( - newState.id === this.client.user.id && - newState.channelId && - newState.channel.type === ChannelType.GuildStageVoice && - newState.guild.members.me.voice.suppress - ) { - if ( - newState.guild.members.me.permissions.has(["Connect", "Speak"]) || - newState.channel.permissionsFor(newState.guild.members.me).has("MuteMembers") - ) { - await newState.guild.members.me.voice.setSuppressed(false).catch(() => {}); - } - } + if ( + newState.id === this.client.user.id && + newState.channelId && + newState.channel.type === ChannelType.GuildStageVoice && + newState.guild.members.me.voice.suppress + ) { + if ( + newState.guild.members.me.permissions.has(["Connect", "Speak"]) || + newState.channel.permissionsFor(newState.guild.members.me).has("MuteMembers") + ) { + await newState.guild.members.me.voice.setSuppressed(false).catch(() => {}); + } + } - if (newState.id === this.client.user.id && !newState.serverDeaf) { - const permissions = vc.permissionsFor(newState.guild.members.me); - if (permissions?.has("DeafenMembers")) { - await newState.setDeaf(true); - } - } + if (newState.id === this.client.user.id && !newState.serverDeaf) { + const permissions = vc.permissionsFor(newState.guild.members.me); + if (permissions?.has("DeafenMembers")) { + await newState.setDeaf(true); + } + } - if (newState.id === this.client.user.id) { - if (newState.serverMute && !player.paused) { - player.pause(); - } else if (!newState.serverMute && player.paused) { - player.pause(); - } - } + if (newState.id === this.client.user.id) { + if (newState.serverMute && !player.paused) { + player.pause(); + } else if (!newState.serverMute && player.paused) { + player.pause(); + } + } - if (vc.members instanceof Map && [...vc.members.values()].filter((x: GuildMember) => !x.user.bot).length <= 0) { - setTimeout(async () => { - const vcConnection = player.node.manager.connections.get(guildId); - if (!vcConnection?.channelId) return; + if (vc.members instanceof Map && [...vc.members.values()].filter((x: GuildMember) => !x.user.bot).length <= 0) { + setTimeout(async () => { + const vcConnection = player.node.manager.connections.get(guildId); + if (!vcConnection?.channelId) return; - const playerVoiceChannel = newState.guild.channels.cache.get(vcConnection.channelId); - if ( - player && - playerVoiceChannel && - playerVoiceChannel.members instanceof Map && - [...playerVoiceChannel.members.values()].filter((x: GuildMember) => !x.user.bot).length <= 0 - ) { - if (!is247) { - player.destroy(); - } - } - }, 5000); + const playerVoiceChannel = newState.guild.channels.cache.get(vcConnection.channelId); + if ( + player && + playerVoiceChannel && + playerVoiceChannel.members instanceof Map && + [...playerVoiceChannel.members.values()].filter((x: GuildMember) => !x.user.bot).length <= 0 + ) { + if (!is247) { + player.destroy(); + } } + }, 5000); } + } } /** diff --git a/src/events/player/NodeConnect.ts b/src/events/player/NodeConnect.ts index 4a186ce96..743292dde 100644 --- a/src/events/player/NodeConnect.ts +++ b/src/events/player/NodeConnect.ts @@ -2,44 +2,42 @@ import { Event, type Lavamusic } from "../../structures/index.js"; import BotLog from "../../utils/BotLog.js"; export default class NodeConnect extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "nodeConnect", - }); - } + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "nodeConnect", + }); + } + + public async run(node: string): Promise { + this.client.logger.success(`Node ${node} is ready!`); - public async run(node: string): Promise { - this.client.logger.success(`Node ${node} is ready!`); + let data = await this.client.db.get_247(); + if (!data) return; - let data = await this.client.db.get_247(); - if (!data) return; + if (!Array.isArray(data)) { + data = [data]; + } - if (!Array.isArray(data)) { - data = [data]; + data.forEach((main, index) => { + setTimeout(async () => { + const guild = this.client.guilds.cache.get(main.guildId); + if (!guild) return; + + const channel = guild.channels.cache.get(main.textId); + const vc = guild.channels.cache.get(main.voiceId); + + if (channel && vc) { + try { + await this.client.queue.create(guild, vc, channel); + } catch (error) { + this.client.logger.error(`Failed to create queue for guild ${guild.id}: ${error.message}`); + } + } else { + this.client.logger.warn(`Missing channels for guild ${guild.id}. Text channel: ${main.textId}, Voice channel: ${main.voiceId}`); } + }, index * 1000); + }); - data.forEach((main, index) => { - setTimeout(async () => { - const guild = this.client.guilds.cache.get(main.guildId); - if (!guild) return; - - const channel = guild.channels.cache.get(main.textId); - const vc = guild.channels.cache.get(main.voiceId); - - if (channel && vc) { - try { - await this.client.queue.create(guild, vc, channel); - } catch (error) { - this.client.logger.error(`Failed to create queue for guild ${guild.id}: ${error.message}`); - } - } else { - this.client.logger.warn( - `Missing channels for guild ${guild.id}. Text channel: ${main.textId}, Voice channel: ${main.voiceId}`, - ); - } - }, index * 1000); - }); - - BotLog.send(this.client, `Node ${node} is ready!`, "success"); - } + BotLog.send(this.client, `Node ${node} is ready!`, "success"); + } } diff --git a/src/events/player/NodeDestroy.ts b/src/events/player/NodeDestroy.ts index 924f7c125..e7e07dd9f 100644 --- a/src/events/player/NodeDestroy.ts +++ b/src/events/player/NodeDestroy.ts @@ -3,27 +3,27 @@ import BotLog from "../../utils/BotLog.js"; let destroyCount = 0; export default class NodeDestroy extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "nodeDestroy", - }); - } + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "nodeDestroy", + }); + } - public async run(node: string, code: number, reason: string): Promise { - const message = `Node ${node} destroyed with code ${code} and reason ${reason}.`; - this.client.logger.error(message); - BotLog.send(this.client, message, "error"); + public async run(node: string, code: number, reason: string): Promise { + const message = `Node ${node} destroyed with code ${code} and reason ${reason}.`; + this.client.logger.error(message); + BotLog.send(this.client, message, "error"); - destroyCount++; + destroyCount++; - if (destroyCount >= 5) { - this.client.shoukaku.removeNode(node); - destroyCount = 0; - const warnMessage = `Node ${node} removed from nodes list due to excessive disconnects.`; - this.client.logger.warn(warnMessage); - BotLog.send(this.client, warnMessage, "warn"); - } + if (destroyCount >= 5) { + this.client.shoukaku.removeNode(node); + destroyCount = 0; + const warnMessage = `Node ${node} removed from nodes list due to excessive disconnects.`; + this.client.logger.warn(warnMessage); + BotLog.send(this.client, warnMessage, "warn"); } + } } /** diff --git a/src/events/player/NodeDisconnect.ts b/src/events/player/NodeDisconnect.ts index fb8c92e2a..428ac71f7 100644 --- a/src/events/player/NodeDisconnect.ts +++ b/src/events/player/NodeDisconnect.ts @@ -2,17 +2,17 @@ import { Event, type Lavamusic } from "../../structures/index.js"; import BotLog from "../../utils/BotLog.js"; export default class NodeDisconnect extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "nodeDisconnect", - }); - } + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "nodeDisconnect", + }); + } - public async run(node: string, count: number): Promise { - const message = `Node ${node} disconnected ${count} times`; - this.client.logger.warn(message); - BotLog.send(this.client, message, "warn"); - } + public async run(node: string, count: number): Promise { + const message = `Node ${node} disconnected ${count} times`; + this.client.logger.warn(message); + BotLog.send(this.client, message, "warn"); + } } /** diff --git a/src/events/player/NodeError.ts b/src/events/player/NodeError.ts index 8f3888dba..2b5f5ddfa 100644 --- a/src/events/player/NodeError.ts +++ b/src/events/player/NodeError.ts @@ -2,18 +2,18 @@ import { Event, type Lavamusic } from "../../structures/index.js"; import BotLog from "../../utils/BotLog.js"; export default class NodeError extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "nodeError", - }); - } + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "nodeError", + }); + } - public async run(node: string, error: any): Promise { - const errorMessage = JSON.stringify(error, null, 2); - const message = `Node ${node} Error: ${errorMessage}`; - this.client.logger.error(message); - BotLog.send(this.client, message, "error"); - } + public async run(node: string, error: any): Promise { + const errorMessage = JSON.stringify(error, null, 2); + const message = `Node ${node} Error: ${errorMessage}`; + this.client.logger.error(message); + BotLog.send(this.client, message, "error"); + } } /** diff --git a/src/events/player/NodeRaw.ts b/src/events/player/NodeRaw.ts index b4d6bd967..e1ff82eb3 100644 --- a/src/events/player/NodeRaw.ts +++ b/src/events/player/NodeRaw.ts @@ -1,16 +1,16 @@ import { Event, type Lavamusic } from "../../structures/index.js"; export default class NodeRaw extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "nodeRaw", - }); - } + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "nodeRaw", + }); + } - public async run(_payload: any): Promise { - // Uncomment the following line for debugging purposes - // this.client.logger.debug(`Node raw event: ${JSON.stringify(payload)}`); - } + public async run(_payload: any): Promise { + // Uncomment the following line for debugging purposes + // this.client.logger.debug(`Node raw event: ${JSON.stringify(payload)}`); + } } /** diff --git a/src/events/player/NodeReconnect.ts b/src/events/player/NodeReconnect.ts index 9a5111c32..73810a906 100644 --- a/src/events/player/NodeReconnect.ts +++ b/src/events/player/NodeReconnect.ts @@ -2,17 +2,17 @@ import { Event, type Lavamusic } from "../../structures/index.js"; import BotLog from "../../utils/BotLog.js"; export default class NodeReconnect extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "nodeReconnect", - }); - } + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "nodeReconnect", + }); + } - public async run(node: string): Promise { - const message = `Node ${node} reconnected`; - this.client.logger.warn(message); - BotLog.send(this.client, message, "warn"); - } + public async run(node: string): Promise { + const message = `Node ${node} reconnected`; + this.client.logger.warn(message); + BotLog.send(this.client, message, "warn"); + } } /** diff --git a/src/events/player/QueueEnd.ts b/src/events/player/QueueEnd.ts index 202964ae5..73f381670 100644 --- a/src/events/player/QueueEnd.ts +++ b/src/events/player/QueueEnd.ts @@ -4,38 +4,38 @@ import { type Dispatcher, Event, type Lavamusic } from "../../structures/index.j import { updateSetup } from "../../utils/SetupSystem.js"; export default class QueueEnd extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "queueEnd", - }); - } - - public async run(_player: Player, track: Song, dispatcher: Dispatcher): Promise { - const guild = this.client.guilds.cache.get(dispatcher.guildId); - if (!guild) return; - const locale = await this.client.db.getLanguage(guild.id); - switch (dispatcher.loop) { - case "repeat": - dispatcher.queue.unshift(track); - break; - case "queue": - dispatcher.queue.push(track); - break; - case "off": - dispatcher.previous = dispatcher.current; - dispatcher.current = null; - break; - } + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "queueEnd", + }); + } - if (dispatcher.autoplay) { - await dispatcher.Autoplay(track); - } else { - dispatcher.autoplay = false; - } + public async run(_player: Player, track: Song, dispatcher: Dispatcher): Promise { + const guild = this.client.guilds.cache.get(dispatcher.guildId); + if (!guild) return; + const locale = await this.client.db.getLanguage(guild.id); + switch (dispatcher.loop) { + case "repeat": + dispatcher.queue.unshift(track); + break; + case "queue": + dispatcher.queue.push(track); + break; + case "off": + dispatcher.previous = dispatcher.current; + dispatcher.current = null; + break; + } - await updateSetup(this.client, guild, locale); - this.client.utils.updateStatus(this.client, guild.id); + if (dispatcher.autoplay) { + await dispatcher.Autoplay(track); + } else { + dispatcher.autoplay = false; } + + await updateSetup(this.client, guild, locale); + this.client.utils.updateStatus(this.client, guild.id); + } } /** diff --git a/src/events/player/TrackEnd.ts b/src/events/player/TrackEnd.ts index ccd09a034..f30072d50 100644 --- a/src/events/player/TrackEnd.ts +++ b/src/events/player/TrackEnd.ts @@ -3,37 +3,37 @@ import type { Song } from "../../structures/Dispatcher.js"; import { type Dispatcher, Event, type Lavamusic } from "../../structures/index.js"; export default class TrackEnd extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "trackEnd", - }); + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "trackEnd", + }); + } + + public async run(_player: Player, track: Song, dispatcher: Dispatcher): Promise { + dispatcher.previous = dispatcher.current; + dispatcher.current = null; + + const nowPlayingMessage = await dispatcher.nowPlayingMessage?.fetch().catch(() => null); + + switch (dispatcher.loop) { + case "repeat": + dispatcher.queue.unshift(track); + break; + case "queue": + dispatcher.queue.push(track); + break; } - public async run(_player: Player, track: Song, dispatcher: Dispatcher): Promise { - dispatcher.previous = dispatcher.current; - dispatcher.current = null; + await dispatcher.play(); - const nowPlayingMessage = await dispatcher.nowPlayingMessage?.fetch().catch(() => null); - - switch (dispatcher.loop) { - case "repeat": - dispatcher.queue.unshift(track); - break; - case "queue": - dispatcher.queue.push(track); - break; - } - - await dispatcher.play(); - - if (dispatcher.autoplay) { - await dispatcher.Autoplay(track); - } + if (dispatcher.autoplay) { + await dispatcher.Autoplay(track); + } - if (nowPlayingMessage?.deletable) { - await nowPlayingMessage.delete().catch(() => {}); - } + if (nowPlayingMessage?.deletable) { + await nowPlayingMessage.delete().catch(() => {}); } + } } /** diff --git a/src/events/player/TrackStart.ts b/src/events/player/TrackStart.ts index 89eced69a..0eea4ea0d 100644 --- a/src/events/player/TrackStart.ts +++ b/src/events/player/TrackStart.ts @@ -1,16 +1,16 @@ import { - ActionRowBuilder, - ButtonBuilder, - type ButtonInteraction, - ButtonStyle, - type ChannelSelectMenuInteraction, - GuildMember, - type MentionableSelectMenuInteraction, - PermissionFlagsBits, - type RoleSelectMenuInteraction, - type StringSelectMenuInteraction, - type TextChannel, - type UserSelectMenuInteraction, + ActionRowBuilder, + ButtonBuilder, + type ButtonInteraction, + ButtonStyle, + type ChannelSelectMenuInteraction, + GuildMember, + type MentionableSelectMenuInteraction, + PermissionFlagsBits, + type RoleSelectMenuInteraction, + type StringSelectMenuInteraction, + type TextChannel, + type UserSelectMenuInteraction, } from "discord.js"; import type { Player } from "shoukaku"; import type { Song } from "../../structures/Dispatcher.js"; @@ -19,242 +19,242 @@ import { type Dispatcher, Event, type Lavamusic } from "../../structures/index.j import { trackStart } from "../../utils/SetupSystem.js"; export default class TrackStart extends Event { - constructor(client: Lavamusic, file: string) { - super(client, file, { - name: "trackStart", - }); - } + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "trackStart", + }); + } - public async run(player: Player, track: Song, dispatcher: Dispatcher): Promise { - if (!track?.info) return; + public async run(player: Player, track: Song, dispatcher: Dispatcher): Promise { + if (!track?.info) return; - const guild = this.client.guilds.cache.get(player.guildId); - if (!guild) return; + const guild = this.client.guilds.cache.get(player.guildId); + if (!guild) return; - const channel = guild.channels.cache.get(dispatcher.channelId) as TextChannel; - if (!channel) return; + const channel = guild.channels.cache.get(dispatcher.channelId) as TextChannel; + if (!channel) return; - this.client.utils.updateStatus(this.client, guild.id); + this.client.utils.updateStatus(this.client, guild.id); - const locale = await this.client.db.getLanguage(guild.id); + const locale = await this.client.db.getLanguage(guild.id); - const embed = this.client - .embed() - .setAuthor({ - name: T(locale, "player.trackStart.now_playing"), - iconURL: this.client.config.icons[track.info.sourceName] ?? this.client.user.displayAvatarURL({ extension: "png" }), - }) - .setColor(this.client.color.main) - .setDescription(`**[${track.info.title}](${track.info.uri})**`) - .setFooter({ - text: T(locale, "player.trackStart.requested_by", { - user: track.info.requester.tag, - }), - iconURL: track.info.requester.avatarURL({}), - }) - .setThumbnail(track.info.artworkUrl) - .addFields( - { - name: T(locale, "player.trackStart.duration"), - value: track.info.isStream ? "LIVE" : this.client.utils.formatTime(track.info.length), - inline: true, - }, - { - name: T(locale, "player.trackStart.author"), - value: track.info.author, - inline: true, - }, - ) - .setTimestamp(); + const embed = this.client + .embed() + .setAuthor({ + name: T(locale, "player.trackStart.now_playing"), + iconURL: this.client.config.icons[track.info.sourceName] ?? this.client.user.displayAvatarURL({ extension: "png" }), + }) + .setColor(this.client.color.main) + .setDescription(`**[${track.info.title}](${track.info.uri})**`) + .setFooter({ + text: T(locale, "player.trackStart.requested_by", { + user: track.info.requester.tag, + }), + iconURL: track.info.requester.avatarURL({}), + }) + .setThumbnail(track.info.artworkUrl) + .addFields( + { + name: T(locale, "player.trackStart.duration"), + value: track.info.isStream ? "LIVE" : this.client.utils.formatTime(track.info.length), + inline: true, + }, + { + name: T(locale, "player.trackStart.author"), + value: track.info.author, + inline: true, + }, + ) + .setTimestamp(); - const setup = await this.client.db.getSetup(guild.id); + const setup = await this.client.db.getSetup(guild.id); - if (setup?.textId) { - const textChannel = guild.channels.cache.get(setup.textId) as TextChannel; - const id = setup.messageId; + if (setup?.textId) { + const textChannel = guild.channels.cache.get(setup.textId) as TextChannel; + const id = setup.messageId; - if (textChannel) { - await trackStart(id, textChannel, dispatcher, track, this.client, locale); - } - } else { - const message = await channel.send({ - embeds: [embed], - components: [createButtonRow(dispatcher, this.client)], - }); + if (textChannel) { + await trackStart(id, textChannel, dispatcher, track, this.client, locale); + } + } else { + const message = await channel.send({ + embeds: [embed], + components: [createButtonRow(dispatcher, this.client)], + }); - dispatcher.nowPlayingMessage = message; - createCollector(message, dispatcher, track, embed, this.client, locale); - } + dispatcher.nowPlayingMessage = message; + createCollector(message, dispatcher, track, embed, this.client, locale); } + } } function createButtonRow(dispatcher: Dispatcher, client: Lavamusic): ActionRowBuilder { - const previousButton = new ButtonBuilder() + const previousButton = new ButtonBuilder() - .setCustomId("previous") - .setEmoji(client.emoji.previous) - .setStyle(ButtonStyle.Secondary) - .setDisabled(!dispatcher.previous); + .setCustomId("previous") + .setEmoji(client.emoji.previous) + .setStyle(ButtonStyle.Secondary) + .setDisabled(!dispatcher.previous); - const resumeButton = new ButtonBuilder() - .setCustomId("resume") - .setEmoji(dispatcher.paused ? client.emoji.resume : client.emoji.pause) - .setStyle(dispatcher.paused ? ButtonStyle.Success : ButtonStyle.Secondary); + const resumeButton = new ButtonBuilder() + .setCustomId("resume") + .setEmoji(dispatcher.paused ? client.emoji.resume : client.emoji.pause) + .setStyle(dispatcher.paused ? ButtonStyle.Success : ButtonStyle.Secondary); - const stopButton = new ButtonBuilder().setCustomId("stop").setEmoji(client.emoji.stop).setStyle(ButtonStyle.Danger); + const stopButton = new ButtonBuilder().setCustomId("stop").setEmoji(client.emoji.stop).setStyle(ButtonStyle.Danger); - const skipButton = new ButtonBuilder().setCustomId("skip").setEmoji(client.emoji.skip).setStyle(ButtonStyle.Secondary); + const skipButton = new ButtonBuilder().setCustomId("skip").setEmoji(client.emoji.skip).setStyle(ButtonStyle.Secondary); - const loopButton = new ButtonBuilder() - .setCustomId("loop") - .setEmoji(dispatcher.loop === "repeat" ? client.emoji.loop.track : client.emoji.loop.none) - .setStyle(dispatcher.loop !== "off" ? ButtonStyle.Success : ButtonStyle.Secondary); + const loopButton = new ButtonBuilder() + .setCustomId("loop") + .setEmoji(dispatcher.loop === "repeat" ? client.emoji.loop.track : client.emoji.loop.none) + .setStyle(dispatcher.loop !== "off" ? ButtonStyle.Success : ButtonStyle.Secondary); - return new ActionRowBuilder().addComponents(resumeButton, previousButton, stopButton, skipButton, loopButton); + return new ActionRowBuilder().addComponents(resumeButton, previousButton, stopButton, skipButton, loopButton); } function createCollector(message: any, dispatcher: Dispatcher, _track: Song, embed: any, client: Lavamusic, locale: string): void { - const collector = message.createMessageComponentCollector({ - filter: async (b: ButtonInteraction) => { - if (b.member instanceof GuildMember) { - const isSameVoiceChannel = b.guild.members.me?.voice.channelId === b.member.voice.channelId; - if (isSameVoiceChannel) return true; - } - await b.reply({ - content: T(locale, "player.trackStart.not_connected_to_voice_channel", { - channel: b.guild.members.me?.voice.channelId ?? "None", - }), - ephemeral: true, - }); - return false; - }, - }); + const collector = message.createMessageComponentCollector({ + filter: async (b: ButtonInteraction) => { + if (b.member instanceof GuildMember) { + const isSameVoiceChannel = b.guild.members.me?.voice.channelId === b.member.voice.channelId; + if (isSameVoiceChannel) return true; + } + await b.reply({ + content: T(locale, "player.trackStart.not_connected_to_voice_channel", { + channel: b.guild.members.me?.voice.channelId ?? "None", + }), + ephemeral: true, + }); + return false; + }, + }); - collector.on("collect", async (interaction) => { - if (!(await checkDj(client, interaction))) { - await interaction.reply({ - content: T(locale, "player.trackStart.need_dj_role"), - ephemeral: true, - }); - return; - } + collector.on("collect", async (interaction) => { + if (!(await checkDj(client, interaction))) { + await interaction.reply({ + content: T(locale, "player.trackStart.need_dj_role"), + ephemeral: true, + }); + return; + } - const editMessage = async (text: string): Promise => { - if (message) { - await message.edit({ - embeds: [ - embed.setFooter({ - text, - iconURL: interaction.user.avatarURL({}), - }), - ], - components: [createButtonRow(dispatcher, client)], - }); - } - }; - switch (interaction.customId) { - case "previous": - if (dispatcher.previous) { - await interaction.deferUpdate(); - dispatcher.previousTrack(); - await editMessage( - T(locale, "player.trackStart.previous_by", { - user: interaction.user.tag, - }), - ); - } else { - await interaction.reply({ - content: T(locale, "player.trackStart.no_previous_song"), - ephemeral: true, - }); - } - break; - case "resume": - dispatcher.pause(); - await interaction.deferUpdate(); - await editMessage( - dispatcher.paused - ? T(locale, "player.trackStart.paused_by", { - user: interaction.user.tag, - }) - : T(locale, "player.trackStart.resumed_by", { - user: interaction.user.tag, - }), - ); - break; - case "stop": - dispatcher.stop(); - await interaction.deferUpdate(); - break; - case "skip": - if (dispatcher.queue.length) { - await interaction.deferUpdate(); - dispatcher.skip(); - await editMessage( - T(locale, "player.trackStart.skipped_by", { - user: interaction.user.tag, - }), - ); - } else { - await interaction.reply({ - content: T(locale, "player.trackStart.no_more_songs_in_queue"), - ephemeral: true, - }); - } - break; - case "loop": - await interaction.deferUpdate(); - switch (dispatcher.loop) { - case "off": - dispatcher.loop = "repeat"; - await editMessage( - T(locale, "player.trackStart.looping_by", { - user: interaction.user.tag, - }), - ); - break; - case "repeat": - dispatcher.loop = "queue"; - await editMessage( - T(locale, "player.trackStart.looping_queue_by", { - user: interaction.user.tag, - }), - ); - break; - case "queue": - dispatcher.loop = "off"; - await editMessage( - T(locale, "player.trackStart.looping_off_by", { - user: interaction.user.tag, - }), - ); - break; - } - break; + const editMessage = async (text: string): Promise => { + if (message) { + await message.edit({ + embeds: [ + embed.setFooter({ + text, + iconURL: interaction.user.avatarURL({}), + }), + ], + components: [createButtonRow(dispatcher, client)], + }); + } + }; + switch (interaction.customId) { + case "previous": + if (dispatcher.previous) { + await interaction.deferUpdate(); + dispatcher.previousTrack(); + await editMessage( + T(locale, "player.trackStart.previous_by", { + user: interaction.user.tag, + }), + ); + } else { + await interaction.reply({ + content: T(locale, "player.trackStart.no_previous_song"), + ephemeral: true, + }); } - }); + break; + case "resume": + dispatcher.pause(); + await interaction.deferUpdate(); + await editMessage( + dispatcher.paused + ? T(locale, "player.trackStart.paused_by", { + user: interaction.user.tag, + }) + : T(locale, "player.trackStart.resumed_by", { + user: interaction.user.tag, + }), + ); + break; + case "stop": + dispatcher.stop(); + await interaction.deferUpdate(); + break; + case "skip": + if (dispatcher.queue.length) { + await interaction.deferUpdate(); + dispatcher.skip(); + await editMessage( + T(locale, "player.trackStart.skipped_by", { + user: interaction.user.tag, + }), + ); + } else { + await interaction.reply({ + content: T(locale, "player.trackStart.no_more_songs_in_queue"), + ephemeral: true, + }); + } + break; + case "loop": + await interaction.deferUpdate(); + switch (dispatcher.loop) { + case "off": + dispatcher.loop = "repeat"; + await editMessage( + T(locale, "player.trackStart.looping_by", { + user: interaction.user.tag, + }), + ); + break; + case "repeat": + dispatcher.loop = "queue"; + await editMessage( + T(locale, "player.trackStart.looping_queue_by", { + user: interaction.user.tag, + }), + ); + break; + case "queue": + dispatcher.loop = "off"; + await editMessage( + T(locale, "player.trackStart.looping_off_by", { + user: interaction.user.tag, + }), + ); + break; + } + break; + } + }); } export async function checkDj( - client: Lavamusic, - interaction: - | ButtonInteraction<"cached"> - | StringSelectMenuInteraction<"cached"> - | UserSelectMenuInteraction<"cached"> - | RoleSelectMenuInteraction<"cached"> - | MentionableSelectMenuInteraction<"cached"> - | ChannelSelectMenuInteraction<"cached">, + client: Lavamusic, + interaction: + | ButtonInteraction<"cached"> + | StringSelectMenuInteraction<"cached"> + | UserSelectMenuInteraction<"cached"> + | RoleSelectMenuInteraction<"cached"> + | MentionableSelectMenuInteraction<"cached"> + | ChannelSelectMenuInteraction<"cached">, ): Promise { - const dj = await client.db.getDj(interaction.guildId); - if (dj?.mode) { - const djRole = await client.db.getRoles(interaction.guildId); - if (!djRole) return false; - const hasDjRole = interaction.member.roles.cache.some((role) => djRole.map((r) => r.roleId).includes(role.id)); - if (!(hasDjRole || interaction.member.permissions.has(PermissionFlagsBits.ManageGuild))) { - return false; - } + const dj = await client.db.getDj(interaction.guildId); + if (dj?.mode) { + const djRole = await client.db.getRoles(interaction.guildId); + if (!djRole) return false; + const hasDjRole = interaction.member.roles.cache.some((role) => djRole.map((r) => r.roleId).includes(role.id)); + if (!(hasDjRole || interaction.member.permissions.has(PermissionFlagsBits.ManageGuild))) { + return false; } - return true; + } + return true; } /** diff --git a/src/index.ts b/src/index.ts index 2fc907477..807e4f56b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,40 +14,40 @@ const theme = new ThemeSelector(); * @param title - The new title for the console window. */ function setConsoleTitle(title: string): void { - // Write the escape sequence to change the console title - process.stdout.write(`\x1b]0;${title}\x07`); + // Write the escape sequence to change the console title + process.stdout.write(`\x1b]0;${title}\x07`); } async function main(): Promise { - try { - if (!fs.existsSync("./src/utils/LavaLogo.txt")) { - logger.error("LavaLogo.txt file is missing"); - process.exit(1); - } - console.clear(); - // Set a custom title for the console window - setConsoleTitle("Lavamusic"); - const logFile = fs.readFileSync("./src/utils/LavaLogo.txt", "utf-8"); - console.log(theme.purpleNeon(logFile)); - const manager = new ShardingManager("./dist/LavaClient.js", { - respawn: true, - token: config.token, - totalShards: "auto", - shardList: "auto", - }); + try { + if (!fs.existsSync("./src/utils/LavaLogo.txt")) { + logger.error("LavaLogo.txt file is missing"); + process.exit(1); + } + console.clear(); + // Set a custom title for the console window + setConsoleTitle("Lavamusic"); + const logFile = fs.readFileSync("./src/utils/LavaLogo.txt", "utf-8"); + console.log(theme.purpleNeon(logFile)); + const manager = new ShardingManager("./dist/LavaClient.js", { + respawn: true, + token: config.token, + totalShards: "auto", + shardList: "auto", + }); - manager.on("shardCreate", (shard) => { - shard.on("ready", () => { - logger.start(`[CLIENT] Shard ${shard.id} connected to Discord's Gateway.`); - }); - }); + manager.on("shardCreate", (shard) => { + shard.on("ready", () => { + logger.start(`[CLIENT] Shard ${shard.id} connected to Discord's Gateway.`); + }); + }); - await manager.spawn(); + await manager.spawn(); - logger.start(`[CLIENT] ${manager.totalShards} shard(s) spawned.`); - } catch (err) { - logger.error("[CLIENT] An error has occurred:", err); - } + logger.start(`[CLIENT] ${manager.totalShards} shard(s) spawned.`); + } catch (err) { + logger.error("[CLIENT] An error has occurred:", err); + } } main(); diff --git a/src/plugin/index.ts b/src/plugin/index.ts index dd455b10f..fe6da1a3d 100644 --- a/src/plugin/index.ts +++ b/src/plugin/index.ts @@ -7,26 +7,26 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); const pluginsFolder = path.join(__dirname, "plugins"); export default async function loadPlugins(client: Lavamusic): Promise { - try { - const pluginFiles = fs.readdirSync(pluginsFolder).filter((file) => file.endsWith(".js")); - for (const file of pluginFiles) { - const pluginPath = path.join(pluginsFolder, file); - const { default: plugin } = await import(`file://${pluginPath}`); - if (plugin.initialize) plugin.initialize(client); - client.logger.info(`Loaded plugin: ${plugin.name} v${plugin.version}`); - } - } catch (error) { - client.logger.error("Error loading plugins:", error); + try { + const pluginFiles = fs.readdirSync(pluginsFolder).filter((file) => file.endsWith(".js")); + for (const file of pluginFiles) { + const pluginPath = path.join(pluginsFolder, file); + const { default: plugin } = await import(`file://${pluginPath}`); + if (plugin.initialize) plugin.initialize(client); + client.logger.info(`Loaded plugin: ${plugin.name} v${plugin.version}`); } + } catch (error) { + client.logger.error("Error loading plugins:", error); + } } export interface BotPlugin { - name: string; - version: string; - author: string; - description?: string; - initialize: (client: Lavamusic) => void; - shutdown?: (client: Lavamusic) => void; + name: string; + version: string; + author: string; + description?: string; + initialize: (client: Lavamusic) => void; + shutdown?: (client: Lavamusic) => void; } /** diff --git a/src/plugin/plugins/antiCrash.ts b/src/plugin/plugins/antiCrash.ts index bd84eb4ff..fef290106 100644 --- a/src/plugin/plugins/antiCrash.ts +++ b/src/plugin/plugins/antiCrash.ts @@ -2,28 +2,28 @@ import type { Lavamusic } from "../../structures/index.js"; import type { BotPlugin } from "../index.js"; const antiCrash: BotPlugin = { - name: "AntiCrash Plugin", - version: "1.0.0", - author: "Appu", - initialize: (client: Lavamusic) => { - const handleExit = async (): Promise => { - if (client) { - client.logger.star("Disconnecting from Discord..."); - await client.destroy(); - client.logger.success("Successfully disconnected from Discord!"); - process.exit(); - } - }; - process.on("unhandledRejection", (reason, promise) => { - client.logger.error("Unhandled Rejection at:", promise, "reason:", reason); - }); - process.on("uncaughtException", (err) => { - client.logger.error("Uncaught Exception thrown:", err); - }); - process.on("SIGINT", handleExit); - process.on("SIGTERM", handleExit); - process.on("SIGQUIT", handleExit); - }, + name: "AntiCrash Plugin", + version: "1.0.0", + author: "Appu", + initialize: (client: Lavamusic) => { + const handleExit = async (): Promise => { + if (client) { + client.logger.star("Disconnecting from Discord..."); + await client.destroy(); + client.logger.success("Successfully disconnected from Discord!"); + process.exit(); + } + }; + process.on("unhandledRejection", (reason, promise) => { + client.logger.error("Unhandled Rejection at:", promise, "reason:", reason); + }); + process.on("uncaughtException", (err) => { + client.logger.error("Uncaught Exception thrown:", err); + }); + process.on("SIGINT", handleExit); + process.on("SIGTERM", handleExit); + process.on("SIGQUIT", handleExit); + }, }; export default antiCrash; diff --git a/src/plugin/plugins/keepAlive.ts b/src/plugin/plugins/keepAlive.ts index adf545818..2604f6077 100644 --- a/src/plugin/plugins/keepAlive.ts +++ b/src/plugin/plugins/keepAlive.ts @@ -3,20 +3,20 @@ import type { Lavamusic } from "../../structures/index.js"; import type { BotPlugin } from "../index.js"; const keepAlive: BotPlugin = { - name: "KeepAlive Plugin", - version: "1.0.0", - author: "Appu", - initialize: (client: Lavamusic) => { - if (client.config.keepAlive) { - const server = http.createServer((_req, res) => { - res.writeHead(200, { "Content-Type": "text/plain" }); - res.end(`I'm alive! Currently serving ${client.guilds.cache.size} guilds.`); - }); - server.listen(3000, () => { - client.logger.info("Keep-Alive server is running on port 3000"); - }); - } - }, + name: "KeepAlive Plugin", + version: "1.0.0", + author: "Appu", + initialize: (client: Lavamusic) => { + if (client.config.keepAlive) { + const server = http.createServer((_req, res) => { + res.writeHead(200, { "Content-Type": "text/plain" }); + res.end(`I'm alive! Currently serving ${client.guilds.cache.size} guilds.`); + }); + server.listen(3000, () => { + client.logger.info("Keep-Alive server is running on port 3000"); + }); + } + }, }; export default keepAlive; diff --git a/src/plugin/plugins/updateStatus.ts b/src/plugin/plugins/updateStatus.ts index e8487f547..affe1e5b0 100644 --- a/src/plugin/plugins/updateStatus.ts +++ b/src/plugin/plugins/updateStatus.ts @@ -2,12 +2,12 @@ import type { Lavamusic } from "../../structures/index.js"; import type { BotPlugin } from "../index.js"; const updateStatusPlugin: BotPlugin = { - name: "Update Status Plugin", - version: "1.0.0", - author: "Appu", - initialize: (client: Lavamusic) => { - client.on("ready", () => client.utils.updateStatus(client)); - }, + name: "Update Status Plugin", + version: "1.0.0", + author: "Appu", + initialize: (client: Lavamusic) => { + client.on("ready", () => client.utils.updateStatus(client)); + }, }; export default updateStatusPlugin; diff --git a/src/structures/Command.ts b/src/structures/Command.ts index 2e2f5b990..1cf08afb6 100644 --- a/src/structures/Command.ts +++ b/src/structures/Command.ts @@ -2,89 +2,89 @@ import type { APIApplicationCommandOption, PermissionResolvable } from "discord. import type Lavamusic from "./Lavamusic.js"; interface CommandDescription { - content: string; - usage: string; - examples: string[]; + content: string; + usage: string; + examples: string[]; } interface CommandPlayer { - voice: boolean; - dj: boolean; - active: boolean; - djPerm: string | null; + voice: boolean; + dj: boolean; + active: boolean; + djPerm: string | null; } interface CommandPermissions { - dev: boolean; - client: string[] | PermissionResolvable; - user: string[] | PermissionResolvable; + dev: boolean; + client: string[] | PermissionResolvable; + user: string[] | PermissionResolvable; } interface CommandOptions { - name: string; - name_localizations?: Record; - description?: Partial; - description_localizations?: Record; - aliases?: string[]; - cooldown?: number; - args?: boolean; - vote?: boolean; - player?: Partial; - permissions?: Partial; - slashCommand?: boolean; - options?: APIApplicationCommandOption[]; - category?: string; + name: string; + name_localizations?: Record; + description?: Partial; + description_localizations?: Record; + aliases?: string[]; + cooldown?: number; + args?: boolean; + vote?: boolean; + player?: Partial; + permissions?: Partial; + slashCommand?: boolean; + options?: APIApplicationCommandOption[]; + category?: string; } export default class Command { - public client: Lavamusic; - public name: string; - public name_localizations?: Record; - public description: CommandDescription; - public description_localizations?: Record; - public aliases: string[]; - public cooldown: number; - public args: boolean; - public vote: boolean; - public player: CommandPlayer; - public permissions: CommandPermissions; - public slashCommand: boolean; - public options: APIApplicationCommandOption[]; - public category: string; + public client: Lavamusic; + public name: string; + public name_localizations?: Record; + public description: CommandDescription; + public description_localizations?: Record; + public aliases: string[]; + public cooldown: number; + public args: boolean; + public vote: boolean; + public player: CommandPlayer; + public permissions: CommandPermissions; + public slashCommand: boolean; + public options: APIApplicationCommandOption[]; + public category: string; - constructor(client: Lavamusic, options: CommandOptions) { - this.client = client; - this.name = options.name; - this.name_localizations = options.name_localizations ?? {}; - this.description = { - content: options.description?.content ?? "No description provided", - usage: options.description?.usage ?? "No usage provided", - examples: options.description?.examples ?? ["No examples provided"], - }; - this.description_localizations = options.description_localizations ?? {}; - this.aliases = options.aliases ?? []; - this.cooldown = options.cooldown ?? 3; - this.args = options.args ?? false; - this.vote = options.vote ?? false; - this.player = { - voice: options.player?.voice ?? false, - dj: options.player?.dj ?? false, - active: options.player?.active ?? false, - djPerm: options.player?.djPerm ?? null, - }; - this.permissions = { - dev: options.permissions?.dev ?? false, - client: options.permissions?.client ?? ["SendMessages", "ViewChannel", "EmbedLinks"], - user: options.permissions?.user ?? [], - }; - this.slashCommand = options.slashCommand ?? false; - this.options = options.options ?? []; - this.category = options.category ?? "general"; - } + constructor(client: Lavamusic, options: CommandOptions) { + this.client = client; + this.name = options.name; + this.name_localizations = options.name_localizations ?? {}; + this.description = { + content: options.description?.content ?? "No description provided", + usage: options.description?.usage ?? "No usage provided", + examples: options.description?.examples ?? ["No examples provided"], + }; + this.description_localizations = options.description_localizations ?? {}; + this.aliases = options.aliases ?? []; + this.cooldown = options.cooldown ?? 3; + this.args = options.args ?? false; + this.vote = options.vote ?? false; + this.player = { + voice: options.player?.voice ?? false, + dj: options.player?.dj ?? false, + active: options.player?.active ?? false, + djPerm: options.player?.djPerm ?? null, + }; + this.permissions = { + dev: options.permissions?.dev ?? false, + client: options.permissions?.client ?? ["SendMessages", "ViewChannel", "EmbedLinks"], + user: options.permissions?.user ?? [], + }; + this.slashCommand = options.slashCommand ?? false; + this.options = options.options ?? []; + this.category = options.category ?? "general"; + } - public async run(_client: Lavamusic, _message: any, _args: string[]): Promise { - return await Promise.resolve(); - } + public async run(_client: Lavamusic, _message: any, _args: string[]): Promise { + return await Promise.resolve(); + } } /** diff --git a/src/structures/Context.ts b/src/structures/Context.ts index da14bb27b..3bfd1d10e 100644 --- a/src/structures/Context.ts +++ b/src/structures/Context.ts @@ -1,139 +1,139 @@ import { - type APIInteractionGuildMember, - ChannelType, - ChatInputCommandInteraction, - type CommandInteraction, - type DMChannel, - type Guild, - type GuildMember, - type GuildMemberResolvable, - type GuildTextBasedChannel, - type InteractionEditReplyOptions, - type InteractionReplyOptions, - Message, - type MessageCreateOptions, - type MessageEditOptions, - type MessagePayload, - type PartialDMChannel, - type TextChannel, - type User, + type APIInteractionGuildMember, + ChannelType, + ChatInputCommandInteraction, + type CommandInteraction, + type DMChannel, + type Guild, + type GuildMember, + type GuildMemberResolvable, + type GuildTextBasedChannel, + type InteractionEditReplyOptions, + type InteractionReplyOptions, + Message, + type MessageCreateOptions, + type MessageEditOptions, + type MessagePayload, + type PartialDMChannel, + type TextChannel, + type User, } from "discord.js"; import { T } from "./I18n.js"; import type { Lavamusic } from "./index.js"; export default class Context { - public ctx: CommandInteraction | Message; - public interaction: CommandInteraction | null; - public message: Message | null; - public id: string; - public channelId: string; - public client: Lavamusic; - public author: User | null; - public channel: PartialDMChannel | GuildTextBasedChannel | TextChannel | DMChannel | null = null; - public guild: Guild | null; - public createdAt: Date; - public createdTimestamp: number; - public member: GuildMemberResolvable | GuildMember | APIInteractionGuildMember | null; - public args: any[]; - public msg: any; - public guildLocale: string; - - constructor(ctx: ChatInputCommandInteraction | Message, args: any[]) { - this.ctx = ctx; - this.interaction = ctx instanceof ChatInputCommandInteraction ? ctx : null; - this.message = ctx instanceof Message ? ctx : null; - - if (ctx.channel && ctx.channel.type !== ChannelType.GroupDM) { - this.channel = ctx.channel; - } else { - this.channel = null; - } - - this.id = ctx.id; - this.channelId = ctx.channelId; - this.client = ctx.client as Lavamusic; - this.author = ctx instanceof Message ? ctx.author : ctx.user; - this.guild = ctx.guild; - this.createdAt = ctx.createdAt; - this.createdTimestamp = ctx.createdTimestamp; - this.member = ctx.member; - this.args = args; - this.setArgs(args); - this.setUpLocale(); + public ctx: CommandInteraction | Message; + public interaction: CommandInteraction | null; + public message: Message | null; + public id: string; + public channelId: string; + public client: Lavamusic; + public author: User | null; + public channel: PartialDMChannel | GuildTextBasedChannel | TextChannel | DMChannel | null = null; + public guild: Guild | null; + public createdAt: Date; + public createdTimestamp: number; + public member: GuildMemberResolvable | GuildMember | APIInteractionGuildMember | null; + public args: any[]; + public msg: any; + public guildLocale: string; + + constructor(ctx: ChatInputCommandInteraction | Message, args: any[]) { + this.ctx = ctx; + this.interaction = ctx instanceof ChatInputCommandInteraction ? ctx : null; + this.message = ctx instanceof Message ? ctx : null; + + if (ctx.channel && ctx.channel.type !== ChannelType.GroupDM) { + this.channel = ctx.channel; + } else { + this.channel = null; } - private async setUpLocale(): Promise { - this.guildLocale = this.guild ? await this.client.db.getLanguage(this.guild.id) : "en"; - } - - public get isInteraction(): boolean { - return this.ctx instanceof ChatInputCommandInteraction; - } - - public setArgs(args: any[]): void { - this.args = this.isInteraction ? args.map((arg: { value: any }) => arg.value) : args; - } - - public async sendMessage(content: string | MessagePayload | MessageCreateOptions | InteractionReplyOptions): Promise { - if (this.isInteraction) { - if (typeof content === "string" || isInteractionReplyOptions(content)) { - this.msg = await this.interaction.reply(content); - return this.msg; - } - } else if (typeof content === "string" || isMessagePayload(content)) { - this.msg = await (this.message.channel as TextChannel).send(content); - return this.msg; - } + this.id = ctx.id; + this.channelId = ctx.channelId; + this.client = ctx.client as Lavamusic; + this.author = ctx instanceof Message ? ctx.author : ctx.user; + this.guild = ctx.guild; + this.createdAt = ctx.createdAt; + this.createdTimestamp = ctx.createdTimestamp; + this.member = ctx.member; + this.args = args; + this.setArgs(args); + this.setUpLocale(); + } + + private async setUpLocale(): Promise { + this.guildLocale = this.guild ? await this.client.db.getLanguage(this.guild.id) : "en"; + } + + public get isInteraction(): boolean { + return this.ctx instanceof ChatInputCommandInteraction; + } + + public setArgs(args: any[]): void { + this.args = this.isInteraction ? args.map((arg: { value: any }) => arg.value) : args; + } + + public async sendMessage(content: string | MessagePayload | MessageCreateOptions | InteractionReplyOptions): Promise { + if (this.isInteraction) { + if (typeof content === "string" || isInteractionReplyOptions(content)) { + this.msg = await this.interaction.reply(content); return this.msg; + } + } else if (typeof content === "string" || isMessagePayload(content)) { + this.msg = await (this.message.channel as TextChannel).send(content); + return this.msg; } + return this.msg; + } - public async editMessage(content: string | MessagePayload | InteractionEditReplyOptions | MessageEditOptions): Promise { - if (this.isInteraction && this.msg) { - this.msg = await this.interaction.editReply(content); - return this.msg; - } - if (this.msg) { - this.msg = await this.msg.edit(content); - return this.msg; - } - return this.msg; + public async editMessage(content: string | MessagePayload | InteractionEditReplyOptions | MessageEditOptions): Promise { + if (this.isInteraction && this.msg) { + this.msg = await this.interaction.editReply(content); + return this.msg; } - - public async sendDeferMessage(content: string | MessagePayload | MessageCreateOptions): Promise { - if (this.isInteraction) { - this.msg = await this.interaction.deferReply({ fetchReply: true }); - return this.msg; - } - - this.msg = await (this.message.channel as TextChannel).send(content); - return this.msg; + if (this.msg) { + this.msg = await this.msg.edit(content); + return this.msg; } + return this.msg; + } - public locale(key: string, ...args: any) { - return T(this.guildLocale, key, ...args); + public async sendDeferMessage(content: string | MessagePayload | MessageCreateOptions): Promise { + if (this.isInteraction) { + this.msg = await this.interaction.deferReply({ fetchReply: true }); + return this.msg; } - public async sendFollowUp(content: string | MessagePayload | MessageCreateOptions | InteractionReplyOptions): Promise { - if (this.isInteraction) { - if (typeof content === "string" || isInteractionReplyOptions(content)) { - await this.interaction.followUp(content); - } - } else if (typeof content === "string" || isMessagePayload(content)) { - this.msg = await (this.message.channel as TextChannel).send(content); - } + this.msg = await (this.message.channel as TextChannel).send(content); + return this.msg; + } + + public locale(key: string, ...args: any) { + return T(this.guildLocale, key, ...args); + } + + public async sendFollowUp(content: string | MessagePayload | MessageCreateOptions | InteractionReplyOptions): Promise { + if (this.isInteraction) { + if (typeof content === "string" || isInteractionReplyOptions(content)) { + await this.interaction.followUp(content); + } + } else if (typeof content === "string" || isMessagePayload(content)) { + this.msg = await (this.message.channel as TextChannel).send(content); } + } - public get deferred(): boolean | Promise { - return this.isInteraction ? this.interaction.deferred : !!this.msg; - } + public get deferred(): boolean | Promise { + return this.isInteraction ? this.interaction.deferred : !!this.msg; + } } function isInteractionReplyOptions(content: any): content is InteractionReplyOptions { - return content instanceof Object; + return content instanceof Object; } function isMessagePayload(content: any): content is MessagePayload { - return content instanceof Object; + return content instanceof Object; } /** diff --git a/src/structures/Dispatcher.ts b/src/structures/Dispatcher.ts index a31b2c82c..aa44af7f8 100644 --- a/src/structures/Dispatcher.ts +++ b/src/structures/Dispatcher.ts @@ -4,299 +4,296 @@ import { SearchEngine } from "../types.js"; import type { Lavamusic } from "./index.js"; export class Song implements Track { - encoded: string; - info: { - identifier: string; - isSeekable: boolean; - author: string; - length: number; - isStream: boolean; - position: number; - title: string; - uri?: string; - artworkUrl?: string; - isrc?: string; - sourceName: string; - requester: User; - }; - pluginInfo: unknown; + encoded: string; + info: { + identifier: string; + isSeekable: boolean; + author: string; + length: number; + isStream: boolean; + position: number; + title: string; + uri?: string; + artworkUrl?: string; + isrc?: string; + sourceName: string; + requester: User; + }; + pluginInfo: unknown; - constructor(track: Song | Track, user: User) { - if (!track) throw new Error("Track is not provided"); - this.encoded = track.encoded; - this.info = { - ...track.info, - requester: user, - }; - } + constructor(track: Song | Track, user: User) { + if (!track) throw new Error("Track is not provided"); + this.encoded = track.encoded; + this.info = { + ...track.info, + requester: user, + }; + } } interface DispatcherOptions { - client: Lavamusic; - guildId: string; - channelId: string; - player: Player; - node: Node; + client: Lavamusic; + guildId: string; + channelId: string; + player: Player; + node: Node; } export default class Dispatcher { - private client: Lavamusic; - public guildId: string; - public channelId: string; - public player: Player; - public queue: Song[]; - public stopped: boolean; - public previous: Song | null; - public current: Song | null; - public loop: "off" | "repeat" | "queue"; - public requester: User; - public repeat: number; - public node: Node; - public paused: boolean; - public filters: string[]; - public autoplay: boolean; - public nowPlayingMessage: Message | null; - public history: Song[]; + private client: Lavamusic; + public guildId: string; + public channelId: string; + public player: Player; + public queue: Song[]; + public stopped: boolean; + public previous: Song | null; + public current: Song | null; + public loop: "off" | "repeat" | "queue"; + public requester: User; + public repeat: number; + public node: Node; + public paused: boolean; + public filters: string[]; + public autoplay: boolean; + public nowPlayingMessage: Message | null; + public history: Song[]; - constructor(options: DispatcherOptions) { - this.client = options.client; - this.guildId = options.guildId; - this.channelId = options.channelId; - this.player = options.player; - this.queue = []; - this.stopped = false; - this.previous = null; - this.current = null; - this.loop = "off"; - this.repeat = 0; - this.node = options.node; - this.paused = false; - this.filters = []; - this.autoplay = false; - this.nowPlayingMessage = null; - this.history = []; - this.player - .on("start", () => this.client.shoukaku.emit("trackStart" as any, this.player, this.current, this)) - .on("end", () => { - if (!this.queue.length) { - this.client.shoukaku.emit("queueEnd" as any, this.player, this.current, this); - } - this.client.shoukaku.emit("trackEnd" as any, this.player, this.current, this); - }) - .on("stuck", () => this.client.shoukaku.emit("trackStuck" as any, this.player, this.current)) - .on("closed", (...args) => this.client.shoukaku.emit("socketClosed" as any, this.player, ...args)); - } + constructor(options: DispatcherOptions) { + this.client = options.client; + this.guildId = options.guildId; + this.channelId = options.channelId; + this.player = options.player; + this.queue = []; + this.stopped = false; + this.previous = null; + this.current = null; + this.loop = "off"; + this.repeat = 0; + this.node = options.node; + this.paused = false; + this.filters = []; + this.autoplay = false; + this.nowPlayingMessage = null; + this.history = []; + this.player + .on("start", () => this.client.shoukaku.emit("trackStart" as any, this.player, this.current, this)) + .on("end", () => { + if (!this.queue.length) { + this.client.shoukaku.emit("queueEnd" as any, this.player, this.current, this); + } + this.client.shoukaku.emit("trackEnd" as any, this.player, this.current, this); + }) + .on("stuck", () => this.client.shoukaku.emit("trackStuck" as any, this.player, this.current)) + .on("closed", (...args) => this.client.shoukaku.emit("socketClosed" as any, this.player, ...args)); + } - get exists(): boolean { - return this.client.queue.has(this.guildId); - } + get exists(): boolean { + return this.client.queue.has(this.guildId); + } - get volume(): number { - return this.player.volume; - } + get volume(): number { + return this.player.volume; + } - public play(): Promise { - if (!(this.exists && (this.queue.length || this.current))) return; - this.current = this.queue.length ? this.queue.shift() : this.queue[0]; - if (this.current) { - this.player.playTrack({ track: { encoded: this.current.encoded } }); - this.history.push(this.current); - if (this.history.length > 100) this.history.shift(); - } + public play(): Promise { + if (!(this.exists && (this.queue.length || this.current))) return; + this.current = this.queue.length ? this.queue.shift() : this.queue[0]; + if (this.current) { + this.player.playTrack({ track: { encoded: this.current.encoded } }); + this.history.push(this.current); + if (this.history.length > 100) this.history.shift(); } + } - public pause(): void { - if (this.player) { - this.paused = !this.paused; - this.player.setPaused(this.paused); - } + public pause(): void { + if (this.player) { + this.paused = !this.paused; + this.player.setPaused(this.paused); } + } - public remove(index: number): void { - if (this.player && index <= this.queue.length) { - this.queue.splice(index, 1); - } + public remove(index: number): void { + if (this.player && index <= this.queue.length) { + this.queue.splice(index, 1); } + } - public previousTrack(): void { - if (this.player && this.previous) { - this.queue.unshift(this.previous); - this.player.stopTrack(); - } + public previousTrack(): void { + if (this.player && this.previous) { + this.queue.unshift(this.previous); + this.player.stopTrack(); } + } - public destroy(): void { - this.queue.length = 0; - this.history = []; - this.client.shoukaku.leaveVoiceChannel(this.guildId); - this.player.destroy(); - this.client.queue.delete(this.guildId); - if (!this.stopped) { - this.client.shoukaku.emit("playerDestroy" as any, this.player); - } + public destroy(): void { + this.queue.length = 0; + this.history = []; + this.client.shoukaku.leaveVoiceChannel(this.guildId); + this.player.destroy(); + this.client.queue.delete(this.guildId); + if (!this.stopped) { + this.client.shoukaku.emit("playerDestroy" as any, this.player); } + } - public setShuffle(): void { - if (this.player) { - for (let i = this.queue.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - [this.queue[i], this.queue[j]] = [this.queue[j], this.queue[i]]; - } - } + public setShuffle(): void { + if (this.player) { + for (let i = this.queue.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [this.queue[i], this.queue[j]] = [this.queue[j], this.queue[i]]; + } } + } - public skip(skipto = 1): void { - if (this.player) { - if (skipto > this.queue.length) { - this.queue.length = 0; - } else { - this.queue.splice(0, skipto - 1); - } - this.repeat = this.repeat === 1 ? 0 : this.repeat; - this.player.stopTrack(); - } + public skip(skipto = 1): void { + if (this.player) { + if (skipto > this.queue.length) { + this.queue.length = 0; + } else { + this.queue.splice(0, skipto - 1); + } + this.repeat = this.repeat === 1 ? 0 : this.repeat; + this.player.stopTrack(); } + } - public seek(time: number): void { - if (this.player) { - this.player.seekTo(time); - } + public seek(time: number): void { + if (this.player) { + this.player.seekTo(time); } + } - public stop(): void { - if (this.player) { - this.queue.length = 0; - this.history = []; - this.loop = "off"; - this.autoplay = false; - this.repeat = 0; - this.stopped = true; - this.player.stopTrack(); - } + public stop(): void { + if (this.player) { + this.queue.length = 0; + this.history = []; + this.loop = "off"; + this.autoplay = false; + this.repeat = 0; + this.stopped = true; + this.player.stopTrack(); } + } - public setLoop(loop: "off" | "repeat" | "queue"): void { - this.loop = loop; - } + public setLoop(loop: "off" | "repeat" | "queue"): void { + this.loop = loop; + } - public buildTrack(track: Song | Track, user: User): Song { - return new Song(track, user); - } + public buildTrack(track: Song | Track, user: User): Song { + return new Song(track, user); + } - public async isPlaying(): Promise { - if (this.queue.length && !this.current && !this.player.paused) { - await this.play(); - } + public async isPlaying(): Promise { + if (this.queue.length && !this.current && !this.player.paused) { + await this.play(); } + } - public async Autoplay(song: Song): Promise { - if (!song?.info) return; + public async Autoplay(song: Song): Promise { + if (!song?.info) return; - try { - const node = this.client.shoukaku.options.nodeResolver(this.client.shoukaku.nodes); - if (!node) return; - switch (song.info.sourceName) { - case "youtube": { - const resolve = await node.rest.resolve(`${SearchEngine.YouTubeMusic}:${song.info.author}`); - this.addAutoplayTrack(resolve); - break; - } - case "soundcloud": - await node.rest.resolve(`${SearchEngine.SoundCloud}:${song.info.author}`); - break; - case "spotify": { - // need lavaSrc plugin in lavalink - const data = await node.rest.resolve(`sprec:seed_tracks=${song.info.identifier}`); - if (!data) return; - if (data.loadType === LoadType.PLAYLIST) { - const tracks = data.data.tracks; - const trackUrl = tracks[Math.floor(Math.random() * tracks.length)]?.info?.uri; - if (!trackUrl) return; - const resolve = await node.rest.resolve(trackUrl); - if (!resolve) return; - if (resolve.loadType === LoadType.TRACK) { - const song = new Song(resolve.data, this.client.user!); - this.queue.push(song); - return this.isPlaying(); - } - } - break; - } - // need jiosaavn plugin in lavalink (https://github.com/appujet/jiosaavn-plugin) - case "jiosaavn": { - const data = await node.rest.resolve(`jsrec:${song.info.identifier}`); - if (!data) return; - if (data.loadType === LoadType.PLAYLIST) { - const tracks = data.data.tracks; - const trackUrl = tracks[Math.floor(Math.random() * tracks.length)]?.info?.uri; - if (!trackUrl) return; - const resolve = await node.rest.resolve(trackUrl); - if (!resolve) return; - if (resolve.loadType === LoadType.TRACK) { - const song = new Song(resolve.data, this.client.user!); - this.queue.push(song); - return this.isPlaying(); - } - } - break; - } - case "deezer": { - const resolve = await node.rest.resolve(`${SearchEngine.Deezer}:${song.info.author}`); - this.addAutoplayTrack(resolve); - break; - } - case "applemusic": { - const resolve = await node.rest.resolve(`${SearchEngine.Apple}:${song.info.author}`); - this.addAutoplayTrack(resolve); - break; - } - default: { - const resolve = await node.rest.resolve(`${SearchEngine.YouTubeMusic}:${song.info.author}`); - this.addAutoplayTrack(resolve); - break; - } + try { + const node = this.client.shoukaku.options.nodeResolver(this.client.shoukaku.nodes); + if (!node) return; + switch (song.info.sourceName) { + case "youtube": { + const resolve = await node.rest.resolve(`${SearchEngine.YouTubeMusic}:${song.info.author}`); + this.addAutoplayTrack(resolve); + break; + } + case "soundcloud": + await node.rest.resolve(`${SearchEngine.SoundCloud}:${song.info.author}`); + break; + case "spotify": { + // need lavaSrc plugin in lavalink + const data = await node.rest.resolve(`sprec:seed_tracks=${song.info.identifier}`); + if (!data) return; + if (data.loadType === LoadType.PLAYLIST) { + const tracks = data.data.tracks; + const trackUrl = tracks[Math.floor(Math.random() * tracks.length)]?.info?.uri; + if (!trackUrl) return; + const resolve = await node.rest.resolve(trackUrl); + if (!resolve) return; + if (resolve.loadType === LoadType.TRACK) { + const song = new Song(resolve.data, this.client.user!); + this.queue.push(song); + return this.isPlaying(); } - } catch (_error) { - return this.destroy(); + } + break; } - } - private addAutoplayTrack(resolve: any) { - if (!(resolve?.data && Array.isArray(resolve.data))) { - console.error("Failed to fetch node resolve data."); - return this.destroy(); + // need jiosaavn plugin in lavalink (https://github.com/appujet/jiosaavn-plugin) + case "jiosaavn": { + const data = await node.rest.resolve(`jsrec:${song.info.identifier}`); + if (!data) return; + if (data.loadType === LoadType.PLAYLIST) { + const tracks = data.data.tracks; + const trackUrl = tracks[Math.floor(Math.random() * tracks.length)]?.info?.uri; + if (!trackUrl) return; + const resolve = await node.rest.resolve(trackUrl); + if (!resolve) return; + if (resolve.loadType === LoadType.TRACK) { + const song = new Song(resolve.data, this.client.user!); + this.queue.push(song); + return this.isPlaying(); + } + } + break; + } + case "deezer": { + const resolve = await node.rest.resolve(`${SearchEngine.Deezer}:${song.info.author}`); + this.addAutoplayTrack(resolve); + break; } + case "applemusic": { + const resolve = await node.rest.resolve(`${SearchEngine.Apple}:${song.info.author}`); + this.addAutoplayTrack(resolve); + break; + } + default: { + const resolve = await node.rest.resolve(`${SearchEngine.YouTubeMusic}:${song.info.author}`); + this.addAutoplayTrack(resolve); + break; + } + } + } catch (_error) { + return this.destroy(); + } + } + private addAutoplayTrack(resolve: any) { + if (!(resolve?.data && Array.isArray(resolve.data))) { + console.error("Failed to fetch node resolve data."); + return this.destroy(); + } - let choosed: Song | null = null; - const maxAttempts = 10; - let attempts = 0; + let choosed: Song | null = null; + const maxAttempts = 10; + let attempts = 0; - const metadata = resolve.data as any[] as any; + const metadata = resolve.data as any[] as any; - while (attempts < maxAttempts) { - const potentialChoice = new Song(metadata[Math.floor(Math.random() * metadata.length)], this.client.user!); - if ( - !( - this.queue.some((s) => s.encoded === potentialChoice.encoded) || - this.history.some((s) => s.encoded === potentialChoice.encoded) - ) - ) { - choosed = potentialChoice; - break; - } - attempts++; - } + while (attempts < maxAttempts) { + const potentialChoice = new Song(metadata[Math.floor(Math.random() * metadata.length)], this.client.user!); + if ( + !(this.queue.some((s) => s.encoded === potentialChoice.encoded) || this.history.some((s) => s.encoded === potentialChoice.encoded)) + ) { + choosed = potentialChoice; + break; + } + attempts++; + } - if (choosed) { - this.queue.push(choosed); - return this.isPlaying(); - } + if (choosed) { + this.queue.push(choosed); + return this.isPlaying(); } - public async setAutoplay(autoplay: boolean): Promise { - this.autoplay = autoplay; - if (autoplay) { - await this.Autoplay(this.current || this.queue[0]); - } + } + public async setAutoplay(autoplay: boolean): Promise { + this.autoplay = autoplay; + if (autoplay) { + await this.Autoplay(this.current || this.queue[0]); } + } } /** diff --git a/src/structures/Event.ts b/src/structures/Event.ts index d5e8edcf3..d0c8a4e64 100644 --- a/src/structures/Event.ts +++ b/src/structures/Event.ts @@ -1,28 +1,28 @@ import type Lavamusic from "./Lavamusic.js"; interface EventOptions { - name: string; - one?: boolean; + name: string; + one?: boolean; } export default class Event { - public client: Lavamusic; - public one: boolean; - public file: string; - public name: string; - public fileName: string; + public client: Lavamusic; + public one: boolean; + public file: string; + public name: string; + public fileName: string; - constructor(client: Lavamusic, file: string, options: EventOptions) { - this.client = client; - this.file = file; - this.name = options.name; - this.one = options.one ?? false; - this.fileName = file.split(".")[0]; - } + constructor(client: Lavamusic, file: string, options: EventOptions) { + this.client = client; + this.file = file; + this.name = options.name; + this.one = options.one ?? false; + this.fileName = file.split(".")[0]; + } - public async run(..._args: any[]): Promise { - return await Promise.resolve(); - } + public async run(..._args: any[]): Promise { + return await Promise.resolve(); + } } /** diff --git a/src/structures/I18n.ts b/src/structures/I18n.ts index d9d286689..f4da7377d 100644 --- a/src/structures/I18n.ts +++ b/src/structures/I18n.ts @@ -8,43 +8,43 @@ import Logger from "./Logger.js"; const logger = new Logger(); export function initI18n() { - i18n.configure({ - locales: Object.keys(Language), - defaultLocale: typeof defaultLanguage === "string" ? defaultLanguage : "EnglishUS", - directory: `${process.cwd()}/locales`, - retryInDefaultLocale: true, - objectNotation: true, - register: global, - logWarnFn: console.warn, - logErrorFn: console.error, - missingKeyFn: (_locale, value) => { - return value; - }, - mustacheConfig: { - tags: ["{", "}"], - disable: false, - }, - }); - - logger.info("I18n has been initialized"); + i18n.configure({ + locales: Object.keys(Language), + defaultLocale: typeof defaultLanguage === "string" ? defaultLanguage : "EnglishUS", + directory: `${process.cwd()}/locales`, + retryInDefaultLocale: true, + objectNotation: true, + register: global, + logWarnFn: console.warn, + logErrorFn: console.error, + missingKeyFn: (_locale, value) => { + return value; + }, + mustacheConfig: { + tags: ["{", "}"], + disable: false, + }, + }); + + logger.info("I18n has been initialized"); } export { i18n }; export function T(locale: string, text: string | i18n.TranslateOptions, ...params: any) { - i18n.setLocale(locale); - return i18n.__mf(text, ...params); + i18n.setLocale(locale); + return i18n.__mf(text, ...params); } export function localization(lan: any, name: any, desc: any) { - return { - name: [Locale[lan], name], - description: [Locale[lan], T(lan, desc)], - }; + return { + name: [Locale[lan], name], + description: [Locale[lan], T(lan, desc)], + }; } export function descriptionLocalization(name: any, text: any) { - return i18n.getLocales().map((locale) => localization(Locale[locale] || locale, name, text)); + return i18n.getLocales().map((locale) => localization(Locale[locale] || locale, name, text)); } /** diff --git a/src/structures/Lavamusic.ts b/src/structures/Lavamusic.ts index 96a58dd27..2fb2c5175 100644 --- a/src/structures/Lavamusic.ts +++ b/src/structures/Lavamusic.ts @@ -3,16 +3,16 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; import { Api } from "@top-gg/sdk"; import { - ApplicationCommandType, - Client, - Collection, - EmbedBuilder, - Events, - type Interaction, - PermissionsBitField, - REST, - type RESTPostAPIChatInputApplicationCommandsJSONBody, - Routes, + ApplicationCommandType, + Client, + Collection, + EmbedBuilder, + Events, + type Interaction, + PermissionsBitField, + REST, + type RESTPostAPIChatInputApplicationCommandsJSONBody, + Routes, } from "discord.js"; import { Locale } from "discord.js"; import config from "../config.js"; @@ -26,195 +26,193 @@ import { type Command, Queue, ShoukakuClient } from "./index.js"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); export default class Lavamusic extends Client { - public commands: Collection = new Collection(); - public aliases: Collection = new Collection(); - public db = new ServerData(); - public cooldown: Collection = new Collection(); - public config = config; - public logger: Logger = new Logger(); - public readonly emoji = config.emoji; - public readonly color = config.color; - private body: RESTPostAPIChatInputApplicationCommandsJSONBody[] = []; - public shoukaku!: ShoukakuClient; - public topGG!: Api; - public utils = Utils; - public queue = new Queue(this); - - public embed(): EmbedBuilder { - return new EmbedBuilder(); - } - - public async start(token: string): Promise { - initI18n(); - const nodes = this.config.autoNode ? await this.getNodes() : this.config.lavalink; - this.shoukaku = new ShoukakuClient(this, nodes); - this.topGG = new Api(this.config.topGG); - await this.loadCommands(); - this.logger.info("Successfully loaded commands!"); - await this.loadEvents(); - this.logger.info("Successfully loaded events!"); - loadPlugins(this); - await this.login(token); - - this.on(Events.InteractionCreate, async (interaction: Interaction) => { - if (interaction.isButton() && interaction.guildId) { - const setup = await this.db.getSetup(interaction.guildId); - if (setup && interaction.channelId === setup.textId && interaction.message.id === setup.messageId) { - this.emit("setupButtons", interaction); - } - } - }); - } + public commands: Collection = new Collection(); + public aliases: Collection = new Collection(); + public db = new ServerData(); + public cooldown: Collection = new Collection(); + public config = config; + public logger: Logger = new Logger(); + public readonly emoji = config.emoji; + public readonly color = config.color; + private body: RESTPostAPIChatInputApplicationCommandsJSONBody[] = []; + public shoukaku!: ShoukakuClient; + public topGG!: Api; + public utils = Utils; + public queue = new Queue(this); + + public embed(): EmbedBuilder { + return new EmbedBuilder(); + } + + public async start(token: string): Promise { + initI18n(); + const nodes = this.config.autoNode ? await this.getNodes() : this.config.lavalink; + this.shoukaku = new ShoukakuClient(this, nodes); + this.topGG = new Api(this.config.topGG); + await this.loadCommands(); + this.logger.info("Successfully loaded commands!"); + await this.loadEvents(); + this.logger.info("Successfully loaded events!"); + loadPlugins(this); + await this.login(token); + + this.on(Events.InteractionCreate, async (interaction: Interaction) => { + if (interaction.isButton() && interaction.guildId) { + const setup = await this.db.getSetup(interaction.guildId); + if (setup && interaction.channelId === setup.textId && interaction.message.id === setup.messageId) { + this.emit("setupButtons", interaction); + } + } + }); + } - private async loadCommands(): Promise { - const commandsPath = path.join(__dirname, "../commands"); - const commandDirs = fs.readdirSync(commandsPath); + private async loadCommands(): Promise { + const commandsPath = path.join(__dirname, "../commands"); + const commandDirs = fs.readdirSync(commandsPath); - for (const dir of commandDirs) { - const commandFiles = fs.readdirSync(path.join(commandsPath, dir)).filter((file) => file.endsWith(".js")); + for (const dir of commandDirs) { + const commandFiles = fs.readdirSync(path.join(commandsPath, dir)).filter((file) => file.endsWith(".js")); - for (const file of commandFiles) { - const cmdModule = await import(`../commands/${dir}/${file}`); - const command: Command = new cmdModule.default(this); - command.category = dir; + for (const file of commandFiles) { + const cmdModule = await import(`../commands/${dir}/${file}`); + const command: Command = new cmdModule.default(this); + command.category = dir; - this.commands.set(command.name, command); - command.aliases.forEach((alias: string) => { - this.aliases.set(alias, command.name); - }); + this.commands.set(command.name, command); + command.aliases.forEach((alias: string) => { + this.aliases.set(alias, command.name); + }); - if (command.slashCommand) { - const data: RESTPostAPIChatInputApplicationCommandsJSONBody = { - name: command.name, - description: T(Locale.EnglishUS, command.description.content), - type: ApplicationCommandType.ChatInput, - options: command.options || [], - default_member_permissions: - Array.isArray(command.permissions.user) && command.permissions.user.length > 0 - ? PermissionsBitField.resolve(command.permissions.user as any).toString() - : null, - name_localizations: null, - description_localizations: null, + if (command.slashCommand) { + const data: RESTPostAPIChatInputApplicationCommandsJSONBody = { + name: command.name, + description: T(Locale.EnglishUS, command.description.content), + type: ApplicationCommandType.ChatInput, + options: command.options || [], + default_member_permissions: + Array.isArray(command.permissions.user) && command.permissions.user.length > 0 + ? PermissionsBitField.resolve(command.permissions.user as any).toString() + : null, + name_localizations: null, + description_localizations: null, + }; + + const localizations = []; + i18n.getLocales().map((locale) => { + localizations.push(localization(locale, command.name, command.description.content)); + }); + + for (const localization of localizations) { + const [language, name] = localization.name; + const [language2, description] = localization.description; + data.name_localizations = { + ...data.name_localizations, + [language]: name, + }; + data.description_localizations = { + ...data.description_localizations, + [language2]: description, + }; + } + + if (command.options.length > 0) { + command.options.map((option) => { + const optionsLocalizations = []; + i18n.getLocales().map((locale) => { + optionsLocalizations.push(localization(locale, option.name, option.description)); + }); + + for (const localization of optionsLocalizations) { + const [language, name] = localization.name; + const [language2, description] = localization.description; + option.name_localizations = { + ...option.name_localizations, + [language]: name, + }; + option.description_localizations = { + ...option.description_localizations, + [language2]: description, + }; + } + option.description = T(Locale.EnglishUS, option.description); + }); + + data.options.map((option) => { + if ("options" in option && option.options.length > 0) { + option.options.map((subOption) => { + const subOptionsLocalizations = []; + i18n.getLocales().map((locale) => { + subOptionsLocalizations.push(localization(locale, subOption.name, subOption.description)); + }); + + for (const localization of subOptionsLocalizations) { + const [language, name] = localization.name; + const [language2, description] = localization.description; + subOption.name_localizations = { + ...subOption.name_localizations, + [language]: name, }; - - const localizations = []; - i18n.getLocales().map((locale) => { - localizations.push(localization(locale, command.name, command.description.content)); - }); - - for (const localization of localizations) { - const [language, name] = localization.name; - const [language2, description] = localization.description; - data.name_localizations = { - ...data.name_localizations, - [language]: name, - }; - data.description_localizations = { - ...data.description_localizations, - [language2]: description, - }; - } - - if (command.options.length > 0) { - command.options.map((option) => { - const optionsLocalizations = []; - i18n.getLocales().map((locale) => { - optionsLocalizations.push(localization(locale, option.name, option.description)); - }); - - for (const localization of optionsLocalizations) { - const [language, name] = localization.name; - const [language2, description] = localization.description; - option.name_localizations = { - ...option.name_localizations, - [language]: name, - }; - option.description_localizations = { - ...option.description_localizations, - [language2]: description, - }; - } - option.description = T(Locale.EnglishUS, option.description); - }); - - data.options.map((option) => { - if ("options" in option && option.options.length > 0) { - option.options.map((subOption) => { - const subOptionsLocalizations = []; - i18n.getLocales().map((locale) => { - subOptionsLocalizations.push(localization(locale, subOption.name, subOption.description)); - }); - - for (const localization of subOptionsLocalizations) { - const [language, name] = localization.name; - const [language2, description] = localization.description; - subOption.name_localizations = { - ...subOption.name_localizations, - [language]: name, - }; - subOption.description_localizations = { - ...subOption.description_localizations, - [language2]: description, - }; - } - subOption.description = T(Locale.EnglishUS, subOption.description); - }); - } - }); - } - this.body.push(data); - } - } + subOption.description_localizations = { + ...subOption.description_localizations, + [language2]: description, + }; + } + subOption.description = T(Locale.EnglishUS, subOption.description); + }); + } + }); + } + this.body.push(data); } + } } + } - public async deployCommands(guildId?: string): Promise { - const route = guildId - ? Routes.applicationGuildCommands(this.user?.id ?? "", guildId) - : Routes.applicationCommands(this.user?.id ?? ""); - - try { - const rest = new REST({ version: "10" }).setToken(this.config.token ?? ""); - await rest.put(route, { body: this.body }); - this.logger.info("Successfully deployed slash commands!"); - } catch (error) { - this.logger.error(error); - } - } + public async deployCommands(guildId?: string): Promise { + const route = guildId ? Routes.applicationGuildCommands(this.user?.id ?? "", guildId) : Routes.applicationCommands(this.user?.id ?? ""); - private async getNodes(): Promise { - const params = new URLSearchParams({ - ssl: "false", - version: "v4", - format: "shoukaku", - }); - const res = await fetch(`https://lavainfo-api.deno.dev/nodes?${params.toString()}`, { - headers: { - "Content-Type": "application/json", - }, - }); - return await res.json(); + try { + const rest = new REST({ version: "10" }).setToken(this.config.token ?? ""); + await rest.put(route, { body: this.body }); + this.logger.info("Successfully deployed slash commands!"); + } catch (error) { + this.logger.error(error); } - - private async loadEvents(): Promise { - const eventsPath = path.join(__dirname, "../events"); - const eventDirs = fs.readdirSync(eventsPath); - - for (const dir of eventDirs) { - const eventFiles = fs.readdirSync(path.join(eventsPath, dir)).filter((file) => file.endsWith(".js")); - - for (const file of eventFiles) { - const eventModule = await import(`../events/${dir}/${file}`); - const event = new eventModule.default(this, file); - - if (dir === "player") { - this.shoukaku.on(event.name, (...args) => event.run(...args)); - } else { - this.on(event.name, (...args) => event.run(...args)); - } - } + } + + private async getNodes(): Promise { + const params = new URLSearchParams({ + ssl: "false", + version: "v4", + format: "shoukaku", + }); + const res = await fetch(`https://lavainfo-api.deno.dev/nodes?${params.toString()}`, { + headers: { + "Content-Type": "application/json", + }, + }); + return await res.json(); + } + + private async loadEvents(): Promise { + const eventsPath = path.join(__dirname, "../events"); + const eventDirs = fs.readdirSync(eventsPath); + + for (const dir of eventDirs) { + const eventFiles = fs.readdirSync(path.join(eventsPath, dir)).filter((file) => file.endsWith(".js")); + + for (const file of eventFiles) { + const eventModule = await import(`../events/${dir}/${file}`); + const event = new eventModule.default(this, file); + + if (dir === "player") { + this.shoukaku.on(event.name, (...args) => event.run(...args)); + } else { + this.on(event.name, (...args) => event.run(...args)); } + } } + } } /** diff --git a/src/structures/Logger.ts b/src/structures/Logger.ts index b097b9cf9..9872cf336 100644 --- a/src/structures/Logger.ts +++ b/src/structures/Logger.ts @@ -2,58 +2,58 @@ import pkg, { type SignaleOptions } from "signale"; const { Signale } = pkg; const options: SignaleOptions = { - disabled: false, - interactive: false, - logLevel: "info", - scope: "Lavamusic", - types: { - info: { - badge: "ℹ", - color: "blue", - label: "info", - }, - warn: { - badge: "⚠", - color: "yellow", - label: "warn", - }, - error: { - badge: "✖", - color: "red", - label: "error", - }, - debug: { - badge: "🐛", - color: "magenta", - label: "debug", - }, - success: { - badge: "✔", - color: "green", - label: "success", - }, - log: { - badge: "📝", - color: "white", - label: "log", - }, - pause: { - badge: "⏸", - color: "yellow", - label: "pause", - }, - start: { - badge: "▶", - color: "green", - label: "start", - }, + disabled: false, + interactive: false, + logLevel: "info", + scope: "Lavamusic", + types: { + info: { + badge: "ℹ", + color: "blue", + label: "info", }, + warn: { + badge: "⚠", + color: "yellow", + label: "warn", + }, + error: { + badge: "✖", + color: "red", + label: "error", + }, + debug: { + badge: "🐛", + color: "magenta", + label: "debug", + }, + success: { + badge: "✔", + color: "green", + label: "success", + }, + log: { + badge: "📝", + color: "white", + label: "log", + }, + pause: { + badge: "⏸", + color: "yellow", + label: "pause", + }, + start: { + badge: "▶", + color: "green", + label: "start", + }, + }, }; export default class Logger extends Signale { - constructor() { - super(options); - } + constructor() { + super(options); + } } /** diff --git a/src/structures/Queue.ts b/src/structures/Queue.ts index 5223677b3..5f1dbcb08 100644 --- a/src/structures/Queue.ts +++ b/src/structures/Queue.ts @@ -3,81 +3,81 @@ import type { LavalinkResponse, Node } from "shoukaku"; import { Dispatcher, type Lavamusic } from "./index.js"; export class Queue extends Map { - public client: Lavamusic; + public client: Lavamusic; - constructor(client: Lavamusic) { - super(); - this.client = client; - } + constructor(client: Lavamusic) { + super(); + this.client = client; + } - public override get(guildId: string): Dispatcher | undefined { - return super.get(guildId); - } + public override get(guildId: string): Dispatcher | undefined { + return super.get(guildId); + } - public override set(guildId: string, dispatcher: Dispatcher): this { - return super.set(guildId, dispatcher); - } + public override set(guildId: string, dispatcher: Dispatcher): this { + return super.set(guildId, dispatcher); + } - public override delete(guildId: string): boolean { - return super.delete(guildId); - } + public override delete(guildId: string): boolean { + return super.delete(guildId); + } - public override clear(): void { - super.clear(); - } + public override clear(): void { + super.clear(); + } - public async create(guild: Guild, voice: any, channel: any, givenNode?: Node): Promise { - if (!voice) throw new Error("No voice channel was provided"); - if (!channel) throw new Error("No text channel was provided"); - if (!guild) throw new Error("No guild was provided"); + public async create(guild: Guild, voice: any, channel: any, givenNode?: Node): Promise { + if (!voice) throw new Error("No voice channel was provided"); + if (!channel) throw new Error("No text channel was provided"); + if (!guild) throw new Error("No guild was provided"); - let dispatcher = this.get(guild.id); - const connection = this.client.shoukaku.connections.get(guild.id); - let player = this.client.shoukaku.players.get(guild.id); - if (player && connection) { - if (!dispatcher) { - dispatcher = new Dispatcher({ - client: this.client, - guildId: guild.id, - channelId: channel.id, - player, - node: player.node, - }); - this.set(guild.id, dispatcher); - } - } else { - const node = givenNode ?? this.client.shoukaku.options.nodeResolver(this.client.shoukaku.nodes); - player = await this.client.shoukaku.joinVoiceChannel({ - guildId: guild.id, - channelId: voice.id, - shardId: guild.shardId, - deaf: true, - }); + let dispatcher = this.get(guild.id); + const connection = this.client.shoukaku.connections.get(guild.id); + let player = this.client.shoukaku.players.get(guild.id); + if (player && connection) { + if (!dispatcher) { + dispatcher = new Dispatcher({ + client: this.client, + guildId: guild.id, + channelId: channel.id, + player, + node: player.node, + }); + this.set(guild.id, dispatcher); + } + } else { + const node = givenNode ?? this.client.shoukaku.options.nodeResolver(this.client.shoukaku.nodes); + player = await this.client.shoukaku.joinVoiceChannel({ + guildId: guild.id, + channelId: voice.id, + shardId: guild.shardId, + deaf: true, + }); - dispatcher = new Dispatcher({ - client: this.client, - guildId: guild.id, - channelId: channel.id, - player, - node, - }); + dispatcher = new Dispatcher({ + client: this.client, + guildId: guild.id, + channelId: channel.id, + player, + node, + }); - this.set(guild.id, dispatcher); - this.client.shoukaku.emit("playerCreate" as any, dispatcher.player); - } - return dispatcher; + this.set(guild.id, dispatcher); + this.client.shoukaku.emit("playerCreate" as any, dispatcher.player); } + return dispatcher; + } - public async search(query: string): Promise { - const node = this.client.shoukaku.options.nodeResolver(this.client.shoukaku.nodes); - const searchQuery = /^https?:\/\//.test(query) ? query : `${this.client.config.searchEngine}:${query}`; - try { - return await node.rest.resolve(searchQuery); - } catch (err) { - console.error("Error during search:", err); - return null; - } + public async search(query: string): Promise { + const node = this.client.shoukaku.options.nodeResolver(this.client.shoukaku.nodes); + const searchQuery = /^https?:\/\//.test(query) ? query : `${this.client.config.searchEngine}:${query}`; + try { + return await node.rest.resolve(searchQuery); + } catch (err) { + console.error("Error during search:", err); + return null; } + } } /** diff --git a/src/structures/Shoukaku.ts b/src/structures/Shoukaku.ts index e74c4bd2e..c4c48f381 100644 --- a/src/structures/Shoukaku.ts +++ b/src/structures/Shoukaku.ts @@ -2,40 +2,40 @@ import { Connectors, type NodeOption, Shoukaku } from "shoukaku"; import type { Lavamusic } from "./index.js"; export default class ShoukakuClient extends Shoukaku { - public client: Lavamusic; - constructor(client: Lavamusic, nodes: NodeOption[]) { - super(new Connectors.DiscordJS(client), nodes, { - resume: true, // Whether to resume a connection on disconnect to Lavalink (Server Side) (Note: DOES NOT RESUME WHEN THE LAVALINK SERVER DIES) - resumeTimeout: 30, - resumeByLibrary: true, // Whether to resume the players by doing it in the library side (Client Side) (Note: TRIES TO RESUME REGARDLESS OF WHAT HAPPENED ON A LAVALINK SERVER) - reconnectTries: 5, - reconnectInterval: 5, - restTimeout: 60, - moveOnDisconnect: false, // Whether to move players to a different Lavalink node when a node disconnects - //voiceConnectionTimeout: 15, - nodeResolver: (nodes) => - [...nodes.values()] - .filter((node) => node.state === 2) - .sort((a, b) => a.penalties - b.penalties) - .shift(), - }); - this.client = client; - this.on("ready", (name, reconnected) => { - this.client.shoukaku.emit(reconnected ? "nodeReconnect" : ("nodeConnect" as any), name); - }); - this.on("error", (name, error) => { - this.client.shoukaku.emit("nodeError" as any, name, error); - }); - this.on("close", (name, code, reason) => { - this.client.shoukaku.emit("nodeDestroy" as any, name, code, reason); - }); - this.on("disconnect", (name, count) => { - this.client.shoukaku.emit("nodeDisconnect" as any, name, count); - }); - this.on("debug", (name, reason) => { - this.client.shoukaku.emit("nodeRaw" as any, name, reason); - }); - } + public client: Lavamusic; + constructor(client: Lavamusic, nodes: NodeOption[]) { + super(new Connectors.DiscordJS(client), nodes, { + resume: true, // Whether to resume a connection on disconnect to Lavalink (Server Side) (Note: DOES NOT RESUME WHEN THE LAVALINK SERVER DIES) + resumeTimeout: 30, + resumeByLibrary: true, // Whether to resume the players by doing it in the library side (Client Side) (Note: TRIES TO RESUME REGARDLESS OF WHAT HAPPENED ON A LAVALINK SERVER) + reconnectTries: 5, + reconnectInterval: 5, + restTimeout: 60, + moveOnDisconnect: false, // Whether to move players to a different Lavalink node when a node disconnects + //voiceConnectionTimeout: 15, + nodeResolver: (nodes) => + [...nodes.values()] + .filter((node) => node.state === 2) + .sort((a, b) => a.penalties - b.penalties) + .shift(), + }); + this.client = client; + this.on("ready", (name, reconnected) => { + this.client.shoukaku.emit(reconnected ? "nodeReconnect" : ("nodeConnect" as any), name); + }); + this.on("error", (name, error) => { + this.client.shoukaku.emit("nodeError" as any, name, error); + }); + this.on("close", (name, code, reason) => { + this.client.shoukaku.emit("nodeDestroy" as any, name, code, reason); + }); + this.on("disconnect", (name, count) => { + this.client.shoukaku.emit("nodeDisconnect" as any, name, count); + }); + this.on("debug", (name, reason) => { + this.client.shoukaku.emit("nodeRaw" as any, name, reason); + }); + } } /** diff --git a/src/types.ts b/src/types.ts index 47fb2b9fe..31af364ae 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,79 +1,79 @@ export enum SearchEngine { - YouTube = "ytsearch", - YouTubeMusic = "ytmsearch", - Spotify = "spsearch", - Deezer = "dzsearch", - Apple = "amsearch", - SoundCloud = "scsearch", - Yandex = "ymsearch", - JioSaavn = "jssearch", + YouTube = "ytsearch", + YouTubeMusic = "ytmsearch", + Spotify = "spsearch", + Deezer = "dzsearch", + Apple = "amsearch", + SoundCloud = "scsearch", + Yandex = "ymsearch", + JioSaavn = "jssearch", } export enum Language { - Bulgarian = "Bulgarian", - ChineseCN = "ChineseCN", - ChineseTW = "ChineseTW", - Croatian = "Croatian", - Czech = "Czech", - Danish = "Danish", - Dutch = "Dutch", - EnglishGB = "EnglishGB", - EnglishUS = "EnglishUS", - Finnish = "Finnish", - French = "French", - German = "German", - Greek = "Greek", - Hindi = "Hindi", - Hungarian = "Hungarian", - Indonesian = "Indonesian", - Italian = "Italian", - Japanese = "Japanese", - Korean = "Korean", - Lithuanian = "Lithuanian", - Norwegian = "Norwegian", - Polish = "Polish", - PortugueseBR = "PortugueseBR", - Romanian = "Romanian", - Russian = "Russian", - SpanishES = "SpanishES", - Swedish = "Swedish", - Thai = "Thai", - Turkish = "Turkish", - Ukrainian = "Ukrainian", - Vietnamese = "Vietnamese", + Bulgarian = "Bulgarian", + ChineseCN = "ChineseCN", + ChineseTW = "ChineseTW", + Croatian = "Croatian", + Czech = "Czech", + Danish = "Danish", + Dutch = "Dutch", + EnglishGB = "EnglishGB", + EnglishUS = "EnglishUS", + Finnish = "Finnish", + French = "French", + German = "German", + Greek = "Greek", + Hindi = "Hindi", + Hungarian = "Hungarian", + Indonesian = "Indonesian", + Italian = "Italian", + Japanese = "Japanese", + Korean = "Korean", + Lithuanian = "Lithuanian", + Norwegian = "Norwegian", + Polish = "Polish", + PortugueseBR = "PortugueseBR", + Romanian = "Romanian", + Russian = "Russian", + SpanishES = "SpanishES", + Swedish = "Swedish", + Thai = "Thai", + Turkish = "Turkish", + Ukrainian = "Ukrainian", + Vietnamese = "Vietnamese", } export const LocaleFlags = { - [Language.Bulgarian]: "🇧🇬", - [Language.ChineseCN]: "🇨🇳", - [Language.ChineseTW]: "🇹🇼", - [Language.Croatian]: "🇭🇷", - [Language.Czech]: "🇨🇿", - [Language.Danish]: "🇩🇰", - [Language.Dutch]: "🇳🇱", - [Language.EnglishGB]: "🇬🇧", - [Language.EnglishUS]: "🇺🇸", - [Language.Finnish]: "🇫🇮", - [Language.French]: "🇫🇷", - [Language.German]: "🇩🇪", - [Language.Greek]: "🇬🇷", - [Language.Hindi]: "🇮🇳", - [Language.Hungarian]: "🇭🇺", - [Language.Indonesian]: "🇮🇩", - [Language.Italian]: "🇮🇹", - [Language.Japanese]: "🇯🇵", - [Language.Korean]: "🇰🇷", - [Language.Lithuanian]: "🇱🇹", - [Language.Norwegian]: "🇳🇴", - [Language.Polish]: "🇵🇱", - [Language.PortugueseBR]: "🇧🇷", - [Language.Romanian]: "🇷🇴", - [Language.Russian]: "🇷🇺", - [Language.SpanishES]: "🇪🇸", - [Language.Swedish]: "🇸🇪", - [Language.Thai]: "🇹🇭", - [Language.Turkish]: "🇹🇷", - [Language.Ukrainian]: "🇺🇦", - [Language.Vietnamese]: "🇻🇳", + [Language.Bulgarian]: "🇧🇬", + [Language.ChineseCN]: "🇨🇳", + [Language.ChineseTW]: "🇹🇼", + [Language.Croatian]: "🇭🇷", + [Language.Czech]: "🇨🇿", + [Language.Danish]: "🇩🇰", + [Language.Dutch]: "🇳🇱", + [Language.EnglishGB]: "🇬🇧", + [Language.EnglishUS]: "🇺🇸", + [Language.Finnish]: "🇫🇮", + [Language.French]: "🇫🇷", + [Language.German]: "🇩🇪", + [Language.Greek]: "🇬🇷", + [Language.Hindi]: "🇮🇳", + [Language.Hungarian]: "🇭🇺", + [Language.Indonesian]: "🇮🇩", + [Language.Italian]: "🇮🇹", + [Language.Japanese]: "🇯🇵", + [Language.Korean]: "🇰🇷", + [Language.Lithuanian]: "🇱🇹", + [Language.Norwegian]: "🇳🇴", + [Language.Polish]: "🇵🇱", + [Language.PortugueseBR]: "🇧🇷", + [Language.Romanian]: "🇷🇴", + [Language.Russian]: "🇷🇺", + [Language.SpanishES]: "🇪🇸", + [Language.Swedish]: "🇸🇪", + [Language.Thai]: "🇹🇭", + [Language.Turkish]: "🇹🇷", + [Language.Ukrainian]: "🇺🇦", + [Language.Vietnamese]: "🇻🇳", }; /** diff --git a/src/utils/BotLog.ts b/src/utils/BotLog.ts index 612d7db77..74dc3f1ff 100644 --- a/src/utils/BotLog.ts +++ b/src/utils/BotLog.ts @@ -2,24 +2,24 @@ import type { TextChannel } from "discord.js"; import type { Lavamusic } from "../structures/index.js"; export default class BotLog { - public static send(client: Lavamusic, message: string, type: "error" | "warn" | "info" | "success" = "info"): void { - if (!client?.channels.cache && client.config.logChannelId) return; + public static send(client: Lavamusic, message: string, type: "error" | "warn" | "info" | "success" = "info"): void { + if (!client?.channels.cache && client.config.logChannelId) return; - const channel = client.channels.cache.get(client.config.logChannelId!) as TextChannel; - if (!channel) return; + const channel = client.channels.cache.get(client.config.logChannelId!) as TextChannel; + if (!channel) return; - const colors = { - error: 0xff0000, - warn: 0xffff00, - info: 0x00ff00, - success: 0x00ff00, - } as const; + const colors = { + error: 0xff0000, + warn: 0xffff00, + info: 0x00ff00, + success: 0x00ff00, + } as const; - const color = colors[type]; - const embed = client.embed().setColor(color).setDescription(message).setTimestamp(); + const color = colors[type]; + const embed = client.embed().setColor(color).setDescription(message).setTimestamp(); - channel.send({ embeds: [embed] }).catch(() => {}); - } + channel.send({ embeds: [embed] }).catch(() => {}); + } } /** diff --git a/src/utils/Buttons.ts b/src/utils/Buttons.ts index d9d46d3f2..b1febb7a7 100644 --- a/src/utils/Buttons.ts +++ b/src/utils/Buttons.ts @@ -2,74 +2,74 @@ import { ActionRowBuilder, ButtonBuilder, ButtonStyle, type EmojiIdentifierResol import type { Dispatcher, Lavamusic } from "../structures/index.js"; function getButtons(player: Dispatcher, client: Lavamusic): ActionRowBuilder[] { - const buttonData = [ - { - customId: "REWIND_BUT", - emoji: client.emoji.replay, - style: ButtonStyle.Secondary, - }, - { - customId: "LOW_VOL_BUT", - emoji: client.emoji.voldown, - style: ButtonStyle.Secondary, - }, - { - customId: "STOP_BUT", - emoji: client.emoji.stop, - style: ButtonStyle.Danger, - }, - { - customId: "HIGH_VOL_BUT", - emoji: client.emoji.volup, - style: ButtonStyle.Secondary, - }, - { - customId: "FORWARD_BUT", - emoji: client.emoji.forward, - style: ButtonStyle.Secondary, - }, - { - customId: "PREV_BUT", - emoji: client.emoji.previous, - style: ButtonStyle.Secondary, - }, - { - customId: "LOOP_BUT", - emoji: client.emoji.loop.none, - style: ButtonStyle.Secondary, - }, - { - customId: "PAUSE_BUT", - emoji: player?.paused ? client.emoji.resume : client.emoji.pause, - style: player?.paused ? ButtonStyle.Success : ButtonStyle.Secondary, - }, - { - customId: "SHUFFLE_BUT", - emoji: client.emoji.shuffle, - style: ButtonStyle.Secondary, - }, - { - customId: "SKIP_BUT", - emoji: client.emoji.skip, - style: ButtonStyle.Secondary, - }, - ]; + const buttonData = [ + { + customId: "PREV_BUT", + emoji: client.emoji.previous, + style: ButtonStyle.Secondary, + }, + { + customId: "REWIND_BUT", + emoji: client.emoji.rewind, + style: ButtonStyle.Secondary, + }, + { + customId: "PAUSE_BUT", + emoji: player?.paused ? client.emoji.resume : client.emoji.pause, + style: player?.paused ? ButtonStyle.Success : ButtonStyle.Secondary, + }, + { + customId: "FORWARD_BUT", + emoji: client.emoji.forward, + style: ButtonStyle.Secondary, + }, + { + customId: "SKIP_BUT", + emoji: client.emoji.skip, + style: ButtonStyle.Secondary, + }, + { + customId: "LOW_VOL_BUT", + emoji: client.emoji.voldown, + style: ButtonStyle.Secondary, + }, + { + customId: "LOOP_BUT", + emoji: client.emoji.loop.none, + style: ButtonStyle.Secondary, + }, + { + customId: "STOP_BUT", + emoji: client.emoji.stop, + style: ButtonStyle.Danger, + }, + { + customId: "SHUFFLE_BUT", + emoji: client.emoji.shuffle, + style: ButtonStyle.Secondary, + }, + { + customId: "HIGH_VOL_BUT", + emoji: client.emoji.volup, + style: ButtonStyle.Secondary, + }, + ]; - return buttonData.reduce((rows, { customId, emoji, style }, index) => { - if (index % 5 === 0) rows.push(new ActionRowBuilder()); + return buttonData.reduce((rows, { customId, emoji, style }, index) => { + if (index % 5 === 0) rows.push(new ActionRowBuilder()); - let emojiFormat: EmojiIdentifierResolvable; - if (typeof emoji === "string" && emoji.startsWith("<:")) { - const match = emoji.match(/^<:\w+:(\d+)>$/); - emojiFormat = match ? match[1] : emoji; - } else { - emojiFormat = emoji; - } + let emojiFormat: EmojiIdentifierResolvable; + if (typeof emoji === "string" && emoji.startsWith("<:")) { + const match = emoji.match(/^<:\w+:(\d+)>$/); + emojiFormat = match ? match[1] : emoji; + } else { + emojiFormat = emoji; + } - const button = new ButtonBuilder().setCustomId(customId).setEmoji(emojiFormat).setStyle(style); - rows[rows.length - 1].addComponents(button); - return rows; - }, [] as ActionRowBuilder[]); + const button = new ButtonBuilder().setCustomId(customId).setEmoji(emojiFormat).setStyle(style); + rows[rows.length - 1].addComponents(button); + return rows; + }, [] as ActionRowBuilder[]); } export { getButtons }; diff --git a/src/utils/SetupSystem.ts b/src/utils/SetupSystem.ts index 452d2d0d4..fc80e1cf4 100644 --- a/src/utils/SetupSystem.ts +++ b/src/utils/SetupSystem.ts @@ -6,340 +6,338 @@ import type { Dispatcher, Lavamusic } from "../structures/index.js"; import { getButtons } from "./Buttons.js"; function neb(embed: EmbedBuilder, player: Dispatcher, client: Lavamusic, locale: string): EmbedBuilder { - if (!player?.current?.info) return embed; - const iconUrl = client.config.icons[player.current.info.sourceName] || client.user.displayAvatarURL({ extension: "png" }); - const icon = player.current.info.artworkUrl || client.config.links.img; + if (!player?.current?.info) return embed; + const iconUrl = client.config.icons[player.current.info.sourceName] || client.user.displayAvatarURL({ extension: "png" }); + const icon = player.current.info.artworkUrl || client.config.links.img; - const description = T(locale, "player.setupStart.description", { - title: player.current.info.title, - uri: player.current.info.uri, - author: player.current.info.author, - length: client.utils.formatTime(player.current.info.length), - requester: player.current.info.requester, - }); - return embed - .setAuthor({ - name: T(locale, "player.setupStart.now_playing"), - iconURL: iconUrl, - }) - .setDescription(description) - .setImage(icon) - .setColor(client.color.main); + const description = T(locale, "player.setupStart.description", { + title: player.current.info.title, + uri: player.current.info.uri, + author: player.current.info.author, + length: client.utils.formatTime(player.current.info.length), + requester: player.current.info.requester, + }); + return embed + .setAuthor({ + name: T(locale, "player.setupStart.now_playing"), + iconURL: iconUrl, + }) + .setDescription(description) + .setImage(icon) + .setColor(client.color.main); } async function setupStart(client: Lavamusic, query: string, player: Dispatcher, message: Message): Promise { - let m: Message; - const embed = client.embed(); - const n = client.embed().setColor(client.color.main); - const data = await client.db.getSetup(message.guild.id); - const locale = await client.db.getLanguage(message.guildId); + let m: Message; + const embed = client.embed(); + const n = client.embed().setColor(client.color.main); + const data = await client.db.getSetup(message.guild.id); + const locale = await client.db.getLanguage(message.guildId); + try { + if (data) + m = await message.channel.messages.fetch({ + message: data.messageId, + cache: true, + }); + } catch (error) { + client.logger.error(error); + } + if (m) { try { - if (data) - m = await message.channel.messages.fetch({ - message: data.messageId, - cache: true, - }); - } catch (error) { - client.logger.error(error); - } - if (m) { - try { - if (message.inGuild()) { - const res = await client.queue.search(query); - switch (res.loadType) { - case LoadType.ERROR: - await message.channel - .send({ - embeds: [embed.setColor(client.color.red).setDescription(T(locale, "player.setupStart.error_searching"))], - }) - .then((msg) => setTimeout(() => msg.delete(), 5000)); - break; - case LoadType.EMPTY: - await message.channel - .send({ - embeds: [embed.setColor(client.color.red).setDescription(T(locale, "player.setupStart.no_results"))], - }) - .then((msg) => setTimeout(() => msg.delete(), 5000)); - break; - case LoadType.TRACK: { - const track = player.buildTrack(res.data, message.author); - if (player.queue.length > client.config.maxQueueSize) { - await message.channel - .send({ - embeds: [ - embed.setColor(client.color.red).setDescription( - T(locale, "player.setupStart.queue_too_long", { - maxQueueSize: client.config.maxQueueSize, - }), - ), - ], - }) - .then((msg) => setTimeout(() => msg.delete(), 5000)); - return; - } - player.queue.push(track); - await player.isPlaying(); - await message.channel - .send({ - embeds: [ - embed.setColor(client.color.main).setDescription( - T(locale, "player.setupStart.added_to_queue", { - title: res.data.info.title, - uri: res.data.info.uri, - }), - ), - ], - }) - .then((msg) => setTimeout(() => msg.delete(), 5000)); - neb(n, player, client, locale); - await m.edit({ embeds: [n] }).catch(() => {}); - break; - } - case LoadType.PLAYLIST: - if (res.data.tracks.length > client.config.maxPlaylistSize) { - await message.channel - .send({ - embeds: [ - embed.setColor(client.color.red).setDescription( - T(locale, "player.setupStart.playlist_too_long", { - maxPlaylistSize: client.config.maxPlaylistSize, - }), - ), - ], - }) - .then((msg) => setTimeout(() => msg.delete(), 5000)); - return; - } - for (const track of res.data.tracks) { - const pl = player.buildTrack(track, message.author); - if (player.queue.length > client.config.maxQueueSize) { - await message.channel - .send({ - embeds: [ - embed.setColor(client.color.red).setDescription( - T(locale, "player.setupStart.queue_too_long", { - maxQueueSize: client.config.maxQueueSize, - }), - ), - ], - }) - .then((msg) => setTimeout(() => msg.delete(), 5000)); - return; - } - player.queue.push(pl); - } - await player.isPlaying(); - await message.channel - .send({ - embeds: [ - embed - .setColor(client.color.main) - .setDescription( - T(locale, "player.setupStart.added_playlist_to_queue", { length: res.data.tracks.length }), - ), - ], - }) - .then((msg) => setTimeout(() => msg.delete(), 5000)); - neb(n, player, client, locale); - await m.edit({ embeds: [n] }).catch(() => {}); - break; - case LoadType.SEARCH: { - const track = player.buildTrack(res.data[0], message.author); - if (player.queue.length > client.config.maxQueueSize) { - await message.channel - .send({ - embeds: [ - embed.setColor(client.color.red).setDescription( - T(locale, "player.setupStart.queue_too_long", { - maxQueueSize: client.config.maxQueueSize, - }), - ), - ], - }) - .then((msg) => setTimeout(() => msg.delete(), 5000)); - return; - } - player.queue.push(track); - await player.isPlaying(); - await message.channel - .send({ - embeds: [ - embed.setColor(client.color.main).setDescription( - T(locale, "player.setupStart.added_to_queue", { - title: res.data[0].info.title, - uri: res.data[0].info.uri, - }), - ), - ], - }) - .then((msg) => setTimeout(() => msg.delete(), 5000)); - neb(n, player, client, locale); - await m.edit({ embeds: [n] }).catch(() => {}); - break; - } - } + if (message.inGuild()) { + const res = await client.queue.search(query); + switch (res.loadType) { + case LoadType.ERROR: + await message.channel + .send({ + embeds: [embed.setColor(client.color.red).setDescription(T(locale, "player.setupStart.error_searching"))], + }) + .then((msg) => setTimeout(() => msg.delete(), 5000)); + break; + case LoadType.EMPTY: + await message.channel + .send({ + embeds: [embed.setColor(client.color.red).setDescription(T(locale, "player.setupStart.no_results"))], + }) + .then((msg) => setTimeout(() => msg.delete(), 5000)); + break; + case LoadType.TRACK: { + const track = player.buildTrack(res.data, message.author); + if (player.queue.length > client.config.maxQueueSize) { + await message.channel + .send({ + embeds: [ + embed.setColor(client.color.red).setDescription( + T(locale, "player.setupStart.queue_too_long", { + maxQueueSize: client.config.maxQueueSize, + }), + ), + ], + }) + .then((msg) => setTimeout(() => msg.delete(), 5000)); + return; + } + player.queue.push(track); + await player.isPlaying(); + await message.channel + .send({ + embeds: [ + embed.setColor(client.color.main).setDescription( + T(locale, "player.setupStart.added_to_queue", { + title: res.data.info.title, + uri: res.data.info.uri, + }), + ), + ], + }) + .then((msg) => setTimeout(() => msg.delete(), 5000)); + neb(n, player, client, locale); + await m.edit({ embeds: [n] }).catch(() => {}); + break; + } + case LoadType.PLAYLIST: + if (res.data.tracks.length > client.config.maxPlaylistSize) { + await message.channel + .send({ + embeds: [ + embed.setColor(client.color.red).setDescription( + T(locale, "player.setupStart.playlist_too_long", { + maxPlaylistSize: client.config.maxPlaylistSize, + }), + ), + ], + }) + .then((msg) => setTimeout(() => msg.delete(), 5000)); + return; } - } catch (error) { - client.logger.error(error); + for (const track of res.data.tracks) { + const pl = player.buildTrack(track, message.author); + if (player.queue.length > client.config.maxQueueSize) { + await message.channel + .send({ + embeds: [ + embed.setColor(client.color.red).setDescription( + T(locale, "player.setupStart.queue_too_long", { + maxQueueSize: client.config.maxQueueSize, + }), + ), + ], + }) + .then((msg) => setTimeout(() => msg.delete(), 5000)); + return; + } + player.queue.push(pl); + } + await player.isPlaying(); + await message.channel + .send({ + embeds: [ + embed + .setColor(client.color.main) + .setDescription(T(locale, "player.setupStart.added_playlist_to_queue", { length: res.data.tracks.length })), + ], + }) + .then((msg) => setTimeout(() => msg.delete(), 5000)); + neb(n, player, client, locale); + await m.edit({ embeds: [n] }).catch(() => {}); + break; + case LoadType.SEARCH: { + const track = player.buildTrack(res.data[0], message.author); + if (player.queue.length > client.config.maxQueueSize) { + await message.channel + .send({ + embeds: [ + embed.setColor(client.color.red).setDescription( + T(locale, "player.setupStart.queue_too_long", { + maxQueueSize: client.config.maxQueueSize, + }), + ), + ], + }) + .then((msg) => setTimeout(() => msg.delete(), 5000)); + return; + } + player.queue.push(track); + await player.isPlaying(); + await message.channel + .send({ + embeds: [ + embed.setColor(client.color.main).setDescription( + T(locale, "player.setupStart.added_to_queue", { + title: res.data[0].info.title, + uri: res.data[0].info.uri, + }), + ), + ], + }) + .then((msg) => setTimeout(() => msg.delete(), 5000)); + neb(n, player, client, locale); + await m.edit({ embeds: [n] }).catch(() => {}); + break; + } } + } + } catch (error) { + client.logger.error(error); } + } } async function trackStart( - msgId: any, - channel: TextChannel, - player: Dispatcher, - track: Song, - client: Lavamusic, - locale: string, + msgId: any, + channel: TextChannel, + player: Dispatcher, + track: Song, + client: Lavamusic, + locale: string, ): Promise { - const icon = player.current ? player.current.info.artworkUrl : client.config.links.img; - let m: Message; + const icon = player.current ? player.current.info.artworkUrl : client.config.links.img; + let m: Message; + + try { + m = await channel.messages.fetch({ message: msgId, cache: true }); + } catch (error) { + client.logger.error(error); + } + + const iconUrl = client.config.icons[player.current.info.sourceName] || client.user.displayAvatarURL({ extension: "png" }); + const description = T(locale, "player.setupStart.description", { + title: track.info.title, + uri: track.info.uri, + author: track.info.author, + length: client.utils.formatTime(track.info.length), + requester: track.info.requester, + }); + + const embed = client + .embed() + .setAuthor({ + name: T(locale, "player.setupStart.now_playing"), + iconURL: iconUrl, + }) + .setColor(client.color.main) + .setDescription(description) + .setImage(icon); + if (m) { + await m + .edit({ + embeds: [embed], + components: getButtons(player, client).map((b) => { + b.components.forEach((c) => c.setDisabled(!player?.current)); + return b; + }), + }) + .catch(() => {}); + } else { + await channel + .send({ + embeds: [embed], + components: getButtons(player, client).map((b) => { + b.components.forEach((c) => c.setDisabled(!player?.current)); + return b; + }), + }) + .then((msg) => { + client.db.setSetup(msg.guild.id, msg.id, msg.channel.id); + }) + .catch(() => {}); + } +} + +async function updateSetup(client: Lavamusic, guild: any, locale: string): Promise { + const setup = await client.db.getSetup(guild.id); + let m: Message; + if (setup?.textId) { + const textChannel = guild.channels.cache.get(setup.textId) as TextChannel; + if (!textChannel) return; try { - m = await channel.messages.fetch({ message: msgId, cache: true }); + m = await textChannel.messages.fetch({ + message: setup.messageId, + cache: true, + }); } catch (error) { - client.logger.error(error); + client.logger.error(error); } + } + if (m) { + const player = client.queue.get(guild.id); + if (player?.current) { + const iconUrl = client.config.icons[player.current.info.sourceName] || client.user.displayAvatarURL({ extension: "png" }); + const description = T(locale, "player.setupStart.description", { + title: player.current.info.title, + uri: player.current.info.uri, + author: player.current.info.author, + length: client.utils.formatTime(player.current.info.length), + requester: player.current.info.requester, + }); - const iconUrl = client.config.icons[player.current.info.sourceName] || client.user.displayAvatarURL({ extension: "png" }); - const description = T(locale, "player.setupStart.description", { - title: track.info.title, - uri: track.info.uri, - author: track.info.author, - length: client.utils.formatTime(track.info.length), - requester: track.info.requester, - }); - - const embed = client + const embed = client .embed() .setAuthor({ - name: T(locale, "player.setupStart.now_playing"), - iconURL: iconUrl, + name: T(locale, "player.setupStart.now_playing"), + iconURL: iconUrl, }) .setColor(client.color.main) .setDescription(description) - .setImage(icon); - - if (m) { - await m - .edit({ - embeds: [embed], - components: getButtons(player, client).map((b) => { - b.components.forEach((c) => c.setDisabled(!player?.current)); - return b; - }), - }) - .catch(() => {}); + .setImage(player.current.info.artworkUrl); + await m + .edit({ + embeds: [embed], + components: getButtons(player, client).map((b) => { + b.components.forEach((c) => c.setDisabled(!player?.current)); + return b; + }), + }) + .catch(() => {}); } else { - await channel - .send({ - embeds: [embed], - components: getButtons(player, client).map((b) => { - b.components.forEach((c) => c.setDisabled(!player?.current)); - return b; - }), - }) - .then((msg) => { - client.db.setSetup(msg.guild.id, msg.id, msg.channel.id); - }) - .catch(() => {}); - } -} - -async function updateSetup(client: Lavamusic, guild: any, locale: string): Promise { - const setup = await client.db.getSetup(guild.id); - let m: Message; - if (setup?.textId) { - const textChannel = guild.channels.cache.get(setup.textId) as TextChannel; - if (!textChannel) return; - try { - m = await textChannel.messages.fetch({ - message: setup.messageId, - cache: true, - }); - } catch (error) { - client.logger.error(error); - } - } - if (m) { - const player = client.queue.get(guild.id); - if (player?.current) { - const iconUrl = client.config.icons[player.current.info.sourceName] || client.user.displayAvatarURL({ extension: "png" }); - const description = T(locale, "player.setupStart.description", { - title: player.current.info.title, - uri: player.current.info.uri, - author: player.current.info.author, - length: client.utils.formatTime(player.current.info.length), - requester: player.current.info.requester, - }); - - const embed = client - .embed() - .setAuthor({ - name: T(locale, "player.setupStart.now_playing"), - iconURL: iconUrl, - }) - .setColor(client.color.main) - .setDescription(description) - .setImage(player.current.info.artworkUrl); - await m - .edit({ - embeds: [embed], - components: getButtons(player, client).map((b) => { - b.components.forEach((c) => c.setDisabled(!player?.current)); - return b; - }), - }) - .catch(() => {}); - } else { - const embed = client - .embed() - .setColor(client.color.main) - .setAuthor({ - name: client.user.username, - iconURL: client.user.displayAvatarURL({ extension: "png" }), - }) - .setDescription(T(locale, "player.setupStart.nothing_playing")) - .setImage(client.config.links.img); - await m - .edit({ - embeds: [embed], - components: getButtons(player, client).map((b) => { - b.components.forEach((c) => c.setDisabled(true)); - return b; - }), - }) - .catch(() => {}); - } + const embed = client + .embed() + .setColor(client.color.main) + .setAuthor({ + name: client.user.username, + iconURL: client.user.displayAvatarURL({ extension: "png" }), + }) + .setDescription(T(locale, "player.setupStart.nothing_playing")) + .setImage(client.config.links.img); + await m + .edit({ + embeds: [embed], + components: getButtons(player, client).map((b) => { + b.components.forEach((c) => c.setDisabled(true)); + return b; + }), + }) + .catch(() => {}); } + } } async function buttonReply(int: any, args: string, color: ColorResolvable): Promise { - const embed = new EmbedBuilder(); - let m: Message; - if (int.replied) { - m = await int.editReply({ embeds: [embed.setColor(color).setDescription(args)] }).catch(() => {}); - } else { - m = await int.followUp({ embeds: [embed.setColor(color).setDescription(args)] }).catch(() => {}); + const embed = new EmbedBuilder(); + let m: Message; + if (int.replied) { + m = await int.editReply({ embeds: [embed.setColor(color).setDescription(args)] }).catch(() => {}); + } else { + m = await int.followUp({ embeds: [embed.setColor(color).setDescription(args)] }).catch(() => {}); + } + setTimeout(async () => { + if (int && !int.ephemeral) { + await m.delete().catch(() => {}); } - setTimeout(async () => { - if (int && !int.ephemeral) { - await m.delete().catch(() => {}); - } - }, 2000); + }, 2000); } async function oops(channel: TextChannel, args: string): Promise { - try { - const embed1 = new EmbedBuilder().setColor("Red").setDescription(`${args}`); - const m = await channel.send({ - embeds: [embed1], - }); - setTimeout(async () => await m.delete().catch(() => {}), 12000); - } catch (e) { - return console.error(e); - } + try { + const embed1 = new EmbedBuilder().setColor("Red").setDescription(`${args}`); + const m = await channel.send({ + embeds: [embed1], + }); + setTimeout(async () => await m.delete().catch(() => {}), 12000); + } catch (e) { + return console.error(e); + } } export { setupStart, trackStart, buttonReply, updateSetup, oops }; diff --git a/src/utils/ThemeSelector.ts b/src/utils/ThemeSelector.ts index eb00e3140..109a8833e 100644 --- a/src/utils/ThemeSelector.ts +++ b/src/utils/ThemeSelector.ts @@ -1,77 +1,77 @@ export class ThemeSelector { - /** - * Applies a yellow fire effect to the text. - * - * @param text - The input text to apply the effect to. - * @returns The processed text with the green fire effect. - */ - fire(text: string): string { - let fade = ""; - let green = 250; + /** + * Applies a yellow fire effect to the text. + * + * @param text - The input text to apply the effect to. + * @returns The processed text with the green fire effect. + */ + fire(text: string): string { + let fade = ""; + let green = 250; - for (const line of text.split("\n")) { - fade += `\x1b[38;2;255;${green};0m${line}\x1b[0m\n`; - green = Math.max(0, green - 25); - } - - return fade; + for (const line of text.split("\n")) { + fade += `\x1b[38;2;255;${green};0m${line}\x1b[0m\n`; + green = Math.max(0, green - 25); } - /** - * Applies a purple neon effect to the text. - * - * @param text - The input text to apply the effect to. - * @returns The processed text with the purple neon effect. - */ - purpleNeon(text: string): string { - let fade = ""; - let purple = 255; + return fade; + } - for (const line of text.split("\n")) { - fade += `\x1b[38;2;255;0;${purple}m${line}\x1b[0m\n`; - purple = Math.max(0, purple - 25); - } + /** + * Applies a purple neon effect to the text. + * + * @param text - The input text to apply the effect to. + * @returns The processed text with the purple neon effect. + */ + purpleNeon(text: string): string { + let fade = ""; + let purple = 255; - return fade; + for (const line of text.split("\n")) { + fade += `\x1b[38;2;255;0;${purple}m${line}\x1b[0m\n`; + purple = Math.max(0, purple - 25); } - /** - * Applies a cyan effect to the text. - * - * @param text - The input text to apply the effect to. - * @returns The processed text with the cyan effect. - */ - cyan(text: string): string { - let fade = ""; - let blue = 100; + return fade; + } - for (const line of text.split("\n")) { - fade += `\x1b[38;2;0;255;${blue}m${line}\x1b[0m\n`; - if (blue < 255) { - blue = Math.min(255, blue + 15); - } - } + /** + * Applies a cyan effect to the text. + * + * @param text - The input text to apply the effect to. + * @returns The processed text with the cyan effect. + */ + cyan(text: string): string { + let fade = ""; + let blue = 100; - return fade; + for (const line of text.split("\n")) { + fade += `\x1b[38;2;0;255;${blue}m${line}\x1b[0m\n`; + if (blue < 255) { + blue = Math.min(255, blue + 15); + } } - /** - * Applies a water effect to the text. - * - * @param text - The input text to apply the effect to. - * @returns The processed text with the water effect. - */ - water(text: string): string { - let fade = ""; - let green = 255; + return fade; + } - for (const line of text.split("\n")) { - fade += `\x1b[38;2;0;${green};255m${line}\x1b[0m\n`; - if (green > 30) { - green = Math.max(30, green - 40); - } - } + /** + * Applies a water effect to the text. + * + * @param text - The input text to apply the effect to. + * @returns The processed text with the water effect. + */ + water(text: string): string { + let fade = ""; + let green = 255; - return fade; + for (const line of text.split("\n")) { + fade += `\x1b[38;2;0;${green};255m${line}\x1b[0m\n`; + if (green > 30) { + green = Math.max(30, green - 40); + } } + + return fade; + } } diff --git a/src/utils/Utils.ts b/src/utils/Utils.ts index 6b59296ce..6c64eb1b2 100644 --- a/src/utils/Utils.ts +++ b/src/utils/Utils.ts @@ -3,165 +3,165 @@ import config from "../config.js"; import type { Context, Lavamusic } from "../structures/index.js"; export class Utils { - public static formatTime(ms: number): string { - const minuteMs = 60 * 1000; - const hourMs = 60 * minuteMs; - const dayMs = 24 * hourMs; - if (ms < minuteMs) return `${ms / 1000}s`; - if (ms < hourMs) return `${Math.floor(ms / minuteMs)}m ${Math.floor((ms % minuteMs) / 1000)}s`; - if (ms < dayMs) return `${Math.floor(ms / hourMs)}h ${Math.floor((ms % hourMs) / minuteMs)}m`; - return `${Math.floor(ms / dayMs)}d ${Math.floor((ms % dayMs) / hourMs)}h`; + public static formatTime(ms: number): string { + const minuteMs = 60 * 1000; + const hourMs = 60 * minuteMs; + const dayMs = 24 * hourMs; + if (ms < minuteMs) return `${ms / 1000}s`; + if (ms < hourMs) return `${Math.floor(ms / minuteMs)}m ${Math.floor((ms % minuteMs) / 1000)}s`; + if (ms < dayMs) return `${Math.floor(ms / hourMs)}h ${Math.floor((ms % hourMs) / minuteMs)}m`; + return `${Math.floor(ms / dayMs)}d ${Math.floor((ms % dayMs) / hourMs)}h`; + } + + public static updateStatus(client: Lavamusic, guildId?: string): void { + const { user } = client; + if (user && guildId === config.guildId) { + const player = client.queue.get(config.guildId!); + user.setPresence({ + activities: [ + { + name: player?.current ? `🎶 | ${player.current.info.title}` : config.botActivity, + type: player?.current ? ActivityType.Listening : config.botActivityType, + }, + ], + status: config.botStatus as any, + }); } + } - public static updateStatus(client: Lavamusic, guildId?: string): void { - const { user } = client; - if (user && guildId === config.guildId) { - const player = client.queue.get(config.guildId!); - user.setPresence({ - activities: [ - { - name: player?.current ? `🎶 | ${player.current.info.title}` : config.botActivity, - type: player?.current ? ActivityType.Listening : config.botActivityType, - }, - ], - status: config.botStatus as any, - }); - } + public static chunk(array: any[], size: number): any[] { + const chunked_arr = []; + for (let index = 0; index < array.length; index += size) { + chunked_arr.push(array.slice(index, size + index)); } - - public static chunk(array: any[], size: number): any[] { - const chunked_arr = []; - for (let index = 0; index < array.length; index += size) { - chunked_arr.push(array.slice(index, size + index)); - } - return chunked_arr; - } - - public static formatBytes(bytes: number, decimals = 2): string { - if (bytes === 0) return "0 Bytes"; - const k = 1024; - const dm = decimals < 0 ? 0 : decimals; - const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; - const i = Math.floor(Math.log(bytes) / Math.log(k)); - return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`; + return chunked_arr; + } + + public static formatBytes(bytes: number, decimals = 2): string { + if (bytes === 0) return "0 Bytes"; + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`; + } + + public static formatNumber(number: number): string { + return number.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,"); + } + + public static parseTime(string: string): number { + const time = string.match(/([0-9]+[d,h,m,s])/g); + if (!time) return 0; + let ms = 0; + for (const t of time) { + const unit = t[t.length - 1]; + const amount = Number(t.slice(0, -1)); + if (unit === "d") ms += amount * 24 * 60 * 60 * 1000; + else if (unit === "h") ms += amount * 60 * 60 * 1000; + else if (unit === "m") ms += amount * 60 * 1000; + else if (unit === "s") ms += amount * 1000; } - - public static formatNumber(number: number): string { - return number.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,"); - } - - public static parseTime(string: string): number { - const time = string.match(/([0-9]+[d,h,m,s])/g); - if (!time) return 0; - let ms = 0; - for (const t of time) { - const unit = t[t.length - 1]; - const amount = Number(t.slice(0, -1)); - if (unit === "d") ms += amount * 24 * 60 * 60 * 1000; - else if (unit === "h") ms += amount * 60 * 60 * 1000; - else if (unit === "m") ms += amount * 60 * 1000; - else if (unit === "s") ms += amount * 1000; - } - return ms; + return ms; + } + + public static progressBar(current: number, total: number, size = 20): string { + const percent = Math.round((current / total) * 100); + const filledSize = Math.round((size * current) / total); + const filledBar = "▓".repeat(filledSize); + const emptyBar = "░".repeat(size - filledSize); + return `${filledBar}${emptyBar} ${percent}%`; + } + + public static async paginate(client: Lavamusic, ctx: Context, embed: any[]): Promise { + if (embed.length < 2) { + if (ctx.isInteraction) { + ctx.deferred ? ctx.interaction.followUp({ embeds: embed }) : ctx.interaction.reply({ embeds: embed }); + return; + } + + (ctx.channel as TextChannel).send({ embeds: embed }); + return; } - public static progressBar(current: number, total: number, size = 20): string { - const percent = Math.round((current / total) * 100); - const filledSize = Math.round((size * current) / total); - const filledBar = "▓".repeat(filledSize); - const emptyBar = "░".repeat(size - filledSize); - return `${filledBar}${emptyBar} ${percent}%`; - } - - public static async paginate(client: Lavamusic, ctx: Context, embed: any[]): Promise { - if (embed.length < 2) { - if (ctx.isInteraction) { - ctx.deferred ? ctx.interaction.followUp({ embeds: embed }) : ctx.interaction.reply({ embeds: embed }); - return; - } - - (ctx.channel as TextChannel).send({ embeds: embed }); - return; - } - - let page = 0; - const getButton = (page: number): any => { - const firstEmbed = page === 0; - const lastEmbed = page === embed.length - 1; - const pageEmbed = embed[page]; - const first = new ButtonBuilder() - .setCustomId("first") - .setEmoji(client.emoji.page.first) - .setStyle(ButtonStyle.Primary) - .setDisabled(firstEmbed); - const back = new ButtonBuilder() - .setCustomId("back") - .setEmoji(client.emoji.page.back) - .setStyle(ButtonStyle.Primary) - .setDisabled(firstEmbed); - const next = new ButtonBuilder() - .setCustomId("next") - .setEmoji(client.emoji.page.next) - .setStyle(ButtonStyle.Primary) - .setDisabled(lastEmbed); - const last = new ButtonBuilder() - .setCustomId("last") - .setEmoji(client.emoji.page.last) - .setStyle(ButtonStyle.Primary) - .setDisabled(lastEmbed); - const stop = new ButtonBuilder().setCustomId("stop").setEmoji(client.emoji.page.cancel).setStyle(ButtonStyle.Danger); - const row = new ActionRowBuilder().addComponents(first, back, stop, next, last); - return { embeds: [pageEmbed], components: [row] }; - }; - - const msgOptions = getButton(0); - const msg = ctx.isInteraction - ? await (ctx.deferred - ? ctx.interaction!.followUp({ - ...msgOptions, - fetchReply: true as boolean, - }) - : ctx.interaction!.reply({ ...msgOptions, fetchReply: true })) - : await (ctx.channel as TextChannel).send({ - ...msgOptions, - fetchReply: true, - }); - - const author = ctx instanceof CommandInteraction ? ctx.user : ctx.author; - - const filter = (int: any): any => int.user.id === author.id; - const collector = msg.createMessageComponentCollector({ - filter, - time: 60000, + let page = 0; + const getButton = (page: number): any => { + const firstEmbed = page === 0; + const lastEmbed = page === embed.length - 1; + const pageEmbed = embed[page]; + const first = new ButtonBuilder() + .setCustomId("first") + .setEmoji(client.emoji.page.first) + .setStyle(ButtonStyle.Primary) + .setDisabled(firstEmbed); + const back = new ButtonBuilder() + .setCustomId("back") + .setEmoji(client.emoji.page.back) + .setStyle(ButtonStyle.Primary) + .setDisabled(firstEmbed); + const next = new ButtonBuilder() + .setCustomId("next") + .setEmoji(client.emoji.page.next) + .setStyle(ButtonStyle.Primary) + .setDisabled(lastEmbed); + const last = new ButtonBuilder() + .setCustomId("last") + .setEmoji(client.emoji.page.last) + .setStyle(ButtonStyle.Primary) + .setDisabled(lastEmbed); + const stop = new ButtonBuilder().setCustomId("stop").setEmoji(client.emoji.page.cancel).setStyle(ButtonStyle.Danger); + const row = new ActionRowBuilder().addComponents(first, back, stop, next, last); + return { embeds: [pageEmbed], components: [row] }; + }; + + const msgOptions = getButton(0); + const msg = ctx.isInteraction + ? await (ctx.deferred + ? ctx.interaction!.followUp({ + ...msgOptions, + fetchReply: true as boolean, + }) + : ctx.interaction!.reply({ ...msgOptions, fetchReply: true })) + : await (ctx.channel as TextChannel).send({ + ...msgOptions, + fetchReply: true, }); - collector.on("collect", async (interaction) => { - if (interaction.user.id === author.id) { - await interaction.deferUpdate(); - if (interaction.customId === "first" && page !== 0) { - page = 0; - } else if (interaction.customId === "back" && page !== 0) { - page--; - } else if (interaction.customId === "stop") { - collector.stop(); - } else if (interaction.customId === "next" && page !== embed.length - 1) { - page++; - } else if (interaction.customId === "last" && page !== embed.length - 1) { - page = embed.length - 1; - } - await interaction.editReply(getButton(page)); - } else { - await interaction.reply({ - content: ctx.locale("buttons.errors.not_author"), - ephemeral: true, - }); - } + const author = ctx instanceof CommandInteraction ? ctx.user : ctx.author; + + const filter = (int: any): any => int.user.id === author.id; + const collector = msg.createMessageComponentCollector({ + filter, + time: 60000, + }); + + collector.on("collect", async (interaction) => { + if (interaction.user.id === author.id) { + await interaction.deferUpdate(); + if (interaction.customId === "first" && page !== 0) { + page = 0; + } else if (interaction.customId === "back" && page !== 0) { + page--; + } else if (interaction.customId === "stop") { + collector.stop(); + } else if (interaction.customId === "next" && page !== embed.length - 1) { + page++; + } else if (interaction.customId === "last" && page !== embed.length - 1) { + page = embed.length - 1; + } + await interaction.editReply(getButton(page)); + } else { + await interaction.reply({ + content: ctx.locale("buttons.errors.not_author"), + ephemeral: true, }); + } + }); - collector.on("end", async () => { - await msg.edit({ embeds: [embed[page]], components: [] }); - }); - } + collector.on("end", async () => { + await msg.edit({ embeds: [embed[page]], components: [] }); + }); + } } /** diff --git a/tsconfig.json b/tsconfig.json index c9bb34f27..d3cbf1fd6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,11 @@ { "compilerOptions": { - "target": "EsNext", - "module": "EsNext", - "lib": ["EsNext"], + "target": "esnext", + "module": "esnext", + "lib": ["esnext"], "declaration": true, "sourceMap": true, + "newLine": "crlf", "outDir": "dist", "rootDir": "src", "strict": false,